aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-06-06 13:25:01 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-06-06 13:25:34 -0700
commit810ae220bc2b1dfa07593b77f391e4da3b57a6bb (patch)
treef5cdf811e673f4674097cb770b4f7d1fe932efe1
parent2d88c68d712cb90f7e122465381899cd9f578e47 (diff)
Added list/dict metatables to make comparison and string representations
simpler. Also deleted Counters.
-rw-r--r--core/collections.nom4
-rw-r--r--core/metaprogramming.nom13
-rw-r--r--core/operators.nom18
-rw-r--r--nomsu.lua51
-rwxr-xr-xnomsu.moon24
-rw-r--r--tests/collections.nom4
-rw-r--r--tests/metaprogramming.nom6
-rw-r--r--tests/text.nom2
-rw-r--r--utils.lua15
9 files changed, 80 insertions, 57 deletions
diff --git a/core/collections.nom b/core/collections.nom
index 0bf5cef..a8a28b2 100644
--- a/core/collections.nom
+++ b/core/collections.nom
@@ -134,10 +134,6 @@ immediately
self[\(%key as lua expr)] = value
return value
end})
-
-immediately
- parse [new counter] as: {} with fallback % -> 0
- parse [new default dict] as: {} with fallback % -> {}
# Sorting
immediately
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index c54a72f..8ad9448 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -132,7 +132,7 @@ immediately
lua> ".."
local lua = nomsu:tree_to_lua(\%tree)
if not lua.is_value then
- error("Invalid thing to convert to lua expr: "..\%tree)
+ error("Invalid thing to convert to lua expr: "..tostring(\%tree))
end
return lua
@@ -164,8 +164,9 @@ immediately
parse [to %var write %code] as: lua> "\%var:append(\%code);"
immediately
- compile [repr %obj] to: Lua value "repr(\(%obj as lua expr))"
- compile [%obj as text] to: Lua value "tostring(\(%obj as lua expr))"
+ compile [quote %s] to
+ Lua value ".."
+ ('"'..\(%s as lua expr):gsub("\\\\", "\\\\\\\\"):gsub("\n","\\\\n"):gsub('"', '\\\\"')..'"')
compile [type of %obj] to: Lua value "type(\(%obj as lua expr))"
immediately
@@ -175,7 +176,7 @@ immediately
# Compiler tools
immediately
compile [run %code] to
- Lua "nomsu:run(Nomsu(\"\(%code.source as text)\", \(%code as lua expr)))"
+ Lua value "nomsu:run(Nomsu(\(quote "\(%code.source)"), \(%code as lua expr)))"
immediately
compile [show lua %block] to
@@ -189,7 +190,7 @@ immediately
if \%message.type == "Text" then
return Lua(tree.source, "print(", \(%message as lua expr), ");");
else
- return Lua(tree.source, "print(stringify(", \(%message as lua expr), "));");
+ return Lua(tree.source, "print(tostring(", \(%message as lua expr), "));");
end
# Return
@@ -208,7 +209,7 @@ immediately
return
Lua ".."
if not \(%condition as lua expr) then
- error(\(repr %assumption), 0);
+ error(\(quote "\%assumption"), 0);
end
compile [assume %condition or barf %message] to
diff --git a/core/operators.nom b/core/operators.nom
index dd57cea..4ec8ff1 100644
--- a/core/operators.nom
+++ b/core/operators.nom
@@ -23,23 +23,9 @@ immediately
compile [%x <= %y] to: Lua value "(\(%x as lua expr) <= \(%y as lua expr))"
compile [%x >= %y] to: Lua value "(\(%x as lua expr) >= \(%y as lua expr))"
compile [%a is %b, %a = %b, %a == %b] to
- lua> ".."
- local safe = {Text=true, Number=true}
- local a_lua, b_lua = \(%a as lua), \(%b as lua)
- if safe[\%a.type] or safe[\%b.type] then
- return Lua.Value(tree.source, "(", a_lua, " == ", b_lua, ")")
- else
- return Lua.Value(tree.source, "utils.equivalent(", a_lua, ", ", b_lua, ")")
- end
+ Lua value "(\(%a as lua expr) == \(%b as lua expr))"
compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to
- lua> ".."
- local safe = {Text=true, Number=true}
- local a_lua, b_lua = \(%a as lua), \(%b as lua)
- if safe[\%a.type] or safe[\%b.type] then
- return Lua.Value(tree.source, "(", a_lua, " ~= ", b_lua, ")")
- else
- return Lua.Value(tree.source, "(not utils.equivalent(", a_lua, ", ", b_lua, "))")
- end
+ Lua value "(\(%a as lua expr) ~= \(%b as lua expr))"
# For strict identity checking, use (%x's id) is (%y's id)
compile [%'s id, id of %] to: Lua value "nomsu.ids[\(% as lua expr)]"
diff --git a/nomsu.lua b/nomsu.lua
index bf644c4..dc1a5d8 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -677,7 +677,7 @@ do
end
return lua
elseif "List" == _exp_0 then
- local lua = Lua.Value(tree.source, "{")
+ local lua = Lua.Value(tree.source, "list{")
local line_length = 0
for i, item in ipairs(tree) do
local item_lua = self:tree_to_lua(item)
@@ -707,7 +707,7 @@ do
lua:append("}")
return lua
elseif "Dict" == _exp_0 then
- local lua = Lua.Value(tree.source, "{")
+ local lua = Lua.Value(tree.source, "dict{")
local line_length = 0
for i, entry in ipairs(tree) do
local entry_lua = self:tree_to_lua(entry)
@@ -1216,6 +1216,43 @@ do
end
})
self.source_map = { }
+ local _list_mt = {
+ __eq = utils.equivalent,
+ __tostring = 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] = repr(b)
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)(), ", ") .. "]"
+ end
+ }
+ local list
+ list = function(t)
+ return setmetatable(t, _list_mt)
+ end
+ local _dict_mt = {
+ __eq = utils.equivalent,
+ __tostring = function(self)
+ return "{" .. concat((function()
+ local _accum_0 = { }
+ local _len_0 = 1
+ for k, v in pairs(self) do
+ _accum_0[_len_0] = tostring(repr(k)) .. ": " .. tostring(repr(v))
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)(), ", ") .. "}"
+ end
+ }
+ local dict
+ dict = function(t)
+ return setmetatable(t, _dict_mt)
+ end
self.environment = {
nomsu = self,
repr = repr,
@@ -1256,9 +1293,9 @@ do
debug = debug,
math = math,
io = io,
- pairs = pairs,
load = load,
- ipairs = ipairs
+ list = list,
+ dict = dict
}
if jit then
self.environment.len = function(x)
@@ -1289,11 +1326,10 @@ do
if mt.__ipairs then
return mt.__ipairs(x)
end
- else
- return _ipairs(x)
end
end
end
+ return _ipairs(x)
end
self.environment.pairs = function(x)
if type(x) == 'function' then
@@ -1307,11 +1343,10 @@ do
if mt.__pairs then
return mt.__pairs(x)
end
- else
- return _pairs(x)
end
end
end
+ return _pairs(x)
end
for k, v in pairs(Types) do
self.environment[k] = v
diff --git a/nomsu.moon b/nomsu.moon
index b9ff559..b47b32a 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -245,6 +245,17 @@ class NomsuCompiler
})
@source_map = {}
+ _list_mt =
+ __eq:utils.equivalent
+ -- Could consider adding a __newindex to enforce list-ness, but would hurt performance
+ __tostring: =>
+ "["..concat([repr(b) for b in *@], ", ").."]"
+ list = (t)-> setmetatable(t, _list_mt)
+ _dict_mt =
+ __eq:utils.equivalent
+ __tostring: =>
+ "{"..concat(["#{repr(k)}: #{repr(v)}" for k,v in pairs @], ", ").."}"
+ dict = (t)-> setmetatable(t, _dict_mt)
@environment = {
-- Discretionary/convenience stuff
nomsu:self, repr:repr, stringify:stringify, utils:utils, lpeg:lpeg, re:re,
@@ -252,8 +263,9 @@ class NomsuCompiler
:next, :unpack, :setmetatable, :coroutine, :rawequal, :getmetatable, :pcall,
:error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall, :module,
:print, :loadfile, :rawset, :_VERSION, :collectgarbage, :rawget, :bit32, :rawlen,
- :table, :assert, :dofile, :loadstring, :type, :select, :debug, :math, :io, :pairs,
- :load, :ipairs,
+ :table, :assert, :dofile, :loadstring, :type, :select, :debug, :math, :io, :load,
+ -- Nomsu types:
+ :list, :dict,
}
@environment.len = if jit
(x)->
@@ -270,7 +282,7 @@ class NomsuCompiler
elseif mt = getmetatable(x)
if mt.__ipairs
return mt.__ipairs(x)
- else return _ipairs(x)
+ return _ipairs(x)
@environment.pairs = (x)->
if type(x) == 'function'
return coroutine.wrap(x)
@@ -279,7 +291,7 @@ class NomsuCompiler
elseif mt = getmetatable(x)
if mt.__pairs
return mt.__pairs(x)
- else return _pairs(x)
+ return _pairs(x)
for k,v in pairs(Types) do @environment[k] = v
@environment.Tuple = Tuple
@environment.Lua = Lua
@@ -558,7 +570,7 @@ class NomsuCompiler
return lua
when "List"
- lua = Lua.Value tree.source, "{"
+ lua = Lua.Value tree.source, "list{"
line_length = 0
for i, item in ipairs tree
item_lua = @tree_to_lua(item)
@@ -583,7 +595,7 @@ class NomsuCompiler
return lua
when "Dict"
- lua = Lua.Value tree.source, "{"
+ lua = Lua.Value tree.source, "dict{"
line_length = 0
for i, entry in ipairs tree
entry_lua = @tree_to_lua(entry)
diff --git a/tests/collections.nom b/tests/collections.nom
index 6329d00..2cc6adf 100644
--- a/tests/collections.nom
+++ b/tests/collections.nom
@@ -37,9 +37,5 @@ assume (%x = [3,2,1])
sort %x by % = %keys.%
assume (%x = [2,3,1])
assume ((unique [1,2,1,3,2,3]) = [1,2,3])
-%c <- (new counter)
-for % in ["x","y","x","x","y"]
- %c.% +<- 1
-assume (%c = {x:3,y:2})
say "Collections test passed."
diff --git a/tests/metaprogramming.nom b/tests/metaprogramming.nom
index 26a750a..b9b97af 100644
--- a/tests/metaprogramming.nom
+++ b/tests/metaprogramming.nom
@@ -55,15 +55,13 @@ try: foo 99
assume ((\(5 + 5) as value) = 10) or barf "%tree as value failed."
-assume (((\(foo %x) as nomsu) as text) = "foo %x") or barf "source code failed."
-
-assume ((repr [1,2]) = "{1, 2}") or barf "repr failed."
+assume ("\(\(foo %x) as nomsu)" = "foo %x") or barf "source code failed."
assume ((type of {}) = "table") or barf "type of failed."
assume ((nomsu) = (=lua "nomsu")) or barf "nomsu failed"
-assume (((\%x as lua identifier) as text) = "_x") or barf "converting to identifier failed."
+assume ("\(\%x as lua identifier)" = "_x") or barf "converting to identifier failed."
assume ((run "return 99") = 99) or barf "run % failed."
diff --git a/tests/text.nom b/tests/text.nom
index f2ef225..600cce4 100644
--- a/tests/text.nom
+++ b/tests/text.nom
@@ -30,7 +30,7 @@ assume (%s = "one two\\nthreefour")
list:\[..]
1,2,3
..
-assume (%s = "list:{1, 2, 3}")
+assume (%s = "list:[1, 2, 3]")
assume
".."
diff --git a/utils.lua b/utils.lua
index c78a0c8..ac43757 100644
--- a/utils.lua
+++ b/utils.lua
@@ -241,30 +241,29 @@ local function sort(list, keyFn, reverse)
end
local function equivalent(x, y, depth)
- depth = depth or -1
- if x == y then
+ depth = depth or 0
+ if rawequal(x, y) then
return true
end
if type(x) ~= type(y) then
return false
end
- if type(x) ~= 'table' then
+ if type(x) ~= 'table' then return false end
+ if getmetatable(x) ~= getmetatable(y) then
return false
end
- if depth == 0 then
- return false
- elseif depth < -999 then
+ if depth >= 99 then
error("Exceeded maximum comparison depth")
end
local checked = {}
for k, v in pairs(x) do
- if not equivalent(y[k], v, depth - 1) then
+ if not equivalent(y[k], v, depth + 1) then
return false
end
checked[k] = true
end
for k, v in pairs(y) do
- if not checked[k] and not equivalent(x[k], v, depth - 1) then
+ if not checked[k] and not equivalent(x[k], v, depth + 1) then
return false
end
end