use crate::{ parse::{Ast, Constant, tokenize as lexer, ParseError as PError}, types::{TaggedType, TypeTag, Type, PrimitiveType}, }; use lalrpop_util::ParseError; grammar; extern { type Location = usize; type Error = PError; enum lexer::Token { Nat => lexer::Token::Nat(), Float => lexer::Token::Float(), Bool => lexer::Token::Bool(), Ident => lexer::Token::Ident(), r"\" => lexer::Token::Lambda, "=>" => lexer::Token::FatArrow, "->" => lexer::Token::ThinArrow, ":" => lexer::Token::Colon, "." => lexer::Token::Period, "=" => lexer::Token::Equals, "<>" => lexer::Token::NotEquals, "+" => lexer::Token::Plus, "-" => lexer::Token::Minus, "*" => lexer::Token::Star, "/" => lexer::Token::Slash, "^" => lexer::Token::Hat, "<" => lexer::Token::Less, ">" => lexer::Token::Greater, "<=" => lexer::Token::LessEq, ">=" => lexer::Token::GreaterEq, r"/\" => lexer::Token::Conjunction, r"\/" => lexer::Token::Disjunction, "(" => lexer::Token::ParenOpen, ")" => lexer::Token::ParenClose, } } pub Ast: Ast = { Term => <>, r"\" ":" "." => Ast::Abstraction(x, Some(t), Box::new(ast)), r"\" "." => Ast::Abstraction(x, None, Box::new(ast)), }; Term: Ast = { #[precedence(level="0")] Ident => Ast::Variable(<>), #[precedence(level="0")] Constant => Ast::Constant(<>), #[precedence(level="1")] "(" ")" => <>, #[precedence(level="2")] #[assoc(side = "left")] => Ast::Application(Box::new(lhs), Box::new(rhs)), }; Constant: Constant = { Nat => Constant::Nat(<>), Float => Constant::Float(<>), Bool => Constant::Bool(<>), }; pub TaggedType: TaggedType = { "=>" => TaggedType::Tagged(t, i, Box::new(tt)), => TaggedType::Concrete(t), }; TypeTag: TypeTag = Ident =>? TypeTag::try_from(<>).map_err(|e| ParseError::User{ error: e }); Type: Type = { BasicType, ArrowType }; BasicType: Type = Ident => Type::from_name(<>); ArrowType: Type = { #[precedence(level="0")] "(" ")" "->" => Type::Arrow(Box::new(l), Box::new(r)), #[precedence(level="1")] #[assoc(side = "right")] "->" => Type::Arrow(Box::new(l), Box::new(r)), };