This project is an end-to-end compiler for the While-like Academy Compiler Construction (WACC) programming language. The compiler translates WACC code into x86-64(intel syntax) assembly, enabling execution on x86-based architectures.
- Introduction
- Features
- Prerequisites
- Building the Compiler
- Running the Compiler
- Project Structure
- Web Frontend
- Testing
WACC is a teaching language used at Imperial College London, based on the While family of languages. This compiler project was developed as part of the second-year curriculum to provide hands-on experience in compiler construction.
- Lexical Analysis: Tokenizes WACC source code.
- Syntax Analysis: Parses tokens to verify grammatical structure.
- Semantic Analysis: Ensures semantic correctness, including type checking.
- Code Generation: Produces x86 assembly code from WACC source.
- Error Handling: Provides meaningful error messages for syntax and semantic errors.
- Scala: Ensure Scala is installed on your system.
- x86 Architecture/Emulator: This project compiles .wacc programs to x86 assembly. Hence, you won't be able to run programs on ARM architecture (and neither will the integration tests).
- Using Main.scala: You can run programs through the Main.scala pipeline by using scala-cli:
scala run . --"<PATH-TO-WACC-PROGRAM>"
The interface includes sample code to get you started:
begin
int x = 5;
println x
end
begin
int[] arr = [1, 2, 3, 4, 5];
println "Array length: ";
println len arr;
println "First element: ";
println arr[0]
end
begin
int add(int x, int y) is
return x + y
end
int result = call add(10, 20);
println "Result: ";
println result
end
You can browse even more of these in wacc-examples.
-
src/main/: Contains the source code for the compiler, organized into various subdirectories based on functionality:-
frontend/: Includes code responsible for parsing .wacc programs into an Abstract Syntax Treesyntax/: Code handling the syntactical analysis of .wacc programs.semantic/: Code handling the semantic analysis of .wacc programs, including scope and type checking.error/: Error handling and formatting libraries for the front-end.
-
backend/: Includes code responsible for generating assembly code based on the internal representation generated by the front-end.assemblyIR/: Classes/traits for an internal representation tree that represents an assembly program.codeGen/: Code handling the conversion from an Abstract Syntax Tree to the AssemblyIR.formatting/: Code handling the conversion from Internal Representation to assembly files.
-
-
src/test/: Unit and integration tests for the frontend and backend. -
wacc-examples/: Provides example WACC programs for testing and demonstration purposes. -
web-server/: A modern web interface for the WACC compiler.package.json: Node.js dependencies and project configurationserver.js: Express backend server that handles compilation requestspublic/: Frontend static filesindex.html: Main web interfacestyles.css: Modern CSS styling with responsive designscript.js: JavaScript functionality for the web interface
temp/: Temporary files created during compilation (auto-generated)
This project also includes a web interface which can be run locally. You can write WACC code in your browser and see the compiled x86 assembly output in real-time.
- Node.js (v14 or higher)
- WACC compiler properly set up (main project)
- Scala environment properly configured
-
Navigate to the web frontend directory:
cd web-server -
Install dependencies:
npm install
-
Start the server:
npm start
-
Open your browser and navigate to
http://localhost:3000
This uses nodemon to automatically restart the server when files change.
-
Using testSettings.scala: You can comment / uncomment specific test cases in testSettings.scala. Then you can run:
scala test .
Commented test cases will be marked as 'pending'.
-
Using a pattern matcher: You can alternatively run specific tests by specifying a pattern to look for in the test paths.To do this use the --test-only flag followed by a pattern.
scala test . --test-only "<PATTERN>"
For example, to run myTest.scala, this is sufficient:
scala test . --test-only "*myTest*"
-
Using the web server for development: You can use the local webserver to see your changes in realtime with auto restard by running the node server in dev mode.
npm run dev