From 2d387e62794b580ba6eb6efe95d91963326cae8e Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Sun, 4 Aug 2024 23:18:37 +0200 Subject: [PATCH 1/3] TypeID: add Copy trait --- src/dict.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dict.rs b/src/dict.rs index 83b63ee..93bb6ec 100644 --- a/src/dict.rs +++ b/src/dict.rs @@ -2,7 +2,7 @@ use crate::bimap::Bimap; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ -#[derive(Eq, PartialEq, Hash, Clone, Debug)] +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] pub enum TypeID { Fun(u64), Var(u64) From 91cd1cd7d864748b2067eb49180441edb7e08c2a Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 2 Oct 2024 22:37:06 +0200 Subject: [PATCH 2/3] add sugared terms & pretty printing --- Cargo.toml | 5 ++ src/dict.rs | 4 ++ src/lib.rs | 8 ++- src/pretty.rs | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/sugar.rs | 95 ++++++++++++++++++++++++++++++++ src/term.rs | 2 +- 6 files changed, 259 insertions(+), 3 deletions(-) create mode 100644 src/pretty.rs create mode 100644 src/sugar.rs diff --git a/Cargo.toml b/Cargo.toml index 0a57fd3..429541c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,8 @@ edition = "2018" name = "laddertypes" version = "0.1.0" +[dependencies] +tiny-ansi = { version = "0.1.0", optional = true } + +[features] +pretty = ["dep:tiny-ansi"] diff --git a/src/dict.rs b/src/dict.rs index 93bb6ec..419d599 100644 --- a/src/dict.rs +++ b/src/dict.rs @@ -54,6 +54,10 @@ impl TypeDict { pub fn get_typeid(&self, tn: &String) -> Option<TypeID> { self.typenames.mλ.get(tn).cloned() } + + pub fn get_varname(&self, var_id: u64) -> Option<String> { + self.typenames.my.get(&TypeID::Var(var_id)).cloned() + } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/src/lib.rs b/src/lib.rs index 1a270cc..e073b0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod term; pub mod lexer; pub mod parser; pub mod unparser; +pub mod sugar; pub mod curry; pub mod lnf; pub mod subtype; @@ -13,9 +14,12 @@ pub mod unification; #[cfg(test)] mod test; +#[cfg(feature = "pretty")] +mod pretty; + pub use { dict::*, term::*, - unification::* + sugar::*, + unification::*, }; - diff --git a/src/pretty.rs b/src/pretty.rs new file mode 100644 index 0000000..1a4aa60 --- /dev/null +++ b/src/pretty.rs @@ -0,0 +1,148 @@ +use { + crate::TypeDict, + crate::sugar::SugaredTypeTerm, + tiny_ansi::TinyAnsi +}; + +impl SugaredTypeTerm { + pub fn pretty(&self, dict: &TypeDict, indent: u64) -> String { + let indent_width = 4; + match self { + SugaredTypeTerm::TypeID(id) => { + format!("{}", dict.get_typename(id).unwrap_or("??".bright_red())).bright_blue() + }, + + SugaredTypeTerm::Num(n) => { + format!("{}", n).bright_cyan() + } + + SugaredTypeTerm::Char(c) => { + format!("'{}'", c) + } + + SugaredTypeTerm::Univ(t) => { + format!("{} {} . {}", + "∀".yellow().bold(), + dict.get_varname(0).unwrap_or("??".into()).bright_blue(), + t.pretty(dict,indent) + ) + } + + SugaredTypeTerm::Spec(args) => { + let mut s = String::new(); + s.push_str(&"<".yellow().bold()); + for i in 0..args.len() { + let arg = &args[i]; + if i > 0 { + s.push(' '); + } + s.push_str( &arg.pretty(dict,indent+1) ); + } + s.push_str(&">".yellow().bold()); + s + } + + SugaredTypeTerm::Struct(args) => { + let mut s = String::new(); + s.push_str(&"{".yellow().bold()); + for arg in args { + s.push('\n'); + for x in 0..(indent+1)*indent_width { + s.push(' '); + } + s.push_str(&arg.pretty(dict, indent + 1)); + s.push_str(&";\n".bright_yellow()); + } + + s.push('\n'); + for x in 0..indent*indent_width { + s.push(' '); + } + s.push_str(&"}".yellow().bold()); + s + } + + SugaredTypeTerm::Enum(args) => { + let mut s = String::new(); + s.push_str(&"(".yellow().bold()); + for i in 0..args.len() { + let arg = &args[i]; + s.push('\n'); + for x in 0..(indent+1)*indent_width { + s.push(' '); + } + if i > 0 { + s.push_str(&"| ".yellow().bold()); + } + s.push_str(&arg.pretty(dict, indent + 1)); + } + + s.push('\n'); + for x in 0..indent*indent_width { + s.push(' '); + } + s.push_str(&")".yellow().bold()); + s + } + + SugaredTypeTerm::Seq(args) => { + let mut s = String::new(); + s.push_str(&"[ ".yellow().bold()); + for i in 0..args.len() { + let arg = &args[i]; + if i > 0 { + s.push(' '); + } + s.push_str(&arg.pretty(dict, indent+1)); + } + s.push_str(&" ]".yellow().bold()); + s + } + + SugaredTypeTerm::Morph(args) => { + let mut s = String::new(); + for arg in args { + s.push_str(&" ~~morph~~> ".bright_yellow()); + s.push_str(&arg.pretty(dict, indent)); + } + s + } + + SugaredTypeTerm::Func(args) => { + let mut s = String::new(); + for i in 0..args.len() { + let arg = &args[i]; + if i > 0{ + s.push('\n'); + for x in 0..(indent*indent_width) { + s.push(' '); + } + s.push_str(&"--> ".bright_yellow()); + } else { +// s.push_str(" "); + } + s.push_str(&arg.pretty(dict, indent)); + } + s + } + + SugaredTypeTerm::Ladder(rungs) => { + let mut s = String::new(); + for i in 0..rungs.len() { + let rung = &rungs[i]; + if i > 0{ + s.push('\n'); + for x in 0..(indent*indent_width) { + s.push(' '); + } + s.push_str(&"~ ".yellow()); + } + s.push_str(&rung.pretty(dict, indent)); + } + s + } + } + } +} + + diff --git a/src/sugar.rs b/src/sugar.rs new file mode 100644 index 0000000..4d13f78 --- /dev/null +++ b/src/sugar.rs @@ -0,0 +1,95 @@ +use { + crate::{TypeTerm, TypeID} +}; + +pub enum SugaredTypeTerm { + TypeID(TypeID), + Num(i64), + Char(char), + Univ(Box< SugaredTypeTerm >), + Spec(Vec< SugaredTypeTerm >), + Func(Vec< SugaredTypeTerm >), + Morph(Vec< SugaredTypeTerm >), + Ladder(Vec< SugaredTypeTerm >), + Struct(Vec< SugaredTypeTerm >), + Enum(Vec< SugaredTypeTerm >), + Seq(Vec< SugaredTypeTerm >) +} + +impl TypeTerm { + pub fn sugar(self: TypeTerm, dict: &mut crate::TypeDict) -> SugaredTypeTerm { + match self { + TypeTerm::TypeID(id) => SugaredTypeTerm::TypeID(id), + TypeTerm::Num(n) => SugaredTypeTerm::Num(n), + TypeTerm::Char(c) => SugaredTypeTerm::Char(c), + TypeTerm::App(args) => if let Some(first) = args.first() { + if first == &dict.parse("Func").unwrap() { + SugaredTypeTerm::Func( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) + } + else if first == &dict.parse("Morph").unwrap() { + SugaredTypeTerm::Morph( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) + } + else if first == &dict.parse("Struct").unwrap() { + SugaredTypeTerm::Struct( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) + } + else if first == &dict.parse("Enum").unwrap() { + SugaredTypeTerm::Enum( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) + } + else if first == &dict.parse("Seq").unwrap() { + SugaredTypeTerm::Seq( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) + } + else if first == &dict.parse("Spec").unwrap() { + SugaredTypeTerm::Spec( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) + } + else if first == &dict.parse("Univ").unwrap() { + SugaredTypeTerm::Univ(Box::new( + SugaredTypeTerm::Spec( + args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() + ) + )) + } + else { + SugaredTypeTerm::Spec(args.into_iter().map(|t| t.sugar(dict)).collect()) + } + } else { + SugaredTypeTerm::Spec(args.into_iter().map(|t| t.sugar(dict)).collect()) + }, + TypeTerm::Ladder(rungs) => + SugaredTypeTerm::Ladder(rungs.into_iter().map(|t| t.sugar(dict)).collect()) + } + } +} + +impl SugaredTypeTerm { + pub fn desugar(self, dict: &mut crate::TypeDict) -> TypeTerm { + match self { + SugaredTypeTerm::TypeID(id) => TypeTerm::TypeID(id), + SugaredTypeTerm::Num(n) => TypeTerm::Num(n), + SugaredTypeTerm::Char(c) => TypeTerm::Char(c), + SugaredTypeTerm::Univ(t) => t.desugar(dict), + SugaredTypeTerm::Spec(ts) => TypeTerm::App(ts.into_iter().map(|t| t.desugar(dict)).collect()), + SugaredTypeTerm::Ladder(ts) => TypeTerm::Ladder(ts.into_iter().map(|t|t.desugar(dict)).collect()), + SugaredTypeTerm::Func(ts) => TypeTerm::App( + std::iter::once( dict.parse("Func").unwrap() ).chain( + ts.into_iter().map(|t| t.desugar(dict)) + ).collect()), + SugaredTypeTerm::Morph(ts) => TypeTerm::App( + std::iter::once( dict.parse("Morph").unwrap() ).chain( + ts.into_iter().map(|t| t.desugar(dict)) + ).collect()), + SugaredTypeTerm::Struct(ts) => TypeTerm::App( + std::iter::once( dict.parse("Struct").unwrap() ).chain( + ts.into_iter().map(|t| t.desugar(dict)) + ).collect()), + SugaredTypeTerm::Enum(ts) => TypeTerm::App( + std::iter::once( dict.parse("Enum").unwrap() ).chain( + ts.into_iter().map(|t| t.desugar(dict)) + ).collect()), + SugaredTypeTerm::Seq(ts) => TypeTerm::App( + std::iter::once( dict.parse("Seq").unwrap() ).chain( + ts.into_iter().map(|t| t.desugar(dict)) + ).collect()), + } + } +} + diff --git a/src/term.rs b/src/term.rs index f5e8f5f..29c7d27 100644 --- a/src/term.rs +++ b/src/term.rs @@ -57,7 +57,7 @@ impl TypeTerm { pub fn repr_as(&mut self, t: impl Into<TypeTerm>) -> &mut Self { match self { TypeTerm::Ladder(rungs) => { - rungs.push(t.into()); + rungs.push(t.into()); } _ => { From 71a8f4e06be049689cd5ee2500ae9eae07d8fcb8 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Wed, 1 May 2024 11:54:55 +0200 Subject: [PATCH 3/3] wip sugar --- src/dict.rs | 17 ++++++-- src/lexer.rs | 11 +++-- src/lib.rs | 1 + src/parser.rs | 53 +++++++++++++++++++---- src/sugar.rs | 95 ----------------------------------------- src/test/mod.rs | 1 + src/test/parser.rs | 84 ++++++++++++++++++------------------ src/test/sugar.rs | 10 +++++ src/test/unification.rs | 4 +- 9 files changed, 122 insertions(+), 154 deletions(-) delete mode 100644 src/sugar.rs create mode 100644 src/test/sugar.rs diff --git a/src/dict.rs b/src/dict.rs index 419d599..a28573c 100644 --- a/src/dict.rs +++ b/src/dict.rs @@ -1,4 +1,7 @@ -use crate::bimap::Bimap; +use crate::{ + bimap::Bimap, + sugar::SUGARID_LIMIT +}; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ @@ -20,11 +23,19 @@ pub struct TypeDict { impl TypeDict { pub fn new() -> Self { - TypeDict { + let mut dict = TypeDict { typenames: Bimap::new(), type_lit_counter: 0, type_var_counter: 0, - } + }; + + dict.add_typename("Seq".into()); + dict.add_typename("Enum".into()); + dict.add_typename("Struct".into()); + + assert_eq!( dict.type_lit_counter, SUGARID_LIMIT ); + + dict } pub fn add_varname(&mut self, tn: String) -> TypeID { diff --git a/src/lexer.rs b/src/lexer.rs index 8c56a0d..62b8efe 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -6,9 +6,9 @@ pub enum LadderTypeToken { Symbol( String ), Char( char ), Num( i64 ), - Open, - Close, - Ladder, + Open, OpenSeq, OpenStruct, + Close, CloseSeq, CloseStruct, + Ladder, Enum } #[derive(PartialEq, Eq, Clone, Debug)] @@ -75,6 +75,11 @@ where It: Iterator<Item = char> match c { '<' => { self.chars.next(); return Some(Ok(LadderTypeToken::Open)); }, '>' => { self.chars.next(); return Some(Ok(LadderTypeToken::Close)); }, + '[' => { self.chars.next(); return Some(Ok(LadderTypeToken::OpenSeq)); }, + ']' => { self.chars.next(); return Some(Ok(LadderTypeToken::CloseSeq)); }, + '{' => { self.chars.next(); return Some(Ok(LadderTypeToken::OpenStruct)); }, + '}' => { self.chars.next(); return Some(Ok(LadderTypeToken::CloseStruct)); }, + '|' => { self.chars.next(); return Some(Ok(LadderTypeToken::Enum)); }, '~' => { self.chars.next(); return Some(Ok(LadderTypeToken::Ladder)); }, '\'' => { self.chars.next(); state = LexerState::Char(None); }, c => { diff --git a/src/lib.rs b/src/lib.rs index e073b0b..a23069f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ pub mod parser; pub mod unparser; pub mod sugar; pub mod curry; +pub mod sugar; pub mod lnf; pub mod subtype; pub mod unification; diff --git a/src/parser.rs b/src/parser.rs index 85ff9b4..87ed5c1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3,6 +3,7 @@ use { crate::{ dict::*, term::*, + sugar::*, lexer::* } }; @@ -21,7 +22,7 @@ pub enum ParseError { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ impl TypeDict { - pub fn parse(&mut self, s: &str) -> Result<TypeTerm, ParseError> { + pub fn parse(&mut self, s: &str) -> Result<SugaredTypeTerm, ParseError> { let mut tokens = LadderTypeLexer::from(s.chars()).peekable(); match self.parse_ladder(&mut tokens) { @@ -36,7 +37,7 @@ impl TypeDict { } } - fn parse_app<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<TypeTerm, ParseError> + fn parse_app<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<SugaredTypeTerm, ParseError> where It: Iterator<Item = char> { let mut args = Vec::new(); @@ -44,7 +45,11 @@ impl TypeDict { match tok { Ok(LadderTypeToken::Close) => { tokens.next(); - return Ok(TypeTerm::App(args)); + return Ok(SugaredTypeTerm::App(args)); + } + Ok(LadderTypeToken::CloseSeq) | + Ok(LadderTypeToken::CloseStruct) => { + return Err(ParseError::UnexpectedToken) } _ => { match self.parse_ladder(tokens) { @@ -57,29 +62,59 @@ impl TypeDict { Err(ParseError::UnexpectedEnd) } - fn parse_rung<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<TypeTerm, ParseError> + fn parse_seq<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<SugaredTypeTerm, ParseError> + where It: Iterator<Item = char> + { + let mut pattern = Vec::new(); + while let Some(tok) = tokens.peek() { + match tok { + Ok(LadderTypeToken::CloseSeq) => { + tokens.next(); + return Ok(SugaredTypeTerm::Seq(pattern)); + } + Ok(LadderTypeToken::Close) | + Ok(LadderTypeToken::CloseStruct) => { + return Err(ParseError::UnexpectedToken) + } + _ => { + match self.parse_ladder(tokens) { + Ok(a) => { pattern.push(a); } + Err(err) => { return Err(err); } + } + } + } + } + Err(ParseError::UnexpectedEnd) + } + + fn parse_rung<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<SugaredTypeTerm, ParseError> where It: Iterator<Item = char> { match tokens.next() { Some(Ok(LadderTypeToken::Open)) => self.parse_app(tokens), + Some(Ok(LadderTypeToken::OpenSeq)) => self.parse_app(tokens), + Some(Ok(LadderTypeToken::OpenStruct)) => self.parse_app(tokens), + Some(Ok(LadderTypeToken::Enum)) => self.parse_app(tokens), Some(Ok(LadderTypeToken::Close)) => Err(ParseError::UnexpectedClose), + Some(Ok(LadderTypeToken::CloseStruct)) => Err(ParseError::UnexpectedToken), + Some(Ok(LadderTypeToken::CloseSeq)) => Err(ParseError::UnexpectedToken), Some(Ok(LadderTypeToken::Ladder)) => Err(ParseError::UnexpectedLadder), Some(Ok(LadderTypeToken::Symbol(s))) => - Ok(TypeTerm::TypeID( + Ok(SugaredTypeTerm::TypeID( if let Some(tyid) = self.get_typeid(&s) { tyid } else { self.add_typename(s) } )), - Some(Ok(LadderTypeToken::Char(c))) => Ok(TypeTerm::Char(c)), - Some(Ok(LadderTypeToken::Num(n))) => Ok(TypeTerm::Num(n)), + Some(Ok(LadderTypeToken::Char(c))) => Ok(SugaredTypeTerm::Char(c)), + Some(Ok(LadderTypeToken::Num(n))) => Ok(SugaredTypeTerm::Num(n)), Some(Err(err)) => Err(ParseError::LexError(err)), None => Err(ParseError::UnexpectedEnd) } } - fn parse_ladder<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<TypeTerm, ParseError> + fn parse_ladder<It>(&mut self, tokens: &mut Peekable<LadderTypeLexer<It>>) -> Result<SugaredTypeTerm, ParseError> where It: Iterator<Item = char> { let mut rungs = Vec::new(); @@ -115,7 +150,7 @@ impl TypeDict { match rungs.len() { 0 => Err(ParseError::UnexpectedEnd), 1 => Ok(rungs[0].clone()), - _ => Ok(TypeTerm::Ladder(rungs)), + _ => Ok(SugaredTypeTerm::Ladder(rungs)), } } } diff --git a/src/sugar.rs b/src/sugar.rs deleted file mode 100644 index 4d13f78..0000000 --- a/src/sugar.rs +++ /dev/null @@ -1,95 +0,0 @@ -use { - crate::{TypeTerm, TypeID} -}; - -pub enum SugaredTypeTerm { - TypeID(TypeID), - Num(i64), - Char(char), - Univ(Box< SugaredTypeTerm >), - Spec(Vec< SugaredTypeTerm >), - Func(Vec< SugaredTypeTerm >), - Morph(Vec< SugaredTypeTerm >), - Ladder(Vec< SugaredTypeTerm >), - Struct(Vec< SugaredTypeTerm >), - Enum(Vec< SugaredTypeTerm >), - Seq(Vec< SugaredTypeTerm >) -} - -impl TypeTerm { - pub fn sugar(self: TypeTerm, dict: &mut crate::TypeDict) -> SugaredTypeTerm { - match self { - TypeTerm::TypeID(id) => SugaredTypeTerm::TypeID(id), - TypeTerm::Num(n) => SugaredTypeTerm::Num(n), - TypeTerm::Char(c) => SugaredTypeTerm::Char(c), - TypeTerm::App(args) => if let Some(first) = args.first() { - if first == &dict.parse("Func").unwrap() { - SugaredTypeTerm::Func( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) - } - else if first == &dict.parse("Morph").unwrap() { - SugaredTypeTerm::Morph( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) - } - else if first == &dict.parse("Struct").unwrap() { - SugaredTypeTerm::Struct( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) - } - else if first == &dict.parse("Enum").unwrap() { - SugaredTypeTerm::Enum( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) - } - else if first == &dict.parse("Seq").unwrap() { - SugaredTypeTerm::Seq( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) - } - else if first == &dict.parse("Spec").unwrap() { - SugaredTypeTerm::Spec( args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() ) - } - else if first == &dict.parse("Univ").unwrap() { - SugaredTypeTerm::Univ(Box::new( - SugaredTypeTerm::Spec( - args[1..].into_iter().map(|t| t.clone().sugar(dict)).collect() - ) - )) - } - else { - SugaredTypeTerm::Spec(args.into_iter().map(|t| t.sugar(dict)).collect()) - } - } else { - SugaredTypeTerm::Spec(args.into_iter().map(|t| t.sugar(dict)).collect()) - }, - TypeTerm::Ladder(rungs) => - SugaredTypeTerm::Ladder(rungs.into_iter().map(|t| t.sugar(dict)).collect()) - } - } -} - -impl SugaredTypeTerm { - pub fn desugar(self, dict: &mut crate::TypeDict) -> TypeTerm { - match self { - SugaredTypeTerm::TypeID(id) => TypeTerm::TypeID(id), - SugaredTypeTerm::Num(n) => TypeTerm::Num(n), - SugaredTypeTerm::Char(c) => TypeTerm::Char(c), - SugaredTypeTerm::Univ(t) => t.desugar(dict), - SugaredTypeTerm::Spec(ts) => TypeTerm::App(ts.into_iter().map(|t| t.desugar(dict)).collect()), - SugaredTypeTerm::Ladder(ts) => TypeTerm::Ladder(ts.into_iter().map(|t|t.desugar(dict)).collect()), - SugaredTypeTerm::Func(ts) => TypeTerm::App( - std::iter::once( dict.parse("Func").unwrap() ).chain( - ts.into_iter().map(|t| t.desugar(dict)) - ).collect()), - SugaredTypeTerm::Morph(ts) => TypeTerm::App( - std::iter::once( dict.parse("Morph").unwrap() ).chain( - ts.into_iter().map(|t| t.desugar(dict)) - ).collect()), - SugaredTypeTerm::Struct(ts) => TypeTerm::App( - std::iter::once( dict.parse("Struct").unwrap() ).chain( - ts.into_iter().map(|t| t.desugar(dict)) - ).collect()), - SugaredTypeTerm::Enum(ts) => TypeTerm::App( - std::iter::once( dict.parse("Enum").unwrap() ).chain( - ts.into_iter().map(|t| t.desugar(dict)) - ).collect()), - SugaredTypeTerm::Seq(ts) => TypeTerm::App( - std::iter::once( dict.parse("Seq").unwrap() ).chain( - ts.into_iter().map(|t| t.desugar(dict)) - ).collect()), - } - } -} - diff --git a/src/test/mod.rs b/src/test/mod.rs index d116412..ea52c7d 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -2,6 +2,7 @@ pub mod lexer; pub mod parser; pub mod curry; +pub mod sugar; pub mod lnf; pub mod subtype; pub mod substitution; diff --git a/src/test/parser.rs b/src/test/parser.rs index 1166229..49deb7c 100644 --- a/src/test/parser.rs +++ b/src/test/parser.rs @@ -1,6 +1,6 @@ use { - crate::{term::*, dict::*, parser::*} + crate::{term::*, dict::*, parser::*, sugar::SUGARID_LIMIT} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ @@ -17,7 +17,7 @@ fn test_parser_id() { ); assert_eq!( - Ok(TypeTerm::TypeID(TypeID::Fun(0))), + Ok(TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0))), dict.parse("A") ); } @@ -43,16 +43,16 @@ fn test_parser_app() { assert_eq!( TypeDict::new().parse("<A B>"), Ok(TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), ])) ); assert_eq!( TypeDict::new().parse("<A B C>"), Ok(TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(1)), - TypeTerm::TypeID(TypeID::Fun(2)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+2)), ])) ); } @@ -78,16 +78,16 @@ fn test_parser_ladder() { assert_eq!( TypeDict::new().parse("A~B"), Ok(TypeTerm::Ladder(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), ])) ); assert_eq!( TypeDict::new().parse("A~B~C"), Ok(TypeTerm::Ladder(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(1)), - TypeTerm::TypeID(TypeID::Fun(2)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+2)), ])) ); } @@ -98,12 +98,12 @@ fn test_parser_ladder_outside() { TypeDict::new().parse("<A B>~C"), Ok(TypeTerm::Ladder(vec![ TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), ]), - TypeTerm::TypeID(TypeID::Fun(2)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+2)), ])) - ); + ); } #[test] @@ -111,10 +111,10 @@ fn test_parser_ladder_inside() { assert_eq!( TypeDict::new().parse("<A B~C>"), Ok(TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), TypeTerm::Ladder(vec![ - TypeTerm::TypeID(TypeID::Fun(1)), - TypeTerm::TypeID(TypeID::Fun(2)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+2)), ]) ])) ); @@ -125,12 +125,12 @@ fn test_parser_ladder_between() { assert_eq!( TypeDict::new().parse("<A B~<C D>>"), Ok(TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), TypeTerm::Ladder(vec![ - TypeTerm::TypeID(TypeID::Fun(1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(2)), - TypeTerm::TypeID(TypeID::Fun(3)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+2)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+3)), ]) ]) ])) @@ -156,48 +156,48 @@ fn test_parser_ladder_large() { Ok( TypeTerm::Ladder(vec![ TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), TypeTerm::Ladder(vec![ - TypeTerm::TypeID(TypeID::Fun(1)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+1)), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(2)), - TypeTerm::TypeID(TypeID::Fun(3)) + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+2)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+3)) ]), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(4)), - TypeTerm::TypeID(TypeID::Fun(5)) + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+4)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+5)) ]), - TypeTerm::TypeID(TypeID::Fun(6)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+6)), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(7)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+7)), TypeTerm::Num(10), - TypeTerm::TypeID(TypeID::Fun(8)) + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+8)) ]), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), TypeTerm::Ladder(vec![ TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(9)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+9)), TypeTerm::Num(10) ]), - TypeTerm::TypeID(TypeID::Fun(10)) + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+10)) ]) ]) ]) ]), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(11)), - TypeTerm::TypeID(TypeID::Fun(10)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+11)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+10)), TypeTerm::Char(':') ]), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(10)) + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+10)) ]), - TypeTerm::TypeID(TypeID::Fun(12)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+12)), TypeTerm::App(vec![ - TypeTerm::TypeID(TypeID::Fun(0)), - TypeTerm::TypeID(TypeID::Fun(13)) + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+0)), + TypeTerm::TypeID(TypeID::Fun(SUGARID_LIMIT+13)) ]) ]) ) diff --git a/src/test/sugar.rs b/src/test/sugar.rs new file mode 100644 index 0000000..c6a9768 --- /dev/null +++ b/src/test/sugar.rs @@ -0,0 +1,10 @@ + +#[test] +fn test_sugar() { + + let mut dict = crate::TypeDict::new(); + + +} + + diff --git a/src/test/unification.rs b/src/test/unification.rs index 34d355d..19c6768 100644 --- a/src/test/unification.rs +++ b/src/test/unification.rs @@ -13,8 +13,8 @@ fn test_unify(ts1: &str, ts2: &str, expect_unificator: bool) { dict.add_varname(String::from("V")); dict.add_varname(String::from("W")); - let mut t1 = dict.parse(ts1).unwrap(); - let mut t2 = dict.parse(ts2).unwrap(); + let mut t1 = dict.parse(ts1).unwrap().desugar(); + let mut t2 = dict.parse(ts2).unwrap().desugar(); let σ = crate::unify( &t1, &t2 ); if expect_unificator {