Skip to content
Snippets Groups Projects
Commit 5f6af115 authored by Per Lindgren's avatar Per Lindgren
Browse files

mut deref, notice alpha renaming needed

parent 62cca1f7
No related branches found
No related tags found
No related merge requests found
...@@ -387,9 +387,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" ...@@ -387,9 +387,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.21" version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" checksum = "e4b93dba1818d32e781f9d008edd577bab215e83ef50e8a1ddf1ad301b19a09f"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
......
fn f(a: &i32, b: &mut bool) {} fn f(x: &i32, y: &mut bool) {
*y = true;
let c = *x;
// println!("{}", c);
}
fn main() { fn main() {
let mut a = 1; let mut a = 1;
let mut b = false; let mut b = false;
f(&a, &mut b) f(&a, &mut b);
// println!("{}", b);
} }
fn f(a: &i32, b: &mut i32) {} // parameter a is of type &i32
fn f(a: &i32, b: &mut bool) {
*b = true;
let c = *a;
//println!("{}", c);
}
fn main() { fn main() {
let mut a = 1; let mut a = 1;
f(&mut a, &mut a) let mut b = false;
// argument &a, is bound to parameter a in function
f(&a, &mut b);
// println!("{}", b);
} }
// here we don't want to shadow a in main by the
// local a in f.
// this is can be solved by "alpha renaming"
// in a function f(x, ...) = x ...
// x can be "renamed" to a new name y
// by changing all appearances of x to y
// (as long as y don't appear in f)
\ No newline at end of file
#[derive(Debug, Copy, Clone)]
struct A {}
fn main() { fn main() {
let mut a = 5; let mut a = A {};
let b = &mut a; let b = &mut a;
//let q = *b; //let q = *b;
let c = a; let c = *b;
println!("b {:?}", *b); println!("b {:?}", *b);
let d = a;
} }
fn main() {
let mut a = 5;
let b = &a;
a = 4;
let d = *b;
}
fn main() {
let a = 1;
let b = *&a;
}
fn main() {
let a = 1;
let b = &a;
let c = *b;
}
fn main() {
let mut a = 1;
let mut b = &a;
let c = &mut b;
let d = *c;
let e = *d;
}
fn main() -> i32 { fn main() {
let mut a = 7; let mut a = 7;
let mut aa = 8; let mut aa = 8;
let mut b = &a; let mut b = &mut a;
let c = &b; let c = &mut b;
*c = &aa; *c = &mut aa;
*b = 99; *b = 99;
aa
} }
This diff is collapsed.
...@@ -5,7 +5,7 @@ use log::{trace, LevelFilter}; ...@@ -5,7 +5,7 @@ use log::{trace, LevelFilter};
use std::convert::From; use std::convert::From;
use crate::ast::*; use crate::ast::*;
use crate::env::{new_fn_env, new_type_env, Borrow, Error, FnEnv, IdType, TypeEnv, VarEnv}; use crate::env::{new_fn_env, new_type_env, Bc, Error, FnEnv, IdType, TypeEnv, VarEnv};
// type check // type check
...@@ -447,7 +447,7 @@ pub fn check(p: &Program) -> Result<(), Error> { ...@@ -447,7 +447,7 @@ pub fn check(p: &Program) -> Result<(), Error> {
true => Type::Mut(Box::new(ty.clone())), true => Type::Mut(Box::new(ty.clone())),
_ => ty.clone(), _ => ty.clone(),
}; };
arg_ty.insert(id.to_owned(), (Borrow::Free, ty)); arg_ty.insert(id.to_owned(), (Bc::Free, ty));
} }
var_env.push_param_scope(arg_ty); var_env.push_param_scope(arg_ty);
......
...@@ -23,7 +23,7 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv { ...@@ -23,7 +23,7 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv {
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Borrow { pub enum Bc {
Free, // or maybe owned Free, // or maybe owned
Unique, Unique,
Shared(Vec<String>), Shared(Vec<String>),
...@@ -32,7 +32,7 @@ pub enum Borrow { ...@@ -32,7 +32,7 @@ pub enum Borrow {
pub type Address = i32; pub type Address = i32;
type Scope = i32; type Scope = i32;
pub type IdType = HashMap<Id, (Borrow, Type)>; pub type IdType = HashMap<Id, (Bc, Type)>;
#[derive(Debug)] #[derive(Debug)]
pub struct VarEnv { pub struct VarEnv {
env: VecDeque<IdType>, env: VecDeque<IdType>,
...@@ -45,7 +45,7 @@ impl VarEnv { ...@@ -45,7 +45,7 @@ impl VarEnv {
} }
} }
pub fn get(&self, id: String) -> Option<(Scope, &(Borrow, Type))> { pub fn get(&self, id: String) -> Option<(Scope, &(Bc, Type))> {
self.env.iter().enumerate().find_map(|(scope, hm)| { self.env.iter().enumerate().find_map(|(scope, hm)| {
hm.get(id.as_str()) hm.get(id.as_str())
.map(|t| ((self.env.len() - scope) as Scope, t)) .map(|t| ((self.env.len() - scope) as Scope, t))
...@@ -56,7 +56,7 @@ impl VarEnv { ...@@ -56,7 +56,7 @@ impl VarEnv {
self.get(id).map(|(s, t)| (s, &t.1)) self.get(id).map(|(s, t)| (s, &t.1))
} }
pub fn get_mut(&mut self, id: String) -> Option<&mut (Borrow, Type)> { pub fn get_mut(&mut self, id: String) -> Option<&mut (Bc, Type)> {
self.env.iter_mut().find_map(|hm| hm.get_mut(id.as_str())) self.env.iter_mut().find_map(|hm| hm.get_mut(id.as_str()))
} }
...@@ -68,7 +68,7 @@ impl VarEnv { ...@@ -68,7 +68,7 @@ impl VarEnv {
let hm = self.env.front_mut().unwrap(); let hm = self.env.front_mut().unwrap();
println!("insert id {:?}, in scope {:?}", &id, hm); println!("insert id {:?}, in scope {:?}", &id, hm);
hm.insert(id, (Borrow::Free, ty)); hm.insert(id, (Bc::Free, ty));
} }
pub fn update(&mut self, id: String, ty: Type) -> Result<(), Error> { pub fn update(&mut self, id: String, ty: Type) -> Result<(), Error> {
......
...@@ -124,7 +124,7 @@ Param : Param = { ...@@ -124,7 +124,7 @@ Param : Param = {
Type : Type = { Type : Type = {
"bool" => Type::Bool, "bool" => Type::Bool,
"()" => Type::Unit, "()" => Type::Unit,
"i32" => Type::I32, // this should likely be a paratrized Num type later "i32" => Type::I32, // this should likely be a parametrized Num type later
Id => Type::Named(<>), Id => Type::Named(<>),
"&" <Type> => Type::Ref(Box::new(<>)), "&" <Type> => Type::Ref(Box::new(<>)),
"&" "mut" <Type> => Type::Ref(Box::new(Type::Mut(Box::new(<>)))), "&" "mut" <Type> => Type::Ref(Box::new(Type::Mut(Box::new(<>)))),
......
// vm // boorrow
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
// use std::convert::From;
//use std::iter::{FromIterator, Map};
use crate::ast::*; use crate::ast::*;
use crate::env::*; use crate::env::*;
//use crate::grammar::*;
type Id = String; type Id = String;
...@@ -44,7 +41,12 @@ impl Mem { ...@@ -44,7 +41,12 @@ impl Mem {
Some((true, v)) => Some(v), // a mut reference Some((true, v)) => Some(v), // a mut reference
Some((_, v)) => { Some((_, v)) => {
match v { match v {
Val::Uninitialized => Some(v), // an unitialized Val::Uninitialized => Some(v), // an uninitialized
Val::RefMut(_) => {
// a ref mut
println!("get &mut {:?}", v);
Some(v)
}
_ => panic!("cannot access as mutable"), _ => panic!("cannot access as mutable"),
} }
} }
...@@ -175,6 +177,7 @@ fn eval_expr(e: &Expr, m: &mut Mem, fn_env: &FnEnv) -> Val { ...@@ -175,6 +177,7 @@ fn eval_expr(e: &Expr, m: &mut Mem, fn_env: &FnEnv) -> Val {
match ev { match ev {
Val::Ref(id) => eval_expr(&Expr::Id(id), m, fn_env), Val::Ref(id) => eval_expr(&Expr::Id(id), m, fn_env),
Val::RefMut(id) => eval_expr(&Expr::Id(id), m, fn_env),
_ => panic!("cannot deref"), _ => panic!("cannot deref"),
} }
} }
......
use erode::borrow::*;
#[test]
fn minmal_test() {
eval_prog("examples/minimal.rs");
}
#[test]
fn ref_test() {
eval_prog("examples/ref.rs");
}
#[test]
fn assign_test() {
eval_prog("examples/assign.rs");
}
#[test]
fn ref_mut_test() {
eval_prog("examples/ref_mut.rs");
}
#[test]
fn deref_test() {
eval_prog("examples/deref.rs");
}
#[test]
fn deref2_test() {
eval_prog("examples/deref2.rs");
}
#[test]
fn deref3_test() {
eval_prog("examples/deref3.rs");
}
#[test]
fn deref_assign_test() {
eval_prog("examples/deref_assign.rs");
}
#[test]
fn deref_assign2_test() {
eval_prog("examples/deref_assign2.rs");
}
#[test]
fn deref_assign3_test() {
eval_prog("examples/deref_assign3.rs");
}
#[test]
fn scopes_test() {
eval_prog("examples/scopes.rs");
}
#[test]
fn scopes_err_test() {
eval_prog("examples/scopes_err.rs");
}
#[test]
fn vm_test() {
eval_prog("examples/vm.rs");
}
#[test]
fn if_test() {
eval_prog("examples/if.rs");
}
#[test]
fn while_test() {
eval_prog("examples/while.rs");
}
#[test]
fn let_test() {
eval_prog("examples/let.rs");
}
#[test]
fn let2_test() {
eval_prog("examples/let2.rs");
}
#[test]
fn call_test() {
eval_prog("examples/call.rs");
}
#[test]
fn call2_test() {
eval_prog("examples/call2.rs");
}
#[test]
fn call3_test() {
eval_prog("examples/call3.rs");
}
#[test]
fn call_ref_test() {
eval_prog("examples/call_ref.rs");
}
#[test]
fn call_mut_ref_test() {
eval_prog("examples/call_mut_ref.rs");
}
#[test]
fn borrow() {
eval_prog("examples/borrow.rs");
}
#[test]
fn borrow2() {
eval_prog("examples/borrow2.rs");
}
...@@ -20,6 +20,21 @@ fn ref_mut_test() { ...@@ -20,6 +20,21 @@ fn ref_mut_test() {
eval_prog("examples/ref_mut.rs"); eval_prog("examples/ref_mut.rs");
} }
#[test]
fn deref_test() {
eval_prog("examples/deref.rs");
}
#[test]
fn deref2_test() {
eval_prog("examples/deref2.rs");
}
#[test]
fn deref3_test() {
eval_prog("examples/deref3.rs");
}
#[test] #[test]
fn deref_assign_test() { fn deref_assign_test() {
eval_prog("examples/deref_assign.rs"); eval_prog("examples/deref_assign.rs");
...@@ -93,3 +108,13 @@ fn call_ref_test() { ...@@ -93,3 +108,13 @@ fn call_ref_test() {
fn call_mut_ref_test() { fn call_mut_ref_test() {
eval_prog("examples/call_mut_ref.rs"); eval_prog("examples/call_mut_ref.rs");
} }
#[test]
fn borrow() {
eval_prog("examples/borrow.rs");
}
#[test]
fn borrow2() {
eval_prog("examples/borrow2.rs");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment