Skip to content

Instantly share code, notes, and snippets.

@MaikKlein
Created July 20, 2017 17:06
Show Gist options
  • Save MaikKlein/965317af58d574ebbc32b73d4dde37fa to your computer and use it in GitHub Desktop.
Save MaikKlein/965317af58d574ebbc32b73d4dde37fa to your computer and use it in GitHub Desktop.
use ast::*;
use std::str::FromStr;
grammar;
pub Entry: () = {
"#" "[" "entry" "]" => (),
};
pub Statement: Statement<'input> = {
"let" <var:Variable> "=" <init_expr: Expr> ";"
=> Statement::VariableDef(VariableDef{
var,
init_expr
}),
<entry: Entry?> "fn" <ident: Name> "(" <params: Comma<Variable>> ")" <ty:("->" <Name>)?> <block: Block>
=> {
Statement::FunctionDef(
FunctionDef{
ident: Ident(ident),
params,
ret_ty: if let Some(ty) = ty {Type::from(ty)} else {Type::Void},
block,
is_entry: entry.is_some()
}
)
},
<s: Struct> => Statement::StructDef(s)
};
Comma<T>: Vec<T> = { // (1)
<v:(<T> ",")*> <e:T?> => match e { // (2)
None => v,
Some(e) => {
let mut v = v;
v.push(e);
v
}
}
};
pub Struct: Struct<'input> = {
"struct" <ident: Name> "{" <members: Comma<Variable>> "}"
=> Struct{ident: Ident(ident), members: members }
};
pub Variable: Variable<'input> = {
<ident: Name> ":" <ty_name:Name> => Variable(Ident(ident), Type::from(ty_name))
};
pub Literal: Literal<'input> = {
<var:Number> => Literal::Number(var),
r#"""# <var:Name> r#"""# => Literal::Str(var)
};
pub Expr: Box<Expr<'input>> = {
<lit:Literal> => Box::new(Expr::Literal(lit)),
<name: Name> => Box::new(Expr::NamedVariable(Ident(name))),
<name: Name> "(" <expr: Comma<Expr>> ")" => Box::new(Expr::FunctionCall(FunctionCall{ident: Ident(name), arguments: expr })),
"(" ")" => Box::new(Expr::Void),
Addition,
};
pub Addition: Box<Expr<'input>> = {
<l: Expr> "+" <r: Addition> => Box::new(Expr::Addition(l, r)),
"(" <Expr> ")",
Expr
};
pub Block: Block<'input> = {
"{" <stmt:Statement*> <expr:Expr?> "}" => Block(stmt, expr.unwrap_or(Box::new(Expr::Void)))
};
pub Scope: Scope<'input> = {
<stmt:Statement*> => Scope::Module(Module(stmt))
};
Number: isize = <s:Num> => isize::from_str(s).unwrap();
Name: &'input str = <s:Ident> => s;
match{
"*",
"+",
r"[0-9]+" => Num,
":",
"(",
")",
"=",
"let",
";",
r#"""#,
"{",
"}",
"fn",
",",
"->",
"struct",
"entry",
"#",
"[",
"]",
}
else{
r"\w+" => Ident,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment