aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code_obj.lua20
-rw-r--r--code_obj.moon15
-rw-r--r--containers.lua90
-rw-r--r--containers.moon30
-rw-r--r--core/collections.nom2
-rw-r--r--core/metaprogramming.nom24
-rw-r--r--lib/object.nom10
-rw-r--r--nomsu.lua8
-rwxr-xr-xnomsu.moon6
-rw-r--r--nomsu_compiler.lua39
-rw-r--r--nomsu_compiler.moon37
-rw-r--r--parser.lua2
-rw-r--r--parser.moon1
-rw-r--r--string2.lua18
-rw-r--r--string2.moon14
-rw-r--r--syntax_tree.lua58
-rw-r--r--syntax_tree.moon23
17 files changed, 312 insertions, 85 deletions
diff --git a/code_obj.lua b/code_obj.lua
index d51d63f..5be92e6 100644
--- a/code_obj.lua
+++ b/code_obj.lua
@@ -3,8 +3,6 @@ do
local _obj_0 = table
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end
-local repr
-repr = require('utils').repr
local unpack = unpack or table.unpack
local LuaCode, NomsuCode, Source
do
@@ -13,8 +11,8 @@ do
__tostring = function(self)
return "@" .. tostring(self.filename) .. "[" .. tostring(self.start) .. tostring(self.stop and ':' .. self.stop or '') .. "]"
end,
- __repr = function(self)
- return "Source(" .. tostring(repr(self.filename)) .. ", " .. tostring(self.start) .. tostring(self.stop and ', ' .. self.stop or '') .. ")"
+ as_lua = function(self)
+ return "Source(" .. tostring(self.filename:as_lua()) .. ", " .. tostring(self.start) .. tostring(self.stop and ', ' .. self.stop or '') .. ")"
end,
__eq = function(self, other)
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
return self.__str
end,
- __repr = function(self)
+ as_lua = function(self)
return tostring(self.__class.__name) .. "(" .. tostring(concat({
- repr(tostring(self.source)),
+ tostring(self.source):as_lua(),
unpack((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = self.bits
for _index_0 = 1, #_list_0 do
local b = _list_0[_index_0]
- _accum_0[_len_0] = repr(b)
+ _accum_0[_len_0] = b:as_lua()
_len_0 = _len_0 + 1
end
return _accum_0
@@ -158,7 +156,7 @@ do
b.dirty = error
end
if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then
- b = repr(b)
+ b = b:as_lua()
end
bits[#bits + 1] = b
_continue_0 = true
@@ -236,7 +234,7 @@ do
b.dirty = error
end
if type(b) ~= 'string' and not (type(b) == 'table' and b.is_code) then
- b = repr(b)
+ b = b:as_lua()
end
bits[i] = b
end
@@ -276,7 +274,7 @@ do
local _parent_0 = Code
local _base_0 = {
__tostring = Code.__tostring,
- __repr = Code.__repr,
+ as_lua = Code.as_lua,
__len = Code.__len,
add_free_vars = function(self, vars)
if not (#vars > 0) then
@@ -469,7 +467,7 @@ do
local _parent_0 = Code
local _base_0 = {
__tostring = Code.__tostring,
- __repr = Code.__repr,
+ as_lua = Code.as_lua,
__len = Code.__len
}
_base_0.__index = _base_0
diff --git a/code_obj.moon b/code_obj.moon
index bd53c5b..4e70784 100644
--- a/code_obj.moon
+++ b/code_obj.moon
@@ -2,7 +2,6 @@
-- build up generated code, while keeping track of where it came from, and managing
-- indentation levels.
{:insert, :remove, :concat} = table
-{:repr} = require 'utils'
unpack or= table.unpack
local LuaCode, NomsuCode, Source
@@ -19,7 +18,7 @@ class Source
__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)=>
getmetatable(@) == getmetatable(other) and @filename == other.filename and @start == other.start and @stop == other.stop
@@ -67,8 +66,8 @@ class Code
@__str = concat(buff, "")
return @__str
- __repr: =>
- "#{@__class.__name}(#{concat {repr(tostring(@source)), unpack([repr(b) for b in *@bits])}, ", "})"
+ as_lua: =>
+ "#{@__class.__name}(#{concat {tostring(@source)\as_lua!, unpack([b\as_lua! for b in *@bits])}, ", "})"
__len: => #tostring(@)
@@ -93,7 +92,7 @@ class Code
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 = repr(b)
+ b = b\as_lua!
bits[#bits+1] = b
@dirty!
@@ -148,7 +147,7 @@ class Code
b = select(i, ...)
b.dirty = error if 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
@dirty!
@@ -158,7 +157,7 @@ class Code
class LuaCode extends Code
__tostring: Code.__tostring
- __repr: Code.__repr
+ as_lua: Code.as_lua
__len: Code.__len
new: (...)=>
super ...
@@ -253,7 +252,7 @@ class LuaCode extends Code
class NomsuCode extends Code
__tostring: Code.__tostring
- __repr: Code.__repr
+ as_lua: Code.as_lua
__len: Code.__len
Code.__base.append_1 = assert Code.__base.append
diff --git a/containers.lua b/containers.lua
index 1b3fd94..a7819ec 100644
--- a/containers.lua
+++ b/containers.lua
@@ -3,14 +3,50 @@ do
local _obj_0 = table
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end
-local repr, stringify, equivalent, nth_to_last, size
+local equivalent, nth_to_last, size
do
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
local lpeg = require('lpeg')
local re = require('re')
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 = {
__eq = equivalent,
__tostring = function(self)
@@ -19,12 +55,36 @@ local _list_mt = {
local _len_0 = 1
for _index_0 = 1, #self do
local b = self[_index_0]
- _accum_0[_len_0] = repr(b)
+ _accum_0[_len_0] = tostring(b)
+ _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 _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)
assert(type(self) == 'table' and type(other) == 'table', "Incompatible types for comparison")
for i = 1, math.max(#self, #other) do
@@ -162,7 +222,29 @@ local _dict_mt = {
local _accum_0 = { }
local _len_0 = 1
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
end
return _accum_0
diff --git a/containers.moon b/containers.moon
index eaf007a..70a9f70 100644
--- a/containers.moon
+++ b/containers.moon
@@ -1,19 +1,39 @@
-- This file contains container classes, i.e. Lists, Dicts, and Sets
{:insert,:remove,:concat} = table
-{:repr, :stringify, :equivalent, :nth_to_last, :size} = require 'utils'
+{:equivalent, :nth_to_last, :size} = require 'utils'
lpeg = require 'lpeg'
re = require 're'
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
-- used in Nomsu. This way, they retain a notion of whether they were originally lists or dicts.
_list_mt =
__eq:equivalent
-- Could consider adding a __newindex to enforce list-ness, but would hurt performance
__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)=>
assert type(@) == 'table' and type(other) == 'table', "Incompatible types for comparison"
for i=1,math.max(#@, #other)
@@ -74,7 +94,11 @@ _dict_mt =
__eq:equivalent
__len:size
__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
__band: (other)=>
Dict{k,v for k,v in pairs(@) when other[k] != nil}
diff --git a/core/collections.nom b/core/collections.nom
index 8dbc79d..3877d31 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -149,6 +149,8 @@ test:
assume ("\%t" == "XXX")
compile [set %dict 's metatable to %metatable] to (..)
Lua "setmetatable(\(%dict as lua expr), \(%metatable as lua expr));"
+compile [%'s metatable, %' metatable] to (..)
+ Lua value "getmetatable(\(% as lua expr))"
test:
assume (({} with fallback % -> (% + 1)).10 == 11)
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index c50f783..51831ec 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -34,7 +34,7 @@ lua> "\
lua> "\
..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)
table.insert(lua_args, 1, "nomsu")
table.insert(lua_args, 2, "tree")
@@ -66,19 +66,19 @@ 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 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)))
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))}
- lua:append("\\nCOMPILE_ACTIONS[", repr(alias.stub), "] = ")
+ lua:append("\\nCOMPILE_ACTIONS[", alias.stub:as_lua(), "] = ")
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
lua:append("function(")
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:append(")\\nend")
end
@@ -173,7 +173,7 @@ compile [parse %actions as %body] to (..)
if replacements[t[1]] then
return replacements[t[1]]
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
elseif AST.is_syntax_tree(t) then
local ret = {}
@@ -183,7 +183,7 @@ compile [parse %actions as %body] to (..)
ret[#ret+1] = make_tree(t[i])
i = i + 1
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
ret[#ret+1] = k.."= "..make_tree(v)
else
@@ -191,8 +191,10 @@ compile [parse %actions as %body] to (..)
end
end
return t.type.."{"..table.concat(ret, ", ").."}"
+ elseif type(t) == 'number' then
+ return tostring(t)
else
- return repr(t)
+ return t:as_lua()
end
end
local \%new_body = LuaCode(\%body.source,
@@ -257,7 +259,7 @@ action [%tree with vars %replacements] (..)
compile [tree %tree with vars %replacements] to (..)
Lua value "\
- ..\(=lua "repr(\%tree)"):map(function(t)
+ ..\(=lua "(\%tree):as_lua()"):map(function(t)
if t.type == "Var" then
return \(%replacements as lua expr)[t[1]]
end
@@ -312,7 +314,7 @@ test:
..one
"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:
assume ((type of {}) == "table") or barf "type of failed."
@@ -340,7 +342,7 @@ test:
compile [run %nomsu_code] to (..)
Lua value "\
..nomsu:run(NomsuCode(\(..)
- =lua "repr(tostring(\(%nomsu_code.source)))"
+ =lua "tostring(\(%nomsu_code.source)):as_lua()"
.., \(%nomsu_code as lua expr)))"
test:
diff --git a/lib/object.nom b/lib/object.nom
index b49b8f2..600ecf6 100644
--- a/lib/object.nom
+++ b/lib/object.nom
@@ -46,7 +46,7 @@ compile [my 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)
- table.insert(\%args, \(\%me as lua id))
+ table.insert(\%args, 1, \(\%me as lua id))
local lua = LuaCode(tree.source, "class.", fn_name, " = ", \(..)
compile as (%args -> %body)
..)
@@ -54,7 +54,7 @@ compile [my action %actions %body] to:
local alias = \%actions[i]
local alias_name = alias.stub:as_lua_id()
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, " = ")
if utils.equivalent(\%args, \%alias_args) then
lua:append("class.", fn_name)
@@ -110,3 +110,9 @@ compile [object %classname extends %parent %class_body] to:
parse [object %classname %class_body] as (..)
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
diff --git a/nomsu.lua b/nomsu.lua
index 3d78dd1..fa6a6ce 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -91,8 +91,6 @@ do
local _obj_0 = require("code_obj")
NomsuCode, LuaCode, Source = _obj_0.NomsuCode, _obj_0.LuaCode, _obj_0.Source
end
-local repr
-repr = require("utils").repr
if not arg or debug.getinfo(2).func == require then
return NomsuCompiler
end
@@ -324,7 +322,11 @@ say "\
local ret
ok, ret = xpcall(nomsu.run, err_hand, nomsu, buff, Source(pseudo_filename, 1, #buff))
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
Errhand.print_error(ret)
end
diff --git a/nomsu.moon b/nomsu.moon
index 382a5b5..1ab9637 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -48,7 +48,6 @@ Files = require "files"
Errhand = require "error_handling"
NomsuCompiler = require "nomsu_compiler"
{:NomsuCode, :LuaCode, :Source} = require "code_obj"
-{:repr} = require "utils"
-- If this file was reached via require(), then just return the Nomsu compiler
if not arg or debug.getinfo(2).func == require
@@ -222,7 +221,10 @@ say "\
Errhand.print_error error_message
ok, ret = xpcall(nomsu.run, err_hand, nomsu, buff, Source(pseudo_filename, 1, #buff))
if ok and ret != nil
- print "= "..repr(ret)
+ if type(ret) == 'number'
+ print "= #{ret}"
+ else
+ print "= #{ret\as_nomsu!}"
elseif not ok
Errhand.print_error ret
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index 2e286b7..89d247a 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -4,8 +4,8 @@ R, P, S = lpeg.R, lpeg.P, lpeg.S
local re = require('re')
local utils = require('utils')
local Files = require('files')
-local repr, stringify, equivalent
-repr, stringify, equivalent = utils.repr, utils.stringify, utils.equivalent
+local stringify, equivalent
+stringify, equivalent = utils.stringify, utils.equivalent
local List, Dict, Text
do
local _obj_0 = require('containers')
@@ -193,7 +193,6 @@ do
ipairs = ipairs,
_List = List,
_Dict = Dict,
- repr = repr,
stringify = stringify,
utils = utils,
lpeg = lpeg,
@@ -385,7 +384,7 @@ do
add_lua_string_bits = function(self, val_or_stmt, code)
local cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode("
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
local add_bit_lua
add_bit_lua = function(lua, bit_lua)
@@ -395,11 +394,11 @@ do
end
local operate_on_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
local bit = text[_index_0]
if type(bit) == "string" then
- add_bit_lua(lua, repr(bit))
+ add_bit_lua(lua, bit:as_lua())
elseif bit.type == "Text" then
add_bit_lua(lua, operate_on_text(bit))
else
@@ -480,13 +479,13 @@ do
end
return _accum_0
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,
["is jit"] = function(self, tree, code)
return LuaCode.Value(tree.source, jit and "true" or "false")
end,
["Lua version"] = function(self, tree, code)
- return LuaCode.Value(tree.source, repr(_VERSION))
+ return LuaCode.Value(tree.source, _VERSION:as_lua())
end,
__parent = setmetatable({ }, {
__index = function(self, key)
@@ -744,9 +743,9 @@ do
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?")
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
- 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
insert(args, arg_lua)
@@ -762,6 +761,16 @@ do
elseif "EscapedNomsu" == _exp_0 then
local lua = LuaCode.Value(tree.source, tree[1].type, "{")
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
if needs_comma then
lua:append(", ")
@@ -773,12 +782,12 @@ do
elseif type(k) == 'string' and match(k, "[_a-zA-Z][_a-zA-Z0-9]*") then
lua:append(k, "= ")
else
- lua:append("[", (AST.is_syntax_tree(k) and self:compile(k, compile_actions) or repr(k)), "]= ")
+ lua:append("[", as_lua(k), "]= ")
end
if k == "source" then
- lua:append(repr(tostring(v)))
+ lua:append(tostring(v):as_lua())
else
- lua:append(AST.is_syntax_tree(v) and self:compile(v, compile_actions) or repr(v))
+ lua:append(as_lua(v))
end
end
lua:append("}")
@@ -849,7 +858,7 @@ do
if #lua.bits > 0 then
lua:append("..")
end
- lua:append(repr(string_buffer))
+ lua:append(string_buffer:as_lua())
string_buffer = ""
end
local bit_lua = self:compile(bit, compile_actions)
@@ -875,7 +884,7 @@ do
if #lua.bits > 0 then
lua:append("..")
end
- lua:append(repr(string_buffer))
+ lua:append(string_buffer:as_lua())
end
if #lua.bits > 1 then
lua:parenthesize()
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index 19d4049..0718bca 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -14,7 +14,7 @@ lpeg = require 'lpeg'
re = require 're'
utils = require 'utils'
Files = require 'files'
-{:repr, :stringify, :equivalent} = utils
+{:stringify, :equivalent} = utils
{:List, :Dict, :Text} = require 'containers'
export colors, colored
colors = require 'consolecolors'
@@ -104,7 +104,7 @@ with NomsuCompiler
-- Nomsu types:
_List:List, _Dict:Dict,
-- 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{}
:LuaCode, :NomsuCode, :Source
nomsu:NomsuCompiler
@@ -202,16 +202,16 @@ with NomsuCompiler
add_lua_string_bits = (val_or_stmt, code)=>
cls_str = val_or_stmt == "value" and "LuaCode.Value(" or "LuaCode("
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)->
bit_leading_len = #(bit_lua\match("^[^\n]*"))
lua\append(lua\trailing_line_len! + bit_leading_len > MAX_LINE and ",\n " or ", ")
lua\append(bit_lua)
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
if type(bit) == "string"
- add_bit_lua(lua, repr(bit))
+ add_bit_lua(lua, bit\as_lua!)
elseif bit.type == "Text"
add_bit_lua(lua, operate_on_text(bit))
else
@@ -270,13 +270,13 @@ with NomsuCompiler
["tests"]: (tree)=> LuaCode.Value(tree.source, "TESTS")
["test 1"]: (tree, body)=>
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)=>
return LuaCode.Value(tree.source, jit and "true" or "false")
["Lua version"]: (tree, code)=>
- return LuaCode.Value(tree.source, repr(_VERSION))
+ return LuaCode.Value(tree.source, _VERSION\as_lua!)
__parent: setmetatable({}, {
__index: (key)=>
@@ -439,11 +439,11 @@ with NomsuCompiler
elseif tok.type == "Action"
@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."
else
@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
lua\concat_append args, ", "
lua\append ")"
@@ -452,6 +452,13 @@ with NomsuCompiler
when "EscapedNomsu"
lua = LuaCode.Value tree.source, tree[1].type, "{"
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])
if needs_comma then lua\append ", "
else needs_comma = true
@@ -460,11 +467,11 @@ with NomsuCompiler
elseif type(k) == 'string' and match(k,"[_a-zA-Z][_a-zA-Z0-9]*")
lua\append(k, "= ")
else
- lua\append("[", (AST.is_syntax_tree(k) and @compile(k, compile_actions) or repr(k)), "]= ")
+ lua\append("[", as_lua(k), "]= ")
if k == "source"
- lua\append repr(tostring(v))
+ lua\append tostring(v)\as_lua!
else
- lua\append(AST.is_syntax_tree(v) and @compile(v, compile_actions) or repr(v))
+ lua\append as_lua(v)
lua\append "}"
return lua
@@ -499,9 +506,9 @@ with NomsuCompiler
if type(bit) == "string"
string_buffer ..= bit
continue
- if string_buffer ~= ""
+ if string_buffer != ""
if #lua.bits > 0 then lua\append ".."
- lua\append repr(string_buffer)
+ lua\append string_buffer\as_lua!
string_buffer = ""
bit_lua = @compile(bit, compile_actions)
unless bit_lua.is_value
@@ -516,7 +523,7 @@ with NomsuCompiler
if string_buffer ~= "" or #lua.bits == 0
if #lua.bits > 0 then lua\append ".."
- lua\append repr(string_buffer)
+ lua\append string_buffer\as_lua!
if #lua.bits > 1
lua\parenthesize!
diff --git a/parser.lua b/parser.lua
index 0694e3e..5eee8ca 100644
--- a/parser.lua
+++ b/parser.lua
@@ -3,8 +3,6 @@ local re = require('re')
lpeg.setmaxstack(20000)
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
-local repr
-repr = require('utils').repr
local DEFS
do
local _with_0 = { }
diff --git a/parser.moon b/parser.moon
index 9a2e2ff..78e6291 100644
--- a/parser.moon
+++ b/parser.moon
@@ -3,7 +3,6 @@ lpeg = require 'lpeg'
re = require 're'
lpeg.setmaxstack 20000
{:P,:R,:S,:C,:Cmt,:Carg,:Cc} = lpeg
-{:repr} = require 'utils'
DEFS = with {}
-- Newline supports either windows-style CR+LF or unix-style LF
diff --git a/string2.lua b/string2.lua
index 5995de2..2cdfefc 100644
--- a/string2.lua
+++ b/string2.lua
@@ -119,6 +119,24 @@ local string2 = {
end
return table.concat(lines, "\n")
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)
local orig = str
str = gsub(str, "^ *$", "%1 ")
diff --git a/string2.moon b/string2.moon
index 2259272..662cd0d 100644
--- a/string2.moon
+++ b/string2.moon
@@ -45,6 +45,20 @@ string2 = {
lines[#lines+1] = line
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,
-- 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).
diff --git a/syntax_tree.lua b/syntax_tree.lua
index 72b510e..afdb631 100644
--- a/syntax_tree.lua
+++ b/syntax_tree.lua
@@ -1,5 +1,3 @@
-local repr
-repr = require('utils').repr
local insert, remove, concat
do
local _obj_0 = table
@@ -15,6 +13,24 @@ AST.is_syntax_tree = function(n, t)
end
return type(n) == 'table' and getmetatable(n) and AST[n.type] == getmetatable(n) and (t == nil or n.type == t)
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 = {
"Number",
"Var",
@@ -42,10 +58,42 @@ for _index_0 = 1, #types do
return getmetatable(x) == self
end
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
- cls.__repr = function(self)
- return tostring(self.type) .. tostring(repr(self, (function() end)))
+ cls.as_lua = function(self)
+ 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
cls.source_code_for_tree = setmetatable({ }, {
__index = function(self, t)
diff --git a/syntax_tree.moon b/syntax_tree.moon
index 305a1ee..d2f5d37 100644
--- a/syntax_tree.moon
+++ b/syntax_tree.moon
@@ -1,6 +1,5 @@
-- This file contains the datastructures used to represent parsed Nomsu syntax trees,
-- as well as the logic for converting them to Lua code.
-{:repr} = require 'utils'
{:insert, :remove, :concat} = table
{:Source} = require "code_obj"
unpack or= table.unpack
@@ -9,6 +8,14 @@ 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)
+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",
"IndexChain", "Action", "FileChunks", "Error", "Comment"}
for name in *types
@@ -19,8 +26,18 @@ for name in *types
.__name = name
.type = name
.is_instance = (x)=> getmetatable(x) == @
- .__tostring = => "#{@type}#{repr @, (->)}"
- .__repr = => "#{@type}#{repr @, (->)}"
+ .__tostring = =>
+ 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)=>
s = t.source
Files = require 'files'