Fix defining constants

This commit is contained in:
Emi Simpson 2022-04-25 13:05:59 -04:00
parent 2134e96498
commit 1895364870
Signed by: Emi
GPG Key ID: A12F2C2FFDC3D847
2 changed files with 29 additions and 26 deletions

View File

@ -1,5 +1,8 @@
cool_number: Into
cool_number = 1312
main: Int
main = nth_prime 77
main = nth_prime cool_number
nth_prime: Int -> Int
nth_prime n =

View File

@ -183,7 +183,17 @@ impl Expr {
}
Operation::VariantUnion => todo!(),
Operation::FunctionType => todo!(),
Operation::NoOp => ExprEvalResult::Succeeded(Value::Int(0)),
Operation::NoOp => {
// Look up the value, if it's a zero-arg function, evaluate it
let apparent_value =
bindings.lookup(&self.identifier)
.ok_or_else(|| EvaluateError::UndefinedValue(self.identifier.clone()))?;
match apparent_value {
Value::Function(args, exprs) if args.is_empty() =>
ExprEvalResult::EvaluateThis(exprs, LinkedList::new()),
val => ExprEvalResult::Succeeded(val.clone()),
}
}
Operation::Conditional(cases) => {
let mut arguments = arguments;
let value =
@ -280,11 +290,7 @@ pub fn get_last_ident(exprs: &LinkedList<Expr>) -> Option<Identifier> {
}
pub fn evaluate(mut exprs: LinkedList<Expr>, mut bindings: ValueBindings) -> evaluation::Result { loop { return
if exprs.iter().all(|e| !e.isnt_noop()) {
bindings.lookup(&exprs.back().ok_or(EvaluateError::EvaluatingZeroLengthExpr)?.identifier)
.ok_or_else(|| EvaluateError::UndefinedValue(exprs.back().unwrap().identifier.clone()))
.cloned()
} else if exprs.len() == 1 {
if exprs.len() == 1 {
let instr = exprs.back().unwrap();
let res = instr.evaluate(&bindings);
match res {
@ -303,25 +309,19 @@ pub fn evaluate(mut exprs: LinkedList<Expr>, mut bindings: ValueBindings) -> eva
}
} else {
let first_instruction = exprs.pop_front().ok_or(EvaluateError::EvaluatingZeroLengthExpr)?;
if first_instruction.isnt_noop() {
let res = first_instruction.evaluate(&bindings);
let res_value = match res {
ExprEvalResult::Succeeded(v) => v,
ExprEvalResult::EvaluateThis(code, new_bindings) => {
let local_scope = bindings.nested_scope()
.bind_all(new_bindings);
evaluate(code.clone(), local_scope)?
},
ExprEvalResult::Failed(e) => return Err(e),
};
let res = first_instruction.evaluate(&bindings);
let res_value = match res {
ExprEvalResult::Succeeded(v) => v,
ExprEvalResult::EvaluateThis(code, new_bindings) => {
let local_scope = bindings.nested_scope()
.bind_all(new_bindings);
evaluate(code.clone(), local_scope)?
},
ExprEvalResult::Failed(e) => return Err(e),
};
exprs = exprs;
bindings = bindings.bind(&first_instruction.identifier, res_value);
continue; // Tail-recursive "call"
} else {
exprs = exprs;
bindings = bindings;
continue; // Tail-recursive "call"
}
exprs = exprs;
bindings = bindings.bind(&first_instruction.identifier, res_value);
continue; // Tail-recursive "call"
}
}}