Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/further_test_improvements'
Browse files Browse the repository at this point in the history
  • Loading branch information
Fiwo735 committed Feb 21, 2024
2 parents ed4f15d + 4b7bbb0 commit eed378d
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 166 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
id: test
timeout-minutes: 1
run: |
./scripts/test.sh
python -m pip install colorama && ./scripts/test.py
- name: Perm issue fix
if: success() || failure()
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ RUN ../configure --prefix=$RISCV --host=riscv64-unknown-elf --with-arch=rv32imfd
RUN make
RUN make install

# Install Python packages
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir colorama

ENTRYPOINT [ "/bin/bash" ]
4 changes: 0 additions & 4 deletions compiler_tests/default/test_RETURN.c

This file was deleted.

7 changes: 0 additions & 7 deletions compiler_tests/default/test_RETURN_driver.c

This file was deleted.

6 changes: 5 additions & 1 deletion docs/assembler_directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ Assembler directives

The linked guide explains in details all available directives, but fortunately you only need a very small subset to start with and even the more advanced features only require a few additional directives. While [Godbolt](https://godbolt.org/z/vMMnWbsff) emits some directives, to see all of them (more than you actually need) you are advised to run:

```riscv64-unknown-elf-gcc -std=c90 -pedantic -ansi -O0 -march=rv32imfd -mabi=ilp32d -S [source-file.c] -o [dest-file.s]```.
```console
> user@host:langproc-cw# riscv64-unknown-elf-gcc -std=c90 -pedantic -ansi -O0 -march=rv32imfd -mabi=ilp32d -S [source-file.c] -o [dest-file.s]
```

In the [`scripts/test.py`](../scripts/test.py) script, when running testcases, there is the aforementioned call to the compiler and the compiled test programs can be found as `<test_name>.gcc.s`. Your compiler may not produce the exact same assembly as GCC, so it is not advisable to blindly attempt to replicate the GCC output. Instead, the purpose of the `.gcc.s` files is to assist in debugging issues within your own compiler.

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.**

Expand Down
7 changes: 3 additions & 4 deletions docs/basic_compiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ Basic compiler

For the first time ever, you are provided with a basic compiler that can lex, parse and generate code for only the following program:
```
int f()
{
int f() {
return 5;
}
```
Expand All @@ -13,14 +12,14 @@ Having a somewhat functioning compiler should allow you to get started with deve

The provided basic 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 - do not try to fully implement one before the other.

![int_main_return_tree](./int_main_return_tree.png)
![int_main_return_tree](./int_main_return_5_tree.png)


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.

Two versions of the grammar have been provided:

- [parser.y](../src/parser.y) contains a stripped down version of the grammar which contains only the elements from the full grammar that are necessary to parse the above program. **This is the grammar used when you run ./test.sh**.
- [parser.y](../src/parser.y) contains a stripped down version of the grammar which contains only the elements from the full grammar that are necessary to parse the above program. **This is the grammar used when you run ./scripts/test.py**.
- [parser_full.y.example](../src/parser_full.y.example) is the same as `parser.y` but also contains the rest of the C90 grammar not used in the above program. Once you understand how the stripped version works, you have two options: you can extend `parser.y` at your own pace and add pieces of the C90 grammar to it as you implement them; alternatively, you may paste the contents of `parser_full.y.example` into `parser.y` allowing you to parse everything but this may make the file much harder to navigate.

Note that you don't have to use any of the provided grammar examples (or even flex and bison) if you are comfortable with doing something else. However, be warned that TAs will likely only be able to provided limited support for such alternatives.
Expand Down
63 changes: 43 additions & 20 deletions docs/c_compiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,39 @@ If you wish to use C++, then a basic framework for building your compiler has be

Source files can be found in the [./src](../src) folder and header files can be found in the [./include](../include) folder.

If you have Python installed, you can test your compiler by running
You can test your compiler by running
[`scripts/test.py`](../scripts/test.py) from the top of this repo; the
output should look as follows (note: the progress bar will be coloured).
Full usage guide is found in the file header.
output should look as follows (note: the progress bar and results will be coloured):

```console
> scripts/test.py
> user@host:langproc-cw# scripts/test.py
>
make: Entering directory '/home/saturn691/projects/university/iac/langproc-cw'
make: 'bin/c_compiler' is up to date.
make: Leaving directory '/home/saturn691/projects/university/iac/langproc-cw'
Running Tests [################################################################]
Pass: 1 | Fail: 87 | Remaining: 0
Pass: 1 | Fail: 85 | Remaining: 0
See logs for more details (use -v for verbose output).

>> Test Summary: 1 Passed, 87 Failed
>> Test Summary: 1 Passed, 85 Failed
```

Full usage guide of [`scripts/test.py`](../scripts/test.py) is found in the file header or after running:

```console
> user@host:langproc-cw# scripts/test.py --help
```

If Python is not installed, you can also test your compiler against the provided
If for any reason you run into issues with the Python script, you can also test your compiler against the provided
test-suite by running [`scripts/test.sh`](../scripts/test.sh) from the top of
this repo; the output should look as follows:

```console
> scripts/test.sh
> user@host:langproc-cw# scripts/test.sh
>
compiler_tests/_example/example.c
> Pass
compiler_tests/array/declare_global.c
> Fail: simulation did not exit with exit-code 0
...
Passing 1/86 tests
```

By default, the first [`_example/example.c`](../compiler_tests/_example/example.c) test should be passing.
Expand All @@ -56,11 +58,15 @@ Program build and execution

Your program should be built by running the following command in the top-level directory of your repo:

make bin/c_compiler
```console
> user@host:langproc-cw# make bin/c_compiler
```

The compilation function is invoked using the flag `-S`, with the source file and output file specified on the command line:

bin/c_compiler -S [source-file.c] -o [dest-file.s]
```console
> user@host:langproc-cw# bin/c_compiler -S [source-file.c] -o [dest-file.s]
```

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.

Expand Down Expand Up @@ -157,28 +163,45 @@ It should be possible to assemble and link this code against a C run-time, and h

For instance, suppose I have a file called `test_program.c` that contains:

int f() { return 5; }
```
int f() {
return 5;
}
```

and another file called `test_program_driver.c` that contains:

int f();
int main() { return !( 5 == f() ); }
```
int f();
int main() {
return !( 5 == f() );
}
```

I run the compiler on the test program, like so:

bin/c_compiler -S test_program.c -o test_program.s
```console
> user@host:langproc-cw# bin/c_compiler -S test_program.c -o test_program.s
```

I then use GCC to assemble the generated assembly program (`test_program.s`), like so:

riscv64-unknown-elf-gcc -march=rv32imfd -mabi=ilp32d -o test_program.o -c test_program.s
```console
> user@host:langproc-cw# riscv64-unknown-elf-gcc -march=rv32imfd -mabi=ilp32d -o test_program.o -c test_program.s
```

I then use GCC to link the generated object file (`test_program.o`) with the driver program (`test_program_driver.c`), to produce an executable (`test_program`), like so:

riscv64-unknown-elf-gcc -march=rv32imfd -mabi=ilp32d -static -o test_program test_program.o test_program_driver.c
```console
> user@host:langproc-cw# riscv64-unknown-elf-gcc -march=rv32imfd -mabi=ilp32d -static -o test_program test_program.o test_program_driver.c
```

I then use spike to simulate the executable on RISC-V, like so:

spike pk test_program
```console
> user@host:langproc-cw# spike pk test_program
```

This command should produce the exit code `0`.

Expand Down
18 changes: 9 additions & 9 deletions docs/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ This will generate a webpage `coverage/index.html` with a listing of all the sou

![Index.html screenshot](./coverage_example.png)

It can also be used automatically on all test files by running `COVERAGE=1 ./test.sh`.
It can also be used automatically on all test files by running: `./scripts/test.py --coverage` or using the old test script: `COVERAGE=1 ./test.sh`.

## Viewing the coverage webpage

You can view the webpage in your browser by navigating to the coverage directory and running the following command:

```python3 -m http.server```

For example:
You can view the webpage in your browser by navigating to the coverage directory and running a Python HTTP server:

```console
user@host:/workspaces/langproc-cw# cd coverage
user@host:/workspaces/langproc-cw/coverage# python3 -m http.server
> user@host:langproc-cw# cd coverage
> user@host:langproc-cw/coverage# python3 -m http.server
>
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
```
```

VS Code should prompt you to open the webpage in your browser.
You can also manually do so by navigating to [http://0.0.0.0:8000](`http://0.0.0.0:8000`).
Binary file added docs/int_main_return_5_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/int_main_return_tree.png
Binary file not shown.
Loading

0 comments on commit eed378d

Please sign in to comment.