mirror of
https://github.com/HigherOrderCO/Kind1.git
synced 2024-08-15 19:30:41 +03:00
feat: Undo native U1120, partially add F60, refactor
This commit is contained in:
parent
4357ec0078
commit
3e216f2899
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -555,6 +555,7 @@ name = "kind-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
"im",
|
||||
"kind-report",
|
||||
"kind-span",
|
||||
"kind-tree",
|
||||
|
@ -119,7 +119,7 @@ fn desugar_str(input: &str, range: Range) -> Box<desugared::Expr> {
|
||||
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![
|
||||
|
@ -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])?,
|
||||
|
@ -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))
|
||||
});
|
||||
|
@ -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::<Vec<_>>();
|
||||
let render = RenderConfig::ascii(2);
|
||||
|
@ -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 {
|
||||
|
@ -35,7 +35,7 @@ pub fn type_check_book(session: &mut Session, path: &PathBuf) -> Option<untyped:
|
||||
|
||||
let mut book = erasure::erase_book(&desugared_book, session.diagnostic_sender.clone())?;
|
||||
inline_book(&mut book);
|
||||
|
||||
|
||||
Some(book)
|
||||
}
|
||||
|
||||
@ -53,16 +53,12 @@ pub fn to_book(session: &mut Session, path: &PathBuf) -> Option<concrete::Book>
|
||||
Some(concrete_book)
|
||||
}
|
||||
|
||||
pub fn erase_book(
|
||||
session: &mut Session,
|
||||
path: &PathBuf,
|
||||
) -> Option<untyped::Book> {
|
||||
pub fn erase_book(session: &mut Session, path: &PathBuf) -> Option<untyped::Book> {
|
||||
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<desugared::Book> {
|
||||
@ -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<kind_target_kdl::File> {
|
||||
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)
|
||||
|
@ -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),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
@ -25,21 +25,21 @@ impl<'a> Parser<'a> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_pat_num60(&mut self) -> Result<Box<Pat>, SyntaxDiagnostic> {
|
||||
fn parse_pat_u60(&mut self) -> Result<Box<Pat>, 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<Box<Pat>, SyntaxDiagnostic> {
|
||||
fn parse_pat_u120(&mut self) -> Result<Box<Pat>, 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() {
|
||||
|
@ -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() {
|
||||
|
@ -23,7 +23,6 @@ impl<'a> DesugarState<'a> {
|
||||
literal: &expr::Literal,
|
||||
) -> Box<desugared::Expr> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()),
|
||||
|
@ -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::<Vec<_>>();
|
||||
let mut queue = entrypoints
|
||||
.iter()
|
||||
.map(|x| (x, Ambient::Relevant))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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::<Vec<_>>();
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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),
|
||||
}],
|
||||
|
@ -8,7 +8,7 @@ struct Inlinable {
|
||||
body: Box<untyped::Expr>,
|
||||
}
|
||||
struct InlineState {
|
||||
funs: FxHashMap<String, Inlinable>
|
||||
funs: FxHashMap<String, Inlinable>,
|
||||
}
|
||||
|
||||
fn inlinable(entry: &untyped::Entry) -> Option<Inlinable> {
|
||||
@ -16,14 +16,15 @@ fn inlinable(entry: &untyped::Entry) -> Option<Inlinable> {
|
||||
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);
|
||||
}
|
||||
|
@ -8,5 +8,5 @@ pub mod desugar;
|
||||
pub mod erasure;
|
||||
mod errors;
|
||||
pub mod expand;
|
||||
pub mod unbound;
|
||||
pub mod inline;
|
||||
pub mod unbound;
|
||||
|
@ -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 {
|
||||
|
@ -3,7 +3,7 @@ use kind_tree::untyped::*;
|
||||
|
||||
pub struct Subst {
|
||||
vars: FxHashMap<String, Box<Expr>>,
|
||||
ctx: im::HashSet<String>
|
||||
ctx: im::HashSet<String>,
|
||||
}
|
||||
|
||||
pub fn subst_on_expr(expr: &mut Box<Expr>, vars: FxHashMap<String, Box<Expr>>) {
|
||||
@ -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);
|
||||
}
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ pub fn compile_book(book: untyped::Book) -> File {
|
||||
}
|
||||
|
||||
pub fn compile_term(expr: &untyped::Expr) -> Box<Term> {
|
||||
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<Term> {
|
||||
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))
|
||||
}
|
||||
|
@ -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)?;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
_ => {
|
||||
|
@ -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)
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -19,8 +19,12 @@ pub enum PatKind {
|
||||
Var(PatIdent),
|
||||
/// Application of a constructor
|
||||
App(QualifiedIdent, Vec<Box<Pat>>),
|
||||
/// 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<Pat>, Box<Pat>),
|
||||
/// 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, "_"),
|
||||
}
|
||||
|
@ -280,7 +280,9 @@ pub fn walk_pat<T: Visitor>(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 {
|
||||
|
@ -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<Expr> {
|
||||
pub fn type_u60(range: Range) -> Box<Expr> {
|
||||
Box::new(Expr {
|
||||
range,
|
||||
data: ExprKind::NumType {
|
||||
typ: crate::NumType::U60,
|
||||
data: ExprKind::NumTypeU60,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn type_f60(range: Range) -> Box<Expr> {
|
||||
Box::new(Expr {
|
||||
range,
|
||||
data: ExprKind::NumTypeF60,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn num_u60(range: Range, numb: u64) -> Box<Expr> {
|
||||
Box::new(Expr {
|
||||
range,
|
||||
data: ExprKind::NumU60 { numb },
|
||||
})
|
||||
}
|
||||
|
||||
pub fn num_u120(range: Range, numb: u128) -> Box<Expr> {
|
||||
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<Expr> {
|
||||
pub fn num_f60(range: Range, numb: u64) -> Box<Expr> {
|
||||
Box::new(Expr {
|
||||
range,
|
||||
data: ExprKind::NumType {
|
||||
typ: crate::NumType::U120,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn num60(range: Range, num: u64) -> Box<Expr> {
|
||||
Box::new(Expr {
|
||||
range,
|
||||
data: ExprKind::Num {
|
||||
num: crate::Number::U60(num),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn num120(range: Range, num: u128) -> Box<Expr> {
|
||||
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 {
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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<Expr>,
|
||||
next: Box<Expr>,
|
||||
},
|
||||
/// 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<Expr> {
|
||||
pub fn u60(range: Range, numb: u64) -> Box<Expr> {
|
||||
Box::new(Expr {
|
||||
range,
|
||||
data: ExprKind::Num {
|
||||
num: crate::Number::U60(num),
|
||||
},
|
||||
data: ExprKind::U60 { numb },
|
||||
})
|
||||
}
|
||||
|
||||
pub fn num120(range: Range, num: u128) -> Box<Expr> {
|
||||
pub fn f60(range: Range, numb: u64) -> Box<Expr> {
|
||||
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<String, Box<Entry>>,
|
||||
pub names: FxHashMap<String, usize>
|
||||
pub names: FxHashMap<String, usize>,
|
||||
}
|
||||
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user