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
|
(program
|
||||||
1.0.0
|
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)?
|
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()?;
|
let term: Term<Name> = term.try_into()?;
|
||||||
|
|
||||||
println!("{}", term.to_pretty());
|
println!("{}", term.to_pretty());
|
||||||
}
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("{}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Costs - memory: {} & cpu: {}", cost.mem, cost.cpu);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
builtins::DefaultFunction,
|
builtins::DefaultFunction,
|
||||||
debruijn::{self, Converter},
|
debruijn::{self, Converter},
|
||||||
machine::{
|
machine::{
|
||||||
cost_model::{ExBudget, CostModel},
|
cost_model::{CostModel, ExBudget},
|
||||||
Machine,
|
Machine,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -406,11 +406,17 @@ impl From<Term<FakeNamedDeBruijn>> for Term<NamedDeBruijn> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Program<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 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 {
|
pub struct Machine {
|
||||||
costs: CostModel,
|
costs: CostModel,
|
||||||
ex_budget: ExBudget,
|
pub ex_budget: ExBudget,
|
||||||
frames: Vec<Context>,
|
frames: Vec<Context>,
|
||||||
slippage: u32,
|
slippage: u32,
|
||||||
env: Vec<Value>,
|
env: Vec<Value>,
|
||||||
unbudgeted_steps: [u32; 8],
|
unbudgeted_steps: [u32; 8],
|
||||||
|
pub logs: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
|
@ -30,20 +31,16 @@ impl Machine {
|
||||||
frames: vec![Context::NoFrame],
|
frames: vec![Context::NoFrame],
|
||||||
env: vec![],
|
env: vec![],
|
||||||
unbudgeted_steps: [0; 8],
|
unbudgeted_steps: [0; 8],
|
||||||
|
logs: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(
|
pub fn run(&mut self, term: &Term<NamedDeBruijn>) -> Result<Term<NamedDeBruijn>, Error> {
|
||||||
&mut self,
|
|
||||||
term: &Term<NamedDeBruijn>,
|
|
||||||
) -> Result<(Term<NamedDeBruijn>, usize, Vec<String>), Error> {
|
|
||||||
let startup_budget = self.costs.machine_costs.get(StepKind::StartUp);
|
let startup_budget = self.costs.machine_costs.get(StepKind::StartUp);
|
||||||
|
|
||||||
self.spend_budget(startup_budget)?;
|
self.spend_budget(startup_budget)?;
|
||||||
|
|
||||||
let res = self.compute(term)?;
|
self.compute(term)
|
||||||
|
|
||||||
Ok((res, 0, vec![]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute(&mut self, term: &Term<NamedDeBruijn>) -> Result<Term<NamedDeBruijn>, Error> {
|
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> {
|
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
|
// but honestly it should never be empty anyways because Machine
|
||||||
// is initialized with `Context::NoFrame`.
|
// is initialized with `Context::NoFrame`.
|
||||||
let frame = self.frames.last().cloned().unwrap();
|
let frame = self.frames.last().cloned().unwrap();
|
||||||
|
@ -197,7 +194,9 @@ impl Machine {
|
||||||
match value {
|
match value {
|
||||||
Value::Delay(body) => self.compute(&body),
|
Value::Delay(body) => self.compute(&body),
|
||||||
Value::Builtin { fun, term, runtime } => {
|
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);
|
println!("{:#?}", runtime);
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -342,9 +341,14 @@ impl Value {
|
||||||
matches!(self, Value::Con(Constant::Integer(_)))
|
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 {
|
pub fn to_ex_mem(&self) -> i64 {
|
||||||
match self {
|
match self {
|
||||||
Value::Con(_) => todo!(),
|
// TODO: this is not 1
|
||||||
|
Value::Con(_) => 1,
|
||||||
Value::Delay(_) => 1,
|
Value::Delay(_) => 1,
|
||||||
Value::Lambda { .. } => 1,
|
Value::Lambda { .. } => 1,
|
||||||
Value::Builtin { .. } => 1,
|
Value::Builtin { .. } => 1,
|
||||||
|
|
|
@ -569,7 +569,18 @@ impl BuiltinCosts {
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => todo!(),
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => todo!(),
|
||||||
DefaultFunction::DecodeUtf8 => 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::ChooseUnit => todo!(),
|
||||||
DefaultFunction::Trace => todo!(),
|
DefaultFunction::Trace => todo!(),
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
|
|
|
@ -48,12 +48,16 @@ impl BuiltinRuntime {
|
||||||
self.args.len() == self.fun.arity()
|
self.args.len() == self.fun.arity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_all(&self) -> bool {
|
||||||
|
self.args.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn call(&self) -> Result<Value, Error> {
|
pub fn call(&self) -> Result<Value, Error> {
|
||||||
self.fun.call(&self.args)
|
self.fun.call(&self.args)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, arg: Value) -> Result<(), Error> {
|
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);
|
self.args.push(arg);
|
||||||
|
|
||||||
|
@ -102,7 +106,7 @@ impl DefaultFunction {
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => todo!(),
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => todo!(),
|
||||||
DefaultFunction::DecodeUtf8 => todo!(),
|
DefaultFunction::DecodeUtf8 => todo!(),
|
||||||
DefaultFunction::IfThenElse => todo!(),
|
DefaultFunction::IfThenElse => 3,
|
||||||
DefaultFunction::ChooseUnit => todo!(),
|
DefaultFunction::ChooseUnit => todo!(),
|
||||||
DefaultFunction::Trace => todo!(),
|
DefaultFunction::Trace => todo!(),
|
||||||
DefaultFunction::FstPair => 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 {
|
match self {
|
||||||
DefaultFunction::AddInteger => {
|
DefaultFunction::AddInteger => {
|
||||||
if arg.is_integer() {
|
if arg.is_integer() {
|
||||||
|
@ -167,7 +175,17 @@ impl DefaultFunction {
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => todo!(),
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => todo!(),
|
||||||
DefaultFunction::DecodeUtf8 => 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::ChooseUnit => todo!(),
|
||||||
DefaultFunction::Trace => todo!(),
|
DefaultFunction::Trace => todo!(),
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
|
@ -237,7 +255,16 @@ impl DefaultFunction {
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => todo!(),
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => todo!(),
|
||||||
DefaultFunction::DecodeUtf8 => 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::ChooseUnit => todo!(),
|
||||||
DefaultFunction::Trace => todo!(),
|
DefaultFunction::Trace => todo!(),
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
|
|
Loading…
Reference in New Issue