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
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)),
|
|
};
|
|
|