* remove more Rc's
* reconstruct Value::Builtin only when needed

Co-authored-by: Lucas Rosa <x@rvcas.dev>
This commit is contained in:
microproofs 2023-04-12 18:30:36 -04:00 committed by Lucas
parent 09a6ea51d6
commit 564939ab61
4 changed files with 40 additions and 37 deletions

View File

@ -1,4 +0,0 @@
(program
1.0.0
(lam x [ [ (builtin addInteger) (con integer 1) ] x ])
)

View File

@ -22,13 +22,13 @@ use self::{
enum MachineState {
Return(Context, Value),
Compute(Context, Env, Term<NamedDeBruijn>),
Done(Rc<Term<NamedDeBruijn>>),
Done(Term<NamedDeBruijn>),
}
#[derive(Clone)]
enum Context {
FrameApplyFun(Value, Box<Context>),
FrameApplyArg(Env, Rc<Term<NamedDeBruijn>>, Box<Context>),
FrameApplyArg(Env, Term<NamedDeBruijn>, Box<Context>),
FrameForce(Box<Context>),
NoFrame,
}
@ -73,7 +73,7 @@ impl Machine {
Compute(context, env, t) => self.compute(context, env, t)?,
Return(context, value) => self.return_compute(context, value)?,
Done(t) => {
return Ok(t.as_ref().clone());
return Ok(t);
}
};
}
@ -117,7 +117,7 @@ impl Machine {
self.step_and_maybe_spend(StepKind::Apply)?;
Ok(MachineState::Compute(
Context::FrameApplyArg(Rc::clone(&env), argument, context.into()),
Context::FrameApplyArg(env.clone(), argument.as_ref().clone(), context.into()),
env,
function.as_ref().clone(),
))
@ -156,7 +156,7 @@ impl Machine {
Context::FrameApplyArg(arg_var_env, arg, ctx) => Ok(MachineState::Compute(
Context::FrameApplyFun(value, ctx),
arg_var_env,
arg.as_ref().clone(),
arg,
)),
Context::FrameForce(ctx) => self.force_evaluate(*ctx, value),
Context::NoFrame => {
@ -188,9 +188,9 @@ impl Machine {
Ok(MachineState::Return(context, res))
} else {
Err(Error::BuiltinTermArgumentExpected(Term::Constant(
Constant::Unit.into(),
)))
let term = discharge::value_as_term(Value::Builtin { fun, runtime });
Err(Error::BuiltinTermArgumentExpected(term))
}
}
rest => Err(Error::NonPolymorphicInstantiation(rest)),
@ -216,8 +216,6 @@ impl Machine {
))
}
Value::Builtin { fun, runtime } => {
// let arg_term = discharge::value_as_term(argument.clone());
if runtime.is_arrow() && !runtime.needs_force() {
let mut runtime = runtime;
@ -231,9 +229,9 @@ impl Machine {
Ok(MachineState::Return(context, res))
} else {
Err(Error::UnexpectedBuiltinTermArgument(Term::Constant(
Constant::Unit.into(),
)))
let term = discharge::value_as_term(Value::Builtin { fun, runtime });
Err(Error::UnexpectedBuiltinTermArgument(term))
}
}
rest => Err(Error::NonFunctionalApplication(rest, argument)),

View File

@ -1,6 +1,6 @@
use std::rc::Rc;
use crate::ast::{Constant, NamedDeBruijn, Term};
use crate::ast::{NamedDeBruijn, Term};
use super::value::{Env, Value};
@ -19,7 +19,7 @@ enum DischargeStep {
PopArgStack(PartialTerm),
}
pub(super) fn value_as_term(value: Value) -> Rc<Term<NamedDeBruijn>> {
pub(super) fn value_as_term(value: Value) -> Term<NamedDeBruijn> {
let mut stack = vec![DischargeStep::DischargeValue(value)];
let mut arg_stack = vec![];
@ -27,9 +27,18 @@ pub(super) fn value_as_term(value: Value) -> Rc<Term<NamedDeBruijn>> {
while let Some(stack_frame) = stack.pop() {
match stack_frame {
DischargeStep::DischargeValue(value) => match value {
Value::Con(x) => arg_stack.push(Term::Constant(x.clone()).into()),
Value::Builtin { .. } => {
arg_stack.push(Term::Constant(Constant::Unit.into()).into())
Value::Con(x) => arg_stack.push(Term::Constant(x.clone())),
Value::Builtin { runtime, fun } => {
let mut term = Term::Builtin(fun);
for _ in 0..runtime.forces {
term = term.force();
}
for arg in runtime.args {
term = term.apply(value_as_term(arg));
}
arg_stack.push(term)
}
Value::Delay(body, env) => {
stack.push(DischargeStep::DischargeValueEnv(
@ -59,14 +68,14 @@ pub(super) fn value_as_term(value: Value) -> Rc<Term<NamedDeBruijn>> {
let index: usize = name.index.into();
if lam_cnt >= index {
arg_stack.push(Rc::new(Term::Var(name.clone())));
arg_stack.push(Term::Var(name.clone()));
} else {
let env = env.get::<usize>(env.len() - (index - lam_cnt)).cloned();
if let Some(v) = env {
stack.push(DischargeStep::DischargeValue(v));
} else {
arg_stack.push(Rc::new(Term::Var(name.clone())));
arg_stack.push(Term::Var(name.clone()));
}
}
}
@ -114,33 +123,33 @@ pub(super) fn value_as_term(value: Value) -> Rc<Term<NamedDeBruijn>> {
));
}
rest => {
arg_stack.push(rest.to_owned().into());
arg_stack.push(rest.to_owned());
}
},
DischargeStep::PopArgStack(term) => match term {
PartialTerm::Delay => {
let body = arg_stack.pop().unwrap();
arg_stack.push(Term::Delay(body).into())
arg_stack.push(Term::Delay(body.into()))
}
PartialTerm::Lambda(parameter_name) => {
let body = arg_stack.pop().unwrap();
arg_stack.push(
Term::Lambda {
arg_stack.push(Term::Lambda {
parameter_name,
body,
}
.into(),
)
body: body.into(),
})
}
PartialTerm::Apply => {
let argument = arg_stack.pop().unwrap();
let function = arg_stack.pop().unwrap();
arg_stack.push(Term::Apply { function, argument }.into());
arg_stack.push(function.apply(argument));
}
PartialTerm::Force => {
let body = arg_stack.pop().unwrap();
arg_stack.push(Term::Force(body).into())
arg_stack.push(body.force())
}
},
}

View File

@ -23,9 +23,9 @@ use super::{
#[derive(Clone, Debug)]
pub struct BuiltinRuntime {
args: Vec<Value>,
pub(super) args: Vec<Value>,
fun: DefaultFunction,
forces: u32,
pub(super) forces: u32,
}
impl BuiltinRuntime {