summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2017-11-04 20:15:20 -0400
committerDavid Li <li.davidm96@gmail.com>2017-11-04 20:15:20 -0400
commit9f393b2eb7b3fb8f1924e80095bad3384049cc67 (patch)
treec0f288e834e14318a9bfb9ae199076544a9a5a27
parent1e8d8896b36c581121c7ba5c501c45bedce084e2 (diff)
Parse let expressions
-rw-r--r--src/ast.rs19
-rw-r--r--src/taiga.lalrpop19
2 files changed, 38 insertions, 0 deletions
diff --git a/src/ast.rs b/src/ast.rs
index 22d968e..7edf9c7 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -60,6 +60,7 @@ pub enum BinOp {
#[derive(Debug)]
pub enum Expression {
+ Let(Vec<WithLocation<VarDec>>, Box<WithLocation<Expression>>),
UnaryOp(UnaryOp, Box<WithLocation<Expression>>),
BinOp(BinOp, Box<WithLocation<Expression>>, Box<WithLocation<Expression>>),
Number(u64),
@@ -67,3 +68,21 @@ pub enum Expression {
Name(String),
Nil,
}
+
+#[derive(Debug)]
+pub struct VarDec {
+ name: WithLocation<String>,
+ type_: Option<String>,
+ value: Box<WithLocation<Expression>>,
+}
+
+impl VarDec {
+ pub fn new(name: WithLocation<String>, type_: Option<String>,
+ value: Box<WithLocation<Expression>>) -> VarDec {
+ VarDec {
+ name: name,
+ type_: type_,
+ value: value,
+ }
+ }
+}
diff --git a/src/taiga.lalrpop b/src/taiga.lalrpop
index be47147..851cb24 100644
--- a/src/taiga.lalrpop
+++ b/src/taiga.lalrpop
@@ -7,6 +7,19 @@ pub Program: ast::Program = {
Expression => ast::Program(<>),
};
+VarDec: Box<WithLocation<ast::VarDec>> =
+ <l: @L> "var" <name: Name> "=" <exp: Expression> <r: @R> =>
+ Box::new(WithLocation::new(ast::VarDec::new(name, None, exp), l, r));
+
+DeclarationsList: Vec<WithLocation<ast::VarDec>> = {
+ <h: DeclarationsList> <t: VarDec> => {
+ let mut h = h;
+ h.push(*t);
+ h
+ },
+ <VarDec> => vec![*<>],
+};
+
Expression: Box<ast::WithLocation<ast::Expression>> = {
<e1:Expression> "&&" <e2:ExpressionEq> => Box::new(e1.join_map(*e2, |v1, v2| {
ast::Expression::BinOp(ast::BinOp::And, Box::new(v1), Box::new(v2))
@@ -87,6 +100,8 @@ ExpressionBase: Box<ast::WithLocation<ast::Expression>> = {
String => Box::new(<>.map(|v| ast::Expression::String(v))),
Name => Box::new(<>.map(|v| ast::Expression::Name(v))),
Spanned<r"nil"> => Box::new(<>.map(|v| ast::Expression::Nil)),
+ <l: @L> "let" <d: DeclarationsList> "in" <e: Expression> "end" <r: @R> =>
+ Box::new(WithLocation::new(ast::Expression::Let(d, e), l, r)),
"(" <Expression> ")" => <>,
};
@@ -102,6 +117,10 @@ Spanned<T>: WithLocation<T> = {
match {
"nil",
+ "var",
+ "let",
+ "in",
+ "end",
}
else {
r"[[:alpha:]_][[:alpha:]_0-9]*",