feat: impl ifThenElse kinda
Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
parent
83b9294ac1
commit
22f90bf07f
|
@ -1,4 +1,4 @@
|
|||
(program
|
||||
1.0.0
|
||||
[ (force (builtin ifThenElse)) (con bool True) (con integer 1) (con string "yo") ]
|
||||
[ (builtin ifThenElse) (con bool True) (con integer 1) (con string "yo") ]
|
||||
)
|
||||
|
|
|
@ -92,12 +92,21 @@ fn main() -> anyhow::Result<()> {
|
|||
Program::<NamedDeBruijn>::try_from(prog)?
|
||||
};
|
||||
|
||||
let term = program.eval()?;
|
||||
let (term, cost, _logs) = program.eval();
|
||||
|
||||
match term {
|
||||
Ok(term) => {
|
||||
let term: Term<Name> = term.try_into()?;
|
||||
|
||||
println!("{}", term.to_pretty());
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
println!("Costs - memory: {} & cpu: {}", cost.mem, cost.cpu);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
builtins::DefaultFunction,
|
||||
debruijn::{self, Converter},
|
||||
machine::{
|
||||
cost_model::{ExBudget, CostModel},
|
||||
cost_model::{CostModel, ExBudget},
|
||||
Machine,
|
||||
},
|
||||
};
|
||||
|
@ -406,11 +406,17 @@ impl From<Term<FakeNamedDeBruijn>> for Term<NamedDeBruijn> {
|
|||
}
|
||||
|
||||
impl Program<NamedDeBruijn> {
|
||||
pub fn eval(&self) -> Result<Term<NamedDeBruijn>, crate::machine::Error> {
|
||||
pub fn eval(
|
||||
&self,
|
||||
) -> (
|
||||
Result<Term<NamedDeBruijn>, crate::machine::Error>,
|
||||
ExBudget,
|
||||
Vec<String>,
|
||||
) {
|
||||
let mut machine = Machine::new(CostModel::default(), ExBudget::default(), 200);
|
||||
|
||||
let (term, _, _) = machine.run(&self.term)?;
|
||||
let term = machine.run(&self.term);
|
||||
|
||||
Ok(term)
|
||||
(term, machine.ex_budget, machine.logs)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,12 @@ use self::{cost_model::CostModel, runtime::BuiltinRuntime};
|
|||
|
||||
pub struct Machine {
|
||||
costs: CostModel,
|
||||
ex_budget: ExBudget,
|
||||
pub ex_budget: ExBudget,
|
||||
frames: Vec<Context>,
|
||||
slippage: u32,
|
||||
env: Vec<Value>,
|
||||
unbudgeted_steps: [u32; 8],
|
||||
pub logs: Vec<String>,
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
|
@ -30,20 +31,16 @@ impl Machine {
|
|||
frames: vec![Context::NoFrame],
|
||||
env: vec![],
|
||||
unbudgeted_steps: [0; 8],
|
||||
logs: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(
|
||||
&mut self,
|
||||
term: &Term<NamedDeBruijn>,
|
||||
) -> Result<(Term<NamedDeBruijn>, usize, Vec<String>), Error> {
|
||||
pub fn run(&mut self, term: &Term<NamedDeBruijn>) -> Result<Term<NamedDeBruijn>, Error> {
|
||||
let startup_budget = self.costs.machine_costs.get(StepKind::StartUp);
|
||||
|
||||
self.spend_budget(startup_budget)?;
|
||||
|
||||
let res = self.compute(term)?;
|
||||
|
||||
Ok((res, 0, vec![]))
|
||||
self.compute(term)
|
||||
}
|
||||
|
||||
fn compute(&mut self, term: &Term<NamedDeBruijn>) -> Result<Term<NamedDeBruijn>, Error> {
|
||||
|
@ -106,7 +103,7 @@ impl Machine {
|
|||
}
|
||||
|
||||
fn return_compute(&mut self, value: Value) -> Result<Term<NamedDeBruijn>, Error> {
|
||||
// TODO: avoid unwrap if possible and just return an err when None
|
||||
// avoid unwrap if possible and just return an err when None
|
||||
// but honestly it should never be empty anyways because Machine
|
||||
// is initialized with `Context::NoFrame`.
|
||||
let frame = self.frames.last().cloned().unwrap();
|
||||
|
@ -197,7 +194,9 @@ impl Machine {
|
|||
match value {
|
||||
Value::Delay(body) => self.compute(&body),
|
||||
Value::Builtin { fun, term, runtime } => {
|
||||
let force_term = Term::Force(Box::new(term));
|
||||
let force_term = Term::Force(Box::new(dbg!(term)));
|
||||
|
||||
if runtime.is_all() {}
|
||||
println!("{:#?}", runtime);
|
||||
todo!()
|
||||
}
|
||||
|
@ -342,9 +341,14 @@ impl Value {
|
|||
matches!(self, Value::Con(Constant::Integer(_)))
|
||||
}
|
||||
|
||||
pub fn is_bool(&self) -> bool {
|
||||
matches!(self, Value::Con(Constant::Bool(_)))
|
||||
}
|
||||
|
||||
pub fn to_ex_mem(&self) -> i64 {
|
||||
match self {
|
||||
Value::Con(_) => todo!(),
|
||||
// TODO: this is not 1
|
||||
Value::Con(_) => 1,
|
||||
Value::Delay(_) => 1,
|
||||
Value::Lambda { .. } => 1,
|
||||
Value::Builtin { .. } => 1,
|
||||
|
|
|
@ -569,7 +569,18 @@ impl BuiltinCosts {
|
|||
DefaultFunction::EqualsString => todo!(),
|
||||
DefaultFunction::EncodeUtf8 => todo!(),
|
||||
DefaultFunction::DecodeUtf8 => todo!(),
|
||||
DefaultFunction::IfThenElse => todo!(),
|
||||
DefaultFunction::IfThenElse => ExBudget {
|
||||
mem: self.if_then_else.mem.cost(
|
||||
args[0].to_ex_mem(),
|
||||
args[1].to_ex_mem(),
|
||||
args[2].to_ex_mem(),
|
||||
),
|
||||
cpu: self.if_then_else.cpu.cost(
|
||||
args[0].to_ex_mem(),
|
||||
args[1].to_ex_mem(),
|
||||
args[2].to_ex_mem(),
|
||||
),
|
||||
},
|
||||
DefaultFunction::ChooseUnit => todo!(),
|
||||
DefaultFunction::Trace => todo!(),
|
||||
DefaultFunction::FstPair => todo!(),
|
||||
|
|
|
@ -48,12 +48,16 @@ impl BuiltinRuntime {
|
|||
self.args.len() == self.fun.arity()
|
||||
}
|
||||
|
||||
pub fn is_all(&self) -> bool {
|
||||
self.args.is_empty()
|
||||
}
|
||||
|
||||
pub fn call(&self) -> Result<Value, Error> {
|
||||
self.fun.call(&self.args)
|
||||
}
|
||||
|
||||
pub fn push(&mut self, arg: Value) -> Result<(), Error> {
|
||||
self.fun.check_type(&arg)?;
|
||||
self.fun.check_type(&arg, &self.args)?;
|
||||
|
||||
self.args.push(arg);
|
||||
|
||||
|
@ -102,7 +106,7 @@ impl DefaultFunction {
|
|||
DefaultFunction::EqualsString => todo!(),
|
||||
DefaultFunction::EncodeUtf8 => todo!(),
|
||||
DefaultFunction::DecodeUtf8 => todo!(),
|
||||
DefaultFunction::IfThenElse => todo!(),
|
||||
DefaultFunction::IfThenElse => 3,
|
||||
DefaultFunction::ChooseUnit => todo!(),
|
||||
DefaultFunction::Trace => todo!(),
|
||||
DefaultFunction::FstPair => todo!(),
|
||||
|
@ -131,7 +135,11 @@ impl DefaultFunction {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_type(&self, arg: &Value) -> Result<(), Error> {
|
||||
pub fn force_count() -> i32 {
|
||||
3
|
||||
}
|
||||
|
||||
pub fn check_type(&self, arg: &Value, args: &[Value]) -> Result<(), Error> {
|
||||
match self {
|
||||
DefaultFunction::AddInteger => {
|
||||
if arg.is_integer() {
|
||||
|
@ -167,7 +175,17 @@ impl DefaultFunction {
|
|||
DefaultFunction::EqualsString => todo!(),
|
||||
DefaultFunction::EncodeUtf8 => todo!(),
|
||||
DefaultFunction::DecodeUtf8 => todo!(),
|
||||
DefaultFunction::IfThenElse => todo!(),
|
||||
DefaultFunction::IfThenElse => {
|
||||
if args.is_empty() {
|
||||
if arg.is_bool() {
|
||||
return Ok(());
|
||||
} else {
|
||||
todo!("type error")
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
DefaultFunction::ChooseUnit => todo!(),
|
||||
DefaultFunction::Trace => todo!(),
|
||||
DefaultFunction::FstPair => todo!(),
|
||||
|
@ -237,7 +255,16 @@ impl DefaultFunction {
|
|||
DefaultFunction::EqualsString => todo!(),
|
||||
DefaultFunction::EncodeUtf8 => todo!(),
|
||||
DefaultFunction::DecodeUtf8 => todo!(),
|
||||
DefaultFunction::IfThenElse => todo!(),
|
||||
DefaultFunction::IfThenElse => match args[0] {
|
||||
Value::Con(Constant::Bool(condition)) => {
|
||||
if condition {
|
||||
Ok(args[1].clone())
|
||||
} else {
|
||||
Ok(args[2].clone())
|
||||
}
|
||||
}
|
||||
_ => todo!("handle error"),
|
||||
},
|
||||
DefaultFunction::ChooseUnit => todo!(),
|
||||
DefaultFunction::Trace => todo!(),
|
||||
DefaultFunction::FstPair => todo!(),
|
||||
|
|
Loading…
Reference in New Issue