81 lines
2.0 KiB
Plaintext
81 lines
2.0 KiB
Plaintext
use crate::syntax::{
|
|
Binding,
|
|
Block,
|
|
Expression,
|
|
Item,
|
|
InteractiveEntry,
|
|
Name,
|
|
Parameter,
|
|
Program,
|
|
Type,
|
|
};
|
|
|
|
grammar;
|
|
|
|
pub Program: Program = Item*;
|
|
|
|
pub InteractiveEntry: InteractiveEntry = {
|
|
Item => InteractiveEntry::Item(<>),
|
|
<Binding> ";"? => InteractiveEntry::Binding(<>),
|
|
<Expression> ";"? => InteractiveEntry::Expression(<>),
|
|
}
|
|
|
|
Type: Type = {
|
|
Name => Type::Constructor(<>),
|
|
"fn" "(" <parameters:Comma<Type>> ")" "->" <result:Boxed<Type>> => Type::Function { <> },
|
|
"(" <Type> ")",
|
|
}
|
|
|
|
Item: Item = {
|
|
"fn" <name:Name> "(" <parameters:Comma<Parameter>> ")" <return_type:("->" <Type>)?> <body:Block> ";"? => Item::Fn { <> },
|
|
}
|
|
|
|
Parameter: Parameter =
|
|
<name:Name> <annotation:(":" <Type>)?> => Parameter { <> };
|
|
|
|
Binding: Binding =
|
|
"let" <name:Name> <annotation:(":" <Type>)?> "=" <expression:Expression> => Binding { <> };
|
|
|
|
Expression: Expression = {
|
|
"|" <parameters:Comma<Parameter>> "|" <return_type:("->" <Type>)?> <result:Boxed<Expression>> => Expression::Lambda { <> },
|
|
Boxed<Block> => Expression::Block(<>),
|
|
<expression:Boxed<Atom>> ":" <annotation:Type> => Expression::Annotation { <> },
|
|
Atom,
|
|
};
|
|
|
|
Atom: Expression = {
|
|
Name => Expression::Variable(<>),
|
|
<callee:Boxed<Atom>> "(" <arguments:Comma<Expression>> ")" => Expression::Call { <> },
|
|
Integer => Expression::Integer(<>),
|
|
Boolean => Expression::Boolean(<>),
|
|
"(" ")" => Expression::Unit,
|
|
"(" <Expression> ")",
|
|
};
|
|
|
|
BlockBinding = <Binding> ";";
|
|
|
|
Block: Block =
|
|
"{" <bindings:BlockBinding*> <result:Expression> "}" => Block { <> };
|
|
|
|
// TODO: decide on identifier syntax
|
|
Name: Name = r"[a-zA-Z_]+" => <>.to_string();
|
|
|
|
Integer: i64 = r"[0-9]+" => <>.parse::<i64>().unwrap();
|
|
|
|
Boolean: bool = {
|
|
"true" => true,
|
|
"false" => false,
|
|
}
|
|
|
|
Boxed<T>: Box<T> = T => Box::new(<>);
|
|
|
|
Comma<T>: Vec<T> = {
|
|
<mut v:(<T> ",")*> <e:T?> => match e {
|
|
None => v,
|
|
Some(e) => {
|
|
v.push(e);
|
|
v
|
|
}
|
|
}
|
|
};
|