diff --git a/README.md b/README.md index a8cb825f96d4992232244ad049b04b18c5c5cfb7..d4c40918f37ff7f13f7a7690af4162885ff54e9b 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,29 @@ struct Mem(VecDeque<IdVal>); 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). + +## 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). + + diff --git a/examples/borrow.rs b/examples/borrow.rs new file mode 100644 index 0000000000000000000000000000000000000000..3999f25758aa0e21c3fcd9a61f4b30d1729fe6ac --- /dev/null +++ b/examples/borrow.rs @@ -0,0 +1,6 @@ +fn main() { + let mut a = 1; + let b = &mut a; + let c = &mut a; + let c: &mut i32 = b; +} diff --git a/src/env.rs b/src/env.rs index 03f3ddc9c6a744bb3ee3460e85958134acd45bda..1b48063dad27b07099d8ed10fb4c1cbc289a6d6c 100644 --- a/src/env.rs +++ b/src/env.rs @@ -23,6 +23,7 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv { } pub type IdType = HashMap<Id, Type>; + type Scope = i32; #[derive(Debug)] diff --git a/tests/test_check.rs b/tests/test_check.rs index 72e002019bb69103aa0f05572811e66f8135ea39..2c5e71d0525b83df22eb024929b10933c193143a 100644 --- a/tests/test_check.rs +++ b/tests/test_check.rs @@ -170,3 +170,8 @@ fn check_let_if() { fn wip() { check(&read_file::parse("examples/wip.rs")).unwrap(); } + +#[test] +fn borrow() { + check(&read_file::parse("examples/borrow.rs")).unwrap(); +}