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