AtomC-Compiler is an educational compiler project designed to translate and execute AtomC, a simplified subset of the C programming language. The project follows the fundamental stages of compiler construction, culminating in a stack-based virtual machine (VM) that executes the generated code.
The compilation process is divided into seven distinct activities, each handling a specific layer of translation and analysis:
- Purpose: Groups individual characters from the source code into atomic units called tokens (e.g., numbers, identifiers, operators).
- Implementation: Uses a
tokenizefunction to iterate through the source code and build a linked list ofTokenstructures. - Cleanup: Removes non-essential elements like white spaces and comments.
- Algorithm: Implements Recursive Descent Analysis (ASDR).
- Process: Transposes the formal grammar into a series of boolean functions that consume tokens based on language rules.
- Refinement: Includes the elimination of left recursion to prevent infinite loops during parsing.
- Symbol Table (TS): Organized as a stack of domains to handle nested scopes.
- Scope Management: Tracks global and local variables, function parameters, and structure members.
- Validation: Detects incorrect symbol redefinitions.
- Semantic Rules: Verifies that expressions and instructions adhere to AtomC semantic constraints.
- L-values vs. R-values: Distinguishes between expressions that represent memory addresses (left-values) and those that represent simple values (right-values).
- Type Synthesis: Propagates data types through expressions to ensure compatibility (e.g., operations between
intanddouble).
- Minimalist Approach: Injects semantic actions into the syntactic rules to generate instructions for the VM.
- Stack Logic: Generates instructions for loading addresses (
FPADDR), dereferencing (LOAD), and storing values (STORE).
The execution environment is a stack-based virtual machine.
- Instruction Set: Includes operations such as
OP_PUSH,OP_POP,OP_CALL,OP_HALT, and arithmetic comparisons likeLESS.i. - Universal Values: The stack uses a
Valstructure capable of storing any supported AtomC data type. - External Functions: Supports pre-defined internal functions (e.g.,
put_i,put_d) to facilitate I/O operations.
- Recursive Descent Parser: Manual implementation without external generator tools.
- Scope & Type Safety: Full validation of variable visibility and operation compatibility.
- Execution: Native VM execution with instruction tracing for debugging.
- Rust (stable toolchain)
cargo buildFor an optimized release build:
cargo build --releasecargo runcargo run -- <input_file> [output_file]
cargo run -- parser/test_parser_code_example.c parser/lexer_output.txtThe release binary is available at target/release/atomc_compiler after a release build.
cargo testTo see output from passing tests as well:
cargo test -- --nocapturecargo fmt # auto-format code
cargo clippy # lint and catch common mistakes