From 4fd6b61a0074ea69f0ce3e11768e867d355307ac Mon Sep 17 00:00:00 2001
From: Bruce Hill <bitbucket@bruce-hill.com>
Date: Thu, 21 Sep 2017 14:11:34 -0700
Subject: [PATCH] Fixed bug that caused files to get reloaded if they returned
 nil.

---
 lib/operators.nom | 45 +++++++++++++++++++++++++++------------------
 nomsu.lua         |  2 +-
 nomsu.moon        |  6 +++++-
 3 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/lib/operators.nom b/lib/operators.nom
index 01289ef..3f2336f 100644
--- a/lib/operators.nom
+++ b/lib/operators.nom
@@ -21,7 +21,7 @@ macro [%if_expr if %condition else %else_expr] =:
 
 # Variable assignment operator, and += type versions
 lua block ".."
-    |local function helper(callback)
+    |local function assign(callback)
     |    return function(compiler, vars, kind)
     |        if kind == "Expression" then
     |            compiler:error("Cannot use an assignment operation as an expression value.")
@@ -41,19 +41,20 @@ lua block ".."
     |            compiler:tree_to_lua(vars.rhs.value.value[1].value)), true
     |    end
     |end
-    |compiler:defmacro("%var = %rhs", helper(function(var,result) return var.." = "..result end))
-    |compiler:defmacro("%var += %rhs", helper(function(var,result) return var.." = "..var.." + "..result end))
-    |compiler:defmacro("%var -= %rhs", helper(function(var,result) return var.." = "..var.." - "..result end))
-    |compiler:defmacro("%var *= %rhs", helper(function(var,result) return var.." = "..var.." * "..result end))
-    |compiler:defmacro("%var /= %rhs", helper(function(var,result) return var.." = "..var.." / "..result end))
-    |compiler:defmacro("%var ^= %rhs", helper(function(var,result) return var.." = "..var.." ^ "..result end))
-    |compiler:defmacro("%var and= %rhs", helper(function(var,result) return var.." = "..var.." and "..result end))
-    |compiler:defmacro("%var or= %rhs", helper(function(var,result) return var.." = "..var.." or "..result end))
-    |compiler:defmacro("%var join= %rhs", helper(function(var,result) return var.." = "..var.." .. "..result end))
-    |compiler:defmacro("%var mod= %rhs", helper(function(var,result) return var.." = "..var.." % "..result end))
+    |compiler:defmacro("%var = %rhs", assign(function(var,result) return var.." = "..result end))
+    |compiler:defmacro("%var += %rhs", assign(function(var,result) return var.." = "..var.." + "..result end))
+    |compiler:defmacro("%var -= %rhs", assign(function(var,result) return var.." = "..var.." - "..result end))
+    |compiler:defmacro("%var *= %rhs", assign(function(var,result) return var.." = "..var.." * "..result end))
+    |compiler:defmacro("%var /= %rhs", assign(function(var,result) return var.." = "..var.." / "..result end))
+    |compiler:defmacro("%var ^= %rhs", assign(function(var,result) return var.." = "..var.." ^ "..result end))
+    |compiler:defmacro("%var and= %rhs", assign(function(var,result) return var.." = "..var.." and "..result end))
+    |compiler:defmacro("%var or= %rhs", assign(function(var,result) return var.." = "..var.." or "..result end))
+    |compiler:defmacro("%var join= %rhs", assign(function(var,result) return var.." = "..var.." .. "..result end))
+    |compiler:defmacro("%var mod= %rhs", assign(function(var,result) return var.." = "..var.." % "..result end))
 
 # Binary Operators
 lua block ".."
+    |local function make_binops()
     |local binops = {"+","-","*","/","<","<=",">",">=","^",{"===","=="},{"!==","~="},"and","or",{"mod","%"}}
     |for _,op in ipairs(binops) do
     |    local nomsu_alias = op
