From 4d9fd76d4031e2e4045b1a3195e66dea1033cac8 Mon Sep 17 00:00:00 2001 From: Per Lindgren <per.lindgren@ltu.se> Date: Thu, 24 Sep 2020 16:08:33 +0200 Subject: [PATCH] borrow check, wip2 --- README.md | 26 ++++++++++++++++++++++++++ examples/borrow.rs | 6 ++++++ src/env.rs | 1 + tests/test_check.rs | 5 +++++ 4 files changed, 38 insertions(+) create mode 100644 examples/borrow.rs diff --git a/README.md b/README.md index a8cb825..d4c4091 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 0000000..3999f25 --- /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 03f3ddc..1b48063 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 72e0020..2c5e71d 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(); +} -- GitLab