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: Int
main = nth_prime 77 main = nth_prime cool_number
nth_prime: Int -> Int nth_prime: Int -> Int
nth_prime n = nth_prime n =

View File

@ -183,7 +183,17 @@ impl Expr {
} }
Operation::VariantUnion => todo!(), Operation::VariantUnion => todo!(),
Operation::FunctionType => 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) => { Operation::Conditional(cases) => {
let mut arguments = arguments; let mut arguments = arguments;
let value = 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 pub fn evaluate(mut exprs: LinkedList<Expr>, mut bindings: ValueBindings) -> evaluation::Result { loop { return
if exprs.iter().all(|e| !e.isnt_noop()) { if exprs.len() == 1 {
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 {
let instr = exprs.back().unwrap(); let instr = exprs.back().unwrap();
let res = instr.evaluate(&bindings); let res = instr.evaluate(&bindings);
match res { match res {
@ -303,25 +309,19 @@ pub fn evaluate(mut exprs: LinkedList<Expr>, mut bindings: ValueBindings) -> eva
} }
} else { } else {
let first_instruction = exprs.pop_front().ok_or(EvaluateError::EvaluatingZeroLengthExpr)?; let first_instruction = exprs.pop_front().ok_or(EvaluateError::EvaluatingZeroLengthExpr)?;
if first_instruction.isnt_noop() { let res = first_instruction.evaluate(&bindings);
let res = first_instruction.evaluate(&bindings); let res_value = match res {
let res_value = match res { ExprEvalResult::Succeeded(v) => v,
ExprEvalResult::Succeeded(v) => v, ExprEvalResult::EvaluateThis(code, new_bindings) => {
ExprEvalResult::EvaluateThis(code, new_bindings) => { let local_scope = bindings.nested_scope()
let local_scope = bindings.nested_scope() .bind_all(new_bindings);
.bind_all(new_bindings); evaluate(code.clone(), local_scope)?
evaluate(code.clone(), local_scope)? },
}, ExprEvalResult::Failed(e) => return Err(e),
ExprEvalResult::Failed(e) => return Err(e), };
};
exprs = exprs; exprs = exprs;
bindings = bindings.bind(&first_instruction.identifier, res_value); bindings = bindings.bind(&first_instruction.identifier, res_value);
continue; // Tail-recursive "call" continue; // Tail-recursive "call"
} else {
exprs = exprs;
bindings = bindings;
continue; // Tail-recursive "call"
}
} }
}} }}