Skip to content
/ compiler Public

A C89 (ANSI C) Compiler to MIPS assembly, including a custom built bytecode interpreter & stack simulator.

Notifications You must be signed in to change notification settings

1rre/compiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C Compiler

Compiling from source

run make bin/c_compiler

Compilation to MIPS

From ANSI C

A C source file can be compiled to MIPS assembly using the -S switch, such as in bin/c_compiler -S <file>`.

From SegFault Bytecode

A Segfault bytecode file can be compiled to MIPS assembly using the -ir and -S switches together, such as in bin/c_compiler -ir -S <file>.

Directing Output

Mips code can be output to a file using the -o <output_file> switch, such as in bin/c_compiler -S <input_file> -o <output_file>

Debug Mode

Debug mode can be enabled using the -d switch, and prints the AST & IR before generating the assembly. It also prints the raw representation of the assembly before it is printed.

Compilation to SegFault Bytecode

From ANSI C

A C source file can be compiled to SegFault Bytecode using the -ir switch, such as in bin/c_compiler -ir <input_file>.

Bytecode interpreter

An interpreter for SegFault bytecode with a working stack has been included in the compiler. === Normal Mode The interpreter can be run using the -vm switch & takes a single C source file & runs the last function in the file, calling it with any integer arguments supplied on the command line, such as in bin/c_compiler -vm <input_file> <arg1> …​.

Debug Mode

The debug output can be enabled with the -d switch. This prints the state of the stack & registers, next instruction to be executed & the type of each data value, along with a few other useful insights which can be used when testing the compilation of C programs to the IR.

Testing

A test script, test.sh, has been included which will run any tests 1 subdirectory deep in the compiler_tests folder. An indication is given as to whether the test passed or failed, and if it failed a reason is given. The percentage of tests passed is printed at the end of testing.

IR Syntax

Global Statements

Syntax Usage

{function,<type>,<name>,<args>,<st>}

Define a function name (identifier) with return type type, args args (list of types), defining it as st (scoped statement list).

{global,<type>,<name>,<data>}

Declare a global variable name (identifier) with type type & initialise it to data (either local or data statement).

Data Statements

Syntax Usage

{data,<type>,<init>}

Initialises a static space in the program data at compile time for type & initialises that space to init (in the form reference level, type, width)

{local,<data>}

Declare a subsection of an array (as stated in an initialiser list) & initialise it to data (data statement list).

Scoped Statements

Syntax Usage

{address,<rs>,<rd>}

Finds the memory location of the object in rs (register or stack) & stores a pointer to it in rd (register)

{allocate,<n>}

Allocate n (integer) bits on the stack

{call,<fn>,<ar>,<ra>}

Call fn (function) with ar (integer) arguments contiguous from ra (stack)

{cast,<ra>,<type>}

Advises the compiler of a variable’s type (in the form reference level, type, width) of a variable which would otherwise be incorrectly inferred, such as char c = 5l;[{move,{i,5},<rd>}, {cast,<rd>,{0,i,8>}]

{gc,<n>}

Trim the local stack to n (integer) items & delete any associated data in the heap.

{jump,<lb>}

Unconditionally jump to lb (label)

{label,<lb>}

Create lb (label) which can be jumped to using test

{load,<rs>,<rd>}

Finds the memory location pointed to by rs (register or stack) & stores the value in rd (register)

{move,<data>,<rd>}

Copy the value of data (register, stack or immediate) to rd (register or stack)

return

Return the value in register 0 to the calling function (this is fine for all functions as return value of void functions is undefined)

{store,<rs>,<rd>}

Stores the value in rs (register) in the memory location pointed to by rd (register)

{test,<ra>,<lb>}

Branch to lb (label) if the value in ra is 0

{<op>,[<ra>,<rb>],<rd>}

Perform the operation specified in op (BIF) on ra (register) and rb (register), storing the result in rd (register)

Arguments

Argument Meaning

{x,<n>}

Register n (integer), given an infinite register system

{y,<n>}

The nth (integer) item on the current function’s part of the stack, which is mapped to an address

{z,<n>}

The nth argument to a function

{i,<n>}

A literal with value n (integer).

{g,<str>}

A global variable with name str (string). (subject to change as it hasn’t yet been implemented)

{f,<N>}

A literal with value n (float)

{l,<N>}

The label n (integer), numbering is global, however only labels within the same function are valid.

{<p>,<t>,<s>}

A type with "reference level" p (integer), ie how many levels of dereferencing would be required to get the actual object, type t (char: f for float, i for int and n for void, which is only used internally), and width s (integer), which refers to the width of type t rather than any memory address.

About

A C89 (ANSI C) Compiler to MIPS assembly, including a custom built bytecode interpreter & stack simulator.

Topics

Resources

Stars

Watchers

Forks

Languages