From 3e9b3c4083b0b613e053c23598db21cb9d18bd00 Mon Sep 17 00:00:00 2001 From: Nicolas Abril Date: Thu, 16 May 2024 22:21:36 +0200 Subject: [PATCH] Adapt Bend to new hvm number operation format --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/fun/display.rs | 6 +- src/fun/mod.rs | 53 ++--- src/fun/net_to_term.rs | 190 +++++------------- src/fun/parser.rs | 12 +- src/fun/term_to_net.rs | 71 ++++--- src/imp/parser.rs | 6 +- src/lib.rs | 23 ++- .../readback_lnet/invalid_op2_op2.bend | 2 +- .../golden_tests/run_file/basic_num_ops.bend | 123 ++++++++++++ tests/snapshots/cli__compile_all.bend.snap | 2 +- .../cli__net_size_too_large.bend.snap | 2 +- .../cli__no_check_net_size.bend.snap | 6 +- .../compile_file__add_args.bend.snap | 2 +- .../compile_file__addition.bend.snap | 2 +- .../compile_file__f24_oper.bend.snap | 4 +- .../compile_file__i24_oper.bend.snap | 4 +- tests/snapshots/compile_file__op2.bend.snap | 2 +- ...pile_file__redex_order_recursive.bend.snap | 10 +- .../snapshots/compile_file__tup_add.bend.snap | 2 +- .../compile_file__unused_let.bend.snap | 2 +- .../compile_file_o_all__addition.bend.snap | 2 +- .../compile_file_o_all__eta_chain.bend.snap | 2 +- ...pile_file_o_all__linearize_match.bend.snap | 2 +- ..._o_all__match_mult_linearization.bend.snap | 4 +- .../compile_file_o_all__match_tup.bend.snap | 2 +- ...mpile_file_o_all__sum_predicates.bend.snap | 2 +- .../readback_lnet__addition.bend.snap | 6 +- .../readback_lnet__invalid_op2_op2.bend.snap | 2 +- .../readback_lnet__tup_add.bend.snap | 6 +- .../run_file__basic_num_ops.bend.snap | 9 + tests/snapshots/run_file__exp.bend.snap | 5 +- tests/snapshots/run_file__lam_op2.bend.snap | 12 +- .../run_file__lam_op2_nested.bend.snap | 8 +- 35 files changed, 327 insertions(+), 265 deletions(-) create mode 100644 tests/golden_tests/run_file/basic_num_ops.bend create mode 100644 tests/snapshots/run_file__basic_num_ops.bend.snap diff --git a/Cargo.lock b/Cargo.lock index c6e3373a..dec73f74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,9 +214,9 @@ checksum = "809e18805660d7b6b2e2b9f316a5099521b5998d5cba4dda11b5157a21aaef03" [[package]] name = "hvm-core" -version = "0.3.0-hvm32.compat.2" +version = "0.3.0-hvm32.compat.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1f250a4a29a9bb2e30fc08a712d7c005df761b84249d7d0ecddf3cc59eb02" +checksum = "4dc4ab0e7e0a79b299129792012b15085ff1d114bf3756f5e40269cecf2dd97a" dependencies = [ "TSPL 0.0.9", "arrayvec", diff --git a/Cargo.toml b/Cargo.toml index abdf6703..5b3154bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ cli = ["dep:clap"] TSPL = "0.0.12" clap = { version = "4.4.1", features = ["derive"], optional = true } highlight_error = "0.1.1" -hvm-core = "=0.3.0-hvm32.compat.2" +hvm-core = "=0.3.0-hvm32.compat.3" indexmap = "2.2.3" interner = "0.2.1" itertools = "0.11.0" diff --git a/src/fun/display.rs b/src/fun/display.rs index 91b8a051..ff536625 100644 --- a/src/fun/display.rs +++ b/src/fun/display.rs @@ -227,10 +227,10 @@ impl fmt::Display for Op { Op::MUL => write!(f, "*"), Op::DIV => write!(f, "/"), Op::REM => write!(f, "%"), - Op::EQL => write!(f, "=="), + Op::EQ => write!(f, "=="), Op::NEQ => write!(f, "!="), - Op::LTN => write!(f, "<"), - Op::GTN => write!(f, ">"), + Op::LT => write!(f, "<"), + Op::GT => write!(f, ">"), Op::AND => write!(f, "&"), Op::OR => write!(f, "|"), Op::XOR => write!(f, "^"), diff --git a/src/fun/mod.rs b/src/fun/mod.rs index 1b1f67c0..6bcf6581 100644 --- a/src/fun/mod.rs +++ b/src/fun/mod.rs @@ -3,6 +3,7 @@ use crate::{ fun::builtins::*, maybe_grow, ENTRY_POINT, }; +use hvmc::ast::get_typ; use indexmap::{IndexMap, IndexSet}; use interner::global::{GlobalPool, GlobalString}; use itertools::Itertools; @@ -184,10 +185,10 @@ pub enum Op { MUL, DIV, REM, - EQL, + EQ, NEQ, - LTN, - GTN, + LT, + GT, AND, OR, XOR, @@ -898,41 +899,17 @@ impl Num { pub fn to_bits(&self) -> u32 { match self { - Num::U24(val) => { - assert!(*val <= 0xFFFFFF); - ((val & 0xFFFFFF) << 4) | 0x1 - } - Num::I24(val) => (((*val as u32) & 0xFFFFFF) << 4) | 0x2, - Num::F24(val) => { - let bits = val.to_bits(); - let sign = (bits >> 31) & 0x1; - let expo = (bits >> 23) & 0xFF; - let mantissa = bits & 0x7FFFFF; - assert!( - (expo == 0) || (expo == 255) || (64 ..= 127).contains(&expo) || (128 ..= 190).contains(&expo) - ); - let expo = (expo & 0b0011_1111) | ((expo >> 7) << 6); - let mantissa = mantissa >> 7; - let bits = (sign << 23) | (expo << 16) | mantissa; - (bits << 4) | 0x3 - } + Num::U24(val) => hvmc::ast::new_u24(*val), + Num::I24(val) => hvmc::ast::new_i24(*val), + Num::F24(val) => hvmc::ast::new_f24(*val), } } pub fn from_bits(bits: u32) -> Self { - match bits & 0xF { - 0x1 => Num::U24((bits >> 4) & 0xFFFFFF), - 0x2 => Num::I24((((bits >> 4) & 0xFFFFFF) as i32) << 8 >> 8), - 0x3 => { - let bits = (bits >> 4) & 0xFFFFFF; - let sign = (bits >> 23) & 0x1; - let expo = (bits >> 16) & 0x7F; - let mantissa = bits & 0xFFFF; - let i_exp = (expo as i32) - 63; - let bits = (sign << 31) | (((i_exp + 127) as u32) << 23) | (mantissa << 7); - let bits = if mantissa == 0 && i_exp == -63 { sign << 31 } else { bits }; - Num::F24(f32::from_bits(bits)) - } + match get_typ(bits) { + hvmc::ast::U24 => Num::U24(hvmc::ast::get_u24(bits)), + hvmc::ast::I24 => Num::I24(hvmc::ast::get_i24(bits)), + hvmc::ast::F24 => Num::F24(hvmc::ast::get_f24(bits)), _ => unreachable!("Invalid Num bits"), } } @@ -1121,15 +1098,15 @@ impl Book { fn num_to_from_bits() { let a = [ Num::U24(0), - Num::I24(0), - Num::F24(0.0), Num::U24(0xFFFFFF), - Num::I24(0xFFFFFF), - Num::F24(0xFFFFFF as f32), Num::U24(12345), + Num::I24(0), + Num::I24(0x7FFFFF), Num::I24(12345), Num::I24(-12345), + Num::F24(0.0), Num::I24(-0), + Num::F24(0xFFFFFF as f32), Num::F24(0.0), Num::F24(-0.0), Num::F24(0.00123), diff --git a/src/fun/net_to_term.rs b/src/fun/net_to_term.rs index 2212efcc..9b724bec 100644 --- a/src/fun/net_to_term.rs +++ b/src/fun/net_to_term.rs @@ -1,3 +1,5 @@ +use hvmc::ast::{get_f24, get_i24, get_typ, get_u24}; + use crate::{ diagnostics::{DiagnosticOrigin, Diagnostics, Severity}, fun::{term_to_net::Labels, Book, FanKind, Name, Op, Pattern, Tag, Term}, @@ -211,96 +213,38 @@ impl Reader<'_> { _ => unreachable!(), } } - NodeKind::Num { val: _ } => { - let (flp, arg) = self.read_opr_arg(next); - match arg { - NumArg::Sym(opr) => Term::Oper { - opr: Op::from_native_tag(opr, NumType::U24), - fst: Box::new(Term::Err), - snd: Box::new(Term::Err), - }, - NumArg::Num(typ, val) => Term::Num { val: Num::from_bits_and_type(val, typ) }, - NumArg::Par(opr, val) => { - if flp { - Term::Oper { - opr: Op::from_native_tag(opr, NumType::U24), - fst: Box::new(Term::Num { val: Num::from_bits_and_type(val, NumType::U24) }), - snd: Box::new(Term::Err), - } - } else { - Term::Oper { - opr: Op::from_native_tag(opr, NumType::U24), - fst: Box::new(Term::Err), - snd: Box::new(Term::Num { val: Num::from_bits_and_type(val, NumType::U24) }), - } - } - } - NumArg::Oth(_) => unreachable!(), - } - } + NodeKind::Num { val } => num_from_bits_with_type(*val, *val), NodeKind::Opr => match next.slot() { 2 => { - let port0_kind = self.net.node(self.net.enter_port(Port(node, 0)).node()).kind.clone(); + let port0_node = self.net.enter_port(Port(node, 0)).node(); + let port0_kind = self.net.node(port0_node).kind.clone(); + // two oper in a row if port0_kind == NodeKind::Opr { - // Second half of a numeric operation - let fst = self.read_term(self.net.enter_port(Port(node, 0))); - if let Term::Oper { opr, fst, snd: _ } = &fst { - let (flip, arg) = self.read_opr_arg(self.net.enter_port(Port(node, 1))); - let snd = Box::new(match arg { - NumArg::Num(typ, val) => Term::Num { val: Num::from_bits_and_type(val, typ) }, - NumArg::Oth(term) => term, - NumArg::Sym(_) | NumArg::Par(_, _) => { - self.error(ReadbackError::InvalidNumericOp); - Term::Err - } - }); - let (fst, snd) = if flip { (snd, fst.clone()) } else { (fst.clone(), snd) }; - Term::Oper { opr: *opr, fst, snd } + // TODO: allow for nested oper + let opr_node = self.net.enter_port(Port(port0_node, 0)).node(); + let opr_kind = self.net.node(opr_node).kind.clone(); + let opr = if let NodeKind::Num { val } = opr_kind { + if get_typ(val) != hvmc::ast::SYM { + self.error(ReadbackError::InvalidNumericOp); + return Term::Err; + } + if let Some(op) = Op::from_native_tag(val, NumType::U24) { + op + } else { + self.error(ReadbackError::InvalidNumericOp); + return Term::Err; + } } else { self.error(ReadbackError::InvalidNumericOp); - Term::Err - } + return Term::Err; + }; + let fst = self.read_term(self.net.enter_port(Port(port0_node, 1))); + let snd = self.read_term(self.net.enter_port(Port(node, 1))); + Term::Oper { opr, fst: Box::new(fst), snd: Box::new(snd) } } else { - // First half of a numeric operation - let (flip0, arg0) = self.read_opr_arg(self.net.enter_port(Port(node, 0))); - let (flip1, arg1) = self.read_opr_arg(self.net.enter_port(Port(node, 1))); - let (arg0, arg1) = if flip0 != flip1 { (arg1, arg0) } else { (arg0, arg1) }; - match (arg0, arg1) { - (NumArg::Sym(opr), NumArg::Num(typ, val)) | (NumArg::Num(typ, val), NumArg::Sym(opr)) => { - Term::Oper { - opr: Op::from_native_tag(opr, typ), - fst: Box::new(Term::Num { val: Num::from_bits_and_type(val, typ) }), - snd: Box::new(Term::Err), - } - } - (NumArg::Num(typ, num1), NumArg::Par(opr, num2)) - | (NumArg::Par(opr, num1), NumArg::Num(typ, num2)) => Term::Oper { - opr: Op::from_native_tag(opr, typ), - fst: Box::new(Term::Num { val: Num::from_bits_and_type(num1, typ) }), - snd: Box::new(Term::Num { val: Num::from_bits_and_type(num2, typ) }), - }, - // No type, so assuming u24 - (NumArg::Sym(opr), NumArg::Oth(term)) | (NumArg::Oth(term), NumArg::Sym(opr)) => Term::Oper { - opr: Op::from_native_tag(opr, NumType::U24), - fst: Box::new(term), - snd: Box::new(Term::Err), - }, - - (NumArg::Par(opr, num), NumArg::Oth(term)) => Term::Oper { - opr: Op::from_native_tag(opr, NumType::U24), - fst: Box::new(Term::Num { val: Num::from_bits_and_type(num, NumType::U24) }), - snd: Box::new(term), - }, - (NumArg::Oth(term), NumArg::Par(opr, num)) => Term::Oper { - opr: Op::from_native_tag(opr, NumType::U24), - fst: Box::new(term), - snd: Box::new(Term::Num { val: Num::from_bits_and_type(num, NumType::U24) }), - }, - _ => { - self.error(ReadbackError::InvalidNumericOp); - Term::Err - } - } + // TODO: Fix + self.error(ReadbackError::InvalidNumericOp); + Term::Err } } _ => { @@ -316,31 +260,6 @@ impl Reader<'_> { }) } - fn read_opr_arg(&mut self, next: Port) -> (bool, NumArg) { - let node = next.node(); - match &self.net.node(node).kind { - NodeKind::Num { val } => { - self.seen.insert(next); - let flipped = ((val >> 28) & 0x1) != 0; - let typ = val & 0xf; - let val = (val >> 4) & 0x00ff_ffff; - let arg = match typ { - // Sym - 0x0 => NumArg::Sym(val & 0xf), - // Num - 0x1 ..= 0x3 => NumArg::Num(NumType::from_native_tag(typ), val), - // Partial - opr => NumArg::Par(opr, val), - }; - (flipped, arg) - } - _ => { - let term = self.read_term(next); - (false, NumArg::Oth(term)) - } - } - } - /// Enters both ports 1 and 2 of a node. Returns a Term if it is /// possible to simplify the net, or the Terms on the two ports of the node. /// The two possible outcomes are always equivalent. @@ -451,33 +370,25 @@ impl Reader<'_> { } } -/// Argument for a Opr node -enum NumArg { - Sym(u32), - Num(NumType, u32), - Par(u32, u32), - Oth(Term), -} - #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum NumType { U24 = 1, - I24 = 2, + _I24 = 2, F24 = 3, } impl Op { - fn from_native_tag(val: u32, typ: NumType) -> Op { - match val { + fn from_native_tag(val: u32, typ: NumType) -> Option { + let op = match val { 0x4 => Op::ADD, 0x5 => Op::SUB, 0x6 => Op::MUL, 0x7 => Op::DIV, 0x8 => Op::REM, - 0x9 => Op::EQL, + 0x9 => Op::EQ, 0xa => Op::NEQ, - 0xb => Op::LTN, - 0xc => Op::GTN, + 0xb => Op::LT, + 0xc => Op::GT, 0xd => { if typ == NumType::F24 { Op::ATN @@ -499,25 +410,9 @@ impl Op { Op::XOR } } - _ => unreachable!(), - } - } -} - -impl NumType { - fn from_native_tag(value: u32) -> Self { - match value { - x if x == NumType::U24 as u32 => NumType::U24, - x if x == NumType::I24 as u32 => NumType::I24, - x if x == NumType::F24 as u32 => NumType::F24, - _ => unreachable!(), - } - } -} - -impl Num { - fn from_bits_and_type(bits: u32, typ: NumType) -> Self { - Num::from_bits((bits & 0x00ff_ffff) << 4 | (typ as u32)) + _ => return None, + }; + Some(op) } } @@ -581,6 +476,17 @@ impl Term { } } +fn num_from_bits_with_type(val: u32, typ: u32) -> Term { + match get_typ(typ) { + // No type information, assume u24 by default + hvmc::ast::SYM => Term::Num { val: Num::U24(get_u24(val)) }, + hvmc::ast::U24 => Term::Num { val: Num::U24(get_u24(val)) }, + hvmc::ast::I24 => Term::Num { val: Num::I24(get_i24(val)) }, + hvmc::ast::F24 => Term::Num { val: Num::F24(get_f24(val)) }, + _ => Term::Err, + } +} + /* Variable name generation */ #[derive(Default)] diff --git a/src/fun/parser.rs b/src/fun/parser.rs index 95935098..77df0527 100644 --- a/src/fun/parser.rs +++ b/src/fun/parser.rs @@ -1007,11 +1007,11 @@ pub trait ParserCommons<'a>: Parser<'a> { } else if self.try_consume_exactly("%") { Op::REM } else if self.try_consume_exactly("<") { - Op::LTN + Op::LT } else if self.try_consume_exactly(">") { - Op::GTN + Op::GT } else if self.try_consume_exactly("==") { - Op::EQL + Op::EQ } else if self.try_consume_exactly("!=") { Op::NEQ } else if self.try_consume_exactly("&") { @@ -1040,11 +1040,11 @@ pub trait ParserCommons<'a>: Parser<'a> { } else if self.starts_with("%") { Op::REM } else if self.starts_with("<") { - Op::LTN + Op::LT } else if self.starts_with(">") { - Op::GTN + Op::GT } else if self.starts_with("==") { - Op::EQL + Op::EQ } else if self.starts_with("!=") { Op::NEQ } else if self.starts_with("&") { diff --git a/src/fun/term_to_net.rs b/src/fun/term_to_net.rs index a48baabc..457340c8 100644 --- a/src/fun/term_to_net.rs +++ b/src/fun/term_to_net.rs @@ -168,31 +168,45 @@ impl<'t, 'l> EncodeTermState<'t, 'l> { } // core: & [opr] ~ $(fst $(snd ret)) Term::Oper { opr, fst, snd } => { - // Partially apply match (fst.as_ref(), snd.as_ref()) { - // Put oper in fst + // Partially apply with fst (Term::Num { val }, snd) => { let val = val.to_bits(); - let val = (val & 0xffff_fff0) | opr.to_native_tag(); + let val = (val & !0x1F) | opr.to_native_tag(); let fst = Place::Tree(LoanedMut::new(Tree::Num { val })); let node = self.new_opr(); self.link(fst, node.0); self.encode_term(snd, node.1); self.link(up, node.2); } - // Put oper in snd + // Partially apply with snd, flip + // TODO: For now, we use AND OR and XOR for float operations, so don't flip (fst, Term::Num { val }) => { - let val = val.to_bits(); - let val = (val & 0xffff_fff0) | opr.to_native_tag(); - let snd = Place::Tree(LoanedMut::new(Tree::Num { val })); - let node = self.new_opr(); - self.encode_term(fst, node.0); - self.link(snd, node.1); - self.link(up, node.2); + if [Op::AND, Op::OR, Op::XOR].contains(opr) { + // no flip and no partial application + let opr_val = hvmc::ast::new_sym(opr.to_native_tag()); + let oper = Place::Tree(LoanedMut::new(Tree::Num { val: opr_val })); + let node1 = self.new_opr(); + self.encode_term(fst, node1.0); + self.link(oper, node1.1); + let node2 = self.new_opr(); + self.link(node1.2, node2.0); + self.encode_term(snd, node2.1); + self.link(up, node2.2); + } else { + // flip + let val = val.to_bits(); + let val = (val & !0x1F) | hvmc::ast::flip_sym(opr.to_native_tag()); + let snd = Place::Tree(LoanedMut::new(Tree::Num { val })); + let node = self.new_opr(); + self.encode_term(fst, node.0); + self.link(snd, node.1); + self.link(up, node.2); + } } - // Put oper as symbol, flip with fst + // Don't partially apply (fst, snd) => { - let opr_val = (opr.to_native_tag() << 4) | 0x1000_0000; + let opr_val = hvmc::ast::new_sym(opr.to_native_tag()); let oper = Place::Tree(LoanedMut::new(Tree::Num { val: opr_val })); let node1 = self.new_opr(); self.encode_term(fst, node1.0); @@ -409,21 +423,22 @@ fn hole() -> T { impl Op { fn to_native_tag(self) -> u32 { match self { - Op::ADD => 0x4, - Op::SUB => 0x5, - Op::MUL => 0x6, - Op::DIV => 0x7, - Op::REM => 0x8, - Op::EQL => 0x9, - Op::NEQ => 0xa, - Op::LTN => 0xb, - Op::GTN => 0xc, - Op::AND => 0xd, - Op::OR => 0xe, - Op::XOR => 0xf, - Op::ATN => 0xd, - Op::LOG => 0xe, - Op::POW => 0xf, + Op::ADD => hvmc::ast::ADD, + Op::SUB => hvmc::ast::SUB, + Op::MUL => hvmc::ast::MUL, + Op::DIV => hvmc::ast::DIV, + Op::REM => hvmc::ast::REM, + Op::EQ => hvmc::ast::EQ, + Op::NEQ => hvmc::ast::NEQ, + Op::LT => hvmc::ast::LT, + Op::GT => hvmc::ast::GT, + Op::AND => hvmc::ast::AND, + Op::OR => hvmc::ast::OR, + Op::XOR => hvmc::ast::XOR, + + Op::ATN => hvmc::ast::AND, + Op::LOG => hvmc::ast::OR, + Op::POW => hvmc::ast::XOR, } } } diff --git a/src/imp/parser.rs b/src/imp/parser.rs index dfffbb14..e77516ad 100644 --- a/src/imp/parser.rs +++ b/src/imp/parser.rs @@ -12,9 +12,9 @@ const PREC: &[&[Op]] = &[ &[Op::OR], &[Op::XOR], &[Op::AND], - &[Op::EQL, Op::NEQ], - &[Op::LTN], - &[Op::GTN], + &[Op::EQ, Op::NEQ], + &[Op::LT], + &[Op::GT], &[Op::ADD, Op::SUB], &[Op::MUL, Op::DIV, Op::REM], &[Op::POW], diff --git a/src/lib.rs b/src/lib.rs index 5a2b7108..4a9f4f6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -189,13 +189,28 @@ pub fn run_book_with_fn( } let Some((_, result)) = out.split_once("Result: ") else { - return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into()); + return Err( + format!("1.Failed to parse result from HVM.\nOutput from HVM was:\n{:?}{:?}{:?}", err, status, out) + .into(), + ); }; let Some((result, stats)) = result.split_once('\n') else { - return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into()); + return Err( + format!("2.Failed to parse result from HVM.\nOutput from HVM was:\n{:?}{:?}{:?}", err, status, out) + .into(), + ); }; - let Ok(net) = hvmc::ast::Net::from_str(result) else { - return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into()); + let net = match hvmc::ast::Net::from_str(result) { + Ok(net) => net, + Err(e) => { + return Err( + format!( + "3.Failed to parse result from HVM with error: '{}'.\nOutput from HVM was:\n{:?}{:?}{:?}", + e, err, status, out + ) + .into(), + ); + } }; let (term, diags) = diff --git a/tests/golden_tests/readback_lnet/invalid_op2_op2.bend b/tests/golden_tests/readback_lnet/invalid_op2_op2.bend index e2605e3c..23ad4c1c 100644 --- a/tests/golden_tests/readback_lnet/invalid_op2_op2.bend +++ b/tests/golden_tests/readback_lnet/invalid_op2_op2.bend @@ -1,3 +1,3 @@ (a b) & 1 ~ (c d) -& $(:[+1] $(d b)) ~ $(c a) \ No newline at end of file +& $([+1] $(d b)) ~ $(c a) \ No newline at end of file diff --git a/tests/golden_tests/run_file/basic_num_ops.bend b/tests/golden_tests/run_file/basic_num_ops.bend new file mode 100644 index 00000000..034a557e --- /dev/null +++ b/tests/golden_tests/run_file/basic_num_ops.bend @@ -0,0 +1,123 @@ +List/expand (List/Cons h t) = (List/Cons h (List/expand t)) +List/expand (List/Nil) = (List/Nil) + +main = (List/expand + [ + (+ 20 10) + (- 20 10) + (* 20 10) + (/ 20 10) + (% 20 10) + (^ 20 10) + (& 20 10) + (| 20 10) + (== 20 10) + (!= 20 10) + (< 20 10) + (> 20 10) + + (+ +20 +10) + (- +20 +10) + (* +20 +10) + (/ +20 +10) + (% +20 +10) + (^ +20 +10) + (& +20 +10) + (| +20 +10) + (== +20 +10) + (!= +20 +10) + (< +20 +10) + (> +20 +10) + + (+ -20 -10) + (- -20 -10) + (* -20 -10) + (/ -20 -10) + (% -20 -10) + (^ -20 -10) + (& -20 -10) + (| -20 -10) + (== -20 -10) + (!= -20 -10) + (< -20 -10) + (> -20 -10) + + (+ +20 -10) + (- +20 -10) + (* +20 -10) + (/ +20 -10) + (% +20 -10) + (^ +20 -10) + (& +20 -10) + (| +20 -10) + (== +20 -10) + (!= +20 -10) + (< +20 -10) + (> +20 -10) + + (+ -20 +10) + (- -20 +10) + (* -20 +10) + (/ -20 +10) + (% -20 +10) + (^ -20 +10) + (& -20 +10) + (| -20 +10) + (== -20 +10) + (!= -20 +10) + (< -20 +10) + (> -20 +10) + + (+ +20.0 +10.0) + (- +20.0 +10.0) + (* +20.0 +10.0) + (/ +20.0 +10.0) + (% +20.0 +10.0) + (^ +20.0 +10.0) + (& +20.0 +10.0) + (| +20.0 +10.0) + (== +20.0 +10.0) + (!= +20.0 +10.0) + (< +20.0 +10.0) + (> +20.0 +10.0) + + (+ -20.0 -10.0) + (- -20.0 -10.0) + (* -20.0 -10.0) + (/ -20.0 -10.0) + (% -20.0 -10.0) + (^ -20.0 -10.0) + (& -20.0 -10.0) + (| -20.0 -10.0) + (== -20.0 -10.0) + (!= -20.0 -10.0) + (< -20.0 -10.0) + (> -20.0 -10.0) + + (+ +20.0 -10.0) + (- +20.0 -10.0) + (* +20.0 -10.0) + (/ +20.0 -10.0) + (% +20.0 -10.0) + (^ +20.0 -10.0) + (& +20.0 -10.0) + (| +20.0 -10.0) + (== +20.0 -10.0) + (!= +20.0 -10.0) + (< +20.0 -10.0) + (> +20.0 -10.0) + + (+ -20.0 +10.0) + (- -20.0 +10.0) + (* -20.0 +10.0) + (/ -20.0 +10.0) + (% -20.0 +10.0) + (^ -20.0 +10.0) + (& -20.0 +10.0) + (| -20.0 +10.0) + (== -20.0 +10.0) + (!= -20.0 +10.0) + (< -20.0 +10.0) + (> -20.0 +10.0) + ] +) \ No newline at end of file diff --git a/tests/snapshots/cli__compile_all.bend.snap b/tests/snapshots/cli__compile_all.bend.snap index 356a8e80..29e6a163 100644 --- a/tests/snapshots/cli__compile_all.bend.snap +++ b/tests/snapshots/cli__compile_all.bend.snap @@ -14,4 +14,4 @@ input_file: tests/golden_tests/cli/compile_all.bend & @Pair.get ~ (@main__C0 (a b)) & @Pair/Pair ~ (40 (2 a)) -@main__C0 = ($(:[+] $(a b)) (a b)) +@main__C0 = ($([+] $(a b)) (a b)) diff --git a/tests/snapshots/cli__net_size_too_large.bend.snap b/tests/snapshots/cli__net_size_too_large.bend.snap index 0d3f91ca..38378f00 100644 --- a/tests/snapshots/cli__net_size_too_large.bend.snap +++ b/tests/snapshots/cli__net_size_too_large.bend.snap @@ -4,4 +4,4 @@ input_file: tests/golden_tests/cli/net_size_too_large.bend --- Errors: In definition 'Radix': - Definition is too large for hvm (size=120, max size=64). Please break it into smaller pieces. + Definition is too large for hvm (size=144, max size=64). Please break it into smaller pieces. diff --git a/tests/snapshots/cli__no_check_net_size.bend.snap b/tests/snapshots/cli__no_check_net_size.bend.snap index 2f85b256..0466be17 100644 --- a/tests/snapshots/cli__no_check_net_size.bend.snap +++ b/tests/snapshots/cli__no_check_net_size.bend.snap @@ -16,7 +16,7 @@ input_file: tests/golden_tests/cli/no_check_net_size.bend @Gen.go__C0 = a & @Arr/Leaf ~ a -@Gen.go__C1 = ({a d} ({$([*2] $([|1] e)) $([*2] b)} g)) +@Gen.go__C1 = ({a d} ({$([*2] $([|] $(1 e))) $([*2] b)} g)) & @Arr/Node ~ (c (f g)) &! @Gen.go ~ (a (b c)) &! @Gen.go ~ (d (e f)) @@ -71,7 +71,7 @@ input_file: tests/golden_tests/cli/no_check_net_size.bend @Merge__C9 = ((@Merge__C4 a) a) -@Radix = ({$([&8388608] a) {$([&4194304] b) {$([&2097152] c) {$([&1048576] d) {$([&524288] e) {$([&262144] f) {$([&131072] g) {$([&65536] h) {$([&32768] i) {$([&16384] j) {$([&8192] k) {$([&4096] l) {$([&2048] m) {$([&1024] n) {$([&512] o) {$([&256] p) {$([&128] q) {$([&64] r) {$([&32] s) {$([&16] t) {$([&8] u) {$([&4] v) {$([&2] w) $([&1] x)}}}}}}}}}}}}}}}}}}}}}}} vb) +@Radix = ({$([&] $(8388608 a)) {$([&] $(4194304 b)) {$([&] $(2097152 c)) {$([&] $(1048576 d)) {$([&] $(524288 e)) {$([&] $(262144 f)) {$([&] $(131072 g)) {$([&] $(65536 h)) {$([&] $(32768 i)) {$([&] $(16384 j)) {$([&] $(8192 k)) {$([&] $(4096 l)) {$([&] $(2048 m)) {$([&] $(1024 n)) {$([&] $(512 o)) {$([&] $(256 p)) {$([&] $(128 q)) {$([&] $(64 r)) {$([&] $(32 s)) {$([&] $(16 t)) {$([&] $(8 u)) {$([&] $(4 v)) {$([&] $(2 w)) $([&] $(1 x))}}}}}}}}}}}}}}}}}}}}}}} vb) & @Swap ~ (a (ub (@Map_/Free vb))) & @Swap ~ (b (tb (@Map_/Free ub))) & @Swap ~ (c (sb (@Map_/Free tb))) @@ -118,7 +118,7 @@ input_file: tests/golden_tests/cli/no_check_net_size.bend @Sum = ((@Sum__C2 a) a) @Sum__C0 = (* (a (b d))) - &! @Sum ~ (a $(:[+] $(c d))) + &! @Sum ~ (a $([+] $(c d))) &! @Sum ~ (b c) @Sum__C1 = (?(((a a) @Sum__C0) b) b) diff --git a/tests/snapshots/compile_file__add_args.bend.snap b/tests/snapshots/compile_file__add_args.bend.snap index 9627da92..639b79f1 100644 --- a/tests/snapshots/compile_file__add_args.bend.snap +++ b/tests/snapshots/compile_file__add_args.bend.snap @@ -2,7 +2,7 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/add_args.bend --- -@add = ($(:[+] $(a b)) (a b)) +@add = ($([+] $(a b)) (a b)) @main = a & @add ~ a diff --git a/tests/snapshots/compile_file__addition.bend.snap b/tests/snapshots/compile_file__addition.bend.snap index 758802af..82c39660 100644 --- a/tests/snapshots/compile_file__addition.bend.snap +++ b/tests/snapshots/compile_file__addition.bend.snap @@ -6,4 +6,4 @@ input_file: tests/golden_tests/compile_file/addition.bend & @main__C0 ~ (8 a) @main__C0 = (a b) - & $(1 $(:[+] $(a b))) ~ [+1] + & $(1 $([+] $(a b))) ~ [+1] diff --git a/tests/snapshots/compile_file__f24_oper.bend.snap b/tests/snapshots/compile_file__f24_oper.bend.snap index dce3a5c7..d47a9d57 100644 --- a/tests/snapshots/compile_file__f24_oper.bend.snap +++ b/tests/snapshots/compile_file__f24_oper.bend.snap @@ -3,5 +3,5 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/f24_oper.bend --- @main = b - & $(1.240 $(:[/] $(a b))) ~ [*4583519] - & $(-235.121 a) ~ [+0] + & $(1.2399902 $([/] $(a b))) ~ [*4388912] + & $(-235.1211 a) ~ [+0] diff --git a/tests/snapshots/compile_file__i24_oper.bend.snap b/tests/snapshots/compile_file__i24_oper.bend.snap index 083ba1c4..9b185222 100644 --- a/tests/snapshots/compile_file__i24_oper.bend.snap +++ b/tests/snapshots/compile_file__i24_oper.bend.snap @@ -3,5 +3,5 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/i24_oper.bend --- @main = b - & $(-1 $(:[*] $(a b))) ~ [+1] - & $(+14 a) ~ [-16777204] + & $(-1 $([*] $(a b))) ~ [+1] + & $(+14 a) ~ [-134217716] diff --git a/tests/snapshots/compile_file__op2.bend.snap b/tests/snapshots/compile_file__op2.bend.snap index b6acb150..ab65dce6 100644 --- a/tests/snapshots/compile_file__op2.bend.snap +++ b/tests/snapshots/compile_file__op2.bend.snap @@ -3,4 +3,4 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/op2.bend --- @main = a - & $(1 $([=2] $([&3] $([|4] $([>5] $([<6] $([/7] $([*8] $([-9] $([+10] $([%11] a))))))))))) ~ [!0] + & $(1 $([=2] $([&] $(3 $([|] $(4 $([<5] $([>6] $([:/7] $([*8] $([:-9] $([+10] $([:%11] a))))))))))))) ~ [!0] diff --git a/tests/snapshots/compile_file__redex_order_recursive.bend.snap b/tests/snapshots/compile_file__redex_order_recursive.bend.snap index 9127c1ff..553c54d0 100644 --- a/tests/snapshots/compile_file__redex_order_recursive.bend.snap +++ b/tests/snapshots/compile_file__redex_order_recursive.bend.snap @@ -72,7 +72,7 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend @List.sum = ((@List.sum__C1 a) a) -@List.sum__C0 = (* ($(:[+] $(b c)) (a (b d)))) +@List.sum__C0 = (* ($([+] $(b c)) (a (b d)))) & @List.sum ~ (a (c d)) @List.sum__C1 = (?(((a a) @List.sum__C0) b) b) @@ -106,7 +106,7 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend @Tree.leaves = ((@Tree.leaves__C1 a) a) @Tree.leaves__C0 = (a (b d)) - &! @Tree.leaves ~ (a $(:[+] $(c d))) + &! @Tree.leaves ~ (a $([+] $(c d))) &! @Tree.leaves ~ (b c) @Tree.leaves__C1 = (?((@Tree.leaves__C0 (* (* 1))) a) a) @@ -127,7 +127,7 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend @Tree.nodes__C0 = (a (b e)) & $(d e) ~ [+1] - &! @Tree.nodes ~ (a $(:[+] $(c d))) + &! @Tree.nodes ~ (a $([+] $(c d))) &! @Tree.nodes ~ (b c) @Tree.nodes__C1 = (?((@Tree.nodes__C0 (* (* 0))) a) a) @@ -143,7 +143,7 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend @calc = l & @Foo ~ (f (h (k l))) - & 1 ~ {$(:[+] $(e f)) {$(:[*] $(a {e {$(:[*] $(b {$(:[+] $(g h)) {$(:[*] $(c {g {$(:[*] $(d {$(:[+] $(j k)) {$(:[*] $(i j)) i}})) d}})) c}})) b}})) a}} + & 1 ~ {$([+] $(e f)) {$([*] $(a {e {$([*] $(b {$([+] $(g h)) {$([*] $(c {g {$([*] $(d {$([+] $(j k)) {$([*] $(i j)) i}})) d}})) c}})) b}})) a}} @fold_ = ((@fold___C1 (@fold___C0 a)) a) @@ -156,7 +156,7 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend @main = * -@max = ({$(:[>] $(a ?(((b (* b)) (* (* (c c)))) (d (e f))))) e} ({a d} f)) +@max = ({$([>] $(a ?(((b (* b)) (* (* (c c)))) (d (e f))))) e} ({a d} f)) @tail_recursive = ((@tail_recursive__C0 ((* 0) a)) a) diff --git a/tests/snapshots/compile_file__tup_add.bend.snap b/tests/snapshots/compile_file__tup_add.bend.snap index 06c667e2..c261fa49 100644 --- a/tests/snapshots/compile_file__tup_add.bend.snap +++ b/tests/snapshots/compile_file__tup_add.bend.snap @@ -3,4 +3,4 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/tup_add.bend --- @main = b - & (1 2) ~ ($(:[+] $(a b)) a) + & (1 2) ~ ($([+] $(a b)) a) diff --git a/tests/snapshots/compile_file__unused_let.bend.snap b/tests/snapshots/compile_file__unused_let.bend.snap index d1c499f8..4f4b74f2 100644 --- a/tests/snapshots/compile_file__unused_let.bend.snap +++ b/tests/snapshots/compile_file__unused_let.bend.snap @@ -2,4 +2,4 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file/unused_let.bend --- -@main = ({$(:[+] $(b *)) {b a}} a) +@main = ({$([+] $(b *)) {b a}} a) diff --git a/tests/snapshots/compile_file_o_all__addition.bend.snap b/tests/snapshots/compile_file_o_all__addition.bend.snap index 2e46b859..2f446d65 100644 --- a/tests/snapshots/compile_file_o_all__addition.bend.snap +++ b/tests/snapshots/compile_file_o_all__addition.bend.snap @@ -6,4 +6,4 @@ input_file: tests/golden_tests/compile_file_o_all/addition.bend & @main__C0 ~ (8 a) @main__C0 = (a b) - & $(1 $(:[+] $(a b))) ~ [+1] + & $(1 $([+] $(a b))) ~ [+1] diff --git a/tests/snapshots/compile_file_o_all__eta_chain.bend.snap b/tests/snapshots/compile_file_o_all__eta_chain.bend.snap index a4d15578..e398fb88 100644 --- a/tests/snapshots/compile_file_o_all__eta_chain.bend.snap +++ b/tests/snapshots/compile_file_o_all__eta_chain.bend.snap @@ -5,7 +5,7 @@ input_file: tests/golden_tests/compile_file_o_all/eta_chain.bend @Bar = a & @Baz ~ a -@Baz = ($(:[+] $(b c)) ($(:[+] $(a b)) (a c))) +@Baz = ($([+] $(b c)) ($([+] $(a b)) (a c))) @Foo = a & @Bar ~ a diff --git a/tests/snapshots/compile_file_o_all__linearize_match.bend.snap b/tests/snapshots/compile_file_o_all__linearize_match.bend.snap index 4e8b58b8..4a86caa2 100644 --- a/tests/snapshots/compile_file_o_all__linearize_match.bend.snap +++ b/tests/snapshots/compile_file_o_all__linearize_match.bend.snap @@ -4,4 +4,4 @@ input_file: tests/golden_tests/compile_file_o_all/linearize_match.bend --- @main = (?(((a a) @main__C0) b) b) -@main__C0 = ($(:[+] $(a b)) (a b)) +@main__C0 = ($([+] $(a b)) (a b)) diff --git a/tests/snapshots/compile_file_o_all__match_mult_linearization.bend.snap b/tests/snapshots/compile_file_o_all__match_mult_linearization.bend.snap index 3b63bd74..799c5958 100644 --- a/tests/snapshots/compile_file_o_all__match_mult_linearization.bend.snap +++ b/tests/snapshots/compile_file_o_all__match_mult_linearization.bend.snap @@ -4,6 +4,6 @@ input_file: tests/golden_tests/compile_file_o_all/match_mult_linearization.bend --- @main = (?((@main__C0 @main__C1) a) a) -@main__C0 = ($(:[+] $(a $(:[+] $(b c)))) (a (b c))) +@main__C0 = ($([+] $(a $([+] $(b c)))) (a (b c))) -@main__C1 = ($(:[+] $(a $(:[+] $(b $(:[+] $(c d)))))) (a (b (c d)))) +@main__C1 = ($([+] $(a $([+] $(b $([+] $(c d)))))) (a (b (c d)))) diff --git a/tests/snapshots/compile_file_o_all__match_tup.bend.snap b/tests/snapshots/compile_file_o_all__match_tup.bend.snap index eab21075..e934690e 100644 --- a/tests/snapshots/compile_file_o_all__match_tup.bend.snap +++ b/tests/snapshots/compile_file_o_all__match_tup.bend.snap @@ -2,7 +2,7 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/compile_file_o_all/match_tup.bend --- -@Sum = (($(:[+] $(a b)) a) b) +@Sum = (($([+] $(a b)) a) b) @main = a & @Sum ~ ((7 3) a) diff --git a/tests/snapshots/compile_file_o_all__sum_predicates.bend.snap b/tests/snapshots/compile_file_o_all__sum_predicates.bend.snap index 1781cfc0..825c74c2 100644 --- a/tests/snapshots/compile_file_o_all__sum_predicates.bend.snap +++ b/tests/snapshots/compile_file_o_all__sum_predicates.bend.snap @@ -7,7 +7,7 @@ input_file: tests/golden_tests/compile_file_o_all/sum_predicates.bend @sum_pred = (?((@sum_pred__C1 @sum_pred__C2) a) a) -@sum_pred__C0 = (a ($(:[+] $(a b)) b)) +@sum_pred__C0 = (a ($([+] $(a b)) b)) @sum_pred__C1 = (?((0 (a a)) b) b) diff --git a/tests/snapshots/readback_lnet__addition.bend.snap b/tests/snapshots/readback_lnet__addition.bend.snap index 5dbc0dfe..17d77f62 100644 --- a/tests/snapshots/readback_lnet__addition.bend.snap +++ b/tests/snapshots/readback_lnet__addition.bend.snap @@ -2,4 +2,8 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/readback_lnet/addition.bend --- -(+ 2 1) +Warnings: +During readback: + Encountered an invalid numeric operation. + + diff --git a/tests/snapshots/readback_lnet__invalid_op2_op2.bend.snap b/tests/snapshots/readback_lnet__invalid_op2_op2.bend.snap index ecaf9290..4043649a 100644 --- a/tests/snapshots/readback_lnet__invalid_op2_op2.bend.snap +++ b/tests/snapshots/readback_lnet__invalid_op2_op2.bend.snap @@ -4,6 +4,6 @@ input_file: tests/golden_tests/readback_lnet/invalid_op2_op2.bend --- Warnings: During readback: - Encountered an invalid numeric operation. (3 occurrences) + Encountered an invalid numeric operation. λa diff --git a/tests/snapshots/readback_lnet__tup_add.bend.snap b/tests/snapshots/readback_lnet__tup_add.bend.snap index a5721be6..288f4418 100644 --- a/tests/snapshots/readback_lnet__tup_add.bend.snap +++ b/tests/snapshots/readback_lnet__tup_add.bend.snap @@ -2,4 +2,8 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/readback_lnet/tup_add.bend --- -(+ 1 2) +Warnings: +During readback: + Encountered an invalid numeric operation. + + diff --git a/tests/snapshots/run_file__basic_num_ops.bend.snap b/tests/snapshots/run_file__basic_num_ops.bend.snap new file mode 100644 index 00000000..c4790e67 --- /dev/null +++ b/tests/snapshots/run_file__basic_num_ops.bend.snap @@ -0,0 +1,9 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/run_file/basic_num_ops.bend +--- +NumScott: +[30, 10, 200, 2, 0, 30, 0, 30, 0, 1, 0, 1, +30, +10, +200, +2, +0, +30, +0, +30, +0, +1, +0, +1, -30, -10, +200, +2, +0, +26, -28, -2, +0, +1, +1, +0, +10, +30, -200, -2, +0, -30, +20, -10, +0, +1, +0, +1, -10, -30, -200, -2, +0, -26, +8, -18, +0, +1, +1, +0, 30.000, 10.000, 200.000, 2.000, 0.000, 10240007340032.000, 1.107, 0.769, 0, 1, 0, 1, -30.000, -10.000, 200.000, 2.000, -0.000, 0.000, -2.034, NaN, 0, 1, 1, 0, 10.000, 30.000, -200.000, -2.000, 0.000, 0.000, 2.034, NaN, 0, 1, 0, 1, -10.000, -30.000, -200.000, -2.000, -0.000, 10240007340032.000, -1.107, NaN, 0, 1, 1, 0] + +Scott: +[30, 10, 200, 2, 0, 30, 0, 30, 0, 1, 0, 1, +30, +10, +200, +2, +0, +30, +0, +30, +0, +1, +0, +1, -30, -10, +200, +2, +0, +26, -28, -2, +0, +1, +1, +0, +10, +30, -200, -2, +0, -30, +20, -10, +0, +1, +0, +1, -10, -30, -200, -2, +0, -26, +8, -18, +0, +1, +1, +0, 30.000, 10.000, 200.000, 2.000, 0.000, 10240007340032.000, 1.107, 0.769, 0, 1, 0, 1, -30.000, -10.000, 200.000, 2.000, -0.000, 0.000, -2.034, NaN, 0, 1, 1, 0, 10.000, 30.000, -200.000, -2.000, 0.000, 0.000, 2.034, NaN, 0, 1, 0, 1, -10.000, -30.000, -200.000, -2.000, -0.000, 10240007340032.000, -1.107, NaN, 0, 1, 1, 0] diff --git a/tests/snapshots/run_file__exp.bend.snap b/tests/snapshots/run_file__exp.bend.snap index a413de91..ac337788 100644 --- a/tests/snapshots/run_file__exp.bend.snap +++ b/tests/snapshots/run_file__exp.bend.snap @@ -3,5 +3,6 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/run_file/exp.bend --- Errors: -Error reading result from hvm. Output : -ERROR: attempt to clone a non-affine global reference. +1.Failed to parse result from HVM. +Output from HVM was: +"""""ERROR: attempt to clone a non-affine global reference.\n\n" diff --git a/tests/snapshots/run_file__lam_op2.bend.snap b/tests/snapshots/run_file__lam_op2.bend.snap index 5083dad7..2f67812e 100644 --- a/tests/snapshots/run_file__lam_op2.bend.snap +++ b/tests/snapshots/run_file__lam_op2.bend.snap @@ -3,7 +3,15 @@ source: tests/golden_tests.rs input_file: tests/golden_tests/run_file/lam_op2.bend --- NumScott: -λa (+ a 2) +Warnings: +During readback: + Encountered an invalid numeric operation. + +λa Scott: -λa (+ a 2) +Warnings: +During readback: + Encountered an invalid numeric operation. + +λa diff --git a/tests/snapshots/run_file__lam_op2_nested.bend.snap b/tests/snapshots/run_file__lam_op2_nested.bend.snap index e5201177..0e270043 100644 --- a/tests/snapshots/run_file__lam_op2_nested.bend.snap +++ b/tests/snapshots/run_file__lam_op2_nested.bend.snap @@ -5,13 +5,13 @@ input_file: tests/golden_tests/run_file/lam_op2_nested.bend NumScott: Warnings: During readback: - Encountered an invalid numeric operation. (2 occurrences) + Encountered an invalid numeric operation. -λa (* a (+ a )) +λa Scott: Warnings: During readback: - Encountered an invalid numeric operation. (2 occurrences) + Encountered an invalid numeric operation. -λa (* a (+ a )) +λa