wrap_env in moonscript, separate module

This commit is contained in:
leaf corcoran 2015-02-28 15:01:28 -08:00
parent b9013efcdc
commit 5b0df1cd62
3 changed files with 123 additions and 55 deletions

View File

@ -12,8 +12,8 @@ local literals = require "moonscript.parse.literals"
local ntype = types.ntype
local trim = util.trim
local getfenv = util.getfenv
local setfenv = util.setfenv
local wrap_env = require("moonscript.parse.env").wrap_env
local unpack = util.unpack
local Stack = data.Stack
@ -55,58 +55,6 @@ local function ensure(patt, finally)
return patt * finally + finally * Cut
end
-- auto declare Proper variables with lpeg.V
local function wrap_env(fn)
local env = getfenv(fn)
local wrap_name = V
if debug_grammar then
local indent = 0
local indent_char = " "
local function iprint(...)
local args = {...}
for i=1,#args do
args[i] = tostring(args[i])
end
io.stdout:write(indent_char:rep(indent) .. table.concat(args, ", ") .. "\n")
end
wrap_name = function(name)
local v = V(name)
v = Cmt("", function()
iprint("* " .. name)
indent = indent + 1
return true
end) * Cmt(v, function(str, pos, ...)
iprint(name, true)
indent = indent - 1
return true, ...
end) + Cmt("", function()
iprint(name, false)
indent = indent - 1
return false
end)
return v
end
end
return setfenv(fn, setmetatable({}, {
__index = function(self, name)
local value = env[name]
if value ~= nil then return value end
if name:match"^[A-Z][A-Za-z0-9]*$" then
local v = wrap_name(name)
rawset(self, name, v)
return v
end
error("unknown variable referenced: "..name)
end
}))
end
local function extract_line(str, start_pos)
str = str:sub(start_pos)
local m = str:match"^(.-)\n"
@ -268,7 +216,7 @@ end
local err_msg = "Failed to parse:%s\n [%d] >> %s"
local build_grammar = wrap_env(function()
local build_grammar = wrap_env(debug_grammar, function()
local _indent = Stack(0) -- current indent
local _do_stack = Stack(0)

70
moonscript/parse/env.lua Normal file
View File

@ -0,0 +1,70 @@
local getfenv, setfenv
do
local _obj_0 = require("moonscript.util")
getfenv, setfenv = _obj_0.getfenv, _obj_0.setfenv
end
local wrap_env
wrap_env = function(debug, fn)
local V, Cmt
do
local _obj_0 = require("lpeg")
V, Cmt = _obj_0.V, _obj_0.Cmt
end
local env = getfenv(fn)
local wrap_name = V
if debug then
local indent = 0
local indent_char = " "
local iprint
iprint = function(...)
local args = table.concat((function(...)
local _accum_0 = { }
local _len_0 = 1
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local a = _list_0[_index_0]
_accum_0[_len_0] = tostring(a)
_len_0 = _len_0 + 1
end
return _accum_0
end)(...), ", ")
return io.stderr:write(tostring(indent_char:rep(indent)) .. tostring(args) .. "\n")
end
wrap_name = function(name)
local v = V(name)
v = Cmt("", function()
iprint("* " .. name)
indent = indent + 1
return true
end) * Cmt(v, function(str, pos, ...)
iprint(name, true)
indent = indent - 1
return true, ...
end) + Cmt("", function()
iprint(name, false)
indent = indent - 1
return false
end)
return v
end
end
return setfenv(fn, setmetatable({ }, {
__index = function(self, name)
local value = env[name]
if value ~= nil then
return value
end
if name:match("^[A-Z][A-Za-z0-9]*$") then
local v = wrap_name(name)
rawset(self, name, v)
return v
end
return error("unknown variable referenced: " .. tostring(name))
end
}))
end
return {
wrap_env = wrap_env
}

50
moonscript/parse/env.moon Normal file
View File

@ -0,0 +1,50 @@
import getfenv, setfenv from require "moonscript.util"
-- all undefined Proper globals are automaticlly converted into lpeg.V
wrap_env = (debug, fn) ->
import V, Cmt from require "lpeg"
env = getfenv fn
wrap_name = V
if debug
indent = 0
indent_char = " "
iprint = (...) ->
args = table.concat [tostring a for a in *{...}], ", "
io.stderr\write "#{indent_char\rep(indent)}#{args}\n"
wrap_name = (name) ->
v = V name
v = Cmt("", ->
iprint "* " .. name
indent += 1
true
) * Cmt(v, (str, pos, ...) ->
iprint name, true
indent -= 1
true, ...
) + Cmt("", ->
iprint name, false
indent -= 1
false
)
v
setfenv fn, setmetatable {}, {
__index: (name) =>
value = env[name]
return value if value != nil
if name\match"^[A-Z][A-Za-z0-9]*$"
v = wrap_name name
rawset @, name, v
return v
error "unknown variable referenced: #{name}"
}
{ :wrap_env }