@@ -64,12 +65,16 @@ lua block ".."
     |        return "("..compiler:tree_to_lua(vars.a).." "..op.." "..compiler:tree_to_lua(vars.b)..")"
     |    end), [[".."|(\\%a as lua\\ ]]..op..[[ \\%b as lua\\)]])
     |end
+    |end
+    |make_binops()
 # == and != do equivalence checking, rather than identity checking
 macro [%a == %b] =: ".."|compiler.utils.equivalent(\%a as lua\, \%b as lua\)
 macro [%a != %b] =: ".."|(not compiler.utils.equivalent(\%a as lua\, \%b as lua\))
 
 # Commutative Operators defined for up to 8 operands
+# TODO: work out solution for commutative operators using more clever macros
 lua block ".."
+    |local function make_comops()
     |local comops = {"+","*","and","or"}
     |for _,_op in ipairs(comops) do
     |    local op = _op
@@ -85,11 +90,14 @@ lua block ".."
     |        end))
     |    end
     |end
+    |end
+    |make_comops()
 
-# Chained compairsions (e.g. x < y <= z < w) are defined up to 8 operands
+# Chained compairsions (e.g. x < y <= z < w) are defined up to 3 operands
 lua block ".."
-    |for _,chainers in ipairs{{"<","<="},{">",">="}} do
-    |    local function recurse(chain)
+    |local function chained_comparisons(max_operands)
+    |for _,chainers in ipairs({{"<","<="},{">",">="}}) do
+    |    local function recurse(chainers, chain)
     # The 1-op versions are already more efficiently defined, and a 0-op version doesnt make sense
     |        if #chain >= 2 then
     |            local spec = "%1"
@@ -109,16 +117,17 @@ lua block ".."
     |                end
     |            end)
     |        end
-    # 7 operators == 8 operands, so don't continue any further
-    |        if #chain >= 7 then return end
+    |        if #chain + 1 >= max_operands then return end
     |        for _,c in ipairs(chainers) do
     |            table.insert(chain, c)
-    |            recurse(chain)
+    |            recurse(chainers, chain)
     |            table.remove(chain)
     |        end
     |    end
-    |    recurse({})
+    |    recurse(chainers, {})
     |end
+    |end
+    |chained_comparisons(3)
 
 # Unary operators
 macro [- %a] =: ".."|-(\%a as lua\)
diff --git a/nomsu.lua b/nomsu.lua
index 3e2a891..11ae3ae 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -733,7 +733,7 @@ do
           if not file then
             self:error("File does not exist: " .. tostring(vars.filename))
           end
-          self.loaded_files[vars.filename] = self:run(file:read('*a'), vars.filename)
+          self.loaded_files[vars.filename] = (self:run(file:read('*a'), vars.filename)) or true
         end
         return self.loaded_files[vars.filename]
       end)
diff --git a/nomsu.moon b/nomsu.moon
index ca888a8..6dce00b 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -548,7 +548,7 @@ class NomsuCompiler
                 file = io.open(vars.filename)
                 if not file
                     @error "File does not exist: #{vars.filename}"
-                @loaded_files[vars.filename] = @run(file\read('*a'), vars.filename)
+                @loaded_files[vars.filename] = (@run(file\read('*a'), vars.filename)) or true
             return @loaded_files[vars.filename]
 
         @def "run file %filename", (vars)=>
@@ -561,6 +561,8 @@ class NomsuCompiler
 -- Run on the command line via "./nomsu.moon input_file.nom" to execute
 -- and "./nomsu.moon input_file.nom output_file.lua" to compile (use "-" to compile to stdout)
 if arg and arg[1]
+    --ProFi = require 'ProFi'
+    --ProFi\start()
     c = NomsuCompiler()
     input = io.open(arg[1])\read("*a")
     -- If run via "./nomsu.moon file.nom -", then silence output and print generated
@@ -586,6 +588,8 @@ if arg and arg[1]
     local c = NomsuCompiler()
     return load()(c, {})
     ]]
+    --ProFi\stop()
+    --ProFi\writeReport( 'MyProfilingReport.txt' )
 
 elseif arg
     -- REPL: