mirror of
https://github.com/leafo/moonscript.git
synced 2025-01-09 00:04:22 +00:00
wrap_env in moonscript, separate module
This commit is contained in:
parent
b9013efcdc
commit
5b0df1cd62
@ -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
70
moonscript/parse/env.lua
Normal 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
50
moonscript/parse/env.moon
Normal 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 }
|
Loading…
Reference in New Issue
Block a user