mcc
Another MicroC compiler. This used to be a fork of the reference compiler for Columbia's Programming Languages and Translators course, but has since grown to include very important C features such as pointers and structs. The original can be found at https://github.com/cwabbott0/microc-llvm. Students in the class are allowed to write the compiler for their own final semester project in OCaml or Haskell, but since the provided reference compiler is in OCaml, almost no one chooses Haskell. This project is an attempt to remedy that situation and open the possibility of using Haskell to more students. The compat
branch of the repo has only features that are present in the original repo, whereas master has some additions, such as pointers, structs, bitwise operators and an exponentiation operator that demonstrates how to link llvm intrinsic functions. For comparison, two separate parsers are provided, one recursive descent parser implemented with Megaparsec and one more classical LR-style parser implemented with Alex and Happy, Haskell's analogues to the venerable lex and yacc. The test suite checks that they return identical parse trees for identical valid source files, although for files which fail to parse correctly, they do not emit the same error messages.
Setup
Note: As of March 2020, the recommended setup for hacking on mcc
is to just use nix. Running nix-shell --pure
at the root of the project should drop you into a shell that has the right versions of ghc, llvm, clang, and all the libraries that mcc
depends on. The default.nix
file included is pinned to a particular nixpkgs commit, so hopefully this will continue to be true in perpetuity. To run the test suite, nix-shell --pure --run 'cabal new-test'
should do. Using stack to build mcc
is no longer supported, as I don't use it anymore. The legacy instructions below are included for posterity.
Legacy Setup
mcc
requires the stack
package manager for Haskell. To install stack
, see https://docs.haskellstack.org/en/stable/README/. It also requires that clang
and llc
binaries be available in your PATH. There are two options to ensure that these will be available:
- Use Nix:
Using
stack
'snix
integration will set up a local environment with the correct versions ofclang
andllc
installed and added to the PATH. To acquire nix, follow the installation instructions. Nix is enabled by default, so simply runningstack test
should work if everything is nix and stack are installed correctly. - Manual Installation:
To install the
llvm
toolchain, which includesllc
,clang
, and a host of other compiler tools, go to http://releases.llvm.org/download.html#6.0.1. For macOS, the maintainers of the Haskell-LLVM bindings provide a brew tap, so runningbrew install llvm-hs/llvm/llvm-6.0
and adding/usr/local/opt/llvm/bin
to your$PATH
should be sufficient. They also provide more detailed instructions on how to install llvm on other platforms. Note that unlike the OCaml version of MicroC, this project requires LLVM 6, not LLVM 3.4. To use stack commands without nix integration, pass the--no-nix
flag to them.
Running and testing the compiler
Once everything is installed, to run the compiler's test suite, navigate to the project home directory and run stack test
. To build compiler executable, run stack build mcc
. Remember to add --no-nix
to these commands if you would like to disable nix
integration.
Questions, contributions
Please don't hesitate to open an issue or pull request if you don't understand something in here or you see something that could be improved! Once most of the functionality is complete, I'm planning on releasing a detailed walkthrough on the whole compilation process in a series of posts, but until then, documentation is very sparse.