Cleaned up code generation to have less cruft.

This commit is contained in:
Bruce Hill 2017-09-22 11:44:07 -07:00
parent d3a5fc73bc
commit 6882862d0f
8 changed files with 56 additions and 47 deletions

View File

@ -29,13 +29,11 @@ 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
|end
# Membership testing
rule [%item is in %list, %list contains %item, %list has %item] =:
@ -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

View File

@ -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

View File

@ -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]\,

View File

@ -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\)

View File

@ -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

View File

@ -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))"\)

View File

@ -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

View File

@ -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