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
Branches
No related tags found
No related merge requests found
......@@ -387,9 +387,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro2"
version = "1.0.21"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
checksum = "e4b93dba1818d32e781f9d008edd577bab215e83ef50e8a1ddf1ad301b19a09f"
dependencies = [
"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() {
let mut a = 1;
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() {
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() {
let mut a = 5;
let mut a = A {};
let b = &mut a;
//let q = *b;
let c = a;
let c = *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 aa = 8;
let mut b = &a;
let c = &b;
let mut b = &mut a;
let c = &mut b;
*c = &aa;
*c = &mut aa;
*b = 99;
aa
}
This diff is collapsed.
......@@ -5,7 +5,7 @@ use log::{trace, LevelFilter};
use std::convert::From;
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
......@@ -447,7 +447,7 @@ pub fn check(p: &Program) -> Result<(), Error> {
true => Type::Mut(Box::new(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);
......
......@@ -23,7 +23,7 @@ pub fn new_fn_env(v: &Vec<FnDecl>) -> FnEnv {
}
#[derive(Debug, PartialEq)]
pub enum Borrow {
pub enum Bc {
Free, // or maybe owned
Unique,
Shared(Vec<String>),
......@@ -32,7 +32,7 @@ pub enum Borrow {
pub type Address = i32;
type Scope = i32;
pub type IdType = HashMap<Id, (Borrow, Type)>;
pub type IdType = HashMap<Id, (Bc, Type)>;
#[derive(Debug)]
pub struct VarEnv {
env: VecDeque<IdType>,
......@@ -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)| {
hm.get(id.as_str())
.map(|t| ((self.env.len() - scope) as Scope, t))
......@@ -56,7 +56,7 @@ impl VarEnv {
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()))
}
......@@ -68,7 +68,7 @@ impl VarEnv {
let hm = self.env.front_mut().unwrap();
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> {
......
......@@ -124,7 +124,7 @@ Param : Param = {
Type : Type = {
"bool" => Type::Bool,
"()" => 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(<>),
"&" <Type> => Type::Ref(Box::new(<>)),
"&" "mut" <Type> => Type::Ref(Box::new(Type::Mut(Box::new(<>)))),
......
// vm
// boorrow
use std::collections::{HashMap, VecDeque};
// use std::convert::From;
//use std::iter::{FromIterator, Map};
use crate::ast::*;
use crate::env::*;
//use crate::grammar::*;
type Id = String;
......@@ -44,7 +41,12 @@ impl Mem {
Some((true, v)) => Some(v), // a mut reference
Some((_, 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"),
}
}
......@@ -175,6 +177,7 @@ fn eval_expr(e: &Expr, m: &mut Mem, fn_env: &FnEnv) -> Val {
match ev {
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"),
}
}
......
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() {
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");
......@@ -93,3 +108,13 @@ fn call_ref_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");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment