summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2017-11-04 19:18:49 -0400
committerDavid Li <li.davidm96@gmail.com>2017-11-04 19:18:49 -0400
commitc9d3f7629cfdacededf2a92252e6c9de8a8b75ae (patch)
tree842a534556cdda149250c70bddd8a18d21ecd061
parentd756b309068eaf991290c39963462efec27ebe6f (diff)
Parse unary operators
-rw-r--r--src/ast.rs7
-rw-r--r--src/taiga.lalrpop18
2 files changed, 22 insertions, 3 deletions
diff --git a/src/ast.rs b/src/ast.rs
index 2814ef9..97ed91d 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -35,6 +35,12 @@ impl<T> WithLocation<T> {
pub struct Program(pub Box<WithLocation<Expression>>);
#[derive(Debug)]
+pub enum UnaryOp {
+ Pos,
+ Neg,
+}
+
+#[derive(Debug)]
pub enum BinOp {
Add,
Sub,
@@ -45,6 +51,7 @@ pub enum BinOp {
#[derive(Debug)]
pub enum Expression {
+ UnaryOp(UnaryOp, Box<WithLocation<Expression>>),
BinOp(BinOp, Box<WithLocation<Expression>>, Box<WithLocation<Expression>>),
Number(u64),
Nil,
diff --git a/src/taiga.lalrpop b/src/taiga.lalrpop
index 0182a04..6bf750d 100644
--- a/src/taiga.lalrpop
+++ b/src/taiga.lalrpop
@@ -18,15 +18,27 @@ Expression: Box<ast::WithLocation<ast::Expression>> = {
};
ExpressionMul: Box<ast::WithLocation<ast::Expression>> = {
- <e1:ExpressionMul> "*" <e2:ExpressionBase> => Box::new(e1.join_map(*e2, |v1, v2| {
+ <e1:ExpressionMul> "*" <e2:ExpressionSign> => Box::new(e1.join_map(*e2, |v1, v2| {
ast::Expression::BinOp(ast::BinOp::Mul, Box::new(v1), Box::new(v2))
})),
- <e1:ExpressionMul> "/" <e2:ExpressionBase> => Box::new(e1.join_map(*e2, |v1, v2| {
+ <e1:ExpressionMul> "/" <e2:ExpressionSign> => Box::new(e1.join_map(*e2, |v1, v2| {
ast::Expression::BinOp(ast::BinOp::Div, Box::new(v1), Box::new(v2))
})),
- <e1:ExpressionMul> "//" <e2:ExpressionBase> => Box::new(e1.join_map(*e2, |v1, v2| {
+ <e1:ExpressionMul> "//" <e2:ExpressionSign> => Box::new(e1.join_map(*e2, |v1, v2| {
ast::Expression::BinOp(ast::BinOp::FloorDiv, Box::new(v1), Box::new(v2))
})),
+ <ExpressionSign> => <>,
+};
+
+ExpressionSign: Box<ast::WithLocation<ast::Expression>> = {
+ <l: @L> "+" <e: ExpressionBase> <r: @R> => Box::new(WithLocation::new(
+ ast::Expression::UnaryOp(ast::UnaryOp::Pos, e),
+ l, r
+ )),
+ <l: @L> "-" <e: ExpressionBase> <r: @R> => Box::new(WithLocation::new(
+ ast::Expression::UnaryOp(ast::UnaryOp::Neg, e),
+ l, r
+ )),
<ExpressionBase> => <>,
};