fix: start trying to get rid of recursion for discharge value

This commit is contained in:
rvcas 2023-01-28 02:05:46 -05:00 committed by Lucas
parent cb8bdac39d
commit 790e8ba680
2 changed files with 79 additions and 59 deletions

View File

@ -32,6 +32,11 @@ impl TryFrom<Option<MachineStep>> for Term<NamedDeBruijn> {
} }
} }
enum DischargeStep {
DischargeValue(Value),
DischargeValueEnv(usize, Rc<Vec<Value>>, Rc<Term<NamedDeBruijn>>),
}
pub struct Machine { pub struct Machine {
costs: CostModel, costs: CostModel,
pub ex_budget: ExBudget, pub ex_budget: ExBudget,
@ -205,69 +210,84 @@ impl Machine {
} }
fn discharge_value(&mut self, value: Value) -> Rc<Term<NamedDeBruijn>> { fn discharge_value(&mut self, value: Value) -> Rc<Term<NamedDeBruijn>> {
match value { let mut stack = vec![DischargeStep::DischargeValue(value)];
Value::Con(x) => Rc::new(Term::Constant(x)),
Value::Builtin { term, .. } => term,
Value::Delay(body, env) => self.discharge_value_env(env, Rc::new(Term::Delay(body))),
Value::Lambda {
parameter_name,
body,
env,
} => self.discharge_value_env(
env,
Rc::new(Term::Lambda {
parameter_name: NamedDeBruijn {
text: parameter_name.text,
index: 0.into(),
},
body,
}),
),
}
}
fn discharge_value_env( while let Some(stack_frame) = stack.pop() {
&mut self, match stack_frame {
env: Rc<Vec<Value>>, DischargeStep::DischargeValue(value) => match value {
term: Rc<Term<NamedDeBruijn>>, Value::Con(x) => Rc::new(Term::Constant(x)),
) -> Rc<Term<NamedDeBruijn>> { Value::Builtin { term, .. } => term,
fn rec( Value::Delay(body, env) => {
lam_cnt: usize, stack.push(DischargeStep::DischargeValueEnv(
t: Rc<Term<NamedDeBruijn>>, 0,
this: &mut Machine, env,
env: Rc<Vec<Value>>, Rc::new(Term::Delay(body)),
) -> Rc<Term<NamedDeBruijn>> { ));
match t.as_ref() {
Term::Var(name) => {
let index: usize = name.index.into();
if lam_cnt >= index {
Rc::new(Term::Var(name.clone()))
} else {
env.get::<usize>(env.len() - (index - lam_cnt))
.cloned()
.map_or(Rc::new(Term::Var(name.clone())), |v| {
this.discharge_value(v)
})
} }
} Value::Lambda {
Term::Lambda { parameter_name,
parameter_name, body,
body, env,
} => Rc::new(Term::Lambda { } => {
parameter_name: parameter_name.clone(), stack.push(DischargeStep::DischargeValueEnv(
body: rec(lam_cnt + 1, Rc::clone(body), this, env), 0,
}), env,
Term::Apply { function, argument } => Rc::new(Term::Apply { Rc::new(Term::Lambda {
function: rec(lam_cnt, Rc::clone(function), this, Rc::clone(&env)), parameter_name: NamedDeBruijn {
argument: rec(lam_cnt, Rc::clone(argument), this, env), text: parameter_name.text,
}), index: 0.into(),
},
body,
}),
));
}
},
DischargeStep::DischargeValueEnv(lam_cnt, env, term) => match term.as_ref() {
Term::Var(name) => {
let index: usize = name.index.into();
Term::Delay(x) => Rc::new(Term::Delay(rec(lam_cnt, Rc::clone(x), this, env))), if lam_cnt >= index {
Term::Force(x) => Rc::new(Term::Force(rec(lam_cnt, Rc::clone(x), this, env))), Rc::new(Term::Var(name.clone()))
rest => Rc::new(rest.clone()), } else {
env.get::<usize>(env.len() - (index - lam_cnt))
.cloned()
.map_or(Rc::new(Term::Var(name.clone())), |v| {
self.discharge_value(v)
})
}
}
Term::Lambda {
parameter_name,
body,
} => Rc::new(Term::Lambda {
parameter_name: parameter_name.clone(),
body: self.discharge_value_env(lam_cnt + 1, env, Rc::clone(body)),
}),
Term::Apply { function, argument } => Rc::new(Term::Apply {
function: self.discharge_value_env(
lam_cnt,
Rc::clone(&env),
Rc::clone(function),
),
argument: self.discharge_value_env(lam_cnt, env, Rc::clone(argument)),
}),
Term::Delay(x) => Rc::new(Term::Delay(self.discharge_value_env(
lam_cnt,
env,
Rc::clone(x),
))),
Term::Force(x) => Rc::new(Term::Force(self.discharge_value_env(
lam_cnt,
env,
Rc::clone(x),
))),
rest => Rc::new(rest.clone()),
},
} }
} }
rec(0, term, self, env)
todo!()
} }
fn force_evaluate(&mut self, context: Rc<Context>, value: Value) -> Result<(), Error> { fn force_evaluate(&mut self, context: Rc<Context>, value: Value) -> Result<(), Error> {

View File

@ -84,6 +84,6 @@
i_0 i_0
] ]
) )
(con integer 0) (con integer 15)
] ]
) )