A toy C compiler
Clone or download
Latest commit 12b3c17 Oct 6, 2015
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
c99 Tidying. Jul 11, 2014
test_programs Ensure we use a fresh context when compiling each function. Jan 24, 2015
.clang-format Using clang-format to standardise formatting. Jan 10, 2015
.gitignore Ignore TAGS files. Aug 25, 2014
.travis.yml Removing Coverity, I can't see how to make it work currently. Jan 6, 2015
Makefile Factoring out context management and ensuring we free it. Jan 24, 2015
README.md Documenting the yacc version. Oct 6, 2015
assembly.c Factoring out context management and ensuring we free it. Jan 24, 2015
assembly.h Separating out a header for assembly.c. Jul 28, 2014
babyc_lex.l Don't use the undefined `error`. Should help with #4. May 15, 2015
babyc_parse.y Ensure we parse function arguments. Jan 25, 2015
context.c Factoring out context management and ensuring we free it. Jan 24, 2015
context.h Factoring out context management and ensuring we free it. Jan 24, 2015
environment.c Adding clarifying comment. Jan 24, 2015
environment.h Defining an environment datatype. Aug 24, 2014
link Ensure our linked binaries are always 32-bit. Aug 2, 2014
link_and_run Print the return code in link_and_run. Jul 20, 2014
list.c Using clang-format to standardise formatting. Jan 10, 2015
list.h Using clang-format to standardise formatting. Jan 10, 2015
main.c Print unparsed stack, rather than just saying its size. Jan 25, 2015
run_tests.c Using clang-format to standardise formatting. Jan 10, 2015
stack.c Using clang-format to standardise formatting. Jan 10, 2015
stack.h Adding a stack_empty predicate function. Aug 10, 2014
syntax.c Fixing another memory leak. Jan 24, 2015
syntax.h Using clang-format to standardise formatting. Jan 10, 2015

README.md

Babyc

Build Status

An educational foray into compiler writing. Written in C, compiling C to x86 assembly (handy x86 reference site, assembly directives reference, System V ABI reference).

Technically targetting C11 (standard PDF), but we will implement such a small subset of C that it's academic.

Table of Contents

Current feature set

  • positive integers (no other types yet)
  • integer constants
  • logical negation (!FOO)
  • bitwise negation (~FOO)
  • addition (foo + bar)
  • subtraction (foo - bar binary only)
  • multiplication (foo * bar)
  • less than comparison (foo < bar, foo <= bar)
  • comments (// foo and /* foo */)
  • sequences of statements (foo; bar)
  • return statements
  • if statements (if (foo) { bar }, no else yet)
  • local variables (int only, function scope only, must be initialised)
  • variable assignment (int only)
  • while loops (while (foo) { bar })
  • function calls (only int foo() i.e. no arguments, returning int)
  • preprocessor usage (we shell out to gcc)

License

GPL v2 license.

Usage

You will need clang, lex and yacc installed. GNU Bison is known to work, other yacc implementations may not.

Compiling babyc:

# Compile the compiler.
$ make

Usage:

# Run it, producing an assembly file.
$ build/babyc test_programs/immediate__return_1.c
# Use the GNU toolchain to assemble and link.
$ ./link

Viewing the code after preprocessing:

$ build/babyc --dump-expansion test_programs/if_false__return_2.c

Viewing the AST:

$ build/babyc --dump-ast test_programs/if_false__return_2.c

Running tests:

$ make test

Debugging

If you're debugging a compiled program that segfaults, you may want to simply read the out.s file.

To use gdb (given we have no signal table, function prologues or other conveniences), do the following:

$ gdb out
(gdb) run
... it segfaults
(gdb) layout asm
... shows which line the segfault occurred on
(gdb) info registers
... shows the current state of the registers (`layout reg' also
... provides this data)

If you want to debug a program that doesn't segfault, you can set a breakpoint to the entrypoint:

$ gdb out
(gdb) info files
    ...
    Entry point: 0x80000000
    ...
(gdb) break *0x80000000
(gdb) run

Improving code quality

The make command will generate warnings, fix them. You can also run with clang-analyzer to catch further issues:

$ scan-build make

For code formatting, run:

$ make format