aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2017-09-22 11:44:07 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2017-09-22 11:44:07 -0700
commit6882862d0ff226d73bc6a010d335896c44d8cde9 (patch)
treefe91165713eacf3f55b3884be27bd305f9ad88a2
parentd3a5fc73bc9aa37f58b2e159a9959afb53df73e3 (diff)
Cleaned up code generation to have less cruft.
-rw-r--r--lib/collections.nom12
-rw-r--r--lib/control_flow.nom17
-rw-r--r--lib/metaprogramming.nom4
-rw-r--r--lib/operators.nom13
-rw-r--r--lib/secrets.nom9
-rw-r--r--lib/utils.nom6
-rw-r--r--nomsu.lua24
-rwxr-xr-xnomsu.moon18
8 files changed, 56 insertions, 47 deletions
diff --git a/lib/collections.nom b/lib/collections.nom
index 41bf173..4a40c0f 100644
--- a/lib/collections.nom
+++ b/lib/collections.nom
@@ -29,12 +29,10 @@ macro block [for %key -> %value in %dict %body] =:
assert ((%value's "type") == "Var") ".."
|For loop has the wrong type for the value variable. Expected Var, but got: \%value's "type"\
".."
- |do
- | local vars = setmetatable({}, {__index=vars})
- | for k, v in pairs(\%dict as lua\) do
- | \%key as lua\, \%value as lua\ = k, v
- | \%body as lua\
- | end
+ |local vars = setmetatable({}, {__index=vars})
+ |for k, v in pairs(\%dict as lua\) do
+ | \%key as lua\, \%value as lua\ = k, v
+ | \%body as lua\
|end
# Membership testing
@@ -72,7 +70,7 @@ macro [%list ->* %indices] =:
".."|(\%ret\)
# Assignment
-macro block [..]
+macro statement [..]
%list's %index = %new_value, %index st in %list = %new_value, %index nd in %list = %new_value
%index rd in %list = %new_value, %index th in %list = %new_value, %index in %list = %new_value
%list -> %index = %new_value
diff --git a/lib/control_flow.nom b/lib/control_flow.nom
index fdde318..4bdaa06 100644
--- a/lib/control_flow.nom
+++ b/lib/control_flow.nom
@@ -16,7 +16,7 @@ macro statement [if %condition %if_body else %else_body] =:
|end
# Return
-macro block [return] =: "return nil"
+macro statement [return] =: "do return end"
macro block [return %return-value] =: ".."
|return \%return-value as lua\
@@ -117,9 +117,8 @@ macro block [when %body] =:
%result join=: ".."
|
|do
- | local ret
| \(lua expr "vars.thunk.value") as lua\
- | return ret
+ | goto finished_when
|end
..else:
if (lua expr "#vars.condition_bits == 1 and vars.condition_bits[1].type ~= 'Word'"):
@@ -132,11 +131,10 @@ macro block [when %body] =:
%result join=: ".."
|
|if \%condition as lua\ then
- | local ret
| \(lua expr "vars.thunk.value") as lua\
- | return ret
+ | goto finished_when
|end
-
+ %result join=: "\n::finished_when::"
%result
# Switch statement
@@ -160,9 +158,8 @@ macro block [when %branch-value %body] =:
%result join=: ".."
|
|do
- | local ret
| \(lua expr "vars.thunk.value") as lua\
- | return ret
+ | goto finished_when
|end
..else:
if (lua expr "#vars.condition_bits == 1 and vars.condition_bits[1].type ~= 'Word'"):
@@ -175,9 +172,9 @@ macro block [when %branch-value %body] =:
%result join=: ".."
|
|if compiler.utils.equivalent(branch_condition, \%condition as lua\) then
- | local ret
| \(lua expr "vars.thunk.value") as lua\
- | return ret
+ | goto finished_when
|end
+ %result join=: "\n::finished_when::"
%result
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom
index fa04232..19df984 100644
--- a/lib/metaprogramming.nom
+++ b/lib/metaprogramming.nom
@@ -31,7 +31,7 @@ lua block ".."
|compiler:defmacro("macro statement %macro_def = %user_macro", make_fn(false), "see:lib/metaprogramming.nom")
|compiler:defmacro("macro block %macro_def = %user_macro", make_fn(true), "see:lib/metaprogramming.nom")
-macro block [macro %macro_def = %user_macro] =:
+macro statement [macro %macro_def = %user_macro] =:
".."|compiler:defmacro(
| \lua expr "compiler:get_aliases(vars.macro_def)"\,
| \lua expr "compiler:tree_to_lua(vars.user_macro)"\,
@@ -60,7 +60,7 @@ macro [compiler utils %method %args] =:
function calls and convert it into a list of strings (rather than call a function that
is currently in the middle of being defined). Being a macro also allows us to snatch
the source code and store that
-macro block [rule %rule_def = %body] =: ".."
+macro statement [rule %rule_def = %body] =: ".."
|compiler:def(
| \compiler "repr" [compiler "get_aliases" [%rule_def]]\,
| \compiler "tree_to_lua" [%body]\,
diff --git a/lib/operators.nom b/lib/operators.nom
index 67383fa..38e8758 100644
--- a/lib/operators.nom
+++ b/lib/operators.nom
@@ -4,7 +4,7 @@ require "lib/metaprogramming.nom"
macro [true, yes] =: "true"
macro [false, no] =: "false"
macro [nil, null] =: "nil"
-macro block [nop, pass] =: ""
+macro statement [nop, pass] =: ""
# Ternary operator
macro [%if_expr if %condition else %else_expr] =:
@@ -54,7 +54,6 @@ lua block ".."
# Binary Operators
lua block ".."
- |local function make_binops()
|local binops = {"+","-","*","/","<","<=",">",">=","^",{"===","=="},{"!==","~="},"and","or",{"mod","%"}}
|for _,op in ipairs(binops) do
| local nomsu_alias = op
@@ -65,8 +64,6 @@ 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\))
@@ -74,7 +71,7 @@ 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(max_operands)
+ |local max_operands = 8
|local comops = {"+","*","and","or"}
|for _,_op in ipairs(comops) do
| local op = _op
@@ -90,12 +87,10 @@ lua block ".."
| end))
| end
|end
- |end
- |make_comops(8)
# Chained compairsions (e.g. x < y <= z) are defined up to 3 operands
lua block ".."
- |local function chained_comparisons(max_operands)
+ |local max_operands = 3
|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
@@ -126,8 +121,6 @@ lua block ".."
| end
| recurse(chainers, {})
|end
- |end
- |chained_comparisons(3)
# Unary operators
macro [- %a] =: ".."|-(\%a as lua\)
diff --git a/lib/secrets.nom b/lib/secrets.nom
index 60f7748..5d9551f 100644
--- a/lib/secrets.nom
+++ b/lib/secrets.nom
@@ -27,8 +27,7 @@ macro block [secret %key = %new_value] =:
| compiler:error("Assignment operation has the wrong type for the right hand side. "
| .."Expected Thunk, but got: "..vars.new_value.type.."\\nMaybe you used '=' instead of '=:'?")
|end
- ".."|do
- | local ret
- | \lua expr "compiler:tree_to_lua(vars.new_value.value)"\
- | secrets[\repr (%key's "value")\] = ret
- |end
+ ".."
+ |local ret
+ |\lua expr "compiler:tree_to_lua(vars.new_value.value)"\
+ |secrets[\repr (%key's "value")\] = ret
diff --git a/lib/utils.nom b/lib/utils.nom
index ff261f7..41c5d61 100644
--- a/lib/utils.nom
+++ b/lib/utils.nom
@@ -5,16 +5,16 @@ rule [error!, panic!, fail!, abort!] =:
compiler "error"[]
rule [error %msg] =:
compiler "error"[%msg]
-macro block [assert %condition] =: ".."
+macro statement [assert %condition] =: ".."
|if not (\%condition as lua\) then
| compiler:error()
|end
-macro block [assert %condition %msg] =: ".."
+macro statement [assert %condition %msg] =: ".."
|if not (\%condition as lua\) then
| compiler:error(\%msg as lua\)
|end
-macro block [show generated lua %block] =: ".."
+macro statement [show generated lua %block] =: ".."
|compiler:writeln(\lua expr "compiler:repr(compiler:tree_to_lua(vars.block.value))"\)
diff --git a/nomsu.lua b/nomsu.lua
index 08f9797..e5ebf4d 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -427,11 +427,22 @@ do
return concat(buffer, "\n")
elseif "Thunk" == _exp_0 then
assert(tree.value.type == "Block", "Non-block value in Thunk")
- return [[ (function(compiler, vars)
+ local lua = self:tree_to_lua(tree.value)
+ if #tree.value.value == 1 then
+ do
+ local ret_value = lua:match("^%s*ret = (.*)")
+ if ret_value then
+ return ([[ (function(compiler, vars)
+ return %s
+ end)]]):format(ret_value)
+ end
+ end
+ end
+ return ([[ (function(compiler, vars)
local ret
- ]] .. self:tree_to_lua(tree.value) .. "\n" .. [[ return ret
- end)
- ]]
+ %s
+ return ret
+ end)]]):format(lua)
elseif "Statement" == _exp_0 then
if tree.value.type == "FunctionCall" then
local alias = self:get_alias(tree.value)
@@ -759,7 +770,10 @@ do
end
})
local lua = self:tree_to_value(vars.lua_code, inner_vars)
- return "do\n" .. tostring(lua) .. "\nend", true
+ if not lua:match("^do\n.*\nend$") then
+ lua = "do\n" .. tostring(lua) .. "\nend"
+ end
+ return lua, true
end)
self:defmacro("lua expr %lua_code", function(self, vars, kind)
local lua_code = vars.lua_code.value
diff --git a/nomsu.moon b/nomsu.moon
index 0127c9b..d274c6e 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -318,13 +318,19 @@ class NomsuCompiler
when "Thunk"
assert tree.value.type == "Block", "Non-block value in Thunk"
- return [[
+ lua = @tree_to_lua(tree.value)
+ if #tree.value.value == 1
+ if ret_value = lua\match("^%s*ret = (.*)")
+ return ([[
+ (function(compiler, vars)
+ return %s
+ end)]])\format(ret_value)
+ return ([[
(function(compiler, vars)
local ret
- ]]..@tree_to_lua(tree.value).."\n"..[[
+ %s
return ret
- end)
- ]]
+ end)]])\format(lua)
when "Statement"
-- This case here is to prevent "ret =" from getting prepended when the macro might not want it
@@ -543,7 +549,9 @@ class NomsuCompiler
if kind == "Expression" then error("Expected to be in statement.")
inner_vars = setmetatable({}, {__index:(_,key)-> "vars[#{repr(key)}]"})
lua = @tree_to_value(vars.lua_code, inner_vars)
- return "do\n#{lua}\nend", true
+ if not lua\match("^do\n.*\nend$")
+ lua = "do\n#{lua}\nend"
+ return lua, true
@defmacro "lua expr %lua_code", (vars, kind)=>
lua_code = vars.lua_code.value