On a function call, the parameters are pushed to the stack, and a new stack frame is generated (on entry of each sequence of statements).
On a function call, the parameters are pushed to the stack, and a new stack frame is generated (on entry of each sequence of statements).
References are handled through `Ref(Id)`, and are transitive. You cannot reference memory items in any other way (so this is a limitation compared to real Rust).
References are handled through `Ref(Id)`, and are transitive. You cannot reference memory items in any other way (so this is a limitation compared to real Rust).
## check
The `check` module performs basic type checking and borrow checking. In the following the basic reasoning is discussed.
``` Rust
pub enum Type {
Unit, // (), // maybe just a special case of tuple, see todo
Never, // !
Bool, // bool
I32, // i32
Ref(Box<Type>), // & mut? Type -- used in parser
Mut(Box<Type>), // mut Type
Unknown, // Not yet assigned
}
pub type IdType = HashMap<Id, Type>;
type Scope = i32;
pub struct VarEnv(VecDeque<IdType>);
```
The `var_env : VarEnv` holds a stack of scopes. A lookup (`get(Id)-> Option<(Scope, &Type)>`), returns the type and what scope it is defined in (0, being arguments, 1, function body, 2 ... inner scopes). Inner scopes emerge from blocks, or block statements (if/while etc).