diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/grammar.lalrpop | 13 | ||||
-rw-r--r-- | src/lexer.rs | 29 |
2 files changed, 35 insertions, 7 deletions
diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index e940da9..3d4603d 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -19,6 +19,11 @@ extern { Nat => Tok::Natural(<usize>), Bool => Tok::Bool(<bool>), Label => Tok::Identifier(<String>), + Let => Tok::Reserved(Keyword::Let), + In => Tok::Reserved(Keyword::In), + If => Tok::Reserved(Keyword::If), + Then => Tok::Reserved(Keyword::Then), + Else => Tok::Reserved(Keyword::Else), Reserved => Tok::Reserved(<Keyword>), "(" => Tok::ParenL, @@ -43,7 +48,11 @@ pub Expr: BoxExpr = { // exprA ExprB: BoxExpr = { Lambda "(" <Label> ":" <Expr> ")" "->" <ExprB> => bx(Lam(<>)), - ExprC0, + Pi "(" <Label> ":" <Expr> ")" "->" <ExprB> => bx(Pi(<>)), + If <Expr> Then <ExprB> Else <ExprC> => bx(BoolIf(<>)), + <ExprC> "->" <ExprB> => bx(Pi("_".to_owned(), <>)), + Let <Label> <(":" <Expr>)?> "=" <Expr> In <ExprB> => bx(Let(<>)), + ExprC, }; BoolOr: ExprOpFn = { "||" => BoolOr }; @@ -61,7 +70,7 @@ Tier<NextTier, Op>: BoxExpr = { NextTier, }; -ExprC0 = Tier<ExprC1, BoolOr>; +ExprC = Tier<ExprC1, BoolOr>; ExprC1 = Tier<ExprC2, NaturalPlus>; ExprC2 = Tier<ExprC3, TextAppend>; ExprC3 = Tier<ExprC4, BoolAnd>; diff --git a/src/lexer.rs b/src/lexer.rs index 5f028b0..23457ac 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -24,6 +24,11 @@ pub enum Keyword { Optional, OptionalFold, Bool, + Let, + In, + If, + Then, + Else, } #[derive(Debug, PartialEq, Eq)] @@ -93,11 +98,20 @@ fn is_symbol(c: char) -> bool { named!(symbol<&str, &str>, take_while1_s!(is_symbol)); */ +#[allow(dead_code)] +fn is_identifier_first_char(c: char) -> bool { + c.is_alphabetic() || c == '_' +} + +fn is_identifier_rest_char(c: char) -> bool { + c.is_alphabetic() || is_decimal(c) || c == '_' || c == '/' +} + fn is_decimal(c: char) -> bool { c.is_digit(10) } -named!(identifier<&str, &str>, take_while1_s!(char::is_alphabetic)); // FIXME [A-Za-z_][A-Za-z0-9_/]* +named!(identifier<&str, &str>, take_while1_s!(is_identifier_rest_char)); // FIXME use is_identifier_first_char named!(natural<&str, &str>, preceded!(tag!("+"), take_while1_s!(is_decimal))); named!(integral<&str, isize>, map_res!(take_while1_s!(is_decimal), |s| isize::from_str(s))); named!(integer<&str, isize>, alt!( @@ -110,16 +124,15 @@ named!(boolean<&str, bool>, alt!( )); named!(keyword<&str, Keyword>, alt!( - value!(Keyword::Natural, tag!("Natural")) | value!(Keyword::NaturalFold, tag!("Natural/fold")) | value!(Keyword::NaturalBuild, tag!("Natural/build")) | value!(Keyword::NaturalIsZero, tag!("Natural/isZero")) | value!(Keyword::NaturalEven, tag!("Natural/even")) | value!(Keyword::NaturalOdd, tag!("Natural/odd")) | + value!(Keyword::Natural, tag!("Natural")) | value!(Keyword::Integer, tag!("Integer")) | value!(Keyword::Double, tag!("Double")) | value!(Keyword::Text, tag!("Text")) | - value!(Keyword::List, tag!("List")) | value!(Keyword::ListBuild, tag!("List/build")) | value!(Keyword::ListFold, tag!("List/fold")) | value!(Keyword::ListLength, tag!("List/length")) | @@ -127,9 +140,15 @@ named!(keyword<&str, Keyword>, alt!( value!(Keyword::ListLast, tag!("List/last")) | value!(Keyword::ListIndexed, tag!("List/indexed")) | value!(Keyword::ListReverse, tag!("List/reverse")) | - value!(Keyword::Optional, tag!("Optional")) | + value!(Keyword::List, tag!("List")) | value!(Keyword::OptionalFold, tag!("Optional/fold")) | - value!(Keyword::Bool, tag!("Bool")) + value!(Keyword::Optional, tag!("Optional")) | + value!(Keyword::Bool, tag!("Bool")) | + value!(Keyword::Let, tag!("let")) | + value!(Keyword::In, tag!("in")) | + value!(Keyword::If, tag!("if")) | + value!(Keyword::Then, tag!("then")) | + value!(Keyword::Else, tag!("else")) )); named!(token<&str, Tok>, alt!( |