You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: docs/assembler_directives.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -12,4 +12,4 @@ In the [`scripts/test.py`](../scripts/test.py) script, when running testcases, t
12
12
13
13
The below picture offers a quick walk-through of a very simple program with detailed annotations describing the meaning behind the included directives. Some of them a crucial (e.g. section specifiers, labels, data emitting) while others not so much (e.g. file attributes, compiler identifier, symbol types) - you will get a feel for them during the development of the compiler. Most importantly, you only need to set the correct section and provide function directives as long as you deal with local variables. **In other words, you can postpone studying this document in details until you decide to deal with global variables.**
Copy file name to clipboardexpand all lines: docs/basic_compiler.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@ int f() {
10
10
11
11
The compiler is able to traverse the following AST related to the above program. In order to expand its capabilities, you should develop the parser and the corresponding code generation at the same time -- you are advised not to fully implement one before the other.
The lexer and parser are loosely based on the "official" grammar covered [here](https://www.lysator.liu.se/c/ANSI-C-grammar-l.html) and [here](https://www.lysator.liu.se/c/ANSI-C-grammar-y.html) respectively. While they should suffice for a significant portions of features, you might need to improve them to implement the more advanced ones. If you find the grammar too complicated to understand, it is also perfectly fine to create your own simple grammar and build upon it as you add more features.
Copy file name to clipboardexpand all lines: docs/c_compiler.md
+16-26
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,11 @@
1
-
Main coursework: A compiler for the C language
2
-
==============================================
1
+
# Main coursework: A compiler for the C language
3
2
4
3
Your program should read C source code from a given file, and write corresponding RISC-V assembly to another given file.
5
4
6
-
Environment
7
-
-----------
5
+
## Environment
8
6
[How to set up your environment?](./environment_guide.md)
9
7
10
-
Developing your compiler
11
-
------------------------
8
+
## Developing your compiler
12
9
13
10
If you wish to use C++, then a basic framework for building your compiler has been provided. You are strongly recommended to check out its structure [here](./basic_compiler.md).
14
11
@@ -56,8 +53,7 @@ By default, the first [`_example/example.c`](../compiler_tests/_example/example.
56
53
57
54
This basic framework is only able to compile a very simple program, as described [here](./basic_compiler.md).
58
55
59
-
Program build and execution
60
-
---------------------------
56
+
## Program build and execution
61
57
62
58
Your program should be built by running the following command in the top-level directory of your repo:
63
59
@@ -73,8 +69,7 @@ The compilation function is invoked using the flag `-S`, with the source file an
73
69
74
70
You can assume that the command-line (CLI) arguments will always be in this order, and that there will be no spaces in source or destination paths. Note that the provided starting point in this repository already functions as specified above, so these CLI arguments should work out of the box (unless you decide not to use the provided base compiler).
75
71
76
-
Input
77
-
-----
72
+
## Input
78
73
79
74
The input file will be pre-processed [ANSI C](https://en.wikipedia.org/wiki/ANSI_C), also called C90 or C89. It is what is generally thought of as "classic" or "normal" C, but not the _really_ old one without function prototypes (you may never have come across that). C90 is still often used in embedded systems, and pretty much the entire Linux kernel is in C90.
80
75
@@ -84,8 +79,7 @@ The source code will not contain any compiler-specific or platform-specific exte
84
79
85
80
The test inputs will be a set of files of increasing complexity and variety. The test inputs will not have syntax errors or other programming errors, so your code does not need to handle these gracefully.
86
81
87
-
Features
88
-
-------
82
+
## Features
89
83
90
84
Here is a list of basic features that you might like to implement first.
91
85
@@ -117,7 +111,7 @@ Here is a list of more advanced features like you might like to implement once t
117
111
* calling externally-defined functions (i.e. the file being compiled declares a function, but its definition is provided in a different file that is linked in later on)
118
112
* functions that take more than 8 parameters
119
113
* mutually recursive function calls
120
-
* locally scoped variable declarations (e.g. a variable that is declared inside the body of a while loop, such as `while(...) { int x = ...; ... }`.
114
+
* locally scoped variable declarations (e.g. a variable that is declared inside the body of a while loop, such as `while(...) { int x = ...; ... }`).
121
115
* the `typedef` keyword
122
116
* the `sizeof(...)` function (which takes either a type or a variable)
123
117
* taking the address of a variable using the `&` operator
@@ -145,19 +139,17 @@ Here is a (partial) list of features that will not be tested.
145
139
* the `void` type is not tested explicitly, but it appears in some helper functions in the test cases, so your compiler cannot break when it encounters this keyword
146
140
* the `static` keyword
147
141
148
-
Test cases
149
-
----------
142
+
## Test cases
150
143
151
144
All test inputs will be valid; that is, you can assume the absence of programmer errors like syntax faults, type mismatches, and array out-of-bounds errors. The entire compilation and testing process (including compilation, assembly, linking, and RISC-V simulation) is expected to complete within ten seconds per program (which should be plenty of time!), and is expected not to use an inordinate amount of memory or disk space. There is no requirement for the generated assembly to be optimised in any way -- the only requirement is that it produces the correct answer.
152
145
153
146
The [compiler_tests](../compiler_tests) contains a large number of example inputs, divided into various categories, that you might like to use as testcases. Your compiler will be assessed on these "seen" inputs together with a further set of "unseen" inputs that are of a similar form. It is worth emphasising that it is not expected that many compilers will correctly compile all of the "seen" inputs (let alone the "unseen" ones!). You are encouraged to focus on compiling the "basic" features (as listed above) first, before moving on to more advanced features if you have time.
154
147
155
148
The split between test cases last year can be seen below. Do not assume it will stay the same this year, but you can use it as a rough estimate of what to focus on in case you are running short on time. **Remember that tests for advanced features will also test basic features, so you should implement the basic features first (e.g. without working functions the array tests will fail).**
@@ -206,12 +198,10 @@ I then use spike to simulate the executable on RISC-V, like so:
206
198
207
199
This command should produce the exit code `0`.
208
200
209
-
Assembler directives
210
-
---------------
201
+
## Assembler directives
211
202
[You will need to consider assembler directives in your output](./assembler_directives.md)
212
203
213
-
Useful links
214
-
------------
204
+
## Useful links
215
205
*[Godbolt](https://godbolt.org/z/vMMnWbsff) - Great tool for viewing what a real (`gcc` in this case) RISC-V compiler would produce for a given snippet of C code. This link is pre-configured for the correct architecture (`RV32IMFD`) and ABI (`ILP32D`) that the coursework targets. Code optimisation is also disabled to best mimic what you might want your compiler to output. You can replicate Godbolt locally by running `riscv64-unknown-elf-gcc -std=c90 -pedantic -ansi -O0 -march=rv32imfd -mabi=ilp32d -S [source-file.c] -o [dest-file.s]`, which might make debugging and directives analysis easier for some.
216
206
217
207
*[Interactive RISC-V simulator](https://creatorsim.github.io/creator) - Might be helpful when trying to work out the behaviour of certain instructions that Godbolt emits.
@@ -222,10 +212,10 @@ Useful links
222
212
223
213
*[RISC-V Assembler Reference](https://michaeljclark.github.io/asm.html) - Very useful resource containing information about structuring your output assembly files and most importantly the assembler directives - if you don't know the meaning behind `.data`, `.text`, or `.word` then definitely check this out as well as experiment with Godbolt to see how it actually emits them.
224
214
225
-
Getting started
226
-
---------------
215
+
## Getting started
227
216
[How to get started? (previous students' perspectives)](./starting_guide.md)
228
217
229
-
Coverage information
230
-
-----------
218
+
## Coverage information
231
219
[Do you want to know which part of your code is executed when running your compiler on a file?](./coverage.md)
Copy file name to clipboardexpand all lines: docs/coverage.md
+2-3
Original file line number
Diff line number
Diff line change
@@ -1,11 +1,10 @@
1
-
Coverage information
2
-
====================
1
+
# Coverage information
3
2
4
3
If you want to know which part of your code is executed when running your compiler on a file you can run your compiler on the file, then run `make coverage`.
5
4
6
5
This will generate a webpage `coverage/index.html` with a listing of all the source files and for each source file a listing of the number of times each line has been executed.
0 commit comments