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

View File

@ -1,6 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use crate::ast::{Constant, NamedDeBruijn, Term}; use crate::ast::{NamedDeBruijn, Term};
use super::value::{Env, Value}; use super::value::{Env, Value};
@ -19,7 +19,7 @@ enum DischargeStep {
PopArgStack(PartialTerm), 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 stack = vec![DischargeStep::DischargeValue(value)];
let mut arg_stack = vec![]; 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() { while let Some(stack_frame) = stack.pop() {
match stack_frame { match stack_frame {
DischargeStep::DischargeValue(value) => match value { DischargeStep::DischargeValue(value) => match value {
Value::Con(x) => arg_stack.push(Term::Constant(x.clone()).into()), Value::Con(x) => arg_stack.push(Term::Constant(x.clone())),
Value::Builtin { .. } => { Value::Builtin { runtime, fun } => {
arg_stack.push(Term::Constant(Constant::Unit.into()).into()) 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) => { Value::Delay(body, env) => {
stack.push(DischargeStep::DischargeValueEnv( 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(); let index: usize = name.index.into();
if lam_cnt >= index { if lam_cnt >= index {
arg_stack.push(Rc::new(Term::Var(name.clone()))); arg_stack.push(Term::Var(name.clone()));
} else { } else {
let env = env.get::<usize>(env.len() - (index - lam_cnt)).cloned(); let env = env.get::<usize>(env.len() - (index - lam_cnt)).cloned();
if let Some(v) = env { if let Some(v) = env {
stack.push(DischargeStep::DischargeValue(v)); stack.push(DischargeStep::DischargeValue(v));
} else { } 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 => { rest => {
arg_stack.push(rest.to_owned().into()); arg_stack.push(rest.to_owned());
} }
}, },
DischargeStep::PopArgStack(term) => match term { DischargeStep::PopArgStack(term) => match term {
PartialTerm::Delay => { PartialTerm::Delay => {
let body = arg_stack.pop().unwrap(); let body = arg_stack.pop().unwrap();
arg_stack.push(Term::Delay(body).into())
arg_stack.push(Term::Delay(body.into()))
} }
PartialTerm::Lambda(parameter_name) => { PartialTerm::Lambda(parameter_name) => {
let body = arg_stack.pop().unwrap(); let body = arg_stack.pop().unwrap();
arg_stack.push(
Term::Lambda { arg_stack.push(Term::Lambda {
parameter_name, parameter_name,
body, body: body.into(),
} })
.into(),
)
} }
PartialTerm::Apply => { PartialTerm::Apply => {
let argument = arg_stack.pop().unwrap(); let argument = arg_stack.pop().unwrap();
let function = 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 => { PartialTerm::Force => {
let body = arg_stack.pop().unwrap(); 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)] #[derive(Clone, Debug)]
pub struct BuiltinRuntime { pub struct BuiltinRuntime {
args: Vec<Value>, pub(super) args: Vec<Value>,
fun: DefaultFunction, fun: DefaultFunction,
forces: u32, pub(super) forces: u32,
} }
impl BuiltinRuntime { impl BuiltinRuntime {