From 262e02bfa7068bc48065b733cefed49e0238ca73 Mon Sep 17 00:00:00 2001
From: Per Lindgren <per.lindgren@ltu.se>
Date: Sun, 20 Sep 2020 17:21:11 +0200
Subject: [PATCH] syntax tests pass

---
 examples/syntax.rs     | 16 +--------
 examples/syntax2.rs    |  3 ++
 examples/syntax3.rs    |  4 +++
 src/ast/main.rs        | 10 ++++++
 src/ast/parser.lalrpop | 77 ++++++++++++++++++++++++++++++------------
 5 files changed, 74 insertions(+), 36 deletions(-)
 create mode 100644 examples/syntax2.rs
 create mode 100644 examples/syntax3.rs

diff --git a/examples/syntax.rs b/examples/syntax.rs
index 5b2d45f..f328e4d 100644
--- a/examples/syntax.rs
+++ b/examples/syntax.rs
@@ -1,15 +1 @@
-fn main() {
-    let a = false;
-
-    let a = {
-        let b = 1 + 1;
-        // extra `;` are allowed
-        if a {} // no trialing `;`
-        b // return value
-    };
-
-    while false {
-        // do something here
-    }
-    let _b = if a < 5 { 1 } else { 2 };
-}
+fn main() {}
diff --git a/examples/syntax2.rs b/examples/syntax2.rs
new file mode 100644
index 0000000..311e79c
--- /dev/null
+++ b/examples/syntax2.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let a = 5;
+}
diff --git a/examples/syntax3.rs b/examples/syntax3.rs
new file mode 100644
index 0000000..d8152fa
--- /dev/null
+++ b/examples/syntax3.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let a = 5;
+    let b = { 5 };
+}
diff --git a/src/ast/main.rs b/src/ast/main.rs
index 7e980d3..fe8cfad 100644
--- a/src/ast/main.rs
+++ b/src/ast/main.rs
@@ -26,5 +26,15 @@ pub fn parse(file_name: &str) {
 
 #[test]
 fn syntax() {
+    parse("examples/syntax.rs");
+}
+
+#[test]
+fn syntax2() {
+    parse("examples/syntax2.rs");
+}
+
+#[test]
+fn syntax3() {
     parse("examples/syntax3.rs");
 }
diff --git a/src/ast/parser.lalrpop b/src/ast/parser.lalrpop
index 575c6a9..67f5f78 100644
--- a/src/ast/parser.lalrpop
+++ b/src/ast/parser.lalrpop
@@ -14,6 +14,15 @@ match {
     _
 }
 
+// A comma separated sequence without trailing comma
+CommaNoTrail<T>: Vec<T> = { 
+    <v:(<T> ",")*> <e:T> => { 
+        let mut v = v;
+        v.push(e);
+        v
+    }
+}
+
 pub Function: () = {
     "fn" Id Params ("->" Type)? Block => (),
 }
@@ -34,64 +43,90 @@ pub Type:() = {
 }
 
 pub Block: () = {
-    "{" Stmt* "}" => (),
+    "{" StmtSeq* "}" => (),
+    "{" StmtSeq* Stmt "}" => (),
+}
+
+pub StmtSeq: () = {
+    Stmt ";" => (),
+    StmtBlock => (),
+}
+
+pub StmtBlock: () = {
+    "while" Expr Block => (),
+    "if" Expr Block ("else" Block)? => (),
+    Block => (),
 }
 
 pub Stmt: () = {
     ";" => (),
-    "let" "mut"? Id "=" Expr ";" => (),
+    "let" "mut"? Id "=" Expr => (),
     ExprNoBlock "=" Expr => (),
-    "while" Expr Block => (),
-    "if" Expr Block ("else" Block)? => (),
     ExprNoBlock => (),
-    Block => (),
 }
 
+
 pub Expr: () = {
     ExprBlock => (),
     ExprNoBlock => (),    
 }
 
 pub ExprBlock: () = {
-    "if" Expr Block "else" Block => (),
+    "if" ExprNoBlock Block "else" Block => (),
     Block => (),
 }
 
+// Here is our ordinary expressions
 pub ExprNoBlock: () = {
-    ExprNoBlock Cmp Expr1 => (),
-    Expr1 => (),
+    ExprNoBlock "||" Expr0 => (),
+    ExprNoBlock "&&" Expr0 => (),
+    Expr0 => (),
 }
 
-pub Cmp: () = {
-    "<" => ()
+
+// Comparison
+pub Expr0: () = {
+    Expr0 "==" Expr1 => (),
+    Expr0 "!=" Expr1 => (),
+    Expr0 ">" Expr1 => (),
+    Expr0 "<" Expr1 => (),
+    Expr1 => (),
 }
 
+
+// AddSub
 pub Expr1: () = {
-    Expr1 AddSub Expr2 => (),
+    Expr1 "+" Expr2 => (),
+    Expr1 "-" Expr2 => (),
     Expr2 => (),
 }
 
-pub AddSub: () = {
-    "+" => (),
-    "-" => (),
-}
-
+// MulDiv
 pub Expr2: () = {
-    Expr2 MulDiv Term => (),
-    Term => (),
+    Expr2 "/" Expr3 => (),
+    Expr2 "*" Expr3 => (),
+    Expr3 => (),
 }
 
-pub MulDiv: () = {
-    "/" => (),
-    "*" => (),
+// Unary
+pub Expr3: () = {
+    "*" Term => (),
+    "&" Term => (),
+    "&" "mut" Term => (),
+    "!" Term => (),
+    Term => (),
 }
 
 pub Term: () = {
     Id => (),
     Num => (),
+    Id "(" CommaNoTrail<Expr> ")" => (),
+    
     "(" Expr ")" => (),
 }
 
+
+
 pub Num: i32 = {
     r"[0-9]+" => i32::from_str(<>).unwrap(),
 };
-- 
GitLab