handball/src/grammar.lalrpop

52 lines
1.3 KiB
Plaintext
Raw Normal View History

2021-12-27 22:19:29 +00:00
use crate::ast::*;
2021-12-17 03:57:34 +00:00
use std::rc::Rc;
2021-12-16 18:23:02 +00:00
grammar<'s>();
2021-12-27 03:35:57 +00:00
match {
r"\s*" => { }, // The default whitespace skipping is disabled an `ignore pattern` is specified
r";[^\n\r]*[\n\r]*" => { }, // Skip `;` comments
_
}
2021-12-27 15:07:07 +00:00
pub(crate) File = {Lang? <Trees> }
Trees = Tree+;
2021-12-16 18:23:02 +00:00
2021-12-16 22:24:31 +00:00
pub(crate) Tree: Tree = {
"(" <Tree+> ")" => Tree::Branch(<>),
2021-12-17 02:57:20 +00:00
"(" "define" <Sym> <BTree> ")" => Tree::Define(<>),
"(" "define" "(" <name:Sym> <args:Sym*> ")" <body:Trees> ")"
=> Tree::Define(name, Box::new(Tree::Func(Rc::new(Func{args, body})))),
2021-12-17 02:57:20 +00:00
"(" "if" <Tree> <Tree> <Tree> ")" => Tree::If(Box::new([<>])),
"(" "lambda (" <args:Sym*> ")" <body:Trees> ")" => Tree::Func(Rc::new(Func{<>})),
"(" "set!" <Sym> <BTree> ")" => Tree::Set(<>),
2021-12-16 22:24:31 +00:00
Literal => Tree::Leaf(<>),
2021-12-16 18:23:02 +00:00
}
2021-12-16 22:24:31 +00:00
2021-12-17 02:57:20 +00:00
BTree = { Box<Tree> }
2021-12-16 22:24:31 +00:00
Literal: Literal = {
Sym => Literal::Sym(<>),
Num => Literal::Num(<>),
2021-12-17 02:57:20 +00:00
Bool => Literal::Bool(<>),
2021-12-16 22:24:31 +00:00
}
2021-12-16 23:15:31 +00:00
Box<T>: Box<T> = { T => Box::new(<>) }
2021-12-17 03:57:34 +00:00
RcSlice<T>: Rc<[T]> = { T* => <>.into() }
Rc<T>: Rc<T> = { T => Rc::new(<>) }
2021-12-16 22:24:31 +00:00
Sym: String = { r"[A-Za-z!$%&*+\-./:<=>?@^_~][A-Za-z!$%&*+\-./:<=>?@^_~0-9]*" => <>.to_owned() }
2021-12-17 02:57:20 +00:00
Num: f64 = { r"[0-9]+(\.[0-9]+)?" => <>.parse().unwrap() }
Bool: bool = {
"#t" => true,
"#f" => false,
2021-12-27 15:07:07 +00:00
}
Lang: () = { "#lang" LangName }
LangName = {
// TODO: What should these be?
"scheme",
"r7rs",
}