# Take Home Exercise
## General
- Can you explain what changes will need to be added to a compiler to implement structures? In particular, what changes will need to be made to the lexer, parser, resolution phase and the type system ?
- Why is error reporting important in a compiler?
- Noir does not uses LLVM as a backend. Can you explain any similarities and differences that you see with LLVM's framework?
## Coding Exercise
Create a Pratt parser in Rust which successfully parsers the following snippet of code:
```rust=
import "foo/bar/my_mod".
import "foo/*".
struct Car {
a : Car
b : u8
c : boolean
}
impl Car {
// Returns a default type with all fields zeroed out
fn default() :: Default {}
}
// This function returns a boolean and takes three parameters
// the first parameter has type u8, the second paramter has type u32
// and the third parameter has type Car
func example(u8 last_byte, u32 prefix, Car item,) :: u1 {
const u8 multi = woo(last_byte, prefix, item).
/* lines are ended with a full stop but they are also used to
call methods.
*/
not_const Car my_car = item.copy().
not_const u32 mask = my_mod.previous_car().a.
}
#[test]
func test_func() :: () {
example(10, 20, Car::default()).
}
```
### Note
- Error recovery and synchronisation is not needed
- Out of the above code snippet, we expect a coherent set of grammar rules. This means that your parser should not _only_ parse the following code above. For example, although the code only specifies `#[test]`, your implementation can assume that `test` is only one of possible keywords that are allowed.