Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
recursive enviroments simplified
Browse files Browse the repository at this point in the history
gabriel-barrett committed Dec 22, 2023
1 parent bc6ad82 commit ac23188
Showing 1 changed file with 28 additions and 56 deletions.
84 changes: 28 additions & 56 deletions src/lem/eval.rs
Original file line number Diff line number Diff line change
@@ -665,15 +665,6 @@ fn match_and_run_cproc(cprocs: &[(&Symbol, usize)]) -> Func {
fn reduce(cprocs: &[(&Symbol, usize)]) -> Func {
// Auxiliary functions
let car_cdr = car_cdr();
let env_to_use = func!(env_to_use(smaller_env, smaller_rec_env): 1 => {
match smaller_rec_env.tag {
Expr::Nil => {
return (smaller_env)
}
};
let env: Expr::Cons = cons2(smaller_rec_env, smaller_env);
return (env)
});
let expand_bindings = func!(expand_bindings(head, body, body1, rest_bindings): 1 => {
match rest_bindings.tag {
Expr::Nil => {
@@ -836,29 +827,22 @@ fn reduce(cprocs: &[(&Symbol, usize)]) -> Func {
return (expr, env, error, binding)
}
};
let (var_or_rec_binding, val_or_more_rec_env) = car_cdr(binding);
match var_or_rec_binding.tag {
let (var, val) = decons2(binding);
match var.tag {
Expr::Sym => {
let eq_val = eq_val(var_or_rec_binding, expr);
let eq_val = eq_val(var, expr);
if eq_val {
return (val_or_more_rec_env, env, non_rec, binding)
return (val, env, non_rec, binding)
}
return (expr, smaller_env, not_found, binding)
}
Expr::Cons => {
let (v2, val2) = decons2(var_or_rec_binding);

let eq_val = eq_val(v2, expr);
// This is a hack to signal that the binding came from a letrec
Expr::Thunk => {
let eq_val = eq_val(var, expr);
if eq_val {
match val2.tag {
Expr::Fun => {
return (val2, env, rec, binding)
}
};
return (val2, env, non_rec, binding)
return (val, env, rec, binding)
}
let (env_to_use) = env_to_use(smaller_env, val_or_more_rec_env);
return (expr, env_to_use, not_found, binding)
return (expr, smaller_env, not_found, binding)
}
};
return (expr, env, error, binding)
@@ -912,6 +896,7 @@ fn reduce(cprocs: &[(&Symbol, usize)]) -> Func {
let not_found = Symbol("not_found");
let (expr, env, found, binding) = lookup(expr, env, not_found, nil);
let (expr, env, found, binding) = lookup(expr, env, found, binding);
let (expr, env, found, binding) = lookup(expr, env, found, binding);
match symbol found {
"error" => {
return (expr, env, err, errctrl)
@@ -920,12 +905,17 @@ fn reduce(cprocs: &[(&Symbol, usize)]) -> Func {
return (expr, env, cont, apply)
}
"rec" => {
// if `val2` is a closure, then extend its environment
let (arg, body, closed_env, _foo) = decons4(expr);
let extended: Expr::Cons = cons2(binding, closed_env);
// and return the extended closure
let fun: Expr::Fun = cons4(arg, body, extended, foo);
return (fun, env, cont, apply)
match expr.tag {
Expr::Fun => {
// if `val2` is a closure, then extend its environment
let (arg, body, closed_env, _foo) = decons4(expr);
let extended: Expr::Cons = cons2(binding, closed_env);
// and return the extended closure
let fun: Expr::Fun = cons4(arg, body, extended, foo);
return (fun, env, cont, apply)
}
};
return (expr, env, cont, apply)
}
"not_found" => {
return (expr, env, cont, ret)
@@ -1171,27 +1161,6 @@ fn choose_cproc_call(cprocs: &[(&Symbol, usize)], ivc: bool) -> Func {

fn apply_cont(cprocs: &[(&Symbol, usize)], ivc: bool) -> Func {
let car_cdr = car_cdr();
let extend_rec = func!(extend_rec(env, var, result): 1 => {
let nil = Symbol("nil");
let nil = cast(nil, Expr::Nil);
let sym: Expr::Sym;
let (binding_or_env, rest) = car_cdr(env);
let (var_or_binding, _val_or_more_bindings) = car_cdr(binding_or_env);
let binding: Expr::Cons = cons2(var, result);
let var_or_binding_is_sym = eq_tag(var_or_binding, sym);
let var_or_binding_is_nil = eq_tag(var_or_binding, nil);
let var_or_binding_is_sym_or_nil = or(var_or_binding_is_sym, var_or_binding_is_nil);
if var_or_binding_is_sym_or_nil {
// It's a var, so we are extending a simple env with a recursive env.
let list: Expr::Cons = cons2(binding, nil);
let res: Expr::Cons = cons2(list, env);
return (res)
}
// It's a binding, so we are extending a recursive env.
let cons2: Expr::Cons = cons2(binding, binding_or_env);
let res: Expr::Cons = cons2(cons2, rest);
return (res)
});
// Returns 0u64 if both arguments are U64, 0 (num) if the arguments are some kind of number (either U64 or Num),
// and nil otherwise
let args_num_type = func!(args_num_type(arg1, arg2): 1 => {
@@ -1335,7 +1304,10 @@ fn apply_cont(cprocs: &[(&Symbol, usize)], ivc: bool) -> Func {
}
Cont::LetRec => {
let (var, saved_env, body, cont) = decons4(cont);
let (extended_env) = extend_rec(saved_env, var, result);
// This is a hack to signal that the binding came from a letrec
let var = cast(var, Expr::Thunk);
let binding: Expr::Cons = cons2(var, result);
let extended_env: Expr::Cons = cons2(binding, saved_env);
return (body, extended_env, cont, ret)
}
Cont::Unop => {
@@ -1768,7 +1740,7 @@ mod tests {
assert_eq!(
func.slots_count,
SlotsCounter {
hash4: 15,
hash4: 14,
hash6: 0,
hash8: 6,
commitment: 1,
@@ -1779,8 +1751,8 @@ mod tests {
expected.assert_eq(&computed.to_string());
};
expect_eq(cs.num_inputs(), expect!["1"]);
expect_eq(cs.aux().len(), expect!["9185"]);
expect_eq(cs.num_constraints(), expect!["11127"]);
expect_eq(cs.aux().len(), expect!["8883"]);
expect_eq(cs.num_constraints(), expect!["10830"]);
assert_eq!(func.num_constraints(&store), cs.num_constraints());
}
}

0 comments on commit ac23188

Please sign in to comment.