aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin_metatables.lua6
-rw-r--r--builtin_metatables.moon4
-rw-r--r--containers.lua71
-rw-r--r--containers.moon37
-rw-r--r--lib/core/collections.nom4
-rw-r--r--lib/core/control_flow.nom15
-rw-r--r--nomsu_environment.lua44
-rw-r--r--nomsu_environment.moon31
8 files changed, 82 insertions, 130 deletions
diff --git a/builtin_metatables.lua b/builtin_metatables.lua
index 63d865c..3b29e39 100644
--- a/builtin_metatables.lua
+++ b/builtin_metatables.lua
@@ -186,8 +186,11 @@ co_mt = {
return math.huge
end,
__call = coroutine.resume,
- __next = function(self, k)
+ __inext = function(self, k)
local ok, val = coroutine.resume(self)
+ if coroutine.status(self) == 'dead' then
+ return
+ end
if ok then
return (k or 0) + 1, val
end
@@ -207,6 +210,7 @@ co_mt = {
return co_mt[k]
end
}
+co_mt.__next = co_mt.__inext
debug.setmetatable(coroutine.create(function() end), co_mt)
local nil_mt = {
__type = "Nil",
diff --git a/builtin_metatables.moon b/builtin_metatables.moon
index 7af5bf7..430a48a 100644
--- a/builtin_metatables.moon
+++ b/builtin_metatables.moon
@@ -80,8 +80,9 @@ co_mt =
as_text: => (tostring(@)\gsub("thread", "Coroutine")).." ("..coroutine.status(@)..")"
__len: => math.huge
__call: coroutine.resume
- __next: (k)=>
+ __inext: (k)=>
ok, val = coroutine.resume(@)
+ return if coroutine.status(@) == 'dead'
if ok then return (k or 0) + 1, val
__index: (k)=>
if k == (_last_co_i[@] or 0) + 1
@@ -92,6 +93,7 @@ co_mt =
else
return nil
return co_mt[k]
+co_mt.__next = co_mt.__inext
debug.setmetatable(coroutine.create(->), co_mt)
nil_mt =
diff --git a/containers.lua b/containers.lua
index 8d77919..9f3e12e 100644
--- a/containers.lua
+++ b/containers.lua
@@ -1,4 +1,4 @@
-local List, Dict, Undict, DictEntries, _undict_mt, _dict_mt, _dict_entries_mt
+local List, Dict, Undict, _undict_mt, _dict_mt
local insert, remove, concat
do
local _obj_0 = table
@@ -426,62 +426,6 @@ Undict = function(d)
end)())
return u
end
-local _dict_entries_mt
-_dict_entries_mt = {
- __type = "a Dict's Entries",
- __index = function(self, k)
- if type(k) == 'number' then
- if k == 0 then
- return nil
- end
- if k < 0 then
- if k < 0 then
- k = #self.dict + k + 1
- end
- end
- local i, last_k = self._last_i, self._last_k
- if k < i then
- i, last_k = 0, nil
- end
- local d = self.dict
- for i = i + 1, k do
- last_k = next(d, last_k)
- if last_k == nil then
- return nil
- end
- end
- self._last_i, self._last_k = k, last_k
- return Dict({
- key = last_k,
- d[last_k]
- })
- else
- return _dict_entries_mt[k]
- end
- end,
- __len = function(self)
- return #self.dict
- end,
- __eq = function(self, other)
- return type(other) == type(self) and getmetatable(other) == getmetatable(self) and other.dict == self.dict
- end,
- __tostring = function(self)
- return "(entries in " .. tostring(self.dict) .. ")"
- end,
- as_nomsu = function(self)
- return "(entries in " .. _dict_mt.as_nomsu(self.dict) .. ")"
- end,
- as_lua = function(self)
- return "entries_in" .. _dict_mt.as_lua(self.dict)
- end
-}
-DictEntries = function(d)
- return setmetatable({
- dict = d,
- _last_i = 0,
- _last_k = nil
- }, _dict_entries_mt)
-end
_dict_mt = {
__type = "a Dict",
__eq = function(self, other)
@@ -540,8 +484,14 @@ _dict_mt = {
return _accum_0
end)(), ", ") .. "}"
end,
- as_iterable = function(self)
- return DictEntries(self)
+ __inext = function(self, key)
+ local nextkey, value = next(self, key)
+ if nextkey ~= nil then
+ return nextkey, Dict({
+ key = nextkey,
+ value = value
+ })
+ end
end,
__band = function(self, other)
return Dict((function()
@@ -662,6 +612,5 @@ Dict = function(t, more, ...)
end
return {
List = List,
- Dict = Dict,
- DictEntries = DictEntries
+ Dict = Dict
}
diff --git a/containers.moon b/containers.moon
index 312f783..91fa4b2 100644
--- a/containers.moon
+++ b/containers.moon
@@ -1,5 +1,5 @@
-- This file contains container classes, i.e. Lists and Dicts, plus some extended string functionality
-local List, Dict, Undict, DictEntries, _undict_mt, _dict_mt, _dict_entries_mt
+local List, Dict, Undict, _undict_mt, _dict_mt
{:insert,:remove,:concat} = table
as_nomsu = =>
@@ -199,34 +199,6 @@ Undict = (d)->
compliments[u] = Dict{k,true for k,v in pairs(d) when v}
return u
-local _dict_entries_mt
-_dict_entries_mt =
- __type: "a Dict's Entries"
- __index: (k)=>
- if type(k) == 'number'
- return nil if k == 0
- if k < 0 then k = #@dict+k+1 if k < 0
- i, last_k = @_last_i, @_last_k
- if k < i
- i, last_k = 0, nil
- d = @dict
- for i=i+1,k
- last_k = next(d, last_k)
- return nil if last_k == nil
- @_last_i, @_last_k = k, last_k
- return Dict{key:last_k, d[last_k]}
- else
- return _dict_entries_mt[k]
- __len: => #@dict
- __eq: (other)=>
- type(other) == type(@) and getmetatable(other) == getmetatable(@) and other.dict == @dict
- __tostring: => "(entries in "..tostring(@dict)..")"
- as_nomsu: => "(entries in ".._dict_mt.as_nomsu(@dict)..")"
- as_lua: => "entries_in".._dict_mt.as_lua(@dict)
-
-DictEntries = (d)->
- setmetatable {dict:d, _last_i:0, _last_k:nil}, _dict_entries_mt
-
_dict_mt =
__type: "a Dict"
__eq: (other)=>
@@ -247,7 +219,10 @@ _dict_mt =
"{"..concat([v == true and "."..as_nomsu(k) or ".#{as_nomsu(k)} = #{as_nomsu(v)}" for k,v in pairs @], ", ").."}"
as_lua: =>
"a_Dict{"..concat(["[ #{as_lua(k)}]= #{as_lua(v)}" for k,v in pairs @], ", ").."}"
- as_iterable: => DictEntries(@)
+ __inext: (key)=>
+ nextkey, value = next(@, key)
+ if nextkey != nil
+ return nextkey, Dict{key:nextkey, value:value}
__band: (other)=>
Dict{k,v for k,v in pairs(@) when other[k]}
__bor: (other)=>
@@ -300,4 +275,4 @@ Dict = (t,more,...)->
d[k] = v
return d
-return {:List, :Dict, :DictEntries}
+return {:List, :Dict}
diff --git a/lib/core/collections.nom b/lib/core/collections.nom
index 9741faa..60eee3c 100644
--- a/lib/core/collections.nom
+++ b/lib/core/collections.nom
@@ -180,7 +180,6 @@ test:
for $ in $r:
$visited, add $
assume ($visited == [1, 3, 5, 7, 9])
-$(inext) = (=lua "ipairs({})")
$range_mt = {
.__type = "a Range"
.__index =
@@ -212,7 +211,8 @@ $range_mt = {
($self.last == $other.last) and ($self.step == $other.step)
.backwards = (for $self ($self.last to $self.first by (- $self.step)))
- .__ipairs = (for $self: return $(inext) $self 0)
+ .__inext = $(inext)
+ .__next = $(inext)
.as_text =
for $self:
if ($self.step == 1):
diff --git a/lib/core/control_flow.nom b/lib/core/control_flow.nom
index a1fdeee..21e0618 100644
--- a/lib/core/control_flow.nom
+++ b/lib/core/control_flow.nom
@@ -167,13 +167,9 @@ test:
# This uses Lua's approach of only allowing loop-scoped variables in a loop
if (($var.type == "Action") and ($var.stub == "1 =")):
[$key, $value] = [$var.1, $var.3]
- go to (vars set)
- if (($var.type == "Action") and ($var.stub == "1 at")):
- [$key, $value] = [$var.3, $var.1]
..else:
[$key, $value] = [nil, $var]
- --- (vars set) ---
unless $value:
at (this tree) fail "No value here"
@@ -211,21 +207,16 @@ test:
if $key:
$loop =
Lua ("
- local _iterating = \($iterable as lua expr);
- local _next = getmetatable(_iterating).__next or next;
- for \($key as lua identifier),\($value as lua identifier) in _next,_iterating,nil do
- if \($value as lua identifier) == nil and _1_is_a_dead_coroutine(_iterating) then break end
+ for \($key as lua identifier),\($value as lua identifier) in pairs(\($iterable as lua expr)) do
")
..else:
$loop =
Lua ("
- local _iterating = _1_as_an_iterable(\($iterable as lua expr))
- for _i=1,#_iterating do
- local \($value as lua identifier) = _iterating[_i]
- if \($value as lua identifier) == nil and _1_is_a_dead_coroutine(_iterating) then break end
+ for _i,\($value as lua identifier) in _ipairs(\($iterable as lua expr)) do
")
--- (loop set) ---
+ # TODO: don't always wrap in block
$lua =
Lua ("
do -- for-loop
diff --git a/nomsu_environment.lua b/nomsu_environment.lua
index fdfeeb0..9e57cc6 100644
--- a/nomsu_environment.lua
+++ b/nomsu_environment.lua
@@ -3,10 +3,10 @@ do
local _obj_0 = require("code_obj")
NomsuCode, LuaCode, Source = _obj_0.NomsuCode, _obj_0.LuaCode, _obj_0.Source
end
-local List, Dict, DictEntries
+local List, Dict
do
local _obj_0 = require('containers')
- List, Dict, DictEntries = _obj_0.List, _obj_0.Dict, _obj_0.DictEntries
+ List, Dict = _obj_0.List, _obj_0.Dict
end
local Text = require('text')
local SyntaxTree = require("syntax_tree")
@@ -73,21 +73,39 @@ _1_as_text = function(x)
end
return tostring(x)
end
-local _1_as_an_iterable
-_1_as_an_iterable = function(x)
- do
- local mt = getmetatable(x)
- if mt then
- if mt.as_iterable then
- return mt.as_iterable(x)
- end
+local nomsu_pairs
+nomsu_pairs = function(self)
+ local mt = getmetatable(self)
+ if mt and mt.__next then
+ return mt.__next, self, nil
+ else
+ return next, self, nil
+ end
+end
+local inext
+if _VERSION == "Lua 5.2" or _VERSION == "Lua 5.1" then
+ inext = function(self, i)
+ local value = self[i + 1]
+ if value ~= nil then
+ return i + 1, value
end
end
- return x
+else
+ inext = ipairs({ })
+end
+local nomsu_ipairs
+nomsu_ipairs = function(self)
+ local mt = getmetatable(self)
+ if mt and mt.__inext then
+ return mt.__inext, self, 0
+ else
+ return inext, self, 0
+ end
end
local nomsu_environment
nomsu_environment = Importer({
next = next,
+ inext = inext,
unpack = unpack or table.unpack,
setmetatable = setmetatable,
rawequal = rawequal,
@@ -122,8 +140,9 @@ nomsu_environment = Importer({
math = math,
io = io,
load = load,
- pairs = pairs,
+ pairs = nomsu_pairs,
ipairs = ipairs,
+ _ipairs = nomsu_ipairs,
jit = jit,
_VERSION = _VERSION,
LUA_VERSION = (jit and jit.version or _VERSION),
@@ -132,7 +151,6 @@ nomsu_environment = Importer({
a_List = List,
a_Dict = Dict,
Text = Text,
- Dict_Entries = DictEntries,
lpeg = lpeg,
re = re,
Files = Files,
diff --git a/nomsu_environment.moon b/nomsu_environment.moon
index 4aa23f9..c519b06 100644
--- a/nomsu_environment.moon
+++ b/nomsu_environment.moon
@@ -1,7 +1,7 @@
-- This file defines the environment in which Nomsu code runs, including some
-- basic bootstrapping functionality.
{:NomsuCode, :LuaCode, :Source} = require "code_obj"
-{:List, :Dict, :DictEntries} = require 'containers'
+{:List, :Dict} = require 'containers'
Text = require 'text'
SyntaxTree = require "syntax_tree"
Files = require "files"
@@ -44,25 +44,38 @@ _1_as_text = (x)->
if x == false then return "no"
return tostring(x)
-_1_as_an_iterable = (x)->
- if mt = getmetatable(x)
- if mt.as_iterable
- return mt.as_iterable(x)
- return x
+nomsu_pairs = =>
+ mt = getmetatable(@)
+ if mt and mt.__next
+ return mt.__next, @, nil
+ else
+ return next, @, nil
+inext = if _VERSION == "Lua 5.2" or _VERSION == "Lua 5.1"
+ inext = (i)=>
+ value = @[i+1]
+ return i+1, value if value != nil
+else ipairs{}
+nomsu_ipairs = =>
+ mt = getmetatable(@)
+ if mt and mt.__inext
+ return mt.__inext, @, 0
+ else
+ return inext, @, 0
local nomsu_environment
nomsu_environment = Importer{
-- Lua stuff:
- :next, unpack: unpack or table.unpack, :setmetatable, :rawequal, :getmetatable, :pcall,
+ :next, :inext, unpack: unpack or table.unpack, :setmetatable, :rawequal, :getmetatable, :pcall,
yield:coroutine.yield, resume:coroutine.resume, coroutine_status_of:coroutine.status,
coroutine_wrap:coroutine.wrap, coroutine_from: coroutine.create,
:error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall,
:print, :loadfile, :rawset, :_VERSION, :collectgarbage, :rawget, :rawlen,
:table, :assert, :dofile, :loadstring, lua_type_of:type, :select, :math, :io, :load,
- :pairs, :ipairs, :jit, :_VERSION, LUA_VERSION: (jit and jit.version or _VERSION),
+ pairs:nomsu_pairs, :ipairs, _ipairs:nomsu_ipairs, :jit,
+ :_VERSION, LUA_VERSION: (jit and jit.version or _VERSION),
LUA_API: _VERSION, Bit: (jit or _VERSION == "Lua 5.2") and require('bitops') or nil
-- Nomsu types:
- a_List:List, a_Dict:Dict, Text:Text, Dict_Entries:DictEntries,
+ a_List:List, a_Dict:Dict, Text:Text,
-- Utilities and misc.
lpeg:lpeg, re:re, Files:Files,
:SyntaxTree, TESTS: Dict({}), globals: Dict({}),