aboutsummaryrefslogtreecommitdiff
path: root/parser.lua
diff options
context:
space:
mode:
Diffstat (limited to 'parser.lua')
-rw-r--r--parser.lua119
1 files changed, 1 insertions, 118 deletions
diff --git a/parser.lua b/parser.lua
index 8a94314..5eed3be 100644
--- a/parser.lua
+++ b/parser.lua
@@ -113,126 +113,9 @@ setmetatable(NOMSU_DEFS, {
end
})
local Parser = {
- version = 3,
+ version = 4,
patterns = { }
}
-do
- local peg_tidier = re.compile([[ file <- %nl* {~ (def/comment) (%nl+ (def/comment))* %nl* ~}
- def <- anon_def / captured_def
- anon_def <- ({ident} (" "*) ":"
- {~ ((%nl " "+ def_line?)+) / def_line ~}) -> "%1 <- %2"
- captured_def <- ({ident} (" "*) "(" {ident} ")" (" "*) ":"
- {~ ((%nl " "+ def_line?)+) / def_line ~}) -> "%1 <- (({} {| %3 |} {} %%userdata) -> %2)"
- def_line <- (err / [^%nl])+
- err <- ("(!!" { (!("!!)") .)* } "!!)") -> "(({} (%1) %%userdata) => error)"
- ident <- [a-zA-Z_][a-zA-Z0-9_]*
- comment <- "--" [^%nl]*
- ]])
- for version = 1, Parser.version do
- local peg_file = io.open("nomsu." .. tostring(version) .. ".peg")
- if not peg_file and package.nomsupath then
- for path in package.nomsupath:gmatch("[^;]+") do
- peg_file = io.open(path .. "/nomsu." .. tostring(version) .. ".peg")
- if peg_file then
- break
- end
- end
- end
- assert(peg_file, "could not find nomsu .peg file")
- local nomsu_peg = peg_tidier:match(peg_file:read('*a'))
- peg_file:close()
- Parser.patterns[version] = re.compile(nomsu_peg, NOMSU_DEFS)
- end
-end
-local _anon_chunk = 0
-Parser.parse = function(nomsu_code, source, version)
- if source == nil then
- source = nil
- end
- if version == nil then
- version = nil
- end
- source = source or nomsu_code.source
- nomsu_code = tostring(nomsu_code)
- if not (source) then
- source = Source("anonymous chunk #" .. tostring(_anon_chunk), 1, #nomsu_code)
- _anon_chunk = _anon_chunk + 1
- end
- version = version or nomsu_code:match("^#![^\n]*nomsu[ ]+-V[ ]*([0-9.]+)")
- local syntax_version = version and tonumber(version:match("^[0-9]+")) or Parser.version
- local userdata = {
- errors = { },
- source = source,
- comments = { }
- }
- local tree = Parser.patterns[syntax_version]:match(nomsu_code, nil, userdata)
- if not tree or type(tree) == 'number' then
- error("In file " .. tostring(colored.blue(tostring(source or "<unknown>"))) .. " failed to parse:\n" .. tostring(colored.onyellow(colored.black(nomsu_code))))
- end
- if next(userdata.errors) then
- local keys
- do
- local _accum_0 = { }
- local _len_0 = 1
- for k, v in pairs(userdata.errors) do
- _accum_0[_len_0] = k
- _len_0 = _len_0 + 1
- end
- keys = _accum_0
- end
- table.sort(keys)
- local errors
- do
- local _accum_0 = { }
- local _len_0 = 1
- for _index_0 = 1, #keys do
- local k = keys[_index_0]
- _accum_0[_len_0] = userdata.errors[k]
- _len_0 = _len_0 + 1
- end
- errors = _accum_0
- end
- error("Errors occurred while parsing (v" .. tostring(syntax_version) .. "):\n\n" .. table.concat(errors, "\n\n"), 0)
- end
- local comments
- do
- local _accum_0 = { }
- local _len_0 = 1
- for p, c in pairs(userdata.comments) do
- _accum_0[_len_0] = {
- comment = c,
- pos = p
- }
- _len_0 = _len_0 + 1
- end
- comments = _accum_0
- end
- table.sort(comments, function(a, b)
- return a.pos > b.pos
- end)
- local comment_i = 1
- local walk_tree
- walk_tree = function(t)
- local comment_buff = { }
- while comments[#comments] and comments[#comments].pos <= t.source.start do
- table.insert(comment_buff, table.remove(comments))
- end
- for _index_0 = 1, #t do
- local x = t[_index_0]
- if AST.is_syntax_tree(x) then
- walk_tree(x)
- end
- end
- while comments[#comments] and comments[#comments].pos <= t.source.stop do
- table.insert(comment_buff, table.remove(comments))
- end
- if #comment_buff > 0 then
- t.comments = comment_buff
- end
- end
- walk_tree(tree)
- return tree
-end
Parser.is_operator = function(s)
return not not (NOMSU_DEFS.operator_char ^ 1 * -1):match(s)
end