c6
is a toy compiler for an imperative, JavaScirpt-like language. Implemented with flex
and bison
, it targets the stack machine simulator nas2
.
c6
supports loops, multi-dimensional arrays, and functions. It does not support break;
or continue;
statements inside loops yet, but these features may be readily implemented with minimal effort.
There is a hard limit on the number of global data (variable and arrays), local data (w.r.t. functions), and functions. One may declare at most
c6
implements no optimization and garbage collection at all.
$ make nas2.o # build stack machine simulator
$ make c6c.o # build compiler
$ ./c6c.o test/array.sc > test/array.nas2 # compile c6 program
$ ./nas2.o test/array.nas2 # run c6 executable on stack machine
One may also replace test/array.sc
above with his/her own program.
c6
uses
Array | Description |
---|---|
tables[100][100] |
The symbol table, a.k.a. data environment. tables[0][0..99] is for the global scope, and each of the remaining corresponds to a new function. All calls of a recursive function that invokes itself repeatedly share |
symIndex[100] |
Maximum index of symbols per scope. symIndex[i] marks the number of variables and arrays in the |
funcs[100] |
The function environment. funcs[1..99] are functions while funcs[0] is not in use. |
- Use only alphanumeric characters for identifiers of variables. Underscores, such as
comp_3235
, are not allowed. -
c6
is interger-only. Do not use floating-point numbers. - Do not declare arrays and variables with an identical name within a single scope.
c6
does not check duplicate error. For instance, the following is allowed.
However, the code below is invalid.array foo[3] = 0; … func boo() { array foo[2] = 1; @foo[0] = foo[1] + @foo[2]; }
Despite the above,array foo[3] = 0; … foo = 1;
c6
does support variable-array duality, i.e., a variablefoo
is equivalent to an array of size$1$ . When we later access it, eitherfoo
orfoo[0,0,…,0]
works. -
c6
does not check out-of-index or axis mismatch error. Always write the correct code.
Suppose an array is declared asarray a[3,2,3,5];
, then neithera[3,2,5,9] = …
nora[1,1,1,1,1]
works. - Do not update an array entry with
get…(a[…]);
orget…(@a[…])
; always use an assignment statementa[…] = …;
. - Do not declare too many large arrays. The global scope can hold a maximum of
$100$ variables/arrays with$500$ memory cells. - Do not declare singleton arrays.
array a[1] = 3259;
is neither valid nor meaningful. -
c6
does not support dynamic array declaration.x = 1; y = 2; array z[x + y, x * y];
is invalid; always use concrete dimensions:array z[3, 2];
. -
c6
implements static scoping, i.e., the function is bound to the data environment at the time of function definition. If there is global variable access within a function, then the global variable must be declared before the function is declared. - Do not define a function twice.
- Do not define a function with a different parameter list or body.
The repository is organized as follows.
./
├──nas2/
│ ├── nas2.md
│ ├── nas2.l
│ └── nas2.y
├── calc3.h
├── c6.l
├── c6.y
├── c6c.c
├── makefile
└── test/
├── array.sc
├── bb1.sc
├── bb2.sc
└── bb3.sc
nas2/
contains the stack machine simulator. c6.*
is the compiler frontend; c6c.c
is the backend. test/
contains sample c6
programs.
nas2
is a stack machine simulator used in COMP3235 Compiling techinuqes by the University of Hong Kong. See the doc for details.
c6
extends calc3
, a calculator interpreter in Lex and Yacc by Tom Niemann. Building c6
was assignment 3 of COMP3235.