Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
E
erode
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Per Lindgren
erode
Commits
2db9d21c
Commit
2db9d21c
authored
4 years ago
by
Per Lindgren
Browse files
Options
Downloads
Patches
Plain Diff
borrow check, wip0
parent
f62d8f7b
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
Cargo.lock
+16
-16
16 additions, 16 deletions
Cargo.lock
src/bc_env.rs
+111
-0
111 additions, 0 deletions
src/bc_env.rs
src/borrow.rs
+568
-0
568 additions, 0 deletions
src/borrow.rs
src/lib.rs
+2
-0
2 additions, 0 deletions
src/lib.rs
with
697 additions
and
16 deletions
Cargo.lock
+
16
−
16
View file @
2db9d21c
...
@@ -175,9 +175,9 @@ dependencies = [
...
@@ -175,9 +175,9 @@ dependencies = [
[[package]]
[[package]]
name = "either"
name = "either"
version = "1.6.
0
"
version = "1.6.
1
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f
"
checksum = "
e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457
"
[[package]]
[[package]]
name = "ena"
name = "ena"
...
@@ -235,9 +235,9 @@ dependencies = [
...
@@ -235,9 +235,9 @@ dependencies = [
[[package]]
[[package]]
name = "getrandom"
name = "getrandom"
version = "0.1.1
4
"
version = "0.1.1
5
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb
"
checksum = "
fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6
"
dependencies = [
dependencies = [
"cfg-if",
"cfg-if",
"libc",
"libc",
...
@@ -252,9 +252,9 @@ checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
...
@@ -252,9 +252,9 @@ checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
[[package]]
[[package]]
name = "hermit-abi"
name = "hermit-abi"
version = "0.1.1
5
"
version = "0.1.1
6
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9
"
checksum = "
4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151
"
dependencies = [
dependencies = [
"libc",
"libc",
]
]
...
@@ -329,9 +329,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
...
@@ -329,9 +329,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
[[package]]
name = "libc"
name = "libc"
version = "0.2.7
6
"
version = "0.2.7
7
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3
"
checksum = "
f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235
"
[[package]]
[[package]]
name = "log"
name = "log"
...
@@ -387,9 +387,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
...
@@ -387,9 +387,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
[[package]]
name = "proc-macro2"
name = "proc-macro2"
version = "1.0.2
0
"
version = "1.0.2
1
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1
a2
9
"
checksum = "
36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2
a2
c
"
dependencies = [
dependencies = [
"unicode-xid",
"unicode-xid",
]
]
...
@@ -458,18 +458,18 @@ dependencies = [
...
@@ -458,18 +458,18 @@ dependencies = [
[[package]]
[[package]]
name = "serde"
name = "serde"
version = "1.0.11
5
"
version = "1.0.11
6
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d
5"
checksum = "
96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a
5"
dependencies = [
dependencies = [
"serde_derive",
"serde_derive",
]
]
[[package]]
[[package]]
name = "serde_derive"
name = "serde_derive"
version = "1.0.11
5
"
version = "1.0.11
6
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc4
8"
checksum = "
f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae
8"
dependencies = [
dependencies = [
"proc-macro2",
"proc-macro2",
"quote",
"quote",
...
@@ -515,9 +515,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
...
@@ -515,9 +515,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
[[package]]
name = "syn"
name = "syn"
version = "1.0.4
0
"
version = "1.0.4
1
"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "
963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350
"
checksum = "
6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b
"
dependencies = [
dependencies = [
"proc-macro2",
"proc-macro2",
"quote",
"quote",
...
...
This diff is collapsed.
Click to expand it.
src/bc_env.rs
0 → 100644
+
111
−
0
View file @
2db9d21c
// borrow check environment
use
std
::
iter
::
FromIterator
;
// use std::iter::{FromIterator, Map};
use
crate
::
ast
::
*
;
// use crate::grammar::*;
use
std
::
collections
::{
HashMap
,
VecDeque
};
#[derive(Debug)]
pub
enum
Error
{
NotFound
(
String
),
Shared
(
String
),
Unique
(
String
),
}
#[derive(Debug)]
pub
enum
Bc
{
Free
,
Shared
,
Unique
,
Ref
(
Box
<
Bc
>
),
}
type
Scope
=
i32
;
pub
type
IdBc
=
HashMap
<
Id
,
Bc
>
;
#[derive(Debug)]
pub
struct
BcEnv
(
VecDeque
<
IdBc
>
);
impl
BcEnv
{
pub
fn
new
()
->
Self
{
BcEnv
(
VecDeque
::
new
())
}
pub
fn
get
(
&
self
,
id
:
String
)
->
Option
<
(
Scope
,
&
Bc
)
>
{
self
.0
.iter
()
.enumerate
()
.find_map
(|(
i
,
hm
)|
hm
.get
(
id
.as_str
())
.map
(|
bc
|
(
i
as
i32
,
bc
)))
}
pub
fn
get_mut
(
&
mut
self
,
id
:
String
)
->
Option
<
(
Scope
,
&
mut
Bc
)
>
{
self
.0
.iter_mut
()
.enumerate
()
.find_map
(|(
i
,
hm
)|
hm
.get_mut
(
id
.as_str
())
.map
(|
bc
|
(
i
as
i32
,
bc
)))
}
pub
fn
new_id
(
&
mut
self
,
id
:
String
,
bc
:
Bc
)
{
let
hm
=
self
.0
.front_mut
()
.unwrap
();
println!
(
"insert id {:?}, in scope {:?}"
,
id
,
hm
);
hm
.insert
(
id
,
bc
);
}
pub
fn
update
(
&
mut
self
,
id
:
String
,
bc
:
Bc
)
->
Result
<
(),
()
>
{
println!
(
"env: update"
);
match
self
.get_mut
(
id
.clone
())
{
Some
(
b
)
=>
match
b
{
(
_i
,
Bc
::
Free
)
=>
{
*
b
.1
=
bc
;
Ok
(())
}
(
_i
,
Bc
::
Shared
)
=>
match
bc
{
Bc
::
Shared
=>
Ok
(()),
Bc
::
Unique
=>
Err
(()),
_
=>
panic!
(
"ICE update to Free"
),
},
_
=>
Err
(()),
},
None
=>
Err
(()),
}
}
pub
fn
push_empty_scope
(
&
mut
self
)
{
self
.0
.push_front
(
HashMap
::
new
());
}
pub
fn
push_param_scope
(
&
mut
self
,
args
:
IdBc
)
{
self
.0
.push_front
(
args
)
}
pub
fn
pop_scope
(
&
mut
self
)
{
self
.0
.pop_front
();
}
}
#[test]
fn
test_bc_env
()
{
let
mut
bc_env
=
BcEnv
::
new
();
println!
(
"{:?}"
,
bc_env
);
bc_env
.push_empty_scope
();
bc_env
.new_id
(
"a"
.to_string
(),
Bc
::
Free
);
println!
(
"{:?}"
,
bc_env
.get
(
"a"
.to_string
()));
bc_env
.push_empty_scope
();
bc_env
.new_id
(
"b"
.to_string
(),
Bc
::
Free
);
println!
(
"{:?}"
,
bc_env
.get
(
"a"
.to_string
()));
println!
(
"{:?}"
,
bc_env
.get
(
"b"
.to_string
()));
bc_env
.update
(
"a"
.to_string
(),
Bc
::
Shared
)
.unwrap
();
println!
(
"{:?}"
,
bc_env
.get
(
"a"
.to_string
()));
bc_env
.update
(
"a"
.to_string
(),
Bc
::
Shared
)
.unwrap
();
println!
(
"{:?}"
,
bc_env
.get
(
"a"
.to_string
()));
// it should be an error to assign a shared ref to a unique
bc_env
.update
(
"a"
.to_string
(),
Bc
::
Unique
)
.unwrap_err
();
bc_env
.pop_scope
();
println!
(
"{:?}"
,
bc_env
.get
(
"b"
.to_string
()));
println!
(
"{:?}"
,
bc_env
.get
(
"a"
.to_string
()));
}
This diff is collapsed.
Click to expand it.
src/borrow.rs
0 → 100644
+
568
−
0
View file @
2db9d21c
use
std
::
io
::
Write
;
use
env_logger
::
Builder
;
use
log
::{
trace
,
LevelFilter
};
use
std
::
convert
::
From
;
use
crate
::
ast
::
*
;
use
crate
::
bc_env
::{
Bc
,
BcEnv
,
Error
,
IdBc
};
use
crate
::
env
::{
new_fn_env
,
new_type_env
,
FnEnv
,
TypeEnv
};
// type check
fn
bc_expr
(
e
:
&
Expr
,
fn_env
:
&
FnEnv
,
type_env
:
&
TypeEnv
,
bc_env
:
&
mut
BcEnv
,
)
->
Result
<
Type
,
Error
>
{
use
Expr
::
*
;
println!
(
"expr_type {}"
,
e
);
println!
(
"var_env {:?}"
,
bc_env
);
match
e
{
// Num(_) => Ok(Type::I32),
// Bool(_) => Ok(Type::Bool),
// Infix(l, op, r) => {
// let lt = expr_type(l, fn_env, type_env, var_env)?;
// let rt = expr_type(r, fn_env, type_env, var_env)?;
// let lt = strip_mut(lt);
// let rt = strip_mut(rt);
// use Op::*;
// match op {
// // Arithmetic and Boolen
// Add | Mul | Div | Sub | And | Or => {
// // check if op and args are compliant
// let opt = op.get_type();
// if lt == opt && rt == opt {
// Ok(opt)
// } else {
// Err(format!(
// "Expected type {}, found, left {}: {}, {:?} right {}: {}, {:?}",
// opt, l, lt, lt, r, rt, rt
// ))
// }
// }
// // Equality
// Eq | Neq => {
// // check if args are of same type
// if lt == rt {
// Ok(Type::Bool)
// } else {
// Err(format!(
// "Comparison requires operands of same type, left {}, right {}",
// lt, rt
// ))
// }
// }
// // Comparison
// Less | Greater | LessEq | GreaterEq => {
// if lt == Type::I32 && rt == Type::I32 {
// // check if args are of i32
// Ok(Type::Bool)
// } else {
// Err(format!(
// "Comparison requires operands of same type, left {}, right {}",
// lt, rt
// ))
// }
// }
// _ => panic!("ICE on {}", e),
// }
// }
// Prefix(op, r) => {
// let rt = expr_type(r, fn_env, type_env, var_env)?;
// let opt = op.get_type();
// // check if both of same type
// if rt == opt {
// Ok(opt)
// } else {
// Err(format!("op {} rt {}", opt, rt))
// }
// }
// Call(s, args) => {
// trace!("call {} with {}", s, args);
// let arg_t: Vec<Type> = args
// .clone()
// .0
// .into_iter()
// .map(|e| expr_type(&*e, fn_env, type_env, var_env))
// .collect::<Result<_, _>>()?;
// trace!("arg types {:?}", arg_t);
// let f = match fn_env.get(s.as_str()) {
// Some(f) => f,
// None => Err(format!("{} not found", s))?,
// };
// let par_t: Vec<Type> = (f.params.0.clone())
// .into_iter()
// .map(|p| From::from(&p))
// .collect();
// trace!(
// "fn to call {} with params {} and types {:?}",
// f,
// f.params,
// par_t
// );
// if arg_t == par_t {
// Ok(f.result.clone())
// } else {
// Err(format!(
// "arguments types {:?} does not match parameter types {:?}",
// arg_t, par_t
// ))
// }
// }
// Id(id) => match var_env.get(id.to_string()) {
// Some(t) => Ok(t.clone()),
// None => Err(format!("variable not found {}", id)),
// },
// As(_e, _t) => unimplemented!("here we implement explicit type cast"),
// // Convert Expr::Ref to Type::Ref
// Ref(ref_e) => {
// let t = expr_type(ref_e, fn_env, type_env, var_env)?;
// trace!("ref_e {}, t {}", ref_e, t);
// let t = match t {
// Type::Mut(t) => t.clone(),
// t => Box::new(t),
// };
// Ok(Type::Ref(t))
// }
// // Convert Expr::Mut to Type::Mut
// RefMut(ref_mut_e) => {
// let t = expr_type(ref_mut_e, fn_env, type_env, var_env)?;
// match t {
// Type::Mut(_) => Ok(Type::Ref(Box::new(t))),
// _ => Err(format!("{} is not mutable in {}", t, ref_mut_e)),
// }
// }
// DeRef(deref_e) => {
// let t = expr_type(deref_e, fn_env, type_env, var_env)?;
// trace!("deref_t {}", &t);
// let t = strip_mut(t);
// trace!("strip deref_t {}", &t);
// match t {
// Type::Ref(dt) => Ok(*dt),
// _ => Err(format!("cannot deref {} of type {}", e, t)),
// }
// }
// Block(b) => check_stmts(b, fn_env, type_env, var_env),
// Stmt(s) => check_stmt(s, fn_env, type_env, var_env),
_
=>
unimplemented!
(),
}
}
// fn lexpr_type<'a>(
// e: &Expr,
// fn_env: &FnEnv,
// type_env: &TypeEnv,
// var_env: &'a mut VarEnv,
// ) -> Result<&'a mut Type, Error> {
// use Expr::*;
// trace!("expr_type {}", e);
// trace!("var_env {:?}", var_env);
// match e {
// Id(id) => match var_env.get_mut(id.to_string()) {
// Some(t) => Ok(t),
// None => Err(format!("variable not found {}", id)),
// },
// DeRef(deref_e) => {
// let t = lexpr_type(deref_e, fn_env, type_env, var_env)?;
// trace!("deref_t {}", &t);
// // strip mut
// let t = match t {
// Type::Mut(t) => t,
// _ => t,
// };
// trace!("strip deref_t {}", t);
// match t {
// Type::Ref(dt) => Ok(dt),
// _ => Err(format!("cannot deref {} of type {}", e, t)),
// }
// }
// _ => Err(format!("Illegal left hand expression {}", e)),
// }
// }
// strip a "mut T" to a T
fn
strip_mut
(
t
:
Type
)
->
Type
{
match
t
{
Type
::
Mut
(
t
)
=>
*
t
,
_
=>
t
,
}
}
// determine if a type is declared recursively
fn
is_known
(
t
:
&
Type
)
->
bool
{
use
Type
::
*
;
match
t
{
Type
::
Unknown
=>
false
,
Unit
|
Bool
|
I32
=>
true
,
Mut
(
t
)
|
Ref
(
t
)
=>
is_known
(
t
),
_
=>
panic!
(
"ICE is_known"
),
}
}
pub
fn
bc_stmt
(
s
:
&
Stmt
,
fn_env
:
&
FnEnv
,
type_env
:
&
TypeEnv
,
bc_env
:
&
mut
BcEnv
,
)
->
Result
<
(),
Error
>
{
use
Stmt
::
*
;
// trace!("stmt: {}", s);
// match s {
// Stmt::Block(b) => check_stmts(b, fn_env, type_env, var_env),
// Expr(e) => expr_type(&*e, fn_env, type_env, var_env),
// Let(var_id, is_mut, ot, oe) => {
// let t: Type = match (ot, oe) {
// (Some(t), Some(e)) => {
// let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
// let e_type = strip_mut(e_type);
// match strip_mut(t.clone()) == e_type {
// true => t.clone(),
// false => {
// trace!("e {}", e);
// Err(format!("incompatible types, {} <> {}", t, e_type))?
// }
// }
// }
// (None, Some(e)) => {
// let e_type = strip_mut(expr_type(&*e, fn_env, type_env, var_env)?);
// match is_known(&e_type) {
// true => e_type,
// _ => Err("reference to unknown type".to_string())?,
// }
// }
// (Some(t), None) => t.clone(),
// _ => Type::Unknown,
// };
// let t = match is_mut {
// true => Type::Mut(Box::new(t)),
// false => t,
// };
// var_env.new_id(var_id.clone(), t);
// trace!("var_env {:?}", var_env);
// Ok(Type::Unit)
// }
// Assign(lh, e) => {
// trace!("assign");
// let e_type = expr_type(&*e, fn_env, type_env, var_env)?;
// trace!("e_type = {}", &e_type);
// let e_type = strip_mut(e_type);
// trace!("e_type stripped = {}", &e_type);
// trace!("lh expr = {:?}", lh);
// let lh_type = lexpr_type(lh, fn_env, type_env, var_env)?;
// trace!("lh_type {}", lh_type);
// if match lh_type {
// Type::Unknown => {
// trace!("assign to unknown");
// *lh_type = e_type.clone();
// true
// }
// Type::Mut(t) => match **t {
// Type::Unknown => {
// trace!("assign to `mut Unknown`");
// *t = Box::new(e_type.clone());
// true
// }
// _ => **t == e_type,
// },
// _ => Err(format!("assignment to immutable"))?,
// } {
// Ok(Type::Unit)
// } else {
// Err(format!("cannot assign {} = {}", &lh_type, e_type))
// }
// }
// While(e, block) => match expr_type(&*e, fn_env, type_env, var_env) {
// Ok(Type::Bool) => {
// let _ = check_stmts(&block, fn_env, type_env, var_env)?;
// Ok(Type::Unit) // a while statement is of unit type;
// }
// _ => Err("Condition not Boolean".to_string()),
// },
// If(e, then, o_else) => match expr_type(&*e, fn_env, type_env, var_env)? {
// Type::Bool => {
// // The condition is of Bool type
// let then_type = check_stmts(&then, fn_env, type_env, var_env)?;
// trace!("then type {}", then_type);
// match o_else {
// None => Ok(then_type), // type of the arm
// Some(else_stmts) => {
// let else_type = check_stmts(&else_stmts, fn_env, type_env, var_env)?;
// trace!("else type {}", else_type);
// match then_type == else_type {
// true => Ok(then_type), // same type of both arms
// false => {
// trace!("error-----");
// Err(format!(
// "'then' arm :{} does not match 'else' arm :{}",
// then_type, else_type
// ))
// }
// }
// }
// }
// }
// _ => Err("Condition not Boolean".to_string()),
// },
// Semi => Ok(Type::Unit),
// }
Ok
(())
}
pub
fn
bc_stmts
(
stmts
:
&
Stmts
,
fn_env
:
&
FnEnv
,
type_env
:
&
TypeEnv
,
bc_env
:
&
mut
BcEnv
,
)
->
Result
<
(),
Error
>
{
bc_env
.push_empty_scope
();
let
t
=
stmts
.stmts
.iter
()
.try_fold
((),
|
_
,
s
|
bc_stmt
(
s
,
fn_env
,
type_env
,
bc_env
))
?
;
bc_env
.pop_scope
();
// if stmts.trailing_semi {
// Ok(())
// } else {
// Ok(t.clone())
// }
Ok
(())
}
pub
fn
build_env
(
p
:
&
Program
)
->
(
FnEnv
,
TypeEnv
)
{
let
fn_env
=
new_fn_env
(
&
p
.fn_decls
);
let
type_env
=
new_type_env
(
&
p
.type_decls
);
(
fn_env
,
type_env
)
}
// pub fn dump_env(fn_env: &FnEnv, type_env: &TypeEnv) {
// trace!("fn_env {:?}", fn_env);
// trace!("type_env {:?}", type_env);
// }
// check a whole Program
pub
fn
bc_prog
(
p
:
&
Program
)
->
Result
<
(),
Error
>
{
let
(
fn_env
,
type_env
)
=
build_env
(
&
p
);
println!
(
"Input program
\n
{}"
,
&
p
);
for
fd
in
p
.fn_decls
.iter
()
{
println!
(
"check function
\n
{}"
,
fd
);
println!
(
"ast
\n
{:?}"
,
fd
);
let
mut
bc_env
=
BcEnv
::
new
();
// build a scope for the arguments
let
mut
arg_ty
=
IdBc
::
new
();
for
Param
{
is_mut
,
id
,
ty
}
in
fd
.params
.0
.iter
()
{
let
ty
=
match
*
is_mut
{
true
=>
Bc
::
Unique
,
_
=>
Bc
::
Shared
,
};
arg_ty
.insert
(
id
.to_owned
(),
ty
);
}
// var_env.push_param_scope(arg_ty);
// let stmt_type = check_stmts(&fd.body, &fn_env, &type_env, &mut var_env);
// trace!("result {}: {} {:?}", &fd.id, &fd.result, &stmt_type);
// let stmt_type = strip_mut(stmt_type?);
// if stmt_type != fd.result {
// Err(format!(
// "return type {} does not match statements type {}",
// fd.result, stmt_type
// ))?;
// }
}
Ok
(())
}
// unit test
// #[test]
// fn test_stmts() {
// use crate::grammar::*;
// use crate::*;
// // use Type::*;
// // setup environment
// let p = ProgramParser::new().parse(prog1!()).unwrap();
// let fn_env = new_fn_env(&p.fn_decls);
// let type_env = new_type_env(&p.type_decls);
// let mut var_env = VarEnv::new();
// trace!("{}", &p);
// let b = fn_env.get(&"b").unwrap();
// let body = &b.body;
// trace!("{}", &body);
// trace!("{:?}", check_stmts(body, &fn_env, &type_env, &mut var_env));
// }
// #[test]
// fn test_expr_type() {
// use crate::grammar::*;
// use crate::*;
// use Type::*;
// // setup environment
// let i = prog1!();
// println!("{}", i);
// let p = ProgramParser::new().parse(prog1!()).unwrap();
// let fn_env = new_fn_env(&p.fn_decls);
// let type_env = new_type_env(&p.type_decls);
// let mut var_env = VarEnv::new();
// var_env.push_empty_scope();
// // // some test variables in scope
// var_env.new_id("i".to_string(), I32); // let i : i32 ...
// var_env.new_id("j".to_string(), Unknown); // let i ...
// println!("p {}", p);
// // type of number
// assert_eq!(
// expr_type(&Expr::Num(1), &fn_env, &type_env, &mut var_env),
// Ok(I32)
// );
// // type of variables
// // not found
// assert!(expr_type(&Expr::Id("a".to_string()), &fn_env, &type_env, &mut var_env).is_err());
// // let i: i32 ...
// assert_eq!(
// expr_type(&Expr::Id("i".to_string()), &fn_env, &type_env, &mut var_env),
// Ok(I32)
// );
// // let j ... (has no type yet)
// assert_eq!(
// expr_type(&Expr::Id("j".to_string()), &fn_env, &type_env, &mut var_env),
// Ok(Unknown)
// );
// // // let n: A ...
// // assert_eq!(
// // expr_type(&Expr::Id("n".to_string()), &fn_env, &type_env, &var_env),
// // Ok(Named("A".to_string()))
// // );
// // type of arithmetic operation (for now just i32)
// assert_eq!(
// expr_type(
// &*ExprParser::new().parse("1 + 2 - 5").unwrap(),
// &fn_env,
// &type_env,
// &mut var_env
// ),
// Ok(I32)
// );
// // type of arithmetic unary operation (for now just i32)
// assert_eq!(
// expr_type(
// &*ExprParser::new().parse("- 5").unwrap(),
// &fn_env,
// &type_env,
// &mut var_env
// ),
// Ok(I32)
// );
// // call, with check, ok
// assert_eq!(
// expr_type(
// &*ExprParser::new().parse("b(1)").unwrap(),
// &fn_env,
// &type_env,
// &mut var_env
// ),
// Ok(I32)
// );
// // call, with check, ok (i: i32)
// assert_eq!(
// expr_type(
// &*ExprParser::new().parse("b(i)").unwrap(),
// &fn_env,
// &type_env,
// &mut var_env
// ),
// Ok(I32)
// );
// // call, with check, error wrong number args
// assert!(expr_type(
// &*ExprParser::new().parse("b(1, 2)").unwrap(),
// &fn_env,
// &type_env,
// &mut var_env
// )
// .is_err());
// // call, with check, error type of arg
// assert!(expr_type(
// &*ExprParser::new().parse("b(true)").unwrap(),
// &fn_env,
// &type_env,
// &mut var_env
// )
// .is_err());
// // call, with check, ok (i: i32)
// assert_eq!(
// expr_type(
// &*ExprParser::new().parse("c(n)").unwrap(),
// &fn_env,
// &type_env,
// &var_env
// ),
// Ok(Unit)
// );
// TODO, ref/ref mut/deref
// }
This diff is collapsed.
Click to expand it.
src/lib.rs
+
2
−
0
View file @
2db9d21c
...
@@ -11,6 +11,8 @@ pub mod check;
...
@@ -11,6 +11,8 @@ pub mod check;
#[macro_use]
#[macro_use]
pub
mod
input
;
pub
mod
input
;
pub
mod
bc_env
;
pub
mod
borrow
;
pub
mod
env
;
pub
mod
env
;
pub
mod
read_file
;
pub
mod
read_file
;
pub
mod
vm
;
pub
mod
vm
;
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment