mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 03:45:29 +03:00
Adapt Bend to new hvm number operation format
This commit is contained in:
parent
62f0ca0f81
commit
3e9b3c4083
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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, "^"),
|
||||
|
@ -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),
|
||||
|
@ -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,98 +213,40 @@ 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(_, _) => {
|
||||
// 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);
|
||||
Term::Err
|
||||
return Term::Err;
|
||||
}
|
||||
});
|
||||
let (fst, snd) = if flip { (snd, fst.clone()) } else { (fst.clone(), snd) };
|
||||
Term::Oper { opr: *opr, fst, snd }
|
||||
if let Some(op) = Op::from_native_tag(val, NumType::U24) {
|
||||
op
|
||||
} else {
|
||||
self.error(ReadbackError::InvalidNumericOp);
|
||||
Term::Err
|
||||
return Term::Err;
|
||||
}
|
||||
} 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);
|
||||
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 {
|
||||
// TODO: Fix
|
||||
self.error(ReadbackError::InvalidNumericOp);
|
||||
Term::Err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
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<Op> {
|
||||
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)]
|
||||
|
@ -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("&") {
|
||||
|
@ -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 }) => {
|
||||
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 & 0xffff_fff0) | opr.to_native_tag();
|
||||
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: Default>() -> 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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],
|
||||
|
23
src/lib.rs
23
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) =
|
||||
|
@ -1,3 +1,3 @@
|
||||
(a b)
|
||||
& 1 ~ (c d)
|
||||
& $(:[+1] $(d b)) ~ $(c a)
|
||||
& $([+1] $(d b)) ~ $(c a)
|
123
tests/golden_tests/run_file/basic_num_ops.bend
Normal file
123
tests/golden_tests/run_file/basic_num_ops.bend
Normal file
@ -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)
|
||||
]
|
||||
)
|
@ -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))
|
||||
|
@ -4,4 +4,4 @@ input_file: tests/golden_tests/cli/net_size_too_large.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
[1mIn definition '[4mRadix[0m[1m':[0m
|
||||
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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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))))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/readback_lnet/addition.bend
|
||||
---
|
||||
(+ 2 1)
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
<Invalid>
|
||||
|
@ -4,6 +4,6 @@ input_file: tests/golden_tests/readback_lnet/invalid_op2_op2.bend
|
||||
---
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation. (3 occurrences)
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
λa <Invalid>
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/readback_lnet/tup_add.bend
|
||||
---
|
||||
(+ 1 2)
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
<Invalid>
|
||||
|
9
tests/snapshots/run_file__basic_num_ops.bend.snap
Normal file
9
tests/snapshots/run_file__basic_num_ops.bend.snap
Normal file
@ -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]
|
@ -3,5 +3,6 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/exp.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
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"
|
||||
|
@ -3,7 +3,15 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/lam_op2.bend
|
||||
---
|
||||
NumScott:
|
||||
λa (+ a 2)
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
λa <Invalid>
|
||||
|
||||
Scott:
|
||||
λa (+ a 2)
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
λa <Invalid>
|
||||
|
@ -5,13 +5,13 @@ input_file: tests/golden_tests/run_file/lam_op2_nested.bend
|
||||
NumScott:
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation. (2 occurrences)
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
λa (* a (+ a <Invalid>))
|
||||
λa <Invalid>
|
||||
|
||||
Scott:
|
||||
[4m[1m[33mWarnings:[0m
|
||||
[1mDuring readback:[0m
|
||||
Encountered an invalid numeric operation. (2 occurrences)
|
||||
Encountered an invalid numeric operation.
|
||||
|
||||
λa (* a (+ a <Invalid>))
|
||||
λa <Invalid>
|
||||
|
Loading…
Reference in New Issue
Block a user