You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.2 KiB

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(<usize>),
Float => lexer::Token::Float(<f64>),
Bool => lexer::Token::Bool(<bool>),
Ident => lexer::Token::Ident(<String>),
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"\" <x:Ident> ":" <t:TaggedType> "." <ast:Ast> => Ast::Abstraction(x, Some(t), Box::new(ast)),
r"\" <x:Ident> "." <ast:Ast> => Ast::Abstraction(x, None, Box::new(ast)),
};
Term: Ast = {
#[precedence(level="0")]
Ident => Ast::Variable(<>),
#[precedence(level="0")]
Constant => Ast::Constant(<>),
#[precedence(level="1")]
"(" <Ast> ")" => <>,
#[precedence(level="2")] #[assoc(side = "left")]
<lhs:Term> <rhs:Term> => Ast::Application(Box::new(lhs), Box::new(rhs)),
};
Constant: Constant = {
Nat => Constant::Nat(<>),
Float => Constant::Float(<>),
Bool => Constant::Bool(<>),
};
pub TaggedType: TaggedType = {
<t:TypeTag> <i:Ident> "=>" <tt:TaggedType> => TaggedType::Tagged(t, i, Box::new(tt)),
<t:Type> => 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")]
"(" <l:Type> ")" "->" <r:Type> => Type::Arrow(Box::new(l), Box::new(r)),
#[precedence(level="1")] #[assoc(side = "right")]
<l:BasicType> "->" <r:Type> => Type::Arrow(Box::new(l), Box::new(r)),
};