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 ntype = types.ntype
|
||||||
local trim = util.trim
|
local trim = util.trim
|
||||||
|
|
||||||
local getfenv = util.getfenv
|
local wrap_env = require("moonscript.parse.env").wrap_env
|
||||||
local setfenv = util.setfenv
|
|
||||||
local unpack = util.unpack
|
local unpack = util.unpack
|
||||||
|
|
||||||
local Stack = data.Stack
|
local Stack = data.Stack
|
||||||
@ -55,58 +55,6 @@ local function ensure(patt, finally)
|
|||||||
return patt * finally + finally * Cut
|
return patt * finally + finally * Cut
|
||||||
end
|
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)
|
local function extract_line(str, start_pos)
|
||||||
str = str:sub(start_pos)
|
str = str:sub(start_pos)
|
||||||
local m = str:match"^(.-)\n"
|
local m = str:match"^(.-)\n"
|
||||||
@ -268,7 +216,7 @@ end
|
|||||||
|
|
||||||
local err_msg = "Failed to parse:%s\n [%d] >> %s"
|
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 _indent = Stack(0) -- current indent
|
||||||
local _do_stack = Stack(0)
|
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