Grammar updates

main
Avery 3 weeks ago
parent 3fc99af58b
commit bea0783a17
Signed by: Avery
GPG Key ID: 4E53F4CB69B2CC8D

1
.gitignore vendored

@ -1 +1,2 @@
/target
grammar.html

@ -0,0 +1,32 @@
(*
*)
ast = term
| "\", {ident, [":", tagged type], ","}, ident, [":", tagged type], ".", ast ;
term = ident
| constant
| "(", ast, ")"
| term, term ;
constant = nat | float | bool ;
tagged type = type tag, ident
| type tag, ident, "=>", tagged type
| type ;
type tag = "Num" | "Any" ;
type = basic type | arrow type ;
basic type = "Nat" | "Float" | "Bool" | ident ;
arrow type = "(", type, ")", "->", type
| basic type, "->", type ;

@ -172,8 +172,8 @@ fn infer_id_uni() {
typ,
TaggedType::Tagged(
TypeTag::Any,
"?typ_1".to_string(),
Box::new(TaggedType::Concrete(Type::arrow("?typ_1", "?typ_1")))
"?typ_0".to_string(),
Box::new(TaggedType::Concrete(Type::arrow("?typ_0", "?typ_0")))
)
);
}

@ -132,6 +132,66 @@ fn parse_abstraction() {
))
)
);
let ast = parser.parse(Lexer::new(r"\x:Any a.\y:Any b.x")).unwrap();
assert_eq!(
ast,
Ast::Abstraction(
"x".to_string(),
Some(TaggedType::Tagged(
TypeTag::Any,
"a".to_string(),
Box::new(TaggedType::Concrete("a".into()))
)),
Box::new(Ast::Abstraction(
"y".to_string(),
Some(TaggedType::Tagged(
TypeTag::Any,
"b".to_string(),
Box::new(TaggedType::Concrete("b".into()))
)),
Box::new(Ast::Variable("x".to_string()))
))
)
);
let ast = parser
.parse(Lexer::new(r"\x:Any a => a,y:Any b => b.x"))
.unwrap();
assert_eq!(
ast,
Ast::Abstraction(
"x".to_string(),
Some(TaggedType::Tagged(
TypeTag::Any,
"a".to_string(),
Box::new(TaggedType::Concrete("a".into()))
)),
Box::new(Ast::Abstraction(
"y".to_string(),
Some(TaggedType::Tagged(
TypeTag::Any,
"b".to_string(),
Box::new(TaggedType::Concrete("b".into()))
)),
Box::new(Ast::Variable("x".to_string()))
))
)
);
let ast = parser.parse(Lexer::new(r"\x,y.x")).unwrap();
assert_eq!(
ast,
Ast::Abstraction(
"x".to_string(),
None,
Box::new(Ast::Abstraction(
"y".to_string(),
None,
Box::new(Ast::Variable("x".to_string()))
))
)
);
}
#[test]

@ -51,6 +51,8 @@ pub enum Token {
Colon,
#[token(".")]
Period,
#[token(",")]
Comma,
#[token("=")]
Equals,
@ -117,6 +119,7 @@ impl Display for Token {
Token::ThinArrow => write!(f, "->"),
Token::Colon => write!(f, ":"),
Token::Period => write!(f, "."),
Token::Comma => write!(f, ","),
Token::Equals => write!(f, "="),
Token::NotEquals => write!(f, "<>"),
Token::Plus => write!(f, "+"),

@ -22,6 +22,7 @@ extern {
"->" => lexer::Token::ThinArrow,
":" => lexer::Token::Colon,
"." => lexer::Token::Period,
"," => lexer::Token::Comma,
"=" => lexer::Token::Equals,
"<>" => lexer::Token::NotEquals,
@ -43,12 +44,20 @@ extern {
}
Multi<T>: Vec<T> = { // (1)
<mut v:(<T> ",")*> <e:T> => {
v.push(e);
v
}
};
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)),
r"\" <args:Multi<IdentAndType>> "." <ast:Ast> => args.into_iter().rev().fold(ast, |ast, (i, t)| Ast::Abstraction(i, t, Box::new(ast))),
};
pub IdentAndType: (String, Option<TaggedType>) = <x:Ident> <t:(":" <TaggedType>)?> => (<>);
Term: Ast = {
#[precedence(level="0")]
@ -68,6 +77,7 @@ Constant: Constant = {
};
pub TaggedType: TaggedType = {
<t:TypeTag> <i:Ident> => TaggedType::Tagged(t, i.clone(), Box::new(TaggedType::Concrete(Type::Variable(i)))),
<t:TypeTag> <i:Ident> "=>" <tt:TaggedType> => TaggedType::Tagged(t, i, Box::new(tt)),
<t:Type> => TaggedType::Concrete(t),
};

Loading…
Cancel
Save