diff --git a/Cargo.lock b/Cargo.lock index 0d77ce131..460e93720 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,9 +76,9 @@ checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] name = "cc" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd97381a8cc6493395a5afc4c691c1084b3768db713b73aa215217aa245d153" +checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41" [[package]] name = "cfg-if" @@ -207,8 +207,8 @@ checksum = "809e18805660d7b6b2e2b9f316a5099521b5998d5cba4dda11b5157a21aaef03" [[package]] name = "hvm-core" -version = "0.2.23" -source = "git+https://github.com/HigherOrderCO/hvm-core.git?rev=0530c37862db1704f323175322d19d5877e4ff03#0530c37862db1704f323175322d19d5877e4ff03" +version = "0.2.24" +source = "git+https://github.com/HigherOrderCO/hvm-core.git#f13f24cdec1b3a37b4121db67455a16110ed80ba" dependencies = [ "arrayvec", "clap", diff --git a/Cargo.toml b/Cargo.toml index f3f083d27..f9f8ac155 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ cli = ["dep:clap"] chumsky = { version = "= 1.0.0-alpha.4", features = ["label"] } clap = { version = "4.4.1", features = ["derive"], optional = true } highlight_error = "0.1.1" -hvm-core = { git = "https://github.com/HigherOrderCO/hvm-core.git", rev = "0530c37862db1704f323175322d19d5877e4ff03" } +hvm-core = { git = "https://github.com/HigherOrderCO/hvm-core.git" } indexmap = "2.2.3" interner = "0.2.1" itertools = "0.11.0" diff --git a/src/net/hvmc_to_net.rs b/src/net/hvmc_to_net.rs index fa5786a22..495f93e74 100644 --- a/src/net/hvmc_to_net.rs +++ b/src/net/hvmc_to_net.rs @@ -121,7 +121,7 @@ fn tree_to_inodes(tree: &Tree, tree_root: String, net_root: &str, n_vars: &mut N inodes.push(INode { kind, ports: [subtree_root, var.clone(), var] }); } Tree::Num { val } => { - let kind = Num { val: *val }; + let kind = Num { val: *val as u64 }; let var = new_var(n_vars); inodes.push(INode { kind, ports: [subtree_root, var.clone(), var] }); } diff --git a/src/net/net_to_hvmc.rs b/src/net/net_to_hvmc.rs index f982227a4..de0a10805 100644 --- a/src/net/net_to_hvmc.rs +++ b/src/net/net_to_hvmc.rs @@ -79,7 +79,7 @@ fn net_tree_to_hvmc_tree(inet: &INet, tree_root: NodeId, port_to_var_id: &mut Ha ], }, NodeKind::Ref { def_name } => Tree::Ref { nam: def_name.to_string() }, - NodeKind::Num { val } => Tree::Num { val: *val }, + NodeKind::Num { val } => Tree::Num { val: *val as i64 }, NodeKind::Op2 { opr } => Tree::Op { op: *opr, rhs: Box::new(var_or_subtree(inet, Port(tree_root, 1), port_to_var_id)), diff --git a/src/term/builtins.rs b/src/term/builtins.rs index e14941d1a..13c82d1dc 100644 --- a/src/term/builtins.rs +++ b/src/term/builtins.rs @@ -59,7 +59,7 @@ impl Term { pub fn encode_str(val: &str) -> Term { val.chars().rfold(Term::r#ref(SNIL), |acc, char| { - Term::call(Term::r#ref(SCONS), [Term::Num { val: u64::from(char) }, acc]) + Term::call(Term::r#ref(SCONS), [Term::Num { val: char as u64 }, acc]) }) } diff --git a/src/term/display.rs b/src/term/display.rs index ce6d78fae..fa46b3dfe 100644 --- a/src/term/display.rs +++ b/src/term/display.rs @@ -1,4 +1,4 @@ -use super::{Book, Definition, Name, NumCtr, Op, Pattern, Rule, Tag, Term}; +use super::{Book, Definition, Name, NumCtr, Pattern, Rule, Tag, Term}; use std::{fmt, ops::Deref}; /* Some aux structures for things that are not so simple to display */ @@ -103,8 +103,8 @@ impl fmt::Display for Term { Term::Num { val } => write!(f, "{val}"), Term::Nat { val } => write!(f, "#{val}"), Term::Str { val } => write!(f, "{val:?}"), - Term::Opx { op, fst, snd } => { - write!(f, "({} {} {})", op, fst, snd) + Term::Opx { opr, fst, snd } => { + write!(f, "({} {} {})", opr, fst, snd) } Term::Lst { els } => write!(f, "[{}]", DisplayJoin(|| els.iter(), ", "),), Term::Err => write!(f, ""), @@ -171,29 +171,6 @@ impl fmt::Display for NumCtr { } } -impl fmt::Display for Op { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Op::Add => write!(f, "+"), - Op::Sub => write!(f, "-"), - Op::Mul => write!(f, "*"), - Op::Div => write!(f, "/"), - Op::Mod => write!(f, "%"), - Op::Eq => write!(f, "=="), - Op::Ne => write!(f, "!="), - Op::Lt => write!(f, "<"), - Op::Gt => write!(f, ">"), - Op::Lte => write!(f, "<="), - Op::Gte => write!(f, ">="), - Op::And => write!(f, "&"), - Op::Or => write!(f, "|"), - Op::Xor => write!(f, "^"), - Op::Shl => write!(f, "<<"), - Op::Shr => write!(f, ">>"), - } - } -} - impl fmt::Display for Name { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) diff --git a/src/term/mod.rs b/src/term/mod.rs index ae055ec41..7c3fcedf9 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -18,6 +18,7 @@ pub mod parser; pub mod term_to_net; pub mod transform; +pub use hvmc::ops::{IntOp, Op, Ty as OpType}; pub use net_to_term::{net_to_term, ReadbackError}; pub use term_to_net::{book_to_nets, term_to_compat_net}; @@ -135,7 +136,7 @@ pub enum Term { }, /// A numeric operation between built-in numbers. Opx { - op: Op, + opr: Op, fst: Box, snd: Box, }, @@ -186,26 +187,6 @@ pub enum Tag { Static, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Op { - Add, - Sub, - Mul, - Div, - Mod, - Eq, - Ne, - Lt, - Gt, - Lte, - Gte, - And, - Or, - Xor, - Shl, - Shr, -} - /// A user defined datatype #[derive(Debug, Clone, Default)] pub struct Adt { @@ -340,7 +321,7 @@ impl Clone for Term { Self::Nat { val } => Self::Nat { val: *val }, Self::Str { val } => Self::Str { val: val.clone() }, Self::Lst { els } => Self::Lst { els: els.clone() }, - Self::Opx { op, fst, snd } => Self::Opx { op: *op, fst: fst.clone(), snd: snd.clone() }, + Self::Opx { opr, fst, snd } => Self::Opx { opr: *opr, fst: fst.clone(), snd: snd.clone() }, Self::Mat { arg, with, rules } => { Self::Mat { arg: arg.clone(), with: with.clone(), rules: rules.clone() } } @@ -452,7 +433,11 @@ impl Term { if val == 0 { arg } else { - Term::Opx { op: Op::Sub, fst: Box::new(arg), snd: Box::new(Term::Num { val }) } + Term::Opx { + opr: Op { ty: OpType::U60, op: IntOp::Sub }, + fst: Box::new(arg), + snd: Box::new(Term::Num { val }), + } } } @@ -460,7 +445,11 @@ impl Term { if val == 0 { arg } else { - Term::Opx { op: Op::Add, fst: Box::new(arg), snd: Box::new(Term::Num { val }) } + Term::Opx { + opr: Op { ty: OpType::U60, op: IntOp::Add }, + fst: Box::new(arg), + snd: Box::new(Term::Num { val }), + } } } diff --git a/src/term/net_to_term.rs b/src/term/net_to_term.rs index 6f504ec6f..67fc29525 100644 --- a/src/term/net_to_term.rs +++ b/src/term/net_to_term.rs @@ -1,7 +1,7 @@ use crate::{ diagnostics::{DiagnosticOrigin, Diagnostics, Severity}, net::{INet, NodeId, NodeKind::*, Port, SlotId, ROOT}, - term::{num_to_name, term_to_net::Labels, Book, Name, Op, Tag, Term}, + term::{num_to_name, term_to_net::Labels, Book, Name, Tag, Term}, }; use std::collections::{BTreeSet, HashMap, HashSet}; @@ -209,13 +209,13 @@ impl Reader<'_> { } _ => unreachable!(), }, - Num { val } => Term::Num { val: *val }, + Num { val } => Term::Num { val: *val & ((1 << 60) - 1) }, Op2 { opr } => match next.slot() { 2 => { let fst = self.read_term(self.net.enter_port(Port(node, 0))); let snd = self.read_term(self.net.enter_port(Port(node, 1))); let (opr, fst, snd) = if is_op_swapped(*opr) { (opr.swap(), snd, fst) } else { (*opr, fst, snd) }; - Term::Opx { op: Op::from_hvmc_label(opr), fst: Box::new(fst), snd: Box::new(snd) } + Term::Opx { opr, fst: Box::new(fst), snd: Box::new(snd) } } _ => { self.error(ReadbackError::InvalidNumericOp); @@ -426,43 +426,14 @@ impl NameGen { } } -impl Op { - pub fn from_hvmc_label(value: hvmc::ops::Op) -> Op { - use hvmc::ops::Op as RtOp; - match value { - RtOp::Add => Op::Add, - RtOp::Sub => Op::Sub, - RtOp::Mul => Op::Mul, - RtOp::Div => Op::Div, - RtOp::Mod => Op::Mod, - RtOp::Eq => Op::Eq, - RtOp::Ne => Op::Ne, - RtOp::Lt => Op::Lt, - RtOp::Gt => Op::Gt, - RtOp::Lte => Op::Lte, - RtOp::Gte => Op::Gte, - RtOp::And => Op::And, - RtOp::Or => Op::Or, - RtOp::Xor => Op::Xor, - RtOp::Shl => Op::Shl, - RtOp::Shr => Op::Shr, - RtOp::SubS => unreachable!(), - RtOp::DivS => unreachable!(), - RtOp::ModS => unreachable!(), - RtOp::ShlS => unreachable!(), - RtOp::ShrS => unreachable!(), - } - } -} - fn is_op_swapped(op: hvmc::ops::Op) -> bool { matches!( - op, - hvmc::ops::Op::ShlS - | hvmc::ops::Op::ShrS - | hvmc::ops::Op::SubS - | hvmc::ops::Op::DivS - | hvmc::ops::Op::ModS + op.op, + hvmc::ops::IntOp::ShlS + | hvmc::ops::IntOp::ShrS + | hvmc::ops::IntOp::SubS + | hvmc::ops::IntOp::DivS + | hvmc::ops::IntOp::RemS ) } diff --git a/src/term/parser/parser.rs b/src/term/parser/parser.rs index daf9d3e6f..bdfacde2c 100644 --- a/src/term/parser/parser.rs +++ b/src/term/parser/parser.rs @@ -1,6 +1,6 @@ use crate::term::{ parser::lexer::{LexingError, Token}, - Adt, Book, Definition, Name, NumCtr, Op, Pattern, Rule, Tag, Term, LNIL, SNIL, + Adt, Book, Definition, IntOp, Name, NumCtr, Op, OpType, Pattern, Rule, Tag, Term, LNIL, SNIL, }; use chumsky::{ error::{Error, RichReason}, @@ -174,22 +174,22 @@ where I: ValueInput<'a, Token = Token, Span = SimpleSpan>, { select! { - Token::Add => Op::Add, - Token::Sub => Op::Sub, - Token::Asterisk => Op::Mul, - Token::Div => Op::Div, - Token::Mod => Op::Mod, - Token::EqualsEquals => Op::Eq, - Token::NotEquals => Op::Ne, - Token::Ltn => Op::Lt, - Token::Gtn => Op::Gt, - Token::Lte => Op::Lte, - Token::Gte => Op::Gte, - Token::And => Op::And, - Token::Or => Op::Or, - Token::Xor => Op::Xor, - Token::Shl => Op::Shl, - Token::Shr => Op::Shr, + Token::Add => Op{ ty: OpType::U60, op: IntOp::Add }, + Token::Sub => Op{ ty: OpType::U60, op: IntOp::Sub }, + Token::Asterisk => Op{ ty: OpType::U60, op: IntOp::Mul }, + Token::Div => Op{ ty: OpType::U60, op: IntOp::Div }, + Token::Mod => Op{ ty: OpType::U60, op: IntOp::Rem }, + Token::EqualsEquals => Op{ ty: OpType::U60, op: IntOp::Eq }, + Token::NotEquals => Op{ ty: OpType::U60, op: IntOp::Ne }, + Token::Ltn => Op{ ty: OpType::U60, op: IntOp::Lt }, + Token::Gtn => Op{ ty: OpType::U60, op: IntOp::Gt }, + Token::Lte => Op{ ty: OpType::U60, op: IntOp::Le }, + Token::Gte => Op{ ty: OpType::U60, op: IntOp::Ge }, + Token::And => Op{ ty: OpType::U60, op: IntOp::And }, + Token::Or => Op{ ty: OpType::U60, op: IntOp::Or }, + Token::Xor => Op{ ty: OpType::U60, op: IntOp::Xor }, + Token::Shl => Op{ ty: OpType::U60, op: IntOp::Shl }, + Token::Shr => Op{ ty: OpType::U60, op: IntOp::Shr }, } } @@ -371,7 +371,7 @@ where .then(term.clone()) .then(term.clone()) .delimited_by(just(Token::LParen), just(Token::RParen)) - .map(|((op, fst), snd)| Term::Opx { op, fst: Box::new(fst), snd: Box::new(snd) }) + .map(|((opr, fst), snd)| Term::Opx { opr, fst: Box::new(fst), snd: Box::new(snd) }) .boxed(); // (x, ..n) diff --git a/src/term/term_to_net.rs b/src/term/term_to_net.rs index cf87bdedc..0a7907e32 100644 --- a/src/term/term_to_net.rs +++ b/src/term/term_to_net.rs @@ -4,7 +4,7 @@ use crate::{ NodeKind::{self, *}, Port, ROOT, }, - term::{Book, Name, NumCtr, Op, Tag, Term}, + term::{Book, Name, NumCtr, Tag, Term}, }; use std::collections::{hash_map::Entry, HashMap}; @@ -244,8 +244,8 @@ impl EncodeTermState<'_> { Term::Str { .. } => unreachable!(), // Removed in encode_str Term::Lst { .. } => unreachable!(), // Removed in encode_list // core: & fst ~ - Term::Opx { op, fst, snd } => { - let opx = self.inet.new_node(Op2 { opr: op.to_hvmc_label() }); + Term::Opx { opr, fst, snd } => { + let opx = self.inet.new_node(Op2 { opr: *opr }); let fst_port = self.encode_term(fst, Port(opx, 0)); self.link_local(Port(opx, 0), fst_port); @@ -311,30 +311,6 @@ impl EncodeTermState<'_> { } } -impl Op { - pub fn to_hvmc_label(self) -> hvmc::ops::Op { - use hvmc::ops::Op as RtOp; - match self { - Op::Add => RtOp::Add, - Op::Sub => RtOp::Sub, - Op::Mul => RtOp::Mul, - Op::Div => RtOp::Div, - Op::Mod => RtOp::Mod, - Op::Eq => RtOp::Eq, - Op::Ne => RtOp::Ne, - Op::Lt => RtOp::Lt, - Op::Gt => RtOp::Gt, - Op::Lte => RtOp::Lte, - Op::Gte => RtOp::Gte, - Op::And => RtOp::And, - Op::Or => RtOp::Or, - Op::Xor => RtOp::Xor, - Op::Shl => RtOp::Shl, - Op::Shr => RtOp::Shr, - } - } -} - #[derive(Debug, Default, Clone)] pub struct Labels { pub con: LabelGenerator, diff --git a/tests/golden_tests.rs b/tests/golden_tests.rs index 45dc4b727..54f8c92f2 100644 --- a/tests/golden_tests.rs +++ b/tests/golden_tests.rs @@ -324,8 +324,11 @@ fn hangs() { run_golden_test_dir(function_name!(), &move |code, path| { let book = do_parse_book(code, path)?; let compile_opts = CompileOpts { pre_reduce: false, ..CompileOpts::default_strict().set_all() }; - let diagnostics_cfg = - DiagnosticsConfig { recursion_cycle: Severity::Allow, ..DiagnosticsConfig::default_strict() }; + let diagnostics_cfg = DiagnosticsConfig { + recursion_cycle: Severity::Allow, + recursion_pre_reduce: Severity::Allow, + ..DiagnosticsConfig::default_strict() + }; let thread = std::thread::spawn(move || { run_book(book, None, RunOpts::default(), compile_opts, diagnostics_cfg, None)