aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code_obj.moon30
-rw-r--r--containers.moon2
-rw-r--r--core/control_flow.nom129
-rw-r--r--core/math.nom8
-rw-r--r--core/metaprogramming.nom18
-rw-r--r--core/operators.nom8
-rw-r--r--nomnom/ast.nom3
-rw-r--r--nomnom/code_obj.nom74
-rw-r--r--nomnom/compile.nom30
-rw-r--r--nomnom/decompile.nom2
-rw-r--r--nomnom/parser.nom2
-rw-r--r--syntax_tree.moon3
12 files changed, 174 insertions, 135 deletions
diff --git a/code_obj.moon b/code_obj.moon
index 07b7618..3e43b16 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -47,10 +47,10 @@ class Code
@bits = {}
if type(@source) == 'string'
@source = Source\from_string(@source)
- assert(@source and Source\is_instance(@source), "Source has the wrong type")
+ --assert(@source and Source\is_instance(@source), "Source has the wrong type")
@append(...)
- __tostring: =>
+ as_smext: =>
if @__str == nil
buff, indent = {}, 0
{:match, :gsub, :rep} = string
@@ -59,21 +59,23 @@ class Code
if spaces = match(b, "\n([ ]*)[^\n]*$")
indent = #spaces
else
- b = tostring(b)
+ b = b\as_smext!
if indent > 0
b = gsub(b, "\n", "\n"..rep(" ", indent))
buff[#buff+1] = b
@__str = concat(buff, "")
return @__str
+ __tostring: => @as_smext!
+
as_lua: =>
"#{@__class.__name}(#{concat {tostring(@source)\as_lua!, unpack([b\as_lua! for b in *@bits])}, ", "})"
- __len: => #tostring(@)
+ __len: => #@as_smext!
- match: (...)=> tostring(@)\match(...)
+ match: (...)=> @as_smext!\match(...)
- gmatch: (...)=> tostring(@)\gmatch(...)
+ gmatch: (...)=> @as_smext!\gmatch(...)
dirty: =>
@__str = nil
@@ -91,14 +93,14 @@ class Code
assert(not Source\is_instance(b), "code bit is a Source")
if b == '' then continue
b.dirty = error if b.is_code
- if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
- b = b\as_lua!
+ --if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
+ -- b = b\as_lua!
bits[#bits+1] = b
@dirty!
trailing_line_len: =>
if @_trailing_line_len == nil
- @_trailing_line_len = #tostring(@)\match("[^\n]*$")
+ @_trailing_line_len = #@as_smext!\match("[^\n]*$")
return @_trailing_line_len
is_multiline: =>
@@ -130,7 +132,8 @@ class Code
bits[#bits+1] = joiner
bits[#bits+1] = b
b.dirty = error if b.is_code
- b = tostring(b)
+ unless type(b) == 'string'
+ b = b\as_smext!
line = match(b, "\n([^\n]*)$")
if line
line_len = #line
@@ -146,8 +149,8 @@ class Code
for i=1,n
b = select(i, ...)
b.dirty = error if b.is_code
- if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
- b = b\as_lua!
+ --if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
+ -- b = b\as_lua!
bits[i] = b
@dirty!
@@ -237,7 +240,8 @@ class LuaCode extends Code
nomsu_to_lua[lua.source.start] = pos
else
walk b, pos
- pos += #tostring(b)
+ b = b\as_smext!
+ pos += #b
walk self, 1
return {
nomsu_filename:@source.filename
diff --git a/containers.moon b/containers.moon
index 8a91241..0fb9271 100644
--- a/containers.moon
+++ b/containers.moon
@@ -87,6 +87,8 @@ _list_mt =
__newindex: (k,v)=>
assert type(k) == 'number', "List indices must be numbers"
rawset(@, k, v)
+_list_mt.__index.as_lua = _list_mt.as_lua
+_list_mt.__index.as_nomsu = _list_mt.as_nomsu
List = (t)-> setmetatable(t, _list_mt)
diff --git a/core/control_flow.nom b/core/control_flow.nom
index 4254abc..243df96 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -16,11 +16,13 @@ compile [do nothing] to (Lua "")
test:
if (no):
barf "conditional fail"
-compile [if %condition %if_body] to (..)
- Lua "\
- ..if \(%condition as lua expr) then
- \(%if_body as lua statements)
- end"
+compile [if %condition %if_body] to:
+ %lua = (Lua "if ")
+ %lua::append (%condition as lua expr)
+ %lua::append " then\n "
+ %lua::append (%if_body as lua statements)
+ %lua::append "\nend"
+ return %lua
test:
unless (yes):
@@ -28,13 +30,15 @@ test:
parse [unless %condition %unless_body] as (if (not %condition) %unless_body)
compile [..]
if %condition %if_body else %else_body, unless %condition %else_body else %if_body
-..to (..)
- Lua "\
- ..if \(%condition as lua expr) then
- \(%if_body as lua statements)
- else
- \(%else_body as lua statements)
- end"
+..to:
+ %lua = (Lua "if ")
+ %lua::append (%condition as lua expr)
+ %lua::append " then\n "
+ %lua::append (%if_body as lua statements)
+ %lua::append "\nelse\n "
+ %lua::append (%else_body as lua statements)
+ %lua::append "\nend"
+ return %lua
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -149,9 +153,8 @@ test:
compile [repeat %n times %body] to:
define mangler
%lua = (..)
- Lua "\
- ..for \(mangle "i")=1,\(%n as lua expr) do
- \(%body as lua statements)"
+ Lua "for \(mangle "i")=1,\(%n as lua expr) do\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
@@ -208,18 +211,20 @@ compile [..]
..to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
unless (%var.type is "Var"):
- compile error at %var "Expected a variable here, not a \(%var.type)."
+ compile error at %var "Expected a variable here, not a \(%var.type)"
%lua = (..)
Lua "\
..for \(%var as lua expr)=\(%start as lua expr),\(%stop as lua expr),\(..)
%step as lua expr
- .. do
- \(%body as lua statements)"
+ .. do"
+ %lua::append "\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %var)):
- %lua::append "\n \(compile as (===next %var ===))"
+ %lua::append "\n "
+ %lua::append (compile as (===next %var ===))
%lua::append "\nend --numeric for-loop"
if (%body has subtree \(stop %var)):
%inner_lua = %lua
@@ -254,14 +259,14 @@ compile [for %var in %iterable %body] to:
define mangler
# This uses Lua's approach of only allowing loop-scoped variables in a loop
%lua = (..)
- Lua "\
- ..for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do
- \(%body as lua statements)"
+ Lua "for \(mangle "i"),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %var)):
- %lua::append (Lua "\n\(compile as (===next %var ===))")
+ %lua::append "\n "
+ %lua::append (compile as (===next %var ===))
%lua::append "\nend --foreach-loop"
if (%body has subtree \(stop %var)):
%inner_lua = %lua
@@ -277,14 +282,14 @@ compile [for %var in %iterable %body] to:
compile [for %var in %iterable at %i %body] to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
%lua = (..)
- Lua "\
- ..for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do
- \(%body as lua statements)"
+ Lua "for \(%i as lua identifier),\(%var as lua identifier) in ipairs(\(%iterable as lua expr)) do\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %var)):
- %lua::append (Lua "\n\(compile as (===next %var ===))")
+ %lua::append "\n "
+ %lua::append (compile as (===next %var ===))
%lua::append "\nend --foreach-loop"
if (%body has subtree \(stop %var)):
%inner_lua = %lua
@@ -312,28 +317,33 @@ compile [..]
..to:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
unless (%key.type is "Var"):
- compile error at %key "Expected a variable here, not a \(%key.type)."
+ compile error at %key "Expected a variable here, not a \(%key.type)"
unless (%value.type is "Var"):
- compile error at %value "Expected a variable here, not a \(%value.type)."
+ compile error at %value "Expected a variable here, not a \(%value.type)"
%lua = (..)
Lua "\
..for \(%key as lua identifier),\(%value as lua identifier) in pairs(\(..)
%iterable as lua expr
- ..) do
- \(%body as lua statements)"
+ ..) do"
+ %lua::append "\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
if (%body has subtree \(do next %key)):
- %lua::append (Lua "\n\(compile as (===next %key ===))")
+ %lua::append "\n "
+ %lua::append (compile as (===next %key ===))
if (%body has subtree \(do next %value)):
- %lua::append (Lua "\n\(compile as (===next %value ===))")
+ %lua::append "\n "
+ %lua::append (compile as (===next %value ===))
%lua::append "\nend --foreach-loop"
%stop_labels = (Lua "")
if (%body has subtree \(stop %key)):
- %stop_labels::append "\n\(compile as (===stop %key ===))"
+ %stop_labels::append "\n"
+ %stop_labels::append (compile as (===stop %key ===))
if (%body has subtree \(stop %value)):
- %stop_labels::append "\n\(compile as (===stop %value ===))"
+ %stop_labels::append "\n"
+ %stop_labels::append (compile as (===stop %value ===))
if ((size of "\%stop_labels") > 0):
%inner_lua = %lua
%lua = (Lua "do -- scope for stopping for % = % loop\n ")
@@ -390,7 +400,8 @@ compile [if %body, when %body] to:
%code::append (%action as lua statements)
%else_allowed = (no)
..else:
- %code::append "\%clause "
+ %code::append %clause
+ %code::append " "
for %i in 1 to ((size of %line) - 1):
if (%i > 1):
%code::append " or "
@@ -450,11 +461,13 @@ compile [if %branch_value is %body, when %branch_value is %body] to:
%code::append (%action as lua statements)
%else_allowed = (no)
..else:
- %code::append "\%clause "
+ %code::append %clause
+ %code::append " "
for %i in 1 to ((size of %line) - 1):
if (%i > 1):
%code::append " or "
- %code::append "\(mangle "branch value") == \(%line.%i as lua expr)"
+ %code::append "\(mangle "branch value") == "
+ %code::append (%line.%i as lua expr)
%code::append " then\n "
%code::append (%action as lua statements)
@@ -467,18 +480,19 @@ compile [if %branch_value is %body, when %branch_value is %body] to:
%lua = (..)
Lua "\
..do --if % is...
- local \(mangle "branch value") = \(%branch_value as lua expr)"
+ local \(mangle "branch value") = "
+ %lua::append (%branch_value as lua expr)
%lua::append "\n "
%lua::append %code
%lua::append "\nend --if % is..."
return %lua
# Do/finally
-compile [do %action] to (..)
- Lua "\
- ..do
- \(%action as lua statements)
- end --do"
+compile [do %action] to:
+ %lua = (Lua "do\n ")
+ %lua::append (%action as lua statements)
+ %lua::append "\nend -- do"
+ return %lua
test:
%d = {}
@@ -492,18 +506,22 @@ test:
assume (%d.x == "good")
compile [do %action then always %final_action] to:
define mangler
- return (..)
+ %lua = (..)
Lua "\
..do
local \(mangle "fell_through") = false
- local \(mangle "ok"), \(mangle "ret") = pcall(function()
- \(%action as lua statements)
- \(mangle "fell_through") = true
- end)
- \(%final_action as lua statements)
- if not \(mangle "ok") then error(ret, 0) end
- if not \(mangle "fell_through") then return ret end
- end"
+ local \(mangle "ok"), \(mangle "ret") = pcall(function()"
+ %lua::append "\n "
+ %lua::append (%action as lua statements)
+ %lua::append "\
+ .. \(mangle "fell_through") = true
+ end)"
+ %lua::append "\n "
+ %lua::append (%final_action as lua statements)
+ %lua::append "\
+ .. if not \(mangle "ok") then error(ret, 0) end
+ if not \(mangle "fell_through") then return ret end
+ end"
test:
assume ((result of (: return 99)) == 99)
@@ -532,8 +550,9 @@ compile [for %var in recursive %structure %body] to (..)
..do
local \(mangle "stack \(%var.1)") = _List{\(%structure as lua expr)}
while #\(mangle "stack \(%var.1)") > 0 do
- \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)
- \(%body as lua statements)"
+ \(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)"
+ %lua::append "\n "
+ %lua::append (%body as lua statements)
if (%body has subtree \(do next)):
%lua::append "\n ::continue::"
diff --git a/core/math.nom b/core/math.nom
index 5daa2d8..feb64cb 100644
--- a/core/math.nom
+++ b/core/math.nom
@@ -72,21 +72,21 @@ action [%n to the nearest %rounder] (..)
compile [all of %items, all %items] to:
unless (%items.type is "List"):
return (Lua value "utils.all(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::as smext) for % in %items)
return (Lua value "(\(%clauses::joined with " and "))")
parse [not all of %items, not all %items] as (not (all of %items))
compile [any of %items, any %items] to:
unless (%items.type is "List"):
return (Lua value "utils.any(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::as smext) for % in %items)
return (Lua value "(\(%clauses::joined with " or "))")
parse [none of %items, none %items] as (not (any of %items))
compile [sum of %items, sum %items] to:
unless (%items.type is "List"):
return (Lua value "utils.sum(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::as smext) for % in %items)
return (Lua value "(\(%clauses::joined with " + "))")
parse [if all of %items %body, if all of %items then %body] as (..)
@@ -118,7 +118,7 @@ parse [unless none of %items %body else %else, unless none of %items then %body
compile [product of %items, product %items] to:
unless (%items.type is "List"):
return (Lua value "utils.product(\(%items as lua expr))")
- %clauses = ((% as lua expr) for % in %items)
+ %clauses = (((% as lua expr)::as smext) for % in %items)
return (Lua value "(\(%clauses::joined with " * "))")
action [avg of %items, average of %items] (=lua "(utils.sum(\%items)/#\%items)")
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 00151d5..6a457d9 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -23,7 +23,7 @@ lua> "\
..COMPILE_ACTIONS["1 -> 2"] = function(nomsu, tree, \%args, \%body)
local lua = LuaCode.Value(tree.source, "(function(")
if AST.is_syntax_tree(\%args, "Action") then \%args = \%args:get_args() end
- local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and tostring(nomsu:compile(a)) or a end)
+ local lua_args = table.map(\%args, function(a) return AST.is_syntax_tree(a) and nomsu:compile(a):as_smext() or a end)
lua:concat_append(lua_args, ", ")
local body_lua = AST.is_syntax_tree(\%body) and nomsu:compile(\%body):as_statements("return ") or \%body
body_lua:remove_free_vars(lua_args)
@@ -64,14 +64,14 @@ test:
assume (%tmp is (nil)) or barf "compile to is leaking variables"
lua> "\
..COMPILE_ACTIONS["compile 1 to 2"] = function(nomsu, tree, \%actions, \%body)
- local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(\
- ..a)) end))}
+ local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(\
+ ..a):as_smext() end))}
local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", \%actions[1].stub:as_lua(),
"] = ", \(compile as (%args -> %body)))
for i=2,#\%actions do
local alias = \%actions[i]
- local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(\
- ..a)) end))}
+ local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return nomsu:compile(\
+ ..a):as_smext() end))}
lua:append("\\nCOMPILE_ACTIONS[", alias.stub:as_lua(), "] = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append("COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "]")
@@ -114,14 +114,14 @@ test:
compile [local action %actions %body] to:
lua> "\
..local fn_name = \%actions[1].stub:as_lua_id()
- local \%args = table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ local \%args = table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):as_smext() end)
local lua = LuaCode(tree.source, fn_name, " = ", \(compile as (%args -> %body)))
lua:add_free_vars({fn_name})
for i=2,#\%actions do
local alias = \%actions[i]
local alias_name = alias.stub:as_lua_id()
lua:add_free_vars({alias_name})
- local \%alias_args = table.map(alias:get_args(), function(a) return tostring(nomsu:compile(a)) end)
+ local \%alias_args = table.map(alias:get_args(), function(a) return nomsu:compile(a):as_smext() end)
lua:append("\\n", alias_name, " = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append(fn_name)
@@ -170,7 +170,7 @@ compile [parse %actions as %body] to (..)
lua> "\
..local replacements = {}
for i,arg in ipairs(\%actions[1]:get_args()) do
- replacements[arg[1]] = tostring(nomsu:compile(arg))
+ replacements[arg[1]] = nomsu:compile(arg):as_smext()
end
local function make_tree(t)
if AST.is_syntax_tree(t, "Var") then
@@ -239,7 +239,7 @@ action [%var as lua identifier, %var as lua id] (..)
elseif AST.is_syntax_tree(\%var, 'Var') then return \%var[1]:as_lua_id()
elseif AST.is_syntax_tree(\%var) then
local lua = \(%var as lua expr)
- if not tostring(lua):match("^[_a-zA-Z][_a-zA-Z0-9]*$") then
+ if not lua:as_smext():match("^[_a-zA-Z][_a-zA-Z0-9]*$") then
nomsu:compile_error(\%var, "This is not a valid Lua identifier.")
end
return lua
diff --git a/core/operators.nom b/core/operators.nom
index 3ae7c2f..960440e 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -34,7 +34,7 @@ compile [%var = %value] to:
lua> "\
..local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';')
if \%var.type == 'Var' then
- lua:add_free_vars({tostring(nomsu:compile(\%var))})
+ lua:add_free_vars({nomsu:compile(\%var):as_smext()})
end
return lua"
@@ -66,7 +66,7 @@ compile [set %assignments] to:
%value as text
..) end
if \%target.type == "Var" then
- lhs:add_free_vars({tostring(target_lua)})
+ lhs:add_free_vars({target_lua:as_smext()})
end
if i > 1 then
lhs:append(", ")
@@ -107,7 +107,7 @@ test:
compile [with external %externs %body] to:
%body_lua = (%body as lua statements)
lua> "\
- ..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return tostring(nomsu:compile(v)) end))"
+ ..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return nomsu:compile(v):as_smext() end))"
return %body_lua
test:
@@ -141,7 +141,7 @@ compile [with %assignments %body] to:
lhs:append(target_lua)
rhs:append(value_lua)
if \%target.type == "Var" then
- vars[i] = tostring(target_lua)
+ vars[i] = target_lua:as_smext()
end
end
\%lua:remove_free_vars(vars)
diff --git a/nomnom/ast.nom b/nomnom/ast.nom
index da1d0c4..377f4ae 100644
--- a/nomnom/ast.nom
+++ b/nomnom/ast.nom
@@ -16,6 +16,8 @@ object (Syntax Tree):
%stub_bits::add "\%argnum"
%argnum += 1
%me.stub = (%stub_bits::joined with " ")
+ if (%me.stub == "Lua Code 1 2"):
+ lua> "require('ldt').breakpoint()"
(Syntax Tree).source_code_for_tree = (..)
{} with fallback % -> (read file %.source.filename)
@@ -86,3 +88,4 @@ object (Syntax Tree):
%args::add %
return %args
+(Syntax Tree).map = (Syntax Tree).map_1
diff --git a/nomnom/code_obj.nom b/nomnom/code_obj.nom
index 7ff1b23..f573599 100644
--- a/nomnom/code_obj.nom
+++ b/nomnom/code_obj.nom
@@ -14,11 +14,10 @@ object (Code):
for % in %old_bits:
%me::add %
- %depth = 0
my action [as text]:
- external %depth = (%depth + 1)
- if (%depth > 10):
- lua> "require('ldt').breakpoint()"
+ barf "Not implemented"
+
+ my action [as smext]:
if (%me.__str == (nil)):
set {%buff:[], %indent:0}
for %bit in %me.bits:
@@ -26,21 +25,21 @@ object (Code):
%spaces = (%bit::matching "\n([ ]*)[^\n]*$")
if %spaces: %indent = (size of %spaces.1)
..else:
- %bit = "\%bit"
+ %bit = (%bit::as smext)
if (%indent > 0):
%bit = (%bit::with "\n" -> "\n\(" "::* %indent)")
%buff::add %bit
%me.__str = (%buff::joined)
- external %depth = (%depth - 1)
return %me.__str
- my action [as lua] (..)
- "\(%me.class.name::as lua id)_1_2(\(%me.source::as lua), \(%me.bits::as lua))"
+ my action [as lua]:
+ barf
+ return "\(%me.class.name::as lua id)_from_1_2(\(%me.source::as lua), \(%me.bits::as lua))"
my action [as nomsu] (..)
"(\(%me.class.name) \(%me.source::as nomsu) \(%me.bits::as nomsu))"
- my action [size] (size of "\%me")
+ my action [size] (size of (%me::as smext))
my action [mark as dirty]:
%me.__str = (nil)
@@ -52,14 +51,14 @@ object (Code):
%new_bits = [%new_bits]
for % in %new_bits:
if (% == ""): do next %
- if ((% isn't text) and (% isn't a (Code))):
+ #if ((% isn't text) and (% isn't a (Code))):
% = (%::as lua)
%me.bits::add %
%me::mark as dirty
my action [trailing line length]:
if (%me._trailing_line_len == (nil)):
- %me._trailing_line_len = (size of ("\%me"::matching "[^\n]*$"))
+ %me._trailing_line_len = (size of ((%me::as smext)::matching "[^\n]*$"))
return %me._trailing_line_len
my action [number of lines]:
@@ -83,7 +82,6 @@ object (Code):
%line_len = 0
%bits = %me.bits
for %value in %values at %i:
- assume (%value != %me)
if (%i > 1):
if (%line_len > 80):
%bits::add %wrapping_joiner
@@ -91,7 +89,9 @@ object (Code):
..else:
%bits::add %joiner
%bits::add %value
- %line = ("\%value"::matching "\n([^\n]*)$")
+ unless (%value is text):
+ %value = (%value::as smext)
+ %line = (%value::matching "\n([^\n]*)$")
if %line:
%line_len = (size of %line)
..else:
@@ -99,7 +99,7 @@ object (Code):
%me::mark as dirty
my action [prepend %]:
- if ((% isn't text) and (% isn't a %me.__type)):
+ #if ((% isn't text) and (% isn't a %me.__type)):
% = (%::as lua)
%me.bits::add % at index 1
%me::mark as dirty
@@ -129,29 +129,30 @@ object (Lua Code) extends (Code):
%removals.%var = (yes)
%stack = [%me]
- while ((size of %stack) > 0):
+ repeat while ((size of %stack) > 0):
%lua = (%stack::pop)
for %i in (size of %lua.free_vars) to 1 by -1:
- if %removals.(%lua.%free_vars.%i):
- %lua.free_vars::remove index %i
+ if %removals.(%lua.free_vars.%i):
+ lua> "table.remove(\%lua.free_vars, \%i)"
+ #TODO: reinstate this
+ #%lua.free_vars::remove at index %i
for % in %lua.bits:
- if (% is a "Lua Code"):
+ unless (% is text):
%stack::add %
%me::mark as dirty
- my action [declare locals]:
- set {%to_declare:[], %seen:{}}
- for %lua in recursive %me:
- for %var in %lua.free_vars:
- unless %seen.%var:
- %seen.%var = (yes)
- %to_declare::add %var
- for % in %lua.bits:
- if (% is a "Lua Code"):
- recurse %lua on %
- return (%me::declare locals %to_declare)
-
+ my action [declare locals] (%me::declare locals (nil))
my action [declare locals %to_declare]:
+ unless %to_declare:
+ set {%to_declare:[], %seen:{}}
+ for %lua in recursive %me:
+ for %var in %lua.free_vars:
+ unless %seen.%var:
+ %seen.%var = (yes)
+ %to_declare::add %var
+ for % in %lua.bits:
+ unless (% is text):
+ recurse %lua on %
if ((size of %to_declare) > 0):
%me::remove free vars %to_declare
%me::prepend "local \(%to_declare::joined with ", ");\n"
@@ -163,11 +164,11 @@ object (Lua Code) extends (Code):
unless %me.is_value:
return %me
%statements = (Lua Code from %me.source [])
- if (%prefix != ""):
+ if ((%prefix or "") != ""):
%statements::add %prefix
%statements::add %me
if (%suffix != ""):
- %statements::add %suffix
+ %statements::add (%suffix or ";")
return %statements
action [Lua Code from %source %bits]:
@@ -176,12 +177,17 @@ object (Lua Code) extends (Code):
return (..)
Lua Code {source:%source, bits:%bits, is_value:(no), free_vars:[]}
action [Lua Code from %source] (Lua Code from %source [])
- action [Lua Value from %tree %bits]:
+ action [Lua Value from %source %bits]:
if (%bits is text): %bits = [%bits]
if (%source is a "Syntax Tree"): %source = %source.source
return (..)
Lua Code {source:%source, bits:%bits, is_value:(yes), free_vars:[]}
- action [Lua Value from %tree] (Lua Value from %tree [])
+ action [Lua Value from %source] (Lua Value from %source [])
+
+(Lua Code).add_free_vars = (Lua Code).add_free_vars_1
+(Lua Code).remove_free_vars = (Lua Code).remove_free_vars_1
+(Lua Code).declare_locals = (Lua Code).declare_locals_1
+(Lua Code).as_statements = (Lua Code).as_statements_1_2
object (Nomsu Code) extends (Code):
action [Nomsu Code from %source %bits]:
diff --git a/nomnom/compile.nom b/nomnom/compile.nom
index 19daa6a..64465bd 100644
--- a/nomnom/compile.nom
+++ b/nomnom/compile.nom
@@ -4,6 +4,7 @@ use "nomnom/code_obj.nom"
use "nomnom/parser.nom"
use "nomnom/pretty_errors.nom"
+# TODO: use pretty_errors
local action [report compile error at %pos %err]:
barf "Compile error at \%pos: \%err"
@@ -23,7 +24,9 @@ action [compile %tree using %compile_actions]:
%compile_action = %compile_actions.%stub
# Don't apply compiler actions to methods
if (%compile_action and (not %tree.target)):
- %args = ["tree", "compile_actions"]
+ # TODO: restore this:
+ #%args = [%tree, %compile_actions]
+ %args = [%nomsu, %tree]
for % in (%tree::get args): %args::add %
%result = (call %compile_action with %args)
if (%result == (nil)):
@@ -43,7 +46,7 @@ action [compile %tree using %compile_actions]:
%lua = (Lua Value from %tree)
if %tree.target: # Method call
%target_lua = (compile %tree.target using %compile_actions)
- if (("\%target_lua"::matches "^%(.*%)$") or ("\%target_lua"::matches "^[_a-zA-Z][_a-zA-Z0-9]*$")):
+ if (((%target_lua::as smext)::matches "^%(.*%)$") or ((%target_lua::as smext)::matches "^[_a-zA-Z][_a-zA-Z0-9]*$")):
%lua::add [%target_lua, ":"]
..else:
%lua::add ["(", %target_lua, "):"]
@@ -51,12 +54,13 @@ action [compile %tree using %compile_actions]:
%args = []
for %tok in %tree at %i:
if (%tok is text): do next %tok
- # TODO: maybe translate Lua comments
- if (%tok.type == "Comment"): do next %tok
+ # TODO: maybe don't translate Lua comments
+ #if (%tok.type == "Comment"): do next %tok
if (%tok.type == "Block"):
- %values = (..)
- (compile %line using %compile_actions) for %line in %tok
- ..unless (%line.type == "Comment")
+ %values = []
+ for %line in %tok:
+ #unless (%line.type == "Comment"):
+ %values::add (compile %line using %compile_actions)
if all of (%.is_value for % in %values):
if ((size of %values) == 1):
%arg_lua = %values.1
@@ -153,11 +157,11 @@ action [compile %tree using %compile_actions]:
unless %value_lua.is_value:
report compile error at %tree.2 "\
..Can't use this as a dict value, since it's not an expression."
- %key_str = ("\%key_lua"::matching "^[\"']([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
+ %key_str = ((%key_lua::as smext)::matching "^[\"']([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
if:
%key_str:
return (Lua Code from %tree [%key_str, "=", %value_lua])
- ("\%key_lua".1 == "["):
+ ((%key_lua::as smext).1 == "["):
# NOTE: this *must* use a space after the [ to avoid freaking out
Lua's parser if the inner expression is a long string. Lua
parses x[[[y]]] as x("[y]"), not as x["y"]
@@ -170,7 +174,7 @@ action [compile %tree using %compile_actions]:
unless %lua.is_value:
report compile error at %tree.1 "\
..Can't index into this, since it's not an expression."
- %first_char = "\%lua".1
+ %first_char = (%lua::as smext).1
if (any of [%first_char == "{", %first_char == "\"", %first_char == "["]):
%lua::parenthesize
@@ -180,7 +184,7 @@ action [compile %tree using %compile_actions]:
unless %key_lua.is_value:
report compile error at %key "\
..Can't use this as an index, since it's not an expression."
- %key_lua_str = "\%key_lua"
+ %key_lua_str = (%key_lua::as smext)
%lua_id = (%key_lua_str::matching "^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
if:
%lua_id:
@@ -206,8 +210,8 @@ action [compile %tree using %compile_actions]:
..compilation depends on the earlier chunks"
"Comment":
- # TODO: implement?
- return (Lua Code from %tree)
+ # TODO: de-implement?
+ return (Lua Code from %tree "-- \(%tree.1::with "\n" -> "\n-- ")")
"Error":
barf "Can't compile errors"
diff --git a/nomnom/decompile.nom b/nomnom/decompile.nom
index e002f61..58679a2 100644
--- a/nomnom/decompile.nom
+++ b/nomnom/decompile.nom
@@ -266,7 +266,7 @@ action [decompile %tree]:
(((size of %line) > 10) and ((%nomsu::trailing line length) > %max_line)):
%nomsu::add "\\\n.."
- while ((size of %line) > 0):
+ repeat while ((size of %line) > 0):
%space = (%max_line - (%nomsu::trailing line length))
%split = (%line::position of "[%p%s]" after %space)
if ((not %split) or (%split > %space + 10)):
diff --git a/nomnom/parser.nom b/nomnom/parser.nom
index ef06e08..0be394c 100644
--- a/nomnom/parser.nom
+++ b/nomnom/parser.nom
@@ -30,7 +30,7 @@ set {..}
Tree: [%t, %userdata] ->:
%source = (..)
Source {filename:%userdata.filename, start:%t.start, stop:%t.stop}
- set {%t.start: nil, %t.stop: nil}
+ set {%t.start: nil, %t.stop: nil, %t.source: %source}
%t = (Syntax Tree %t)
(Syntax Tree).source_code_for_tree.%t = %userdata.source
return %t
diff --git a/syntax_tree.moon b/syntax_tree.moon
index d2f5d37..926ea09 100644
--- a/syntax_tree.moon
+++ b/syntax_tree.moon
@@ -6,7 +6,7 @@ unpack or= table.unpack
AST = {}
AST.is_syntax_tree = (n, t=nil)->
- type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) and (t == nil or n.type == t)
+ type(n) == 'table' and getmetatable(n) and getmetatable(n).__type == "Syntax Tree" and (t == nil or n.type == t)
as_lua = =>
if type(@) == 'number'
@@ -25,6 +25,7 @@ for name in *types
.__index = cls
.__name = name
.type = name
+ .__type = "Syntax Tree"
.is_instance = (x)=> getmetatable(x) == @
.__tostring = =>
bits = [tostring(b) for b in *@]