An interpreter for a subset of C. Based off the interpreter for the Calculator language modified from js-slang.
- Install Node.js.
- Install the Yarn package manager.
- Install the project dependencies by running
yarnin the project root directory:
The interpreter can be run by passing in a program string, a path to a program, or a name of an existing test case in the /src/__tests__ directory.
First, ensure that you build the project by running yarn build in the project root directory.
$ yarn buildRun the interpreter with a program string by passing s or string followed by the program string:
$ yarn start s <program-string-here>For example, running the following command should result in a program that exits with a return code of 3.
$ yarn start string 'main() { int x = 1; int y = 2; return x + y; }'Indeed, the program outputs the following:
The program exited with return code 3.Run the interpreter with a program file by passing f or file followed by the path to the program file:
$ yarn start f <path-to-program-file-here>For example, we have included a presentation.c file in the project root directory that should takes an integer n from stdin and prints out the n-th fibonacci number.
$ yarn start f presentation.c
10Indeed, it prints out the following:
55
The program exited with return code 55.We have an extensive test suite with over 100 test cases. You can also run them in individually in the interpreter by passing the name of the test case directly.
$ yarn start <test-case-name-here>Our test cases are all stored in the /src/__tests__ directory. As an example, we have a test case called strlen stored in the /src/__tests__/general.ts, which computes the length of the string "Hello, world!". We can run it like so:
$ yarn start strlenIndeed, the program outputs the following:
The program exited with return code 13.where 13 is the length of the string "Hello, world!".
As mentioned in the Usage section, we have an extensive test suite. Test cases are stored in /src/__tests__, but some test utilities are stored in /src/utils/.
Most test cases are unit tests that test the functionality of individual interpreter features. However, we also have some integration tests that test the general code that one might write in a typical code base; these are stored in /src/__tests__/general.ts.
You can run the entire test suite by running the following command:
$ yarn testSome of the test cases might output to stdout, which is expected. However, if you want to suppress the output, you can run the following command instead:
$ yarn test --silentThe typical dev workflow is:
- Run
yarn devto start the watcher that auto-compiles any changes. - Code your changes in
src/and add test cases insrc/__tests__/. - Run
yarn <test utility> <test case name>to test your changes.
yarn parser-testruns the parser and outputs the AST.yarn analyser-testruns the parser and static analyser.yarn interpreter-testtakes as input an AST and runs the interpreter.yarn runner-testtests the entire evaluator, including the parser, type checker, and interpreter.
- Run
yarn testto run the entire test suite and ensure that your changes did not break anything. - Repeat steps 2 and 3.
There are two main ways that we used to merge our changes into main:
- Before starting development, rebase your branch on top of
main(to ensure that you have synced all the changes from main) - Code and create your commits
git mergeyour commits tomainlocally without the merge commitgit pushthemainbranch
Example workflow:
git checkout ownBranch→git fetch main→git rebase maingit checkout main→git merge ownBranch
Same as above, up until step 2.
git pushyour branch- On GitHub, create a PR from your branch to
mainand add change notes. - Merge the pull request without the merge commit.