diff --git a/Cargo.lock b/Cargo.lock index b8693f9c..5ef1d989 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -555,6 +555,7 @@ name = "kind-derive" version = "0.1.0" dependencies = [ "fxhash", + "im", "kind-report", "kind-span", "kind-tree", diff --git a/crates/kind-checker/src/compiler/mod.rs b/crates/kind-checker/src/compiler/mod.rs index c3ef24aa..f8507450 100644 --- a/crates/kind-checker/src/compiler/mod.rs +++ b/crates/kind-checker/src/compiler/mod.rs @@ -119,7 +119,7 @@ fn desugar_str(input: &str, range: Range) -> Box { desugared::Expr::ctr( range, cons.clone(), - vec![desugared::Expr::num60(range, chr as u64), right], + vec![desugared::Expr::num_u60(range, chr as u64), right], ) }) } @@ -152,25 +152,11 @@ fn codegen_all_expr( eval_ctr(quote, TermTag::Typ), vec![range_to_num(expr.range)], ), - NumType { - typ: kind_tree::NumType::U60, - } => mk_lifted_ctr( + NumTypeU60 => mk_lifted_ctr( eval_ctr(quote, TermTag::U60), vec![range_to_num(expr.range)], ), - NumType { - typ: kind_tree::NumType::U120, - } => mk_lifted_ctr( - eval_ctr(quote, TermTag::Ctr(0)), - vec![ - mk_ctr_name_from_str("U120"), - if lhs { - mk_var("orig") - } else { - range_to_num(expr.range) - }, - ], - ), + NumTypeF60 => todo!(), Var { name } => { if quote && !lhs { set_origin(name) @@ -292,28 +278,11 @@ fn codegen_all_expr( codegen_all_expr(lhs_rule, lhs, num, quote, expr), ], ), - Num { - num: kind_tree::Number::U60(n), - } => mk_lifted_ctr( + NumU60 { numb } => mk_lifted_ctr( eval_ctr(quote, TermTag::Num), - vec![range_to_num(expr.range), mk_u60(*n)], + vec![range_to_num(expr.range), mk_u60(*numb)], ), - Num { - num: kind_tree::Number::U120(numb), - } => { - let new = QualifiedIdent::new_static("U120.new", None, expr.range); - - let expr = desugared::Expr::ctr( - expr.range, - new, - vec![ - desugared::Expr::num60(expr.range, (numb >> 60) as u64), - desugared::Expr::num60(expr.range, (numb & 0xFFFFFFFFFFFFFFF) as u64), - ], - ); - - codegen_all_expr(lhs_rule, lhs, num, quote, &expr) - } + NumF60 { numb: _ } => todo!(), Binary { op, left, right } => mk_lifted_ctr( eval_ctr(quote, TermTag::Binary), vec![ diff --git a/crates/kind-checker/src/report.rs b/crates/kind-checker/src/report.rs index 5206cdd2..ccb04f78 100644 --- a/crates/kind-checker/src/report.rs +++ b/crates/kind-checker/src/report.rs @@ -4,7 +4,7 @@ use kind_span::{EncodedRange, Range}; use kind_tree::backend::Term; use kind_tree::symbol::{Ident, QualifiedIdent}; -use kind_tree::{desugared, Number, Operator}; +use kind_tree::{desugared, Operator}; use crate::errors::TypeError; use desugared::Expr; @@ -142,25 +142,7 @@ fn parse_all_expr( for arg in parse_list(&args[2])? { res.push(parse_all_expr(names.clone(), &arg)?); } - - if name.to_str() == "U120.new" && res.len() == 2 { - match (&res[0].data, &res[1].data) { - ( - desugared::ExprKind::Num { - num: Number::U60(hi), - }, - desugared::ExprKind::Num { - num: Number::U60(lo), - }, - ) => { - let num = (*hi as u128) << 60 | *lo as u128; - Ok(Expr::num120(orig, num)) - } - _ => Ok(Expr::ctr(orig, name, res)), - } - } else { - Ok(Expr::ctr(orig, name, res)) - } + Ok(Expr::ctr(orig, name, res)) } "Kind.Quoted.fun" => Ok(Expr::fun( parse_orig(&args[1])?, @@ -174,8 +156,9 @@ fn parse_all_expr( }, )), "Kind.Quoted.hlp" => Ok(Expr::hlp(parse_orig(&args[0])?, Ident::generate("?"))), - "Kind.Quoted.u60" => Ok(Expr::u60(parse_orig(&args[0])?)), - "Kind.Quoted.num" => Ok(Expr::num60(parse_orig(&args[0])?, parse_num(&args[1])?)), // TODO: do something about u120? + "Kind.Quoted.u60" => Ok(Expr::type_u60(parse_orig(&args[0])?)), + // TODO: Change quoting to support floats + "Kind.Quoted.num" => Ok(Expr::num_u60(parse_orig(&args[0])?, parse_num(&args[1])?)), "Kind.Quoted.op2" => Ok(Expr::binary( parse_orig(&args[0])?, parse_op(&args[1])?, diff --git a/crates/kind-cli/src/lib.rs b/crates/kind-cli/src/lib.rs index 8eb146ca..0d560829 100644 --- a/crates/kind-cli/src/lib.rs +++ b/crates/kind-cli/src/lib.rs @@ -190,10 +190,7 @@ pub fn run_cli(config: Cli) { } Command::Run { file } => { let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| { - let book = driver::erase_book( - session, - &PathBuf::from(file.clone()), - )?; + let book = driver::erase_book(session, &PathBuf::from(file.clone()))?; driver::check_main_entry(session, &book)?; Some(driver::compile_book_to_hvm(book)) }); diff --git a/crates/kind-cli/tests/mod.rs b/crates/kind-cli/tests/mod.rs index a37b78d3..d53cef93 100644 --- a/crates/kind-cli/tests/mod.rs +++ b/crates/kind-cli/tests/mod.rs @@ -75,8 +75,8 @@ fn test_eval() -> Result<(), Error> { let root = PathBuf::from("."); let mut session = Session::new(root, rx); - let check = driver::erase_book(&mut session, &PathBuf::from(path)) - .map(driver::compile_book_to_hvm); + let check = + driver::erase_book(&mut session, &PathBuf::from(path)).map(driver::compile_book_to_hvm); let diagnostics = tx.try_iter().collect::>(); let render = RenderConfig::ascii(2); diff --git a/crates/kind-derive/src/subst.rs b/crates/kind-derive/src/subst.rs index 62093be4..9f4edf3a 100644 --- a/crates/kind-derive/src/subst.rs +++ b/crates/kind-derive/src/subst.rs @@ -78,7 +78,9 @@ impl<'a> Visitor for Subst<'a> { match &mut pat.data { PatKind::Var(ident) => self.visit_pat_ident(ident), PatKind::Str(_) => (), - PatKind::Num(_) => (), + PatKind::U60(_) => (), + PatKind::U120(_) => (), + PatKind::F60(_) => (), PatKind::Hole => (), PatKind::List(ls) => { for pat in ls { diff --git a/crates/kind-driver/src/lib.rs b/crates/kind-driver/src/lib.rs index 250a882c..a80f8dc1 100644 --- a/crates/kind-driver/src/lib.rs +++ b/crates/kind-driver/src/lib.rs @@ -35,7 +35,7 @@ pub fn type_check_book(session: &mut Session, path: &PathBuf) -> Option Option Some(concrete_book) } -pub fn erase_book( - session: &mut Session, - path: &PathBuf, -) -> Option { +pub fn erase_book(session: &mut Session, path: &PathBuf) -> Option { let concrete_book = to_book(session, path)?; let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?; let mut book = erasure::erase_book(&desugared_book, session.diagnostic_sender.clone())?; inline_book(&mut book); Some(book) - } pub fn desugar_book(session: &mut Session, path: &PathBuf) -> Option { @@ -84,12 +80,12 @@ pub fn compile_book_to_hvm(book: untyped::Book) -> backend::File { pub fn compile_book_to_kdl( path: &PathBuf, session: &mut Session, - namespace: &str + namespace: &str, ) -> Option { let concrete_book = to_book(session, path)?; let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?; let mut book = erasure::erase_book(&desugared_book, session.diagnostic_sender.clone())?; - + inline_book(&mut book); kind_target_kdl::compile_book(book, session.diagnostic_sender.clone(), namespace) diff --git a/crates/kind-parser/src/expr.rs b/crates/kind-parser/src/expr.rs index 21345bdb..ba658ba2 100644 --- a/crates/kind-parser/src/expr.rs +++ b/crates/kind-parser/src/expr.rs @@ -1,7 +1,7 @@ use kind_span::{Locatable, Range}; use kind_tree::concrete::expr::*; use kind_tree::symbol::{Ident, QualifiedIdent}; -use kind_tree::{NumType, Number, Operator}; +use kind_tree::Operator; use crate::errors::SyntaxDiagnostic; use crate::lexer::tokens::Token; @@ -238,10 +238,10 @@ impl<'a> Parser<'a> { let data = match id.to_string().as_str() { "Type" => ExprKind::Lit { lit: Literal::Type }, "U60" => ExprKind::Lit { - lit: Literal::NumType(NumType::U60), + lit: Literal::NumTypeU60, }, - "U120" => ExprKind::Lit { - lit: Literal::NumType(NumType::U120), + "F60" => ExprKind::Lit { + lit: Literal::NumTypeF60, }, _ => ExprKind::Constr { name: id.clone(), @@ -260,10 +260,10 @@ impl<'a> Parser<'a> { let data = match id.to_string().as_str() { "Type" => ExprKind::Lit { lit: Literal::Type }, "U60" => ExprKind::Lit { - lit: Literal::NumType(NumType::U60), + lit: Literal::NumTypeU60, }, - "U120" => ExprKind::Lit { - lit: Literal::NumType(NumType::U120), + "F60" => ExprKind::Lit { + lit: Literal::NumTypeF60, }, _ => { let (range_end, spine) = self.parse_call_tail(id.range, multiline)?; @@ -283,7 +283,7 @@ impl<'a> Parser<'a> { Ok(Box::new(Expr { range, data: ExprKind::Lit { - lit: Literal::Number(Number::U60(num)), + lit: Literal::NumU60(num), }, })) } @@ -294,7 +294,7 @@ impl<'a> Parser<'a> { Ok(Box::new(Expr { range, data: ExprKind::Lit { - lit: Literal::Number(Number::U120(num)), + lit: Literal::NumU120(num), }, })) } diff --git a/crates/kind-parser/src/pat.rs b/crates/kind-parser/src/pat.rs index b9a1857d..ed49149e 100644 --- a/crates/kind-parser/src/pat.rs +++ b/crates/kind-parser/src/pat.rs @@ -25,21 +25,21 @@ impl<'a> Parser<'a> { })) } - fn parse_pat_num60(&mut self) -> Result, SyntaxDiagnostic> { + fn parse_pat_u60(&mut self) -> Result, SyntaxDiagnostic> { let start = self.range(); let num = eat_single!(self, Token::Num60(n) => *n)?; Ok(Box::new(Pat { range: start, - data: PatKind::Num(kind_tree::Number::U60(num)), + data: PatKind::U60(num), })) } - fn parse_pat_num120(&mut self) -> Result, SyntaxDiagnostic> { + fn parse_pat_u120(&mut self) -> Result, SyntaxDiagnostic> { let start = self.range(); let num = eat_single!(self, Token::Num120(n) => *n)?; Ok(Box::new(Pat { range: start, - data: PatKind::Num(kind_tree::Number::U120(num)), + data: PatKind::U120(num), })) } @@ -132,9 +132,9 @@ impl<'a> Parser<'a> { } else if self.get().is_str() { self.parse_pat_str() } else if self.get().is_num60() { - self.parse_pat_num60() + self.parse_pat_u60() } else if self.get().is_num120() { - self.parse_pat_num120() + self.parse_pat_u120() } else if self.check_actual(Token::LPar) { self.parse_pat_group() } else if self.get().is_lower_id() { diff --git a/crates/kind-pass/src/desugar/app.rs b/crates/kind-pass/src/desugar/app.rs index 80887ec9..4260b9d0 100644 --- a/crates/kind-pass/src/desugar/app.rs +++ b/crates/kind-pass/src/desugar/app.rs @@ -93,10 +93,7 @@ impl<'a> DesugarState<'a> { if entry.arguments[i].hidden { // It's not expected that positional arguments require the range so // it's the reason why we are using a terrible "ghost range" - arguments[i] = Some(( - range, - self.gen_hole_expr(range), - )) + arguments[i] = Some((range, self.gen_hole_expr(range))) } } } else if entry.arguments.len() != args.len() { diff --git a/crates/kind-pass/src/desugar/expr.rs b/crates/kind-pass/src/desugar/expr.rs index b8444854..abac83bc 100644 --- a/crates/kind-pass/src/desugar/expr.rs +++ b/crates/kind-pass/src/desugar/expr.rs @@ -23,7 +23,6 @@ impl<'a> DesugarState<'a> { literal: &expr::Literal, ) -> Box { match literal { - Literal::Number(kind_tree::Number::U120(num)) => desugared::Expr::num120(range, *num), Literal::String(string) => { if !self.check_implementation("String.cons", range, Sugar::String) || !self.check_implementation("String.nil", range, Sugar::String) @@ -34,10 +33,17 @@ impl<'a> DesugarState<'a> { } Literal::Type => desugared::Expr::typ(range), Literal::Help(name) => desugared::Expr::hlp(range, name.clone()), - Literal::NumType(kind_tree::NumType::U60) => desugared::Expr::u60(range), - Literal::NumType(kind_tree::NumType::U120) => desugared::Expr::u120(range), - Literal::Number(kind_tree::Number::U60(num)) => desugared::Expr::num60(range, *num), - Literal::Char(cht) => desugared::Expr::num60(range, *cht as u64), + Literal::NumTypeU60 => desugared::Expr::type_u60(range), + Literal::NumTypeF60 => desugared::Expr::type_f60(range), + Literal::NumU60(num) => desugared::Expr::num_u60(range, *num), + Literal::NumU120(num) => { + if !self.check_implementation("U120.new", range, Sugar::U120) { + return desugared::Expr::err(range); + } + desugared::Expr::num_u120(range, *num) + } + Literal::NumF60(num) => desugared::Expr::num_f60(range, *num), + Literal::Char(cht) => desugared::Expr::num_u60(range, *cht as u64), } } diff --git a/crates/kind-pass/src/desugar/top_level.rs b/crates/kind-pass/src/desugar/top_level.rs index e6d528f9..16184caa 100644 --- a/crates/kind-pass/src/desugar/top_level.rs +++ b/crates/kind-pass/src/desugar/top_level.rs @@ -292,8 +292,9 @@ impl<'a> DesugarState<'a> { desugared::Expr::var(name) } PatKind::Var(ident) => desugared::Expr::var(ident.0.clone()), - PatKind::Num(kind_tree::Number::U60(n)) => desugared::Expr::num60(pat.range, *n), - PatKind::Num(kind_tree::Number::U120(n)) => desugared::Expr::num120(pat.range, *n), + PatKind::U60(n) => desugared::Expr::num_u60(pat.range, *n), + PatKind::U120(n) => desugared::Expr::num_u120(pat.range, *n), + PatKind::F60(n) => desugared::Expr::num_f60(pat.range, *n), PatKind::Pair(fst, snd) => self.desugar_pair_pat(pat.range, fst, snd), PatKind::List(ls) => self.desugar_list_pat(pat.range, ls), PatKind::Str(string) => desugared::Expr::str(pat.range, string.to_owned()), diff --git a/crates/kind-pass/src/erasure/mod.rs b/crates/kind-pass/src/erasure/mod.rs index 13440e4c..ab1f6778 100644 --- a/crates/kind-pass/src/erasure/mod.rs +++ b/crates/kind-pass/src/erasure/mod.rs @@ -7,7 +7,6 @@ use kind_span::Range; use kind_tree::desugared; use kind_tree::symbol::{Ident, QualifiedIdent}; use kind_tree::untyped::{self}; -use kind_tree::Number; use crate::errors::PassError; @@ -99,7 +98,7 @@ impl<'a> ErasureState<'a> { let mut vals = FxHashMap::default(); let mut entrypoints = Vec::new(); - + if let Some(entr) = book.entrs.get("Main") { let id = self.get_edge_or_create(&entr.name); self.set_relevance(id, Relevance::Relevant, entr.name.range); @@ -134,11 +133,14 @@ impl<'a> ErasureState<'a> { names: Default::default(), }; - let mut queue = entrypoints.iter().map(|x| (x, Ambient::Relevant)).collect::>(); + let mut queue = entrypoints + .iter() + .map(|x| (x, Ambient::Relevant)) + .collect::>(); while !queue.is_empty() { let (fst, relev) = queue.pop().unwrap(); - + if visited.contains(&fst) { continue; } @@ -155,15 +157,13 @@ impl<'a> ErasureState<'a> { } } - let entry = vals.get(&edge.name).cloned().unwrap(); - new_book.names.insert(entry.name.to_string(), new_book.entrs.len()); + new_book + .names + .insert(entry.name.to_string(), new_book.entrs.len()); - new_book.entrs.insert( - entry.name.to_string(), - entry - ); + new_book.entrs.insert(entry.name.to_string(), entry); for (to, relevs) in &edge.connections { for (_, relev) in relevs.iter() { @@ -206,7 +206,7 @@ impl<'a> ErasureState<'a> { self.ctx = backup; let mut rules = Vec::new(); - + for rule in &entry.rules { rules.push(self.erase_rule(entry, id, rule)); } @@ -251,7 +251,6 @@ impl<'a> ErasureState<'a> { .map(|res| res.0) .collect::>(); - let body = self.erase_expr(relev(false), edge, &rule.body); self.ctx = backup; @@ -279,7 +278,7 @@ impl<'a> ErasureState<'a> { }; use desugared::ExprKind::*; - + match &expr.data { Var { name } => { self.ctx.insert( @@ -336,12 +335,8 @@ impl<'a> ErasureState<'a> { untyped::Expr::ctr(expr.range, name.clone(), args) } - Num { - num: Number::U60(num), - } => untyped::Expr::num60(expr.range, *num), - Num { - num: Number::U120(num), - } => untyped::Expr::num120(expr.range, *num), + NumU60 { numb } => untyped::Expr::u60(expr.range, *numb), + NumF60 { numb } => untyped::Expr::f60(expr.range, *numb), Str { val } => { let nil = QualifiedIdent::new_static("String.nil", None, expr.range); let cons = QualifiedIdent::new_static("String.cons", None, expr.range); @@ -371,7 +366,7 @@ impl<'a> ErasureState<'a> { } => { let backup = self.ctx.clone(); self.ctx.insert(param.to_string(), Relevance::Irrelevant); - + if ambient != Ambient::Irrelevant { self.set_relevance(edge, Relevance::Irrelevant, expr.range); } @@ -479,12 +474,8 @@ impl<'a> ErasureState<'a> { self.erase_expr(Ambient::Irrelevant, edge, typ); expr } - Num { - num: Number::U60(num), - } => untyped::Expr::num60(expr.range, *num), - Num { - num: Number::U120(num), - } => untyped::Expr::num120(expr.range, *num), + NumU60 { numb } => untyped::Expr::u60(expr.range, *numb), + NumF60 { numb } => untyped::Expr::f60(expr.range, *numb), Str { val } => { let nil = QualifiedIdent::new_static("String.nil", None, expr.range); let cons = QualifiedIdent::new_static("String.cons", None, expr.range); @@ -507,7 +498,7 @@ impl<'a> ErasureState<'a> { let right = self.erase_expr(ambient, edge, right); untyped::Expr::binary(expr.range, *op, left, right) } - Typ | NumType { typ: _ } | Hole { num: _ } | Hlp(_) | Err => { + Typ | NumTypeU60 { .. } | NumTypeF60 { .. } | Hole { .. } | Hlp(_) | Err => { if ambient != Ambient::Irrelevant && ambient != Ambient::Irrelevant { self.set_relevance(edge, Relevance::Irrelevant, expr.range); } diff --git a/crates/kind-pass/src/errors.rs b/crates/kind-pass/src/errors.rs index 730103e8..bc3809fd 100644 --- a/crates/kind-pass/src/errors.rs +++ b/crates/kind-pass/src/errors.rs @@ -9,6 +9,7 @@ pub enum Sugar { Pair, BoolIf, String, + U120, Match(String), Open(String), } @@ -202,6 +203,7 @@ impl Diagnostic for PassError { Sugar::Pair => "You must implement 'Sigma' and 'Sigma.new' in order to use the sigma notation.".to_string(), Sugar::BoolIf => "You must implement 'Bool.if' in order to use the if notation.".to_string(), Sugar::String => "You must implement 'String.cons' in order to use the string notation.".to_string(), + Sugar::U120 => "You must implement 'U120.new' in order to use the u120 notation.".to_string(), Sugar::Match(name) => format!("You must implement '{}.match' in order to use the match notation (or derive match with #derive[match]).", name), Sugar::Open(name) => format!("You must implement '{}.open' in order to use the open notation (or derive open with #derive[open]).", name), }], diff --git a/crates/kind-pass/src/inline/mod.rs b/crates/kind-pass/src/inline/mod.rs index 2c5a7653..47fd54a5 100644 --- a/crates/kind-pass/src/inline/mod.rs +++ b/crates/kind-pass/src/inline/mod.rs @@ -8,7 +8,7 @@ struct Inlinable { body: Box, } struct InlineState { - funs: FxHashMap + funs: FxHashMap, } fn inlinable(entry: &untyped::Entry) -> Option { @@ -16,14 +16,15 @@ fn inlinable(entry: &untyped::Entry) -> Option { let mut names = Vec::new(); for pat in &entry.rules[0].pats { match &pat.data { - untyped::ExprKind::Var { name } => { - names.push(name.to_string()) - }, - _ => return None + untyped::ExprKind::Var { name } => names.push(name.to_string()), + _ => return None, } } // TODO: Check if is recursive - Some(Inlinable { names, body: entry.rules[0].body.clone() }) + Some(Inlinable { + names, + body: entry.rules[0].body.clone(), + }) } else { None } @@ -73,10 +74,11 @@ impl InlineState { } Fun { name, args } | Ctr { name, args } => { if let Some(inlinable) = self.funs.get(name.to_str()) { - let subst = FxHashMap::from_iter(inlinable.names.iter().cloned().zip(args.clone())); + let subst = + FxHashMap::from_iter(inlinable.names.iter().cloned().zip(args.clone())); *expr = inlinable.body.clone(); subst_on_expr(expr, subst); - }else { + } else { for arg in args { self.inline_expr(arg); } diff --git a/crates/kind-pass/src/lib.rs b/crates/kind-pass/src/lib.rs index 3a0ae41e..3c65f2e3 100644 --- a/crates/kind-pass/src/lib.rs +++ b/crates/kind-pass/src/lib.rs @@ -8,5 +8,5 @@ pub mod desugar; pub mod erasure; mod errors; pub mod expand; -pub mod unbound; pub mod inline; +pub mod unbound; diff --git a/crates/kind-pass/src/unbound/mod.rs b/crates/kind-pass/src/unbound/mod.rs index cb045b03..77b94e3d 100644 --- a/crates/kind-pass/src/unbound/mod.rs +++ b/crates/kind-pass/src/unbound/mod.rs @@ -336,7 +336,9 @@ impl Visitor for UnboundCollector { match &mut pat.data { PatKind::Var(ident) => self.visit_pat_ident(ident), PatKind::Str(_) => (), - PatKind::Num(_) => (), + PatKind::U60(_) => (), + PatKind::U120(_) => (), + PatKind::F60(_) => (), PatKind::Hole => (), PatKind::List(ls) => { for pat in ls { diff --git a/crates/kind-pass/src/unbound/subst.rs b/crates/kind-pass/src/unbound/subst.rs index 2ceb480c..da7673cb 100644 --- a/crates/kind-pass/src/unbound/subst.rs +++ b/crates/kind-pass/src/unbound/subst.rs @@ -3,7 +3,7 @@ use kind_tree::untyped::*; pub struct Subst { vars: FxHashMap>, - ctx: im::HashSet + ctx: im::HashSet, } pub fn subst_on_expr(expr: &mut Box, vars: FxHashMap>) { @@ -24,12 +24,11 @@ impl Subst { for rule in &mut entry.rules { self.subst_rule(rule); } - } pub fn subst_rule(&mut self, rule: &mut Rule) { let backup = self.ctx.clone(); - + for pat in &mut rule.pats { self.subst_expr(pat) } @@ -51,7 +50,7 @@ impl Subst { self.subst_pat(arg); } } - _ => () + _ => (), } } @@ -66,7 +65,7 @@ impl Subst { if let Some(res) = self.vars.get(name.to_str()) { *expr = res.clone().clone(); } - }, + } Lambda { param, body, .. } => { let backup = self.ctx.clone(); self.ctx.insert(param.to_string()); @@ -95,7 +94,7 @@ impl Subst { self.subst_expr(left); self.subst_expr(right); } - _ => () + _ => (), } } -} \ No newline at end of file +} diff --git a/crates/kind-target-hvm/src/lib.rs b/crates/kind-target-hvm/src/lib.rs index f5ef4dec..eb4f4637 100644 --- a/crates/kind-target-hvm/src/lib.rs +++ b/crates/kind-target-hvm/src/lib.rs @@ -17,7 +17,6 @@ pub fn compile_book(book: untyped::Book) -> File { } pub fn compile_term(expr: &untyped::Expr) -> Box { - use kind_tree::Number; use untyped::ExprKind::*; match &expr.data { Var { name } => Box::new(Term::Var { @@ -42,25 +41,10 @@ pub fn compile_term(expr: &untyped::Expr) -> Box { expr: compile_term(val), body: compile_term(next), }), - Num { - num: Number::U60(numb), - } => Box::new(Term::U6O { + U60 { numb } => Box::new(Term::U6O { numb: u60::new(*numb), }), - Num { - num: Number::U120(numb), - } => { - let hi = Box::new(Term::U6O { - numb: u60::new((numb >> 60) as u64), - }); - let lo = Box::new(Term::U6O { - numb: u60::new((numb & 0xFFFFFFFFFFFFFFF) as u64), - }); - Box::new(Term::Ctr { - name: String::from("U120.new"), - args: vec![hi, lo], - }) - } + F60 { numb: _ } => todo!(), Binary { op, left, right } => Box::new(Term::Ctr { name: op.to_string(), args: vec![compile_term(left), compile_term(right)], @@ -95,6 +79,7 @@ fn compile_rule(rule: untyped::Rule) -> Rule { } fn compile_entry(file: &mut File, entry: untyped::Entry) { + // TODO: Add optimizations for some functions? for rule in entry.rules { file.rules.push(compile_rule(rule)) } diff --git a/crates/kind-target-kdl/src/compile.rs b/crates/kind-target-kdl/src/compile.rs index 24d3213f..a6c3dc7a 100644 --- a/crates/kind-target-kdl/src/compile.rs +++ b/crates/kind-target-kdl/src/compile.rs @@ -2,7 +2,7 @@ use std::{fmt::Display, sync::mpsc::Sender}; use fxhash::FxHashMap; use kind_report::data::Diagnostic; -use kind_tree::{symbol::QualifiedIdent, untyped, Number}; +use kind_tree::{symbol::QualifiedIdent, untyped}; use linked_hash_map::LinkedHashMap; use tiny_keccak::Hasher; @@ -202,10 +202,13 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kindelia_lang } } From::Ctr { name, args } => { + let name = ctx.kdl_names.get(name.to_str()).unwrap().clone(); + let args = args.iter().map(|x| compile_expr(ctx, &x)).collect(); + To::Ctr { name, args } + } + From::Fun { name, args } => { match name.to_str() { // Special compilation for some numeric functions - // They have no rules because they're compilation defined, - // so they've been initially interpreted as Ctr // Add with no boundary check is just a normal add "U60.add_unsafe" => To::Op2 { @@ -303,20 +306,13 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kindelia_lang val0: Box::new(compile_expr(ctx, &args[0])), val1: Box::new(compile_expr(ctx, &args[1])), }, - - // All other constructors have a normal compilation _ => { let name = ctx.kdl_names.get(name.to_str()).unwrap().clone(); - let args = args.iter().map(|x| compile_expr(ctx, &x)).collect(); - To::Ctr { name, args } + let args = args.iter().map(|x| compile_expr(ctx, x)).collect(); + To::Fun { name, args } } } } - From::Fun { name, args } => { - let name = ctx.kdl_names.get(name.to_str()).unwrap().clone(); - let args = args.iter().map(|x| compile_expr(ctx, x)).collect(); - To::Fun { name, args } - } From::Lambda { param, body, @@ -343,16 +339,13 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kindelia_lang err_term() } } - From::Num { - num: Number::U60(numb), - } => To::Num { + From::U60 { numb } => To::Num { numb: kdl::U120(*numb as u128), }, - From::Num { - num: Number::U120(numb), - } => To::Num { - numb: kdl::U120(*numb), - }, + From::F60 { numb: _ } => { + ctx.send_err(Box::new(KdlError::FloatUsed(expr.range))); + err_term() + } From::Var { name } => { let res_name = kdl::Name::from_str(name.to_str()); if let Ok(name) = res_name { @@ -469,7 +462,7 @@ impl Display for File { for ctr in &self.ctrs { writeln!(f, "{}", ctr.1)?; } - + if self.ctrs.len() > 0 && self.funs.len() > 0 { writeln!(f)?; } diff --git a/crates/kind-target-kdl/src/errors.rs b/crates/kind-target-kdl/src/errors.rs index 98ff8988..ad727d78 100644 --- a/crates/kind-target-kdl/src/errors.rs +++ b/crates/kind-target-kdl/src/errors.rs @@ -6,6 +6,7 @@ pub enum KdlError { ShouldNotHaveArguments(Range), ShouldHaveOnlyOneRule(Range), NoInitEntry(Range), + FloatUsed(Range), } impl Diagnostic for KdlError { @@ -15,6 +16,7 @@ impl Diagnostic for KdlError { KdlError::ShouldNotHaveArguments(range) => Some(range.ctx), KdlError::ShouldHaveOnlyOneRule(range) => Some(range.ctx), KdlError::NoInitEntry(range) => Some(range.ctx), + KdlError::FloatUsed(range) => Some(range.ctx), } } @@ -65,7 +67,21 @@ impl Diagnostic for KdlError { KdlError::NoInitEntry(range) => DiagnosticFrame { code: 604, severity: Severity::Error, - title: "This entry have to have a init entry".to_string(), + title: "This entry must have a init entry".to_string(), + subtitles: vec![], + hints: vec![], + positions: vec![Marker { + position: *range, + color: Color::Fst, + text: "Here!".to_string(), + no_code: false, + main: true, + }], + }, + KdlError::FloatUsed(range) => DiagnosticFrame { + code: 605, + severity: Severity::Error, + title: "Found F60 in kindelia program".to_string(), subtitles: vec![], hints: vec![], positions: vec![Marker { diff --git a/crates/kind-target-kdl/src/flatten.rs b/crates/kind-target-kdl/src/flatten.rs index dc8d2387..02b24b0e 100644 --- a/crates/kind-target-kdl/src/flatten.rs +++ b/crates/kind-target-kdl/src/flatten.rs @@ -10,7 +10,10 @@ fn must_split(rule: &Rule) -> bool { for pat in &rule.pats { if let ExprKind::Ctr { args, .. } = &pat.data { for arg in args { - if matches!(arg.data, ExprKind::Ctr { .. } | ExprKind::Num { .. }) { + if matches!( + arg.data, + ExprKind::Ctr { .. } | ExprKind::U60 { .. } | ExprKind::F60 { .. } + ) { return true; } } @@ -27,19 +30,41 @@ fn matches_together(a: &Rule, b: &Rule) -> (bool, bool) { (ExprKind::Ctr { name: an, .. }, ExprKind::Ctr { name: bn, .. }) if an != bn => { return (false, false); } - (ExprKind::Num { num: a_numb }, ExprKind::Num { num: b_numb }) if a_numb != b_numb => { + (ExprKind::U60 { numb: a_numb }, ExprKind::U60 { numb: b_numb }) + if a_numb != b_numb => + { return (false, false); } - (ExprKind::Ctr { .. }, ExprKind::Num { .. }) => { + (ExprKind::F60 { numb: a_numb }, ExprKind::F60 { numb: b_numb }) + if a_numb != b_numb => + { return (false, false); } - (ExprKind::Num { .. }, ExprKind::Ctr { .. }) => { + (ExprKind::Ctr { .. }, ExprKind::U60 { .. }) => { + return (false, false); + } + (ExprKind::Ctr { .. }, ExprKind::F60 { .. }) => { + return (false, false); + } + (ExprKind::U60 { .. }, ExprKind::Ctr { .. }) => { + return (false, false); + } + (ExprKind::U60 { .. }, ExprKind::F60 { .. }) => { + return (false, false); + } + (ExprKind::F60 { .. }, ExprKind::U60 { .. }) => { + return (false, false); + } + (ExprKind::F60 { .. }, ExprKind::Ctr { .. }) => { return (false, false); } (ExprKind::Ctr { .. }, ExprKind::Var { .. }) => { same_shape = false; } - (ExprKind::Num { .. }, ExprKind::Var { .. }) => { + (ExprKind::U60 { .. }, ExprKind::Var { .. }) => { + same_shape = false; + } + (ExprKind::F60 { .. }, ExprKind::Var { .. }) => { same_shape = false; } _ => {} @@ -80,7 +105,7 @@ fn split_rule( old_rule_pats.push(pat.clone()); old_rule_body_args.push(Expr::var(name.clone())); } - ExprKind::Num { .. } => { + ExprKind::U60 { .. } | ExprKind::F60 { .. } => { old_rule_pats.push(pat.clone()); } ExprKind::Ctr { name, args } => { @@ -88,7 +113,7 @@ fn split_rule( for field in args { let arg = match &field.data { - ExprKind::Ctr { .. } | ExprKind::Num { .. } => { + ExprKind::Ctr { .. } | ExprKind::U60 { .. } | ExprKind::F60 { .. } => { let name = Ident::new(format!(".x{}", var_count), field.range); var_count += 1; Expr::var(name) @@ -150,8 +175,12 @@ fn split_rule( (ExprKind::Var { .. }, _) => { new_rule_pats.push(other_pat.clone()); } - (ExprKind::Num { .. }, ExprKind::Num { .. }) => (), - (ExprKind::Num { .. }, ExprKind::Var { name }) => { + (ExprKind::U60 { .. }, ExprKind::U60 { .. }) => (), + (ExprKind::F60 { .. }, ExprKind::F60 { .. }) => (), + (ExprKind::U60 { .. }, ExprKind::Var { name }) => { + subst(&mut new_rule_body, &name, rule_pat); + } + (ExprKind::F60 { .. }, ExprKind::Var { name }) => { subst(&mut new_rule_body, &name, rule_pat); } _ => { diff --git a/crates/kind-target-kdl/src/lib.rs b/crates/kind-target-kdl/src/lib.rs index 2d4c9af5..d504c4d6 100644 --- a/crates/kind-target-kdl/src/lib.rs +++ b/crates/kind-target-kdl/src/lib.rs @@ -20,7 +20,7 @@ pub fn compile_book( // TODO: Remove kdl_states (maybe check if they're ever called?) // TODO: Convert to some sort of Kindelia.Contract let flattened = flatten(book); - + let file = compile::compile_book(&flattened, sender, namespace)?; let file = linearize::linearize_file(file); Some(file) diff --git a/crates/kind-target-kdl/src/subst.rs b/crates/kind-target-kdl/src/subst.rs index 23547507..1c40ab61 100644 --- a/crates/kind-target-kdl/src/subst.rs +++ b/crates/kind-target-kdl/src/subst.rs @@ -32,11 +32,12 @@ pub fn subst(term: &mut Expr, from: &Ident, to: &Expr) { Lambda { param, body, .. } if param.to_str() != from.to_str() => subst(body, from, to), - Num { .. } => (), + U60 { .. } => (), + F60 { .. } => (), Str { .. } => (), Var { .. } => (), Lambda { .. } => (), - Err => unreachable!("Err should not be used inside the compiledr"), + Err => unreachable!("Err should not be used inside the compiler"), } } diff --git a/crates/kind-tree/src/concrete/expr.rs b/crates/kind-tree/src/concrete/expr.rs index a6e9c19f..e1ccae46 100644 --- a/crates/kind-tree/src/concrete/expr.rs +++ b/crates/kind-tree/src/concrete/expr.rs @@ -84,12 +84,17 @@ pub enum Literal { /// The help operator that prints the context /// and the goal (e.g. ?) Help(Ident), - /// The type of 60 bits numberss (e.g. 2 : U60) - NumType(crate::NumType), + /// The type literal of 60 bit numbers (e.g. 2 : U60) + NumTypeU60, + NumTypeF60, // Char literal Char(char), - /// A number literal of 60 bits (e.g 32132) - Number(crate::Number), + /// A 60 bit number literal (e.g 32132) + NumU60(u64), + // A 120 bit number literal + NumU120(u128), + // A 60 bit floating point number literal + NumF60(u64), // A String literal String(String), } @@ -310,11 +315,12 @@ impl Display for Literal { match self { Literal::Help(s) => write!(f, "?{}", s), Literal::Type => write!(f, "Type"), - Literal::NumType(crate::NumType::U60) => write!(f, "U60"), - Literal::NumType(crate::NumType::U120) => write!(f, "U120"), + Literal::NumTypeU60 => write!(f, "U60"), + Literal::NumTypeF60 => write!(f, "F60"), Literal::Char(c) => write!(f, "'{}'", c), - Literal::Number(crate::Number::U60(numb)) => write!(f, "{}", numb), - Literal::Number(crate::Number::U120(numb)) => write!(f, "{}u120", numb), + Literal::NumU60(numb) => write!(f, "{}", numb), + Literal::NumF60(_numb) => todo!(), + Literal::NumU120(numb) => write!(f, "{}u120", numb), Literal::String(str) => { write!(f, "{:?}", str) } diff --git a/crates/kind-tree/src/concrete/pat.rs b/crates/kind-tree/src/concrete/pat.rs index 4b12644d..6e64874f 100644 --- a/crates/kind-tree/src/concrete/pat.rs +++ b/crates/kind-tree/src/concrete/pat.rs @@ -19,8 +19,12 @@ pub enum PatKind { Var(PatIdent), /// Application of a constructor App(QualifiedIdent, Vec>), - /// Number - Num(crate::Number), + /// 60 bit unsigned integer + U60(u64), + /// 120 bit unsigned integer + U120(u128), + /// 60 bit floating point number + F60(u64), /// Pair Pair(Box, Box), /// List @@ -58,8 +62,9 @@ impl Display for Pat { .join(" ") ), Str(str) => write!(f, "\"{}\"", str), - Num(crate::Number::U60(num)) => write!(f, "{}", num), - Num(crate::Number::U120(num)) => write!(f, "{}u120", num), + U60(num) => write!(f, "{}", num), + U120(num) => write!(f, "{}u120", num), + F60(_num) => todo!(), Pair(fst, snd) => write!(f, "({}, {})", fst, snd), Hole => write!(f, "_"), } diff --git a/crates/kind-tree/src/concrete/visitor.rs b/crates/kind-tree/src/concrete/visitor.rs index 5fddc18f..ba0efe72 100644 --- a/crates/kind-tree/src/concrete/visitor.rs +++ b/crates/kind-tree/src/concrete/visitor.rs @@ -280,7 +280,9 @@ pub fn walk_pat(ctx: &mut T, pat: &mut Pat) { match &mut pat.data { PatKind::Var(ident) => ctx.visit_pat_ident(ident), PatKind::Str(_) => (), - PatKind::Num(_) => (), + PatKind::U60(_) => (), + PatKind::U120(_) => (), + PatKind::F60(_) => (), PatKind::Hole => (), PatKind::List(ls) => { for pat in ls { diff --git a/crates/kind-tree/src/desugared/mod.rs b/crates/kind-tree/src/desugared/mod.rs index a5902986..d8906585 100644 --- a/crates/kind-tree/src/desugared/mod.rs +++ b/crates/kind-tree/src/desugared/mod.rs @@ -7,11 +7,11 @@ use fxhash::FxHashMap; use kind_span::Range; use linked_hash_map::LinkedHashMap; +pub use crate::Operator; use crate::{ symbol::{Ident, QualifiedIdent}, Attributes, }; -pub use crate::{NumType, Number, Operator}; /// Just a vector of expressions. It is called spine because /// it is usually in a form like (a b c d e) that can be interpret @@ -67,10 +67,14 @@ pub enum ExprKind { }, /// Type Literal Typ, - /// Primitive numeric types - NumType { typ: crate::NumType }, - /// Primitive numeric values - Num { num: crate::Number }, + /// 60 bit integer type + NumTypeU60, + /// 60 bit floating point number type + NumTypeF60, + /// 60 bit integer + NumU60 { numb: u64 }, + /// 60 bit floating point number + NumF60 { numb: u64 }, /// Very special constructor :) Str { val: String }, /// Binary operation (e.g. 2 + 3) @@ -207,39 +211,44 @@ impl Expr { }) } - pub fn u60(range: Range) -> Box { + pub fn type_u60(range: Range) -> Box { Box::new(Expr { range, - data: ExprKind::NumType { - typ: crate::NumType::U60, + data: ExprKind::NumTypeU60, + }) + } + + pub fn type_f60(range: Range) -> Box { + Box::new(Expr { + range, + data: ExprKind::NumTypeF60, + }) + } + + pub fn num_u60(range: Range, numb: u64) -> Box { + Box::new(Expr { + range, + data: ExprKind::NumU60 { numb }, + }) + } + + pub fn num_u120(range: Range, numb: u128) -> Box { + let name = QualifiedIdent::new_static("U120.new", None, range); + let lo = Expr::num_u60(range, (numb & 0xFFFFFFFFFFFFFFF) as u64); + let hi = Expr::num_u60(range, (numb >> 60) as u64); + Box::new(Expr { + range, + data: ExprKind::Ctr { + name, + args: vec![hi, lo], }, }) } - pub fn u120(range: Range) -> Box { + pub fn num_f60(range: Range, numb: u64) -> Box { Box::new(Expr { range, - data: ExprKind::NumType { - typ: crate::NumType::U120, - }, - }) - } - - pub fn num60(range: Range, num: u64) -> Box { - Box::new(Expr { - range, - data: ExprKind::Num { - num: crate::Number::U60(num), - }, - }) - } - - pub fn num120(range: Range, num: u128) -> Box { - Box::new(Expr { - range, - data: ExprKind::Num { - num: crate::Number::U120(num), - }, + data: ExprKind::NumF60 { numb }, }) } @@ -371,19 +380,11 @@ impl Display for Expr { use ExprKind::*; match &self.data { Typ => write!(f, "Type"), - NumType { - typ: crate::NumType::U60, - } => write!(f, "U60"), - NumType { - typ: crate::NumType::U120, - } => write!(f, "U120"), + NumTypeU60 => write!(f, "U60"), + NumTypeF60 => write!(f, "F60"), Str { val } => write!(f, "\"{}\"", val), - Num { - num: crate::Number::U60(n), - } => write!(f, "{}", n), - Num { - num: crate::Number::U120(n), - } => write!(f, "{}u120", n), + NumU60 { numb } => write!(f, "{}", numb), + NumF60 { numb: _ } => todo!(), All { .. } => write!(f, "({})", self.traverse_pi_types()), Var { name } => write!(f, "{}", name), Lambda { diff --git a/crates/kind-tree/src/lib.rs b/crates/kind-tree/src/lib.rs index 66f4ab9b..847a0df7 100644 --- a/crates/kind-tree/src/lib.rs +++ b/crates/kind-tree/src/lib.rs @@ -53,16 +53,3 @@ pub enum Operator { Gtn, Neq, } - -#[derive(Clone, Debug, Hash, PartialEq, Eq)] -pub enum Number { - U60(u64), - U120(u128), - // TODO: F60 -} - -#[derive(Clone, Debug, Hash, PartialEq, Eq)] -pub enum NumType { - U60, - U120, -} diff --git a/crates/kind-tree/src/untyped/mod.rs b/crates/kind-tree/src/untyped/mod.rs index 75a68519..62503d35 100644 --- a/crates/kind-tree/src/untyped/mod.rs +++ b/crates/kind-tree/src/untyped/mod.rs @@ -7,11 +7,11 @@ use fxhash::FxHashMap; use kind_span::Range; use linked_hash_map::LinkedHashMap; +pub use crate::Operator; use crate::{ symbol::{Ident, QualifiedIdent}, Attributes, }; -pub use crate::{NumType, Number, Operator}; /// Just a vector of expressions. It is called spine because /// it is usually in a form like (a b c d e) that can be interpret @@ -51,9 +51,13 @@ pub enum ExprKind { val: Box, next: Box, }, - /// Primitive numeric values - Num { - num: crate::Number, + /// 60 bit unsigned integer + U60 { + numb: u64, + }, + /// 60 bit floating point number + F60 { + numb: u64, }, /// Very special constructor :) Str { @@ -129,21 +133,17 @@ impl Expr { }) } - pub fn num60(range: Range, num: u64) -> Box { + pub fn u60(range: Range, numb: u64) -> Box { Box::new(Expr { range, - data: ExprKind::Num { - num: crate::Number::U60(num), - }, + data: ExprKind::U60 { numb }, }) } - pub fn num120(range: Range, num: u128) -> Box { + pub fn f60(range: Range, numb: u64) -> Box { Box::new(Expr { range, - data: ExprKind::Num { - num: crate::Number::U120(num), - }, + data: ExprKind::F60 { numb }, }) } @@ -205,7 +205,7 @@ pub struct Entry { #[derive(Clone, Debug, Default)] pub struct Book { pub entrs: LinkedHashMap>, - pub names: FxHashMap + pub names: FxHashMap, } impl Expr { @@ -223,12 +223,8 @@ impl Display for Expr { match &self.data { Err => write!(f, "ERR"), Str { val } => write!(f, "\"{}\"", val), - Num { - num: crate::Number::U60(n), - } => write!(f, "{}", n), - Num { - num: crate::Number::U120(n), - } => write!(f, "{}u120", n), + U60 { numb } => write!(f, "{}", numb), + F60 { numb: _ } => todo!(), Var { name } => write!(f, "{}", name), Lambda { param,