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 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 { + pub fn parse(&mut self, s: &str) -> Result { let mut tokens = LadderTypeLexer::from(s.chars()).peekable(); match self.parse_ladder(&mut tokens) { @@ -36,7 +37,7 @@ impl TypeDict { } } - fn parse_app(&mut self, tokens: &mut Peekable>) -> Result + fn parse_app(&mut self, tokens: &mut Peekable>) -> Result where It: Iterator { 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(&mut self, tokens: &mut Peekable>) -> Result + fn parse_seq(&mut self, tokens: &mut Peekable>) -> Result + where It: Iterator + { + 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(&mut self, tokens: &mut Peekable>) -> Result where It: Iterator { 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(&mut self, tokens: &mut Peekable>) -> Result + fn parse_ladder(&mut self, tokens: &mut Peekable>) -> Result where It: Iterator { 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(""), 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(""), 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("~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(""), 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(">"), 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 {