---
# System prepended metadata

title: Take Home Exercise

---

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

