From 4e821308af654706b8bda5f3d00dce7a933d9942 Mon Sep 17 00:00:00 2001
From: Bruce Hill <bitbucket@bruce-hill.com>
Date: Wed, 25 Apr 2018 17:43:48 -0700
Subject: [PATCH] Overhauling parsing of Blocks (can no longer contain only one
 statement)

---
 core/control_flow.nom    |  8 ++++++--
 core/math.nom            |  2 +-
 core/metaprogramming.nom |  3 ---
 nomsu.peg                | 19 ++++++++++++-------
 nomsu_tree.lua           | 19 ++++++++++++-------
 nomsu_tree.moon          | 14 +++++++++-----
 6 files changed, 40 insertions(+), 25 deletions(-)

diff --git a/core/control_flow.nom b/core/control_flow.nom
index b51ecdf..d3d18ac 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -261,7 +261,9 @@ immediately
         %fallthroughs <- []
         %is_first <- (yes)
         %seen_else <- (no)
-        for %func_call in %body.value
+        %branches <-
+            %body.value if (%body.type = "Block") else [%body]
+        for %func_call in %branches
             assume (%func_call.type is "Action") or barf ".."
                 Invalid format for 'when' statement. Only '*' blocks are allowed.
             %tokens <- %func_call.value
@@ -308,7 +310,9 @@ immediately
         %fallthroughs <- []
         %is_first <- (yes)
         %seen_else <- (no)
-        for %func_call in %body.value
+        %branches <-
+            %body.value if (%body.type = "Block") else [%body]
+        for %func_call in %branches
             assume (%func_call.type is "Action") or barf ".."
                 Invalid format for 'when' statement. Only '*' blocks are allowed.
             %tokens <- %func_call.value
diff --git a/core/math.nom b/core/math.nom
index 75e41b4..ad419fa 100644
--- a/core/math.nom
+++ b/core/math.nom
@@ -90,6 +90,6 @@ parse [seed random] as: seed random with (=lua "os.time()")
 compile [random number, random, rand] to: Lua value "math.random()"
 compile [random int %n, random integer %n, randint %n] to: Lua value "math.random(\(%n as lua expr))"
 compile [random from %low to %high, random number from %low to %high, rand %low %high] to
-    "math.random(\(%low as lua expr), \(%high as lua expr))"
+    Lua value "math.random(\(%low as lua expr), \(%high as lua expr))"
 action [random choice from %elements, random choice %elements, random %elements]
     =lua "\%elements[math.random(#\%elements)]"
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 9722afd..f6f202f 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -22,9 +22,6 @@ immediately
             for i,tok in ipairs(\%actions.value[1].value) do
                 if tok.type == "Var" then args[#args+1] = nomsu:var_to_lua_identifier(tok.value); end
             end
-            if \%lua.type == "Text" then
-                error("Invalid type for 'compile % to %', expected a dict with expr/statements, but got text.", 0);
-            end
             for i, arg in ipairs(args) do
                 lua:append(", ");
                 lua:append(arg);
diff --git a/nomsu.peg b/nomsu.peg
index af65d93..b1c1f50 100644
--- a/nomsu.peg
+++ b/nomsu.peg
@@ -8,12 +8,12 @@ file (File):
 shebang: "#!" [^%nl]* (!. / %nl)
 
 statement: action / expression
+inline_statement: inline_action / inline_expression
 
-indented_block (Block):
-    {| indent
-            statement (nodent statement)*
-        (dedent / (("" -> "Error while parsing block") => error))
-    |} -> Tuple
+inline_block (Block):
+    {| inline_statement (";" inline_statement)+ |}
+block (Block):
+    {| statement (nodent statement)+ |} -> Tuple
 
 inline_nomsu (Nomsu): "\" noindex_inline_expression
 indented_nomsu (Nomsu):
@@ -29,7 +29,12 @@ noindex_inline_expression:
 inline_expression:
     index_chain / noindex_inline_expression 
 indented_expression:
-    indented_text / indented_nomsu / indented_list / indented_dict / indented_block
+    indented_text / indented_nomsu / indented_list / indented_dict
+    / (indent
+        (action dedent
+        / expression dedent
+        / block (dedent / (("" -> "Error while parsing indented expression") => error)))
+      )
 expression:
     inline_expression / (":" %ws* (inline_action / inline_expression) eol) / indented_expression
 
@@ -65,7 +70,7 @@ inline_text_interpolation:
 text_interpolation:
     inline_text_interpolation /
     ("\" 
-        (block_comment / line_comment / indented_text / indented_list / indented_block)?
+        (block_comment / line_comment / indented_expression)?
     nodent "..")
 
 number (Number): (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / ([0-9]+)))-> tonumber)
diff --git a/nomsu_tree.lua b/nomsu_tree.lua
index 4a3d7f6..f7a56d7 100644
--- a/nomsu_tree.lua
+++ b/nomsu_tree.lua
@@ -110,9 +110,6 @@ Tree("Nomsu", {
 })
 Tree("Block", {
   as_lua = function(self, nomsu)
-    if #self.value == 1 then
-      return self.value[1]:as_lua(nomsu)
-    end
     local lua = Lua(self.source)
     for i, line in ipairs(self.value) do
       local line_lua = line:as_lua(nomsu)
@@ -128,11 +125,19 @@ Tree("Block", {
     if inline == nil then
       inline = false
     end
-    if #self.value == 1 then
-      return self.value[1]:as_nomsu(inline)
-    end
     if inline then
-      return nil
+      local nomsu = Nomsu(self.source)
+      for i, line in ipairs(self.value) do
+        if i > 1 then
+          nomsu:append("; ")
+        end
+        local line_nomsu = line:as_nomsu(true)
+        if not (line_nomsu) then
+          return nil
+        end
+        nomsu:append(line_nomsu)
+      end
+      return nomsu
     end
     local nomsu = Nomsu(self.source)
     for i, line in ipairs(self.value) do
diff --git a/nomsu_tree.moon b/nomsu_tree.moon
index 43ebcd2..2cf0777 100644
--- a/nomsu_tree.moon
+++ b/nomsu_tree.moon
@@ -74,8 +74,6 @@ Tree "Nomsu",
 
 Tree "Block",
     as_lua: (nomsu)=>
-        if #@value == 1
-            return @value[1]\as_lua(nomsu)
         lua = Lua(@source)
         for i,line in ipairs @value
             line_lua = line\as_lua(nomsu)
@@ -86,9 +84,15 @@ Tree "Block",
         return lua
 
     as_nomsu: (inline=false)=>
-        if #@value == 1
-            return @value[1]\as_nomsu(inline)
-        return nil if inline
+        if inline
+            nomsu = Nomsu(@source)
+            for i,line in ipairs @value
+                if i > 1
+                    nomsu\append "; "
+                line_nomsu = line\as_nomsu(true)
+                return nil unless line_nomsu
+                nomsu\append line_nomsu
+            return nomsu
         nomsu = Nomsu(@source)
         for i, line in ipairs @value
             line = assert(line\as_nomsu!, "Could not convert line to nomsu")