Got rid of repr() use and replaced with :as_lua() or :as_nomsu() in as

many places as possible.
This commit is contained in:
Bruce Hill 2018-09-18 19:48:58 -07:00
parent d11f9bc5d3
commit 79d4bd5125
17 changed files with 312 additions and 85 deletions

View File

@ -3,8 +3,6 @@ do
local _obj_0 = table local _obj_0 = table
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end end
local repr
repr = require('utils').repr
local unpack = unpack or table.unpack local unpack = unpack or table.unpack
local LuaCode, NomsuCode, Source local LuaCode, NomsuCode, Source
do do
@ -13,8 +11,8 @@ do
__tostring = function(self) __tostring = function(self)
return "@" .. tostring(self.filename) .. "[" .. tostring(self.start) .. tostring(self.stop and ':' .. self.stop or '') .. "]" return "@" .. tostring(self.filename) .. "[" .. tostring(self.start) .. tostring(self.stop and ':' .. self.stop or '') .. "]"
end, end,
__repr = function(self) as_lua = function(self)
return "Source(" .. tostring(repr(self.filename)) .. ", " .. tostring(self.start) .. tostring(self.stop and ', ' .. self.stop or '') .. ")" return "Source(" .. tostring(self.filename:as_lua()) .. ", " .. tostring(self.start) .. tostring(self.stop and ', ' .. self.stop or '') .. ")"
end, end,
__eq = function(self, other) __eq = function(self, other)
return getmetatable(self) == getmetatable(other) and self.filename == other.filename and self.start == other.start and self.stop == other.stop return getmetatable(self) == getmetatable(other) and self.filename == other.filename and self.start == other.start and self.stop == other.stop
@ -108,16 +106,16 @@ do
end end
return self.__str return self.__str
end, end,
__repr = function(self) as_lua = function(self)
return tostring(self.__class.__name) .. "(" .. tostring(concat({ return tostring(self.__class.__name) .. "(" .. tostring(concat({
repr(tostring(self.source)), tostring(self.source):as_lua(),
unpack((function() unpack((function()
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 1 local _len_0 = 1
local _list_0 = self.bits local _list_0 = self.bits
for _index_0 = 1, #_list_0 do for _index_0 = 1, #_list_0 do
local b = _list_0[_index_0] local b = _list_0[_index_0]
_accum_0[_len_0] = repr(b) _accum_0[_len_0] = b:as_lua()
_len_0 = _len_0 + 1 _len_0 = _len_0 + 1
end end
return _accum_0 return _accum_0
@ -158,7 +156,7 @@ do
b.dirty = error b.dirty = error
end end
if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then
b = repr(b) b = b:as_lua()
end end
bits[#bits + 1] = b bits[#bits + 1] = b
_continue_0 = true _continue_0 = true
@ -236,7 +234,7 @@ do
b.dirty = error b.dirty = error
end end
if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then
b = repr(b) b = b:as_lua()
end end
bits[i] = b bits[i] = b
end end
@ -276,7 +274,7 @@ do
local _parent_0 = Code local _parent_0 = Code
local _base_0 = { local _base_0 = {
__tostring = Code.__tostring, __tostring = Code.__tostring,
__repr = Code.__repr, as_lua = Code.as_lua,
__len = Code.__len, __len = Code.__len,
add_free_vars = function(self, vars) add_free_vars = function(self, vars)
if not (#vars > 0) then if not (#vars > 0) then
@ -469,7 +467,7 @@ do
local _parent_0 = Code local _parent_0 = Code
local _base_0 = { local _base_0 = {
__tostring = Code.__tostring, __tostring = Code.__tostring,
__repr = Code.__repr, as_lua = Code.as_lua,
__len = Code.__len __len = Code.__len
} }
_base_0.__index = _base_0 _base_0.__index = _base_0

View File

@ -2,7 +2,6 @@
-- build up generated code, while keeping track of where it came from, and managing -- build up generated code, while keeping track of where it came from, and managing
-- indentation levels. -- indentation levels.
{:insert, :remove, :concat} = table {:insert, :remove, :concat} = table
{:repr} = require 'utils'
unpack or= table.unpack unpack or= table.unpack
local LuaCode, NomsuCode, Source local LuaCode, NomsuCode, Source
@ -19,7 +18,7 @@ class Source
__tostring: => "@#{@filename}[#{@start}#{@stop and ':'..@stop or ''}]" __tostring: => "@#{@filename}[#{@start}#{@stop and ':'..@stop or ''}]"
__repr: => "Source(#{repr @filename}, #{@start}#{@stop and ', '..@stop or ''})" as_lua: => "Source(#{@filename\as_lua!}, #{@start}#{@stop and ', '..@stop or ''})"
__eq: (other)=> __eq: (other)=>
getmetatable(@) == getmetatable(other) and @filename == other.filename and @start == other.start and @stop == other.stop getmetatable(@) == getmetatable(other) and @filename == other.filename and @start == other.start and @stop == other.stop
@ -67,8 +66,8 @@ class Code
@__str = concat(buff, "") @__str = concat(buff, "")
return @__str return @__str
__repr: => as_lua: =>
"#{@__class.__name}(#{concat {repr(tostring(@source)), unpack([repr(b) for b in *@bits])}, ", "})" "#{@__class.__name}(#{concat {tostring(@source)\as_lua!, unpack([b\as_lua! for b in *@bits])}, ", "})"
__len: => #tostring(@) __len: => #tostring(@)
@ -93,7 +92,7 @@ class Code
if b == '' then continue if b == '' then continue
b.dirty = error if b.is_code b.dirty = error if b.is_code
if type(b) != 'string' and not (type(b) == 'table' and b.is_code) if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
b = repr(b) b = b\as_lua!
bits[#bits+1] = b bits[#bits+1] = b
@dirty! @dirty!
@ -148,7 +147,7 @@ class Code
b = select(i, ...) b = select(i, ...)
b.dirty = error if b.is_code b.dirty = error if b.is_code
if type(b) != 'string' and not (type(b) == 'table' and b.is_code) if type(b) != 'string' and not (type(b) == 'table' and b.is_code)
b = repr(b) b = b\as_lua!
bits[i] = b bits[i] = b
@dirty! @dirty!
@ -158,7 +157,7 @@ class Code
class LuaCode extends Code class LuaCode extends Code
__tostring: Code.__tostring __tostring: Code.__tostring
__repr: Code.__repr as_lua: Code.as_lua
__len: Code.__len __len: Code.__len
new: (...)=> new: (...)=>
super ... super ...
@ -253,7 +252,7 @@ class LuaCode extends Code
class NomsuCode extends Code class NomsuCode extends Code
__tostring: Code.__tostring __tostring: Code.__tostring
__repr: Code.__repr as_lua: Code.as_lua
__len: Code.__len __len: Code.__len
Code.__base.append_1 = assert Code.__base.append Code.__base.append_1 = assert Code.__base.append

View File

@ -3,14 +3,50 @@ do
local _obj_0 = table local _obj_0 = table
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end end
local repr, stringify, equivalent, nth_to_last, size local equivalent, nth_to_last, size
do do
local _obj_0 = require('utils') local _obj_0 = require('utils')
repr, stringify, equivalent, nth_to_last, size = _obj_0.repr, _obj_0.stringify, _obj_0.equivalent, _obj_0.nth_to_last, _obj_0.size equivalent, nth_to_last, size = _obj_0.equivalent, _obj_0.nth_to_last, _obj_0.size
end end
local lpeg = require('lpeg') local lpeg = require('lpeg')
local re = require('re') local re = require('re')
local List, Dict local List, Dict
local as_nomsu
as_nomsu = function(self)
if type(self) == 'number' then
return tostring(self)
end
do
local mt = getmetatable(self)
if mt then
do
local _as_nomsu = mt.as_nomsu
if _as_nomsu then
return _as_nomsu(self)
end
end
end
end
return error("Not supported: " .. tostring(self))
end
local as_lua
as_lua = function(self)
if type(self) == 'number' then
return tostring(self)
end
do
local mt = getmetatable(self)
if mt then
do
local _as_lua = mt.as_lua
if _as_lua then
return _as_lua(self)
end
end
end
end
return error("Not supported: " .. tostring(self))
end
local _list_mt = { local _list_mt = {
__eq = equivalent, __eq = equivalent,
__tostring = function(self) __tostring = function(self)
@ -19,12 +55,36 @@ local _list_mt = {
local _len_0 = 1 local _len_0 = 1
for _index_0 = 1, #self do for _index_0 = 1, #self do
local b = self[_index_0] local b = self[_index_0]
_accum_0[_len_0] = repr(b) _accum_0[_len_0] = tostring(b)
_len_0 = _len_0 + 1 _len_0 = _len_0 + 1
end end
return _accum_0 return _accum_0
end)(), ", ") .. "]" end)(), ", ") .. "]"
end, end,
as_nomsu = function(self)
return "[" .. concat((function()
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #self do
local b = self[_index_0]
_accum_0[_len_0] = as_nomsu(b)
_len_0 = _len_0 + 1
end
return _accum_0
end)(), ", ") .. "]"
end,
as_lua = function(self)
return "_List{" .. concat((function()
local _accum_0 = { }
local _len_0 = 1
for _index_0 = 1, #self do
local b = self[_index_0]
_accum_0[_len_0] = as_lua(b)
_len_0 = _len_0 + 1
end
return _accum_0
end)(), ", ") .. "}"
end,
__lt = function(self, other) __lt = function(self, other)
assert(type(self) == 'table' and type(other) == 'table', "Incompatible types for comparison") assert(type(self) == 'table' and type(other) == 'table', "Incompatible types for comparison")
for i = 1, math.max(#self, #other) do for i = 1, math.max(#self, #other) do
@ -162,7 +222,29 @@ local _dict_mt = {
local _accum_0 = { } local _accum_0 = { }
local _len_0 = 1 local _len_0 = 1
for k, v in pairs(self) do for k, v in pairs(self) do
_accum_0[_len_0] = tostring(repr(k)) .. ": " .. tostring(repr(v)) _accum_0[_len_0] = tostring(tostring(k)) .. ": " .. tostring(tostring(v))
_len_0 = _len_0 + 1
end
return _accum_0
end)(), ", ") .. "}"
end,
as_nomsu = function(self)
return "{" .. concat((function()
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(self) do
_accum_0[_len_0] = tostring(as_nomsu(k)) .. ": " .. tostring(as_nomsu(v))
_len_0 = _len_0 + 1
end
return _accum_0
end)(), ", ") .. "}"
end,
as_lua = function(self)
return "_Dict{" .. concat((function()
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(self) do
_accum_0[_len_0] = "[ " .. tostring(as_lua(k)) .. "]= " .. tostring(as_lua(v))
_len_0 = _len_0 + 1 _len_0 = _len_0 + 1
end end
return _accum_0 return _accum_0

View File

@ -1,19 +1,39 @@
-- This file contains container classes, i.e. Lists, Dicts, and Sets -- This file contains container classes, i.e. Lists, Dicts, and Sets
{:insert,:remove,:concat} = table {:insert,:remove,:concat} = table
{:repr, :stringify, :equivalent, :nth_to_last, :size} = require 'utils' {:equivalent, :nth_to_last, :size} = require 'utils'
lpeg = require 'lpeg' lpeg = require 'lpeg'
re = require 're' re = require 're'
local List, Dict local List, Dict
as_nomsu = =>
if type(@) == 'number'
return tostring(@)
if mt = getmetatable(@)
if _as_nomsu = mt.as_nomsu
return _as_nomsu(@)
error("Not supported: #{@}")
as_lua = =>
if type(@) == 'number'
return tostring(@)
if mt = getmetatable(@)
if _as_lua = mt.as_lua
return _as_lua(@)
error("Not supported: #{@}")
-- List and Dict classes to provide basic equality/tostring functionality for the tables -- List and Dict classes to provide basic equality/tostring functionality for the tables
-- used in Nomsu. This way, they retain a notion of whether they were originally lists or dicts. -- used in Nomsu. This way, they retain a notion of whether they were originally lists or dicts.
_list_mt = _list_mt =
__eq:equivalent __eq:equivalent
-- Could consider adding a __newindex to enforce list-ness, but would hurt performance -- Could consider adding a __newindex to enforce list-ness, but would hurt performance
__tostring: => __tostring: =>
"["..concat([repr(b) for b in *@], ", ").."]" "["..concat([tostring(b) for b in *@], ", ").."]"
as_nomsu: =>
"["..concat([as_nomsu(b) for b in *@], ", ").."]"
as_lua: =>
"_List{"..concat([as_lua(b) for b in *@], ", ").."}"
__lt: (other)=> __lt: (other)=>
assert type(@) == 'table' and type(other) == 'table', "Incompatible types for comparison" assert type(@) == 'table' and type(other) == 'table', "Incompatible types for comparison"
for i=1,math.max(#@, #other) for i=1,math.max(#@, #other)
@ -74,7 +94,11 @@ _dict_mt =
__eq:equivalent __eq:equivalent
__len:size __len:size
__tostring: => __tostring: =>
"{"..concat(["#{repr(k)}: #{repr(v)}" for k,v in pairs @], ", ").."}" "{"..concat(["#{tostring(k)}: #{tostring(v)}" for k,v in pairs @], ", ").."}"
as_nomsu: =>
"{"..concat(["#{as_nomsu(k)}: #{as_nomsu(v)}" for k,v in pairs @], ", ").."}"
as_lua: =>
"_Dict{"..concat(["[ #{as_lua(k)}]= #{as_lua(v)}" for k,v in pairs @], ", ").."}"
__ipairs: => walk_items, {table:@, key:nil}, 0 __ipairs: => walk_items, {table:@, key:nil}, 0
__band: (other)=> __band: (other)=>
Dict{k,v for k,v in pairs(@) when other[k] != nil} Dict{k,v for k,v in pairs(@) when other[k] != nil}

View File

@ -149,6 +149,8 @@ test:
assume ("\%t" == "XXX") assume ("\%t" == "XXX")
compile [set %dict 's metatable to %metatable] to (..) compile [set %dict 's metatable to %metatable] to (..)
Lua "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));" Lua "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
compile [%'s metatable, %' metatable] to (..)
Lua value "getmetatable(\(% as lua expr))"
test: test:
assume (({} with fallback % -> (% + 1)).10 == 11) assume (({} with fallback % -> (% + 1)).10 == 11)

View File

@ -34,7 +34,7 @@ lua> "\
lua> "\ lua> "\
..COMPILE_ACTIONS["compile as 1"] = function(nomsu, tree, \%action) ..COMPILE_ACTIONS["compile as 1"] = function(nomsu, tree, \%action)
local lua = LuaCode.Value(tree.source, "COMPILE_ACTIONS[", repr(\%action.stub), "](") local lua = LuaCode.Value(tree.source, "COMPILE_ACTIONS[", \%action.stub:as_lua(), "](")
local lua_args = table.map(\%action:get_args(), function(a) return nomsu:compile(a) end) local lua_args = table.map(\%action:get_args(), function(a) return nomsu:compile(a) end)
table.insert(lua_args, 1, "nomsu") table.insert(lua_args, 1, "nomsu")
table.insert(lua_args, 2, "tree") table.insert(lua_args, 2, "tree")
@ -66,19 +66,19 @@ lua> "\
..COMPILE_ACTIONS["compile 1 to 2"] = function(nomsu, tree, \%actions, \%body) ..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(\ local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return tostring(nomsu:compile(\
..a)) end))} ..a)) end))}
local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", repr(\%actions[1].stub), local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", \%actions[1].stub:as_lua(),
"] = ", \(compile as (%args -> %body))) "] = ", \(compile as (%args -> %body)))
for i=2,#\%actions do for i=2,#\%actions do
local alias = \%actions[i] local alias = \%actions[i]
local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(\ local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return tostring(nomsu:compile(\
..a)) end))} ..a)) end))}
lua:append("\\nCOMPILE_ACTIONS[", repr(alias.stub), "] = ") lua:append("\\nCOMPILE_ACTIONS[", alias.stub:as_lua(), "] = ")
if utils.equivalent(\%args, \%alias_args) then if utils.equivalent(\%args, \%alias_args) then
lua:append("COMPILE_ACTIONS[", repr(\%actions[1].stub), "]") lua:append("COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "]")
else else
lua:append("function(") lua:append("function(")
lua:concat_append(\%alias_args, ", ") lua:concat_append(\%alias_args, ", ")
lua:append(")\\n return COMPILE_ACTIONS[", repr(\%actions[1].stub), "](") lua:append(")\\n return COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "](")
lua:concat_append(\%args, ", ") lua:concat_append(\%args, ", ")
lua:append(")\\nend") lua:append(")\\nend")
end end
@ -173,7 +173,7 @@ compile [parse %actions as %body] to (..)
if replacements[t[1]] then if replacements[t[1]] then
return replacements[t[1]] return replacements[t[1]]
else else
return t.type.."{mangle("..repr(t[1]).."), source="..repr(tostring(t.source)).."}" return t.type.."{mangle("..t[1]:as_lua().."), source="..tostring(t.source):as_lua().."}"
end end
elseif AST.is_syntax_tree(t) then elseif AST.is_syntax_tree(t) then
local ret = {} local ret = {}
@ -183,7 +183,7 @@ compile [parse %actions as %body] to (..)
ret[#ret+1] = make_tree(t[i]) ret[#ret+1] = make_tree(t[i])
i = i + 1 i = i + 1
elseif k == "source" then elseif k == "source" then
ret[#ret+1] = k.."= "..repr(tostring(v)) ret[#ret+1] = k.."= "..tostring(v):as_lua()
elseif type(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then elseif type(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
ret[#ret+1] = k.."= "..make_tree(v) ret[#ret+1] = k.."= "..make_tree(v)
else else
@ -191,8 +191,10 @@ compile [parse %actions as %body] to (..)
end end
end end
return t.type.."{"..table.concat(ret, ", ").."}" return t.type.."{"..table.concat(ret, ", ").."}"
elseif type(t) == 'number' then
return tostring(t)
else else
return repr(t) return t:as_lua()
end end
end end
local \%new_body = LuaCode(\%body.source, local \%new_body = LuaCode(\%body.source,
@ -257,7 +259,7 @@ action [%tree with vars %replacements] (..)
compile [tree %tree with vars %replacements] to (..) compile [tree %tree with vars %replacements] to (..)
Lua value "\ Lua value "\
..\(=lua "repr(\%tree)"):map(function(t) ..\(=lua "(\%tree):as_lua()"):map(function(t)
if t.type == "Var" then if t.type == "Var" then
return \(%replacements as lua expr)[t[1]] return \(%replacements as lua expr)[t[1]]
end end
@ -312,7 +314,7 @@ test:
..one ..one
"two"" "two""
..== "\"one\\n\\\"two\\\"\"" ..== "\"one\\n\\\"two\\\"\""
compile [quote %s] to (Lua value "repr(\(%s as lua expr))") compile [quote %s] to (Lua value "tostring(\(%s as lua expr)):as_lua()")
test: test:
assume ((type of {}) == "table") or barf "type of failed." assume ((type of {}) == "table") or barf "type of failed."
@ -340,7 +342,7 @@ test:
compile [run %nomsu_code] to (..) compile [run %nomsu_code] to (..)
Lua value "\ Lua value "\
..nomsu:run(NomsuCode(\(..) ..nomsu:run(NomsuCode(\(..)
=lua "repr(tostring(\(%nomsu_code.source)))" =lua "tostring(\(%nomsu_code.source)):as_lua()"
.., \(%nomsu_code as lua expr)))" .., \(%nomsu_code as lua expr)))"
test: test:

View File

@ -46,7 +46,7 @@ compile [my action %actions %body] to:
lua> "\ lua> "\
..local fn_name = \%actions[1].stub:as_lua_id() ..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 tostring(nomsu:compile(a)) end)
table.insert(\%args, \(\%me as lua id)) table.insert(\%args, 1, \(\%me as lua id))
local lua = LuaCode(tree.source, "class.", fn_name, " = ", \(..) local lua = LuaCode(tree.source, "class.", fn_name, " = ", \(..)
compile as (%args -> %body) compile as (%args -> %body)
..) ..)
@ -54,7 +54,7 @@ compile [my action %actions %body] to:
local alias = \%actions[i] local alias = \%actions[i]
local alias_name = alias.stub:as_lua_id() local alias_name = alias.stub:as_lua_id()
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 tostring(nomsu:compile(a)) end)
table.insert(\%alias_args, \(\%me as lua id)) table.insert(\%alias_args, 1, \(\%me as lua id))
lua:append("\\nclass.", alias_name, " = ") lua:append("\\nclass.", alias_name, " = ")
if utils.equivalent(\%args, \%alias_args) then if utils.equivalent(\%args, \%alias_args) then
lua:append("class.", fn_name) lua:append("class.", fn_name)
@ -110,3 +110,9 @@ compile [object %classname extends %parent %class_body] to:
parse [object %classname %class_body] as (..) parse [object %classname %class_body] as (..)
object %classname extends (nil) %class_body object %classname extends (nil) %class_body
parse [%obj is a %class] as (..)
all of [..]
(type of %obj) == "table"
%obj's metatable
(%obj's metatable).__index == %class

View File

@ -91,8 +91,6 @@ do
local _obj_0 = require("code_obj") local _obj_0 = require("code_obj")
NomsuCode, LuaCode, Source = _obj_0.NomsuCode, _obj_0.LuaCode, _obj_0.Source NomsuCode, LuaCode, Source = _obj_0.NomsuCode, _obj_0.LuaCode, _obj_0.Source
end end
local repr
repr = require("utils").repr
if not arg or debug.getinfo(2).func == require then if not arg or debug.getinfo(2).func == require then
return NomsuCompiler return NomsuCompiler
end end
@ -324,7 +322,11 @@ say "\
local ret local ret
ok, ret = xpcall(nomsu.run, err_hand, nomsu, buff, Source(pseudo_filename, 1, #buff)) ok, ret = xpcall(nomsu.run, err_hand, nomsu, buff, Source(pseudo_filename, 1, #buff))
if ok and ret ~= nil then if ok and ret ~= nil then
print("= " .. repr(ret)) if type(ret) == 'number' then
print("= " .. tostring(ret))
else
print("= " .. tostring(ret:as_nomsu()))
end
elseif not ok then elseif not ok then
Errhand.print_error(ret) Errhand.print_error(ret)
end end

View File

@ -48,7 +48,6 @@ Files = require "files"
Errhand = require "error_handling" Errhand = require "error_handling"
NomsuCompiler = require "nomsu_compiler" NomsuCompiler = require "nomsu_compiler"
{:NomsuCode, :LuaCode, :Source} = require "code_obj" {:NomsuCode, :LuaCode, :Source} = require "code_obj"
{:repr} = require "utils"
-- If this file was reached via require(), then just return the Nomsu compiler -- If this file was reached via require(), then just return the Nomsu compiler
if not arg or debug.getinfo(2).func == require if not arg or debug.getinfo(2).func == require
@ -222,7 +221,10 @@ say "\
Errhand.print_error error_message Errhand.print_error error_message
ok, ret = xpcall(nomsu.run, err_hand, nomsu, buff, Source(pseudo_filename, 1, #buff)) ok, ret = xpcall(nomsu.run, err_hand, nomsu, buff, Source(pseudo_filename, 1, #buff))
if ok and ret != nil if ok and ret != nil
print "= "..repr(ret) if type(ret) == 'number'
print "= #{ret}"
else
print "= #{ret\as_nomsu!}"
elseif not ok elseif not ok
Errhand.print_error ret Errhand.print_error ret

View File

@ -4,8 +4,8 @@ R, P, S = lpeg.R, lpeg.P, lpeg.S
local re = require('re') local re = require('re')
local utils = require('utils') local utils = require('utils')
local Files = require('files') local Files = require('files')
local repr, stringify, equivalent local stringify, equivalent
repr, stringify, equivalent = utils.repr, utils.stringify, utils.equivalent stringify, equivalent = utils.stringify, utils.equivalent
local List, Dict, Text local List, Dict, Text
do do
local _obj_0 = require('containers') local _obj_0 = require('containers')
@ -193,7 +193,6 @@ do
ipairs = ipairs, ipairs = ipairs,
_List = List, _List = List,
_Dict = Dict, _Dict = Dict,
repr = repr,
stringify = stringify, stringify = stringify,
utils = utils, utils = utils,
lpeg = lpeg, lpeg = lpeg,
@ -385,7 +384,7 @@ do
add_lua_string_bits = function(self, val_or_stmt, code) add_lua_string_bits = function(self, val_or_stmt, code)
local cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode(" local cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode("
if code.type ~= "Text" then if code.type ~= "Text" then
return LuaCode.Value(code.source, cls_str, repr(tostring(code.source)), ", ", self:compile(code), ")") return LuaCode.Value(code.source, cls_str, tostring(code.source):as_lua(), ", ", self:compile(code), ")")
end end
local add_bit_lua local add_bit_lua
add_bit_lua = function(lua, bit_lua) add_bit_lua = function(lua, bit_lua)
@ -395,11 +394,11 @@ do
end end
local operate_on_text local operate_on_text
operate_on_text = function(text) operate_on_text = function(text)
local lua = LuaCode.Value(text.source, cls_str, repr(tostring(text.source))) local lua = LuaCode.Value(text.source, cls_str, tostring(text.source):as_lua())
for _index_0 = 1, #text do for _index_0 = 1, #text do
local bit = text[_index_0] local bit = text[_index_0]
if type(bit) == "string" then if type(bit) == "string" then
add_bit_lua(lua, repr(bit)) add_bit_lua(lua, bit:as_lua())
elseif bit.type == "Text" then elseif bit.type == "Text" then
add_bit_lua(lua, operate_on_text(bit)) add_bit_lua(lua, operate_on_text(bit))
else else
@ -480,13 +479,13 @@ do
end end
return _accum_0 return _accum_0
end)(), "\n") end)(), "\n")
return LuaCode(tree.source, "TESTS[" .. tostring(repr(tostring(tree.source))) .. "] = ", repr(test_str)) return LuaCode(tree.source, "TESTS[" .. tostring(tostring(tree.source):as_lua()) .. "] = ", test_str:as_lua())
end, end,
["is jit"] = function(self, tree, code) ["is jit"] = function(self, tree, code)
return LuaCode.Value(tree.source, jit and "true" or "false") return LuaCode.Value(tree.source, jit and "true" or "false")
end, end,
["Lua version"] = function(self, tree, code) ["Lua version"] = function(self, tree, code)
return LuaCode.Value(tree.source, repr(_VERSION)) return LuaCode.Value(tree.source, _VERSION:as_lua())
end, end,
__parent = setmetatable({ }, { __parent = setmetatable({ }, {
__index = function(self, key) __index = function(self, key)
@ -744,9 +743,9 @@ do
if tok.type == "Block" then if tok.type == "Block" then
self:compile_error(tok, "Can't compile action (" .. tostring(stub) .. ") with a Block as an argument.", "Maybe there should be a compile-time action with that name that isn't being found?") self:compile_error(tok, "Can't compile action (" .. tostring(stub) .. ") with a Block as an argument.", "Maybe there should be a compile-time action with that name that isn't being found?")
elseif tok.type == "Action" then elseif tok.type == "Action" then
self:compile_error(tok, "Can't use this as an argument to (" .. tostring(stub) .. "), since it's not an expression, it produces: " .. tostring(repr(arg_lua)), "Check the implementation of (" .. tostring(tok.stub) .. ") to see if it is actually meant to produce an expression.") self:compile_error(tok, "Can't use this as an argument to (" .. tostring(stub) .. "), since it's not an expression, it produces: " .. tostring(tostring(arg_lua)), "Check the implementation of (" .. tostring(tok.stub) .. ") to see if it is actually meant to produce an expression.")
else else
self:compile_error(tok, "Can't use this as an argument to (" .. tostring(stub) .. "), since it's not an expression, it produces: " .. tostring(repr(arg_lua))) self:compile_error(tok, "Can't use this as an argument to (" .. tostring(stub) .. "), since it's not an expression, it produces: " .. tostring(tostring(arg_lua)))
end end
end end
insert(args, arg_lua) insert(args, arg_lua)
@ -762,6 +761,16 @@ do
elseif "EscapedNomsu" == _exp_0 then elseif "EscapedNomsu" == _exp_0 then
local lua = LuaCode.Value(tree.source, tree[1].type, "{") local lua = LuaCode.Value(tree.source, tree[1].type, "{")
local needs_comma, i = false, 1 local needs_comma, i = false, 1
local as_lua
as_lua = function(x)
if type(x) == 'number' then
return tostring(x)
elseif AST.is_syntax_tree(x) then
return self:compile(x, compile_actions)
else
return x:as_lua()
end
end
for k, v in pairs(AST.is_syntax_tree(tree[1], "EscapedNomsu") and tree or tree[1]) do for k, v in pairs(AST.is_syntax_tree(tree[1], "EscapedNomsu") and tree or tree[1]) do
if needs_comma then if needs_comma then
lua:append(", ") lua:append(", ")
@ -773,12 +782,12 @@ do
elseif type(k) == 'string' and match(k, "[_a-zA-Z][_a-zA-Z0-9]*") then elseif type(k) == 'string' and match(k, "[_a-zA-Z][_a-zA-Z0-9]*") then
lua:append(k, "= ") lua:append(k, "= ")
else else
lua:append("[", (AST.is_syntax_tree(k) and self:compile(k, compile_actions) or repr(k)), "]= ") lua:append("[", as_lua(k), "]= ")
end end
if k == "source" then if k == "source" then
lua:append(repr(tostring(v))) lua:append(tostring(v):as_lua())
else else
lua:append(AST.is_syntax_tree(v) and self:compile(v, compile_actions) or repr(v)) lua:append(as_lua(v))
end end
end end
lua:append("}") lua:append("}")
@ -849,7 +858,7 @@ do
if #lua.bits > 0 then if #lua.bits > 0 then
lua:append("..") lua:append("..")
end end
lua:append(repr(string_buffer)) lua:append(string_buffer:as_lua())
string_buffer = "" string_buffer = ""
end end
local bit_lua = self:compile(bit, compile_actions) local bit_lua = self:compile(bit, compile_actions)
@ -875,7 +884,7 @@ do
if #lua.bits > 0 then if #lua.bits > 0 then
lua:append("..") lua:append("..")
end end
lua:append(repr(string_buffer)) lua:append(string_buffer:as_lua())
end end
if #lua.bits > 1 then if #lua.bits > 1 then
lua:parenthesize() lua:parenthesize()

View File

@ -14,7 +14,7 @@ lpeg = require 'lpeg'
re = require 're' re = require 're'
utils = require 'utils' utils = require 'utils'
Files = require 'files' Files = require 'files'
{:repr, :stringify, :equivalent} = utils {:stringify, :equivalent} = utils
{:List, :Dict, :Text} = require 'containers' {:List, :Dict, :Text} = require 'containers'
export colors, colored export colors, colored
colors = require 'consolecolors' colors = require 'consolecolors'
@ -104,7 +104,7 @@ with NomsuCompiler
-- Nomsu types: -- Nomsu types:
_List:List, _Dict:Dict, _List:List, _Dict:Dict,
-- Utilities and misc. -- Utilities and misc.
repr:repr, stringify:stringify, utils:utils, lpeg:lpeg, re:re, Files:Files, stringify:stringify, utils:utils, lpeg:lpeg, re:re, Files:Files,
:AST, TESTS: Dict{}, globals: Dict{} :AST, TESTS: Dict{}, globals: Dict{}
:LuaCode, :NomsuCode, :Source :LuaCode, :NomsuCode, :Source
nomsu:NomsuCompiler nomsu:NomsuCompiler
@ -202,16 +202,16 @@ with NomsuCompiler
add_lua_string_bits = (val_or_stmt, code)=> add_lua_string_bits = (val_or_stmt, code)=>
cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode(" cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode("
if code.type != "Text" if code.type != "Text"
return LuaCode.Value(code.source, cls_str, repr(tostring(code.source)), ", ", @compile(code), ")") return LuaCode.Value(code.source, cls_str, tostring(code.source)\as_lua!, ", ", @compile(code), ")")
add_bit_lua = (lua, bit_lua)-> add_bit_lua = (lua, bit_lua)->
bit_leading_len = #(bit_lua\match("^[^\n]*")) bit_leading_len = #(bit_lua\match("^[^\n]*"))
lua\append(lua\trailing_line_len! + bit_leading_len > MAX_LINE and ",\n " or ", ") lua\append(lua\trailing_line_len! + bit_leading_len > MAX_LINE and ",\n " or ", ")
lua\append(bit_lua) lua\append(bit_lua)
operate_on_text = (text)-> operate_on_text = (text)->
lua = LuaCode.Value(text.source, cls_str, repr(tostring(text.source))) lua = LuaCode.Value(text.source, cls_str, tostring(text.source)\as_lua!)
for bit in *text for bit in *text
if type(bit) == "string" if type(bit) == "string"
add_bit_lua(lua, repr(bit)) add_bit_lua(lua, bit\as_lua!)
elseif bit.type == "Text" elseif bit.type == "Text"
add_bit_lua(lua, operate_on_text(bit)) add_bit_lua(lua, operate_on_text(bit))
else else
@ -270,13 +270,13 @@ with NomsuCompiler
["tests"]: (tree)=> LuaCode.Value(tree.source, "TESTS") ["tests"]: (tree)=> LuaCode.Value(tree.source, "TESTS")
["test 1"]: (tree, body)=> ["test 1"]: (tree, body)=>
test_str = table.concat [tostring(@tree_to_nomsu(line)) for line in *body], "\n" test_str = table.concat [tostring(@tree_to_nomsu(line)) for line in *body], "\n"
LuaCode tree.source, "TESTS[#{repr(tostring(tree.source))}] = ", repr(test_str) LuaCode tree.source, "TESTS[#{tostring(tree.source)\as_lua!}] = ", test_str\as_lua!
["is jit"]: (tree, code)=> ["is jit"]: (tree, code)=>
return LuaCode.Value(tree.source, jit and "true" or "false") return LuaCode.Value(tree.source, jit and "true" or "false")
["Lua version"]: (tree, code)=> ["Lua version"]: (tree, code)=>
return LuaCode.Value(tree.source, repr(_VERSION)) return LuaCode.Value(tree.source, _VERSION\as_lua!)
__parent: setmetatable({}, { __parent: setmetatable({}, {
__index: (key)=> __index: (key)=>
@ -439,11 +439,11 @@ with NomsuCompiler
elseif tok.type == "Action" elseif tok.type == "Action"
@compile_error tok, @compile_error tok,
"Can't use this as an argument to (#{stub}), since it's not an expression, it produces: #{repr arg_lua}", "Can't use this as an argument to (#{stub}), since it's not an expression, it produces: #{tostring(arg_lua)}",
"Check the implementation of (#{tok.stub}) to see if it is actually meant to produce an expression." "Check the implementation of (#{tok.stub}) to see if it is actually meant to produce an expression."
else else
@compile_error tok, @compile_error tok,
"Can't use this as an argument to (#{stub}), since it's not an expression, it produces: #{repr arg_lua}" "Can't use this as an argument to (#{stub}), since it's not an expression, it produces: #{tostring(arg_lua)}"
insert args, arg_lua insert args, arg_lua
lua\concat_append args, ", " lua\concat_append args, ", "
lua\append ")" lua\append ")"
@ -452,6 +452,13 @@ with NomsuCompiler
when "EscapedNomsu" when "EscapedNomsu"
lua = LuaCode.Value tree.source, tree[1].type, "{" lua = LuaCode.Value tree.source, tree[1].type, "{"
needs_comma, i = false, 1 needs_comma, i = false, 1
as_lua = (x)->
if type(x) == 'number'
tostring(x)
elseif AST.is_syntax_tree(x)
@compile(x, compile_actions)
else x\as_lua!
for k,v in pairs(AST.is_syntax_tree(tree[1], "EscapedNomsu") and tree or tree[1]) for k,v in pairs(AST.is_syntax_tree(tree[1], "EscapedNomsu") and tree or tree[1])
if needs_comma then lua\append ", " if needs_comma then lua\append ", "
else needs_comma = true else needs_comma = true
@ -460,11 +467,11 @@ with NomsuCompiler
elseif type(k) == 'string' and match(k,"[_a-zA-Z][_a-zA-Z0-9]*") elseif type(k) == 'string' and match(k,"[_a-zA-Z][_a-zA-Z0-9]*")
lua\append(k, "= ") lua\append(k, "= ")
else else
lua\append("[", (AST.is_syntax_tree(k) and @compile(k, compile_actions) or repr(k)), "]= ") lua\append("[", as_lua(k), "]= ")
if k == "source" if k == "source"
lua\append repr(tostring(v)) lua\append tostring(v)\as_lua!
else else
lua\append(AST.is_syntax_tree(v) and @compile(v, compile_actions) or repr(v)) lua\append as_lua(v)
lua\append "}" lua\append "}"
return lua return lua
@ -499,9 +506,9 @@ with NomsuCompiler
if type(bit) == "string" if type(bit) == "string"
string_buffer ..= bit string_buffer ..= bit
continue continue
if string_buffer ~= "" if string_buffer != ""
if #lua.bits > 0 then lua\append ".." if #lua.bits > 0 then lua\append ".."
lua\append repr(string_buffer) lua\append string_buffer\as_lua!
string_buffer = "" string_buffer = ""
bit_lua = @compile(bit, compile_actions) bit_lua = @compile(bit, compile_actions)
unless bit_lua.is_value unless bit_lua.is_value
@ -516,7 +523,7 @@ with NomsuCompiler
if string_buffer ~= "" or #lua.bits == 0 if string_buffer ~= "" or #lua.bits == 0
if #lua.bits > 0 then lua\append ".." if #lua.bits > 0 then lua\append ".."
lua\append repr(string_buffer) lua\append string_buffer\as_lua!
if #lua.bits > 1 if #lua.bits > 1
lua\parenthesize! lua\parenthesize!

View File

@ -3,8 +3,6 @@ local re = require('re')
lpeg.setmaxstack(20000) lpeg.setmaxstack(20000)
local P, R, S, C, Cmt, Carg, Cc local P, R, S, C, Cmt, Carg, Cc
P, R, S, C, Cmt, Carg, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cmt, lpeg.Carg, lpeg.Cc P, R, S, C, Cmt, Carg, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cmt, lpeg.Carg, lpeg.Cc
local repr
repr = require('utils').repr
local DEFS local DEFS
do do
local _with_0 = { } local _with_0 = { }

View File

@ -3,7 +3,6 @@ lpeg = require 'lpeg'
re = require 're' re = require 're'
lpeg.setmaxstack 20000 lpeg.setmaxstack 20000
{:P,:R,:S,:C,:Cmt,:Carg,:Cc} = lpeg {:P,:R,:S,:C,:Cmt,:Carg,:Cc} = lpeg
{:repr} = require 'utils'
DEFS = with {} DEFS = with {}
-- Newline supports either windows-style CR+LF or unix-style LF -- Newline supports either windows-style CR+LF or unix-style LF

View File

@ -119,6 +119,24 @@ local string2 = {
end end
return table.concat(lines, "\n") return table.concat(lines, "\n")
end, end,
as_lua = function(self)
local escaped = gsub(self, "\\", "\\\\")
escaped = gsub(escaped, "\n", "\\n")
escaped = gsub(escaped, '"', '\\"')
escaped = gsub(escaped, "[^ %g]", function(c)
return format("\\%03d", byte(c, 1))
end)
return '"' .. escaped .. '"'
end,
as_nomsu = function(self)
local escaped = gsub(self, "\\", "\\\\")
escaped = gsub(escaped, "\n", "\\n")
escaped = gsub(escaped, '"', '\\"')
escaped = gsub(escaped, "[^ %g]", function(c)
return format("\\%03d", byte(c, 1))
end)
return '"' .. escaped .. '"'
end,
as_lua_id = function(str) as_lua_id = function(str)
local orig = str local orig = str
str = gsub(str, "^ *$", "%1 ") str = gsub(str, "^ *$", "%1 ")

View File

@ -45,6 +45,20 @@ string2 = {
lines[#lines+1] = line lines[#lines+1] = line
return table.concat(lines, "\n") return table.concat(lines, "\n")
as_lua: =>
escaped = gsub(@, "\\", "\\\\")
escaped = gsub(escaped, "\n", "\\n")
escaped = gsub(escaped, '"', '\\"')
escaped = gsub(escaped, "[^ %g]", (c)-> format("\\%03d", byte(c, 1)))
return '"'..escaped..'"'
as_nomsu: =>
escaped = gsub(@, "\\", "\\\\")
escaped = gsub(escaped, "\n", "\\n")
escaped = gsub(escaped, '"', '\\"')
escaped = gsub(escaped, "[^ %g]", (c)-> format("\\%03d", byte(c, 1)))
return '"'..escaped..'"'
-- Convert an arbitrary text into a valid Lua identifier. This function is injective, -- Convert an arbitrary text into a valid Lua identifier. This function is injective,
-- but not idempotent. In logic terms: (x != y) => (as_lua_id(x) != as_lua_id(y)), -- but not idempotent. In logic terms: (x != y) => (as_lua_id(x) != as_lua_id(y)),
-- but not (as_lua_id(a) == b) => (as_lua_id(b) == b). -- but not (as_lua_id(a) == b) => (as_lua_id(b) == b).

View File

@ -1,5 +1,3 @@
local repr
repr = require('utils').repr
local insert, remove, concat local insert, remove, concat
do do
local _obj_0 = table local _obj_0 = table
@ -15,6 +13,24 @@ AST.is_syntax_tree = function(n, t)
end end
return type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) and (t == nil or n.type == t) return type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) and (t == nil or n.type == t)
end end
local as_lua
as_lua = function(self)
if type(self) == 'number' then
return tostring(self)
end
do
local mt = getmetatable(self)
if mt then
do
local _as_lua = mt.as_lua
if _as_lua then
return _as_lua(self)
end
end
end
end
return error("Not supported: " .. tostring(self))
end
local types = { local types = {
"Number", "Number",
"Var", "Var",
@ -42,10 +58,42 @@ for _index_0 = 1, #types do
return getmetatable(x) == self return getmetatable(x) == self
end end
cls.__tostring = function(self) cls.__tostring = function(self)
return tostring(self.type) .. tostring(repr(self, (function() end))) local bits
do
local _accum_0 = { }
local _len_0 = 1
for _index_1 = 1, #self do
local b = self[_index_1]
_accum_0[_len_0] = tostring(b)
_len_0 = _len_0 + 1
end
bits = _accum_0
end
for k, v in pairs(self) do
if not (bits[k]) then
table.insert(bits, "[ " .. tostring(tostring(k)) .. "]=" .. tostring(tostring(v)))
end
end
return tostring(self.type) .. "{" .. tostring(table.concat(bits, ", ")) .. "}"
end end
cls.__repr = function(self) cls.as_lua = function(self)
return tostring(self.type) .. tostring(repr(self, (function() end))) local bits
do
local _accum_0 = { }
local _len_0 = 1
for _index_1 = 1, #self do
local b = self[_index_1]
_accum_0[_len_0] = as_lua(b)
_len_0 = _len_0 + 1
end
bits = _accum_0
end
for k, v in pairs(self) do
if not (bits[k]) then
table.insert(bits, "[ " .. tostring(as_lua(k)) .. "]=" .. tostring(as_lua(v)))
end
end
return tostring(self.type) .. "{" .. tostring(table.concat(bits, ", ")) .. "}"
end end
cls.source_code_for_tree = setmetatable({ }, { cls.source_code_for_tree = setmetatable({ }, {
__index = function(self, t) __index = function(self, t)

View File

@ -1,6 +1,5 @@
-- This file contains the datastructures used to represent parsed Nomsu syntax trees, -- This file contains the datastructures used to represent parsed Nomsu syntax trees,
-- as well as the logic for converting them to Lua code. -- as well as the logic for converting them to Lua code.
{:repr} = require 'utils'
{:insert, :remove, :concat} = table {:insert, :remove, :concat} = table
{:Source} = require "code_obj" {:Source} = require "code_obj"
unpack or= table.unpack unpack or= table.unpack
@ -9,6 +8,14 @@ AST = {}
AST.is_syntax_tree = (n, t=nil)-> 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 AST[n.type] == getmetatable(n) and (t == nil or n.type == t)
as_lua = =>
if type(@) == 'number'
return tostring(@)
if mt = getmetatable(@)
if _as_lua = mt.as_lua
return _as_lua(@)
error("Not supported: #{@}")
types = {"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry", types = {"Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry",
"IndexChain", "Action", "FileChunks", "Error", "Comment"} "IndexChain", "Action", "FileChunks", "Error", "Comment"}
for name in *types for name in *types
@ -19,8 +26,18 @@ for name in *types
.__name = name .__name = name
.type = name .type = name
.is_instance = (x)=> getmetatable(x) == @ .is_instance = (x)=> getmetatable(x) == @
.__tostring = => "#{@type}#{repr @, (->)}" .__tostring = =>
.__repr = => "#{@type}#{repr @, (->)}" bits = [tostring(b) for b in *@]
for k,v in pairs(@)
unless bits[k]
table.insert(bits, "[ #{tostring(k)}]=#{tostring(v)}")
return "#{@type}{#{table.concat(bits, ", ")}}"
.as_lua = =>
bits = [as_lua(b) for b in *@]
for k,v in pairs(@)
unless bits[k]
table.insert(bits, "[ #{as_lua(k)}]=#{as_lua(v)}")
return "#{@type}{#{table.concat(bits, ", ")}}"
.source_code_for_tree = setmetatable({}, {__index:(t)=> .source_code_for_tree = setmetatable({}, {__index:(t)=>
s = t.source s = t.source
Files = require 'files' Files = require 'files'