rufus-lua-moon 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +18 -0
 - data/Gemfile +4 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +51 -0
 - data/Rakefile +1 -0
 - data/lib/rufus/lua/moon/version.rb +12 -0
 - data/lib/rufus/lua/moon.rb +18 -0
 - data/rufus-lua-moon.gemspec +25 -0
 - data/vendor/lua/moon/all.moon +8 -0
 - data/vendor/lua/moon/init.moon +136 -0
 - data/vendor/lua/moonscript/compile/format.lua +55 -0
 - data/vendor/lua/moonscript/compile/statement.lua +217 -0
 - data/vendor/lua/moonscript/compile/value.lua +321 -0
 - data/vendor/lua/moonscript/compile.lua +549 -0
 - data/vendor/lua/moonscript/data.lua +87 -0
 - data/vendor/lua/moonscript/dump.lua +42 -0
 - data/vendor/lua/moonscript/errors.lua +65 -0
 - data/vendor/lua/moonscript/init.lua +90 -0
 - data/vendor/lua/moonscript/parse.lua +505 -0
 - data/vendor/lua/moonscript/transform.lua +1174 -0
 - data/vendor/lua/moonscript/types.lua +237 -0
 - data/vendor/lua/moonscript/util.lua +101 -0
 - data/vendor/lua/moonscript/version.lua +7 -0
 - metadata +109 -0
 
| 
         @@ -0,0 +1,87 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module("moonscript.data", package.seeall)
         
     | 
| 
      
 2 
     | 
    
         
            +
            local concat = table.concat
         
     | 
| 
      
 3 
     | 
    
         
            +
            Set = function(items)
         
     | 
| 
      
 4 
     | 
    
         
            +
              local self = { }
         
     | 
| 
      
 5 
     | 
    
         
            +
              local _list_0 = items
         
     | 
| 
      
 6 
     | 
    
         
            +
              for _index_0 = 1, #_list_0 do
         
     | 
| 
      
 7 
     | 
    
         
            +
                local key = _list_0[_index_0]
         
     | 
| 
      
 8 
     | 
    
         
            +
                self[key] = true
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              return self
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
            Stack = (function()
         
     | 
| 
      
 13 
     | 
    
         
            +
              local _parent_0 = nil
         
     | 
| 
      
 14 
     | 
    
         
            +
              local _base_0 = {
         
     | 
| 
      
 15 
     | 
    
         
            +
                __tostring = function(self)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  return "<Stack {" .. concat(self, ", ") .. "}>"
         
     | 
| 
      
 17 
     | 
    
         
            +
                end,
         
     | 
| 
      
 18 
     | 
    
         
            +
                pop = function(self)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  return table.remove(self)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end,
         
     | 
| 
      
 21 
     | 
    
         
            +
                push = function(self, value)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  table.insert(self, value)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  return value
         
     | 
| 
      
 24 
     | 
    
         
            +
                end,
         
     | 
| 
      
 25 
     | 
    
         
            +
                top = function(self)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  return self[#self]
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              }
         
     | 
| 
      
 29 
     | 
    
         
            +
              _base_0.__index = _base_0
         
     | 
| 
      
 30 
     | 
    
         
            +
              if _parent_0 then
         
     | 
| 
      
 31 
     | 
    
         
            +
                setmetatable(_base_0, _parent_0.__base)
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              local _class_0 = setmetatable({
         
     | 
| 
      
 34 
     | 
    
         
            +
                __init = function(self, ...)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  local _list_0 = {
         
     | 
| 
      
 36 
     | 
    
         
            +
                    ...
         
     | 
| 
      
 37 
     | 
    
         
            +
                  }
         
     | 
| 
      
 38 
     | 
    
         
            +
                  for _index_0 = 1, #_list_0 do
         
     | 
| 
      
 39 
     | 
    
         
            +
                    local v = _list_0[_index_0]
         
     | 
| 
      
 40 
     | 
    
         
            +
                    self:push(v)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  return nil
         
     | 
| 
      
 43 
     | 
    
         
            +
                end,
         
     | 
| 
      
 44 
     | 
    
         
            +
                __base = _base_0,
         
     | 
| 
      
 45 
     | 
    
         
            +
                __name = "Stack",
         
     | 
| 
      
 46 
     | 
    
         
            +
                __parent = _parent_0
         
     | 
| 
      
 47 
     | 
    
         
            +
              }, {
         
     | 
| 
      
 48 
     | 
    
         
            +
                __index = function(cls, name)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  local val = rawget(_base_0, name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  if val == nil and _parent_0 then
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return _parent_0[name]
         
     | 
| 
      
 52 
     | 
    
         
            +
                  else
         
     | 
| 
      
 53 
     | 
    
         
            +
                    return val
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end,
         
     | 
| 
      
 56 
     | 
    
         
            +
                __call = function(cls, ...)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  local _self_0 = setmetatable({}, _base_0)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  cls.__init(_self_0, ...)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  return _self_0
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
              })
         
     | 
| 
      
 62 
     | 
    
         
            +
              _base_0.__class = _class_0
         
     | 
| 
      
 63 
     | 
    
         
            +
              return _class_0
         
     | 
| 
      
 64 
     | 
    
         
            +
            end)()
         
     | 
| 
      
 65 
     | 
    
         
            +
            lua_keywords = Set({
         
     | 
| 
      
 66 
     | 
    
         
            +
              'and',
         
     | 
| 
      
 67 
     | 
    
         
            +
              'break',
         
     | 
| 
      
 68 
     | 
    
         
            +
              'do',
         
     | 
| 
      
 69 
     | 
    
         
            +
              'else',
         
     | 
| 
      
 70 
     | 
    
         
            +
              'elseif',
         
     | 
| 
      
 71 
     | 
    
         
            +
              'end',
         
     | 
| 
      
 72 
     | 
    
         
            +
              'false',
         
     | 
| 
      
 73 
     | 
    
         
            +
              'for',
         
     | 
| 
      
 74 
     | 
    
         
            +
              'function',
         
     | 
| 
      
 75 
     | 
    
         
            +
              'if',
         
     | 
| 
      
 76 
     | 
    
         
            +
              'in',
         
     | 
| 
      
 77 
     | 
    
         
            +
              'local',
         
     | 
| 
      
 78 
     | 
    
         
            +
              'nil',
         
     | 
| 
      
 79 
     | 
    
         
            +
              'not',
         
     | 
| 
      
 80 
     | 
    
         
            +
              'or',
         
     | 
| 
      
 81 
     | 
    
         
            +
              'repeat',
         
     | 
| 
      
 82 
     | 
    
         
            +
              'return',
         
     | 
| 
      
 83 
     | 
    
         
            +
              'then',
         
     | 
| 
      
 84 
     | 
    
         
            +
              'true',
         
     | 
| 
      
 85 
     | 
    
         
            +
              'until',
         
     | 
| 
      
 86 
     | 
    
         
            +
              'while'
         
     | 
| 
      
 87 
     | 
    
         
            +
            })
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module("moonscript.dump", package.seeall)
         
     | 
| 
      
 2 
     | 
    
         
            +
            local flat_value
         
     | 
| 
      
 3 
     | 
    
         
            +
            flat_value = function(op, depth)
         
     | 
| 
      
 4 
     | 
    
         
            +
              if depth == nil then
         
     | 
| 
      
 5 
     | 
    
         
            +
                depth = 1
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              if type(op) == "string" then
         
     | 
| 
      
 8 
     | 
    
         
            +
                return '"' .. op .. '"'
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              if type(op) ~= "table" then
         
     | 
| 
      
 11 
     | 
    
         
            +
                return tostring(op)
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
              local items = (function()
         
     | 
| 
      
 14 
     | 
    
         
            +
                local _accum_0 = { }
         
     | 
| 
      
 15 
     | 
    
         
            +
                local _len_0 = 0
         
     | 
| 
      
 16 
     | 
    
         
            +
                local _list_0 = op
         
     | 
| 
      
 17 
     | 
    
         
            +
                for _index_0 = 1, #_list_0 do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  local item = _list_0[_index_0]
         
     | 
| 
      
 19 
     | 
    
         
            +
                  _len_0 = _len_0 + 1
         
     | 
| 
      
 20 
     | 
    
         
            +
                  _accum_0[_len_0] = flat_value(item, depth + 1)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                return _accum_0
         
     | 
| 
      
 23 
     | 
    
         
            +
              end)()
         
     | 
| 
      
 24 
     | 
    
         
            +
              local pos = op[-1]
         
     | 
| 
      
 25 
     | 
    
         
            +
              return "{" .. (pos and "[" .. pos .. "] " or "") .. table.concat(items, ", ") .. "}"
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
      
 27 
     | 
    
         
            +
            value = function(op)
         
     | 
| 
      
 28 
     | 
    
         
            +
              return flat_value(op)
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
      
 30 
     | 
    
         
            +
            tree = function(block)
         
     | 
| 
      
 31 
     | 
    
         
            +
              return (function()
         
     | 
| 
      
 32 
     | 
    
         
            +
                local _accum_0 = { }
         
     | 
| 
      
 33 
     | 
    
         
            +
                local _len_0 = 0
         
     | 
| 
      
 34 
     | 
    
         
            +
                local _list_0 = block
         
     | 
| 
      
 35 
     | 
    
         
            +
                for _index_0 = 1, #_list_0 do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  value = _list_0[_index_0]
         
     | 
| 
      
 37 
     | 
    
         
            +
                  _len_0 = _len_0 + 1
         
     | 
| 
      
 38 
     | 
    
         
            +
                  _accum_0[_len_0] = print(flat_value(value))
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                return _accum_0
         
     | 
| 
      
 41 
     | 
    
         
            +
              end)()
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module("moonscript.errors", package.seeall)
         
     | 
| 
      
 2 
     | 
    
         
            +
            local moon = require("moonscript")
         
     | 
| 
      
 3 
     | 
    
         
            +
            local util = require("moonscript.util")
         
     | 
| 
      
 4 
     | 
    
         
            +
            require("lpeg")
         
     | 
| 
      
 5 
     | 
    
         
            +
            local concat, insert = table.concat, table.insert
         
     | 
| 
      
 6 
     | 
    
         
            +
            local split, pos_to_line = util.split, util.pos_to_line
         
     | 
| 
      
 7 
     | 
    
         
            +
            local lookup_line
         
     | 
| 
      
 8 
     | 
    
         
            +
            lookup_line = function(fname, pos, cache)
         
     | 
| 
      
 9 
     | 
    
         
            +
              if not cache[fname] then
         
     | 
| 
      
 10 
     | 
    
         
            +
                do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  local _with_0 = io.open(fname)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  cache[fname] = _with_0:read("*a")
         
     | 
| 
      
 13 
     | 
    
         
            +
                  _with_0:close()
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              return pos_to_line(cache[fname], pos)
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
            local reverse_line_number
         
     | 
| 
      
 19 
     | 
    
         
            +
            reverse_line_number = function(fname, line_table, line_num, cache)
         
     | 
| 
      
 20 
     | 
    
         
            +
              for i = line_num, 0, -1 do
         
     | 
| 
      
 21 
     | 
    
         
            +
                if line_table[i] then
         
     | 
| 
      
 22 
     | 
    
         
            +
                  return lookup_line(fname, line_table[i], cache)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              return "unknown"
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
      
 27 
     | 
    
         
            +
            rewrite_traceback = function(text, err)
         
     | 
| 
      
 28 
     | 
    
         
            +
              local line_tables = moon.line_tables
         
     | 
| 
      
 29 
     | 
    
         
            +
              local V, S, Ct, C = lpeg.V, lpeg.S, lpeg.Ct, lpeg.C
         
     | 
| 
      
 30 
     | 
    
         
            +
              local header_text = "stack traceback:"
         
     | 
| 
      
 31 
     | 
    
         
            +
              local Header, Line = V("Header"), V("Line")
         
     | 
| 
      
 32 
     | 
    
         
            +
              local Break = lpeg.S("\n")
         
     | 
| 
      
 33 
     | 
    
         
            +
              local g = lpeg.P({
         
     | 
| 
      
 34 
     | 
    
         
            +
                Header,
         
     | 
| 
      
 35 
     | 
    
         
            +
                Header = header_text * Break * Ct(Line ^ 1),
         
     | 
| 
      
 36 
     | 
    
         
            +
                Line = "\t" * C((1 - Break) ^ 0) * (Break + -1)
         
     | 
| 
      
 37 
     | 
    
         
            +
              })
         
     | 
| 
      
 38 
     | 
    
         
            +
              local cache = { }
         
     | 
| 
      
 39 
     | 
    
         
            +
              local rewrite_single
         
     | 
| 
      
 40 
     | 
    
         
            +
              rewrite_single = function(trace)
         
     | 
| 
      
 41 
     | 
    
         
            +
                local fname, line, msg = trace:match('^%[string "(.-)"]:(%d+): (.*)$')
         
     | 
| 
      
 42 
     | 
    
         
            +
                local tbl = line_tables[fname]
         
     | 
| 
      
 43 
     | 
    
         
            +
                if fname and tbl then
         
     | 
| 
      
 44 
     | 
    
         
            +
                  return concat({
         
     | 
| 
      
 45 
     | 
    
         
            +
                    fname,
         
     | 
| 
      
 46 
     | 
    
         
            +
                    ":",
         
     | 
| 
      
 47 
     | 
    
         
            +
                    reverse_line_number(fname, tbl, line, cache),
         
     | 
| 
      
 48 
     | 
    
         
            +
                    ": ",
         
     | 
| 
      
 49 
     | 
    
         
            +
                    msg
         
     | 
| 
      
 50 
     | 
    
         
            +
                  })
         
     | 
| 
      
 51 
     | 
    
         
            +
                else
         
     | 
| 
      
 52 
     | 
    
         
            +
                  return trace
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
              err = rewrite_single(err)
         
     | 
| 
      
 56 
     | 
    
         
            +
              local match = g:match(text)
         
     | 
| 
      
 57 
     | 
    
         
            +
              for i, trace in ipairs(match) do
         
     | 
| 
      
 58 
     | 
    
         
            +
                match[i] = rewrite_single(trace)
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
              return concat({
         
     | 
| 
      
 61 
     | 
    
         
            +
                "moon:" .. err,
         
     | 
| 
      
 62 
     | 
    
         
            +
                header_text,
         
     | 
| 
      
 63 
     | 
    
         
            +
                "\t" .. concat(match, "\n\t")
         
     | 
| 
      
 64 
     | 
    
         
            +
              }, "\n")
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,90 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module("moonscript", package.seeall)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require("moonscript.compile")
         
     | 
| 
      
 3 
     | 
    
         
            +
            require("moonscript.parse")
         
     | 
| 
      
 4 
     | 
    
         
            +
            require("moonscript.util")
         
     | 
| 
      
 5 
     | 
    
         
            +
            local concat, insert = table.concat, table.insert
         
     | 
| 
      
 6 
     | 
    
         
            +
            local split, dump = util.split, util.dump
         
     | 
| 
      
 7 
     | 
    
         
            +
            local lua = {
         
     | 
| 
      
 8 
     | 
    
         
            +
              loadstring = loadstring
         
     | 
| 
      
 9 
     | 
    
         
            +
            }
         
     | 
| 
      
 10 
     | 
    
         
            +
            dirsep = "/"
         
     | 
| 
      
 11 
     | 
    
         
            +
            line_tables = { }
         
     | 
| 
      
 12 
     | 
    
         
            +
            local create_moonpath
         
     | 
| 
      
 13 
     | 
    
         
            +
            create_moonpath = function(package_path)
         
     | 
| 
      
 14 
     | 
    
         
            +
              local paths = split(package_path, ";")
         
     | 
| 
      
 15 
     | 
    
         
            +
              for i, path in ipairs(paths) do
         
     | 
| 
      
 16 
     | 
    
         
            +
                local p = path:match("^(.-)%.lua$")
         
     | 
| 
      
 17 
     | 
    
         
            +
                if p then
         
     | 
| 
      
 18 
     | 
    
         
            +
                  paths[i] = p .. ".moon"
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
              return concat(paths, ";")
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
      
 23 
     | 
    
         
            +
            to_lua = function(text)
         
     | 
| 
      
 24 
     | 
    
         
            +
              if "string" ~= type(text) then
         
     | 
| 
      
 25 
     | 
    
         
            +
                local t = type(text)
         
     | 
| 
      
 26 
     | 
    
         
            +
                error("expecting string (got " .. t .. ")", 2)
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
              local tree, err = parse.string(text)
         
     | 
| 
      
 29 
     | 
    
         
            +
              if not tree then
         
     | 
| 
      
 30 
     | 
    
         
            +
                error(err, 2)
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              local code, ltable, pos = compile.tree(tree)
         
     | 
| 
      
 33 
     | 
    
         
            +
              if not code then
         
     | 
| 
      
 34 
     | 
    
         
            +
                error(compile.format_error(ltable, pos, text), 2)
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              return code, ltable
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
      
 38 
     | 
    
         
            +
            moon_loader = function(name)
         
     | 
| 
      
 39 
     | 
    
         
            +
              local name_path = name:gsub("%.", dirsep)
         
     | 
| 
      
 40 
     | 
    
         
            +
              local file, file_path = nil, nil
         
     | 
| 
      
 41 
     | 
    
         
            +
              local _list_0 = split(package.moonpath, ";")
         
     | 
| 
      
 42 
     | 
    
         
            +
              for _index_0 = 1, #_list_0 do
         
     | 
| 
      
 43 
     | 
    
         
            +
                local path = _list_0[_index_0]
         
     | 
| 
      
 44 
     | 
    
         
            +
                file_path = path:gsub("?", name_path)
         
     | 
| 
      
 45 
     | 
    
         
            +
                file = io.open(file_path)
         
     | 
| 
      
 46 
     | 
    
         
            +
                if file then
         
     | 
| 
      
 47 
     | 
    
         
            +
                  break
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
              if file then
         
     | 
| 
      
 51 
     | 
    
         
            +
                local text = file:read("*a")
         
     | 
| 
      
 52 
     | 
    
         
            +
                return loadstring(text, file_path)
         
     | 
| 
      
 53 
     | 
    
         
            +
              else
         
     | 
| 
      
 54 
     | 
    
         
            +
                return nil, "Could not find moon file"
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
            if not package.moonpath then
         
     | 
| 
      
 58 
     | 
    
         
            +
              package.moonpath = create_moonpath(package.path)
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
      
 60 
     | 
    
         
            +
            local init_loader
         
     | 
| 
      
 61 
     | 
    
         
            +
            init_loader = function()
         
     | 
| 
      
 62 
     | 
    
         
            +
              return insert(package.loaders, 2, moon_loader)
         
     | 
| 
      
 63 
     | 
    
         
            +
            end
         
     | 
| 
      
 64 
     | 
    
         
            +
            if not _G.moon_no_loader then
         
     | 
| 
      
 65 
     | 
    
         
            +
              init_loader()
         
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
      
 67 
     | 
    
         
            +
            loadstring = function(str, chunk_name)
         
     | 
| 
      
 68 
     | 
    
         
            +
              local passed, code, ltable = pcall(function()
         
     | 
| 
      
 69 
     | 
    
         
            +
                return to_lua(str)
         
     | 
| 
      
 70 
     | 
    
         
            +
              end)
         
     | 
| 
      
 71 
     | 
    
         
            +
              if not passed then
         
     | 
| 
      
 72 
     | 
    
         
            +
                error(chunk_name .. ": " .. code, 2)
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
              if chunk_name then
         
     | 
| 
      
 75 
     | 
    
         
            +
                line_tables[chunk_name] = ltable
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
              return lua.loadstring(code, chunk_name or "=(moonscript.loadstring)")
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
      
 79 
     | 
    
         
            +
            loadfile = function(fname)
         
     | 
| 
      
 80 
     | 
    
         
            +
              local file, err = io.open(fname)
         
     | 
| 
      
 81 
     | 
    
         
            +
              if not file then
         
     | 
| 
      
 82 
     | 
    
         
            +
                return nil, err
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
              local text = assert(file:read("*a"))
         
     | 
| 
      
 85 
     | 
    
         
            +
              return loadstring(text, fname)
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
      
 87 
     | 
    
         
            +
            dofile = function(fname)
         
     | 
| 
      
 88 
     | 
    
         
            +
              local f = assert(loadfile(fname))
         
     | 
| 
      
 89 
     | 
    
         
            +
              return f()
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,505 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module("moonscript.parse", package.seeall)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            local util = require"moonscript.util"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require"lpeg"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            local data = require"moonscript.data"
         
     | 
| 
      
 8 
     | 
    
         
            +
            local types = require"moonscript.types"
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            local ntype = types.ntype
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            local dump = util.dump
         
     | 
| 
      
 13 
     | 
    
         
            +
            local trim = util.trim
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            local Stack = data.Stack
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            local function count_indent(str)
         
     | 
| 
      
 18 
     | 
    
         
            +
            	local sum = 0
         
     | 
| 
      
 19 
     | 
    
         
            +
            	for v in str:gmatch("[\t ]") do
         
     | 
| 
      
 20 
     | 
    
         
            +
            		if v == ' ' then sum = sum + 1 end
         
     | 
| 
      
 21 
     | 
    
         
            +
            		if v == '\t' then sum = sum + 4 end
         
     | 
| 
      
 22 
     | 
    
         
            +
            	end
         
     | 
| 
      
 23 
     | 
    
         
            +
            	return sum
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            local R, S, V, P = lpeg.R, lpeg.S, lpeg.V, lpeg.P
         
     | 
| 
      
 27 
     | 
    
         
            +
            local C, Ct, Cmt, Cg, Cb, Cc = lpeg.C, lpeg.Ct, lpeg.Cmt, lpeg.Cg, lpeg.Cb, lpeg.Cc
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            lpeg.setmaxstack(10000)
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            local White = S" \t\r\n"^0
         
     | 
| 
      
 32 
     | 
    
         
            +
            local _Space = S" \t"^0
         
     | 
| 
      
 33 
     | 
    
         
            +
            local Break = P"\r"^-1 * P"\n"
         
     | 
| 
      
 34 
     | 
    
         
            +
            local Stop = Break + -1
         
     | 
| 
      
 35 
     | 
    
         
            +
            local Indent = C(S"\t "^0) / count_indent
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            local Comment = P"--" * (1 - S"\r\n")^0 * #Stop
         
     | 
| 
      
 38 
     | 
    
         
            +
            local Space = _Space * Comment^-1
         
     | 
| 
      
 39 
     | 
    
         
            +
            local SomeSpace = S" \t"^1 * Comment^-1
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            local SpaceBreak = Space * Break
         
     | 
| 
      
 42 
     | 
    
         
            +
            local EmptyLine = SpaceBreak
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            local AlphaNum = R("az", "AZ", "09", "__")
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            local _Name = C(R("az", "AZ", "__") * AlphaNum^0)
         
     | 
| 
      
 47 
     | 
    
         
            +
            local Name = Space * _Name
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            local Num = P"0x" * R("09", "af", "AF")^1 +
         
     | 
| 
      
 50 
     | 
    
         
            +
            	R"09"^1 * (P"." * R"09"^1)^-1 * (S"eE" * P"-"^-1 * R"09"^1)^-1
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            Num = Space * (Num / function(value) return {"number", value} end)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            local FactorOp = Space * C(S"+-")
         
     | 
| 
      
 55 
     | 
    
         
            +
            local TermOp = Space * C(S"*/%^")
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            local Shebang = P"#!" * P(1 - Stop)^0
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            -- can't have P(false) because it causes preceding patterns not to run
         
     | 
| 
      
 60 
     | 
    
         
            +
            local Cut = P(function() return false end)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            local function ensure(patt, finally)
         
     | 
| 
      
 63 
     | 
    
         
            +
            	return patt * finally + finally * Cut
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            -- auto declare Proper variables with lpeg.V
         
     | 
| 
      
 67 
     | 
    
         
            +
            local function wrap_env(fn)
         
     | 
| 
      
 68 
     | 
    
         
            +
            	local env = getfenv(fn)
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            	return setfenv(fn, setmetatable({}, {
         
     | 
| 
      
 71 
     | 
    
         
            +
            		__index = function(self, name)
         
     | 
| 
      
 72 
     | 
    
         
            +
            			local value = env[name] 
         
     | 
| 
      
 73 
     | 
    
         
            +
            			if value ~= nil then return value end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            			if name:match"^[A-Z][A-Za-z0-9]*$" then
         
     | 
| 
      
 76 
     | 
    
         
            +
            				local v = V(name)
         
     | 
| 
      
 77 
     | 
    
         
            +
            				rawset(self, name, v)
         
     | 
| 
      
 78 
     | 
    
         
            +
            				return v
         
     | 
| 
      
 79 
     | 
    
         
            +
            			end
         
     | 
| 
      
 80 
     | 
    
         
            +
            			error("unknown variable referenced: "..name)
         
     | 
| 
      
 81 
     | 
    
         
            +
            		end
         
     | 
| 
      
 82 
     | 
    
         
            +
            	}))
         
     | 
| 
      
 83 
     | 
    
         
            +
            end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            function extract_line(str, start_pos)
         
     | 
| 
      
 86 
     | 
    
         
            +
            	str = str:sub(start_pos)
         
     | 
| 
      
 87 
     | 
    
         
            +
            	m = str:match"^(.-)\n"
         
     | 
| 
      
 88 
     | 
    
         
            +
            	if m then return m end
         
     | 
| 
      
 89 
     | 
    
         
            +
            	return str:match"^.-$"
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            local function mark(name)
         
     | 
| 
      
 93 
     | 
    
         
            +
            	return function(...)
         
     | 
| 
      
 94 
     | 
    
         
            +
            		return {name, ...}
         
     | 
| 
      
 95 
     | 
    
         
            +
            	end
         
     | 
| 
      
 96 
     | 
    
         
            +
            end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            local function insert_pos(pos, value)
         
     | 
| 
      
 99 
     | 
    
         
            +
                if type(value) == "table" then
         
     | 
| 
      
 100 
     | 
    
         
            +
                    value[-1] = pos
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
                return value
         
     | 
| 
      
 103 
     | 
    
         
            +
            end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
            local function pos(patt)
         
     | 
| 
      
 106 
     | 
    
         
            +
            	return (lpeg.Cp() * patt) / insert_pos
         
     | 
| 
      
 107 
     | 
    
         
            +
            end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            local function got(what)
         
     | 
| 
      
 110 
     | 
    
         
            +
            	return Cmt("", function(str, pos, ...)
         
     | 
| 
      
 111 
     | 
    
         
            +
            		local cap = {...}
         
     | 
| 
      
 112 
     | 
    
         
            +
            		print("++ got "..what, "["..extract_line(str, pos).."]")
         
     | 
| 
      
 113 
     | 
    
         
            +
            		return true
         
     | 
| 
      
 114 
     | 
    
         
            +
            	end)
         
     | 
| 
      
 115 
     | 
    
         
            +
            end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            local function flatten(tbl)
         
     | 
| 
      
 118 
     | 
    
         
            +
            	if #tbl == 1 then
         
     | 
| 
      
 119 
     | 
    
         
            +
            		return tbl[1]
         
     | 
| 
      
 120 
     | 
    
         
            +
            	end
         
     | 
| 
      
 121 
     | 
    
         
            +
            	return tbl
         
     | 
| 
      
 122 
     | 
    
         
            +
            end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            local function flatten_or_mark(name)
         
     | 
| 
      
 125 
     | 
    
         
            +
            	return function(tbl)
         
     | 
| 
      
 126 
     | 
    
         
            +
            		if #tbl == 1 then return tbl[1] end
         
     | 
| 
      
 127 
     | 
    
         
            +
            		table.insert(tbl, 1, name)
         
     | 
| 
      
 128 
     | 
    
         
            +
            		return tbl
         
     | 
| 
      
 129 
     | 
    
         
            +
            	end
         
     | 
| 
      
 130 
     | 
    
         
            +
            end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            -- makes sure the last item in a chain is an index
         
     | 
| 
      
 133 
     | 
    
         
            +
            local _assignable = { index = true, dot = true, slice = true }
         
     | 
| 
      
 134 
     | 
    
         
            +
            local function check_assignable(str, pos, value)
         
     | 
| 
      
 135 
     | 
    
         
            +
            	if ntype(value) == "chain" and _assignable[ntype(value[#value])]
         
     | 
| 
      
 136 
     | 
    
         
            +
            		or type(value) == "string"
         
     | 
| 
      
 137 
     | 
    
         
            +
            	then
         
     | 
| 
      
 138 
     | 
    
         
            +
            		return true, value
         
     | 
| 
      
 139 
     | 
    
         
            +
            	end
         
     | 
| 
      
 140 
     | 
    
         
            +
            	return false
         
     | 
| 
      
 141 
     | 
    
         
            +
            end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            local function sym(chars)
         
     | 
| 
      
 144 
     | 
    
         
            +
            	return Space * chars
         
     | 
| 
      
 145 
     | 
    
         
            +
            end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
            local function symx(chars)
         
     | 
| 
      
 148 
     | 
    
         
            +
            	return chars
         
     | 
| 
      
 149 
     | 
    
         
            +
            end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            local function simple_string(delim, x)
         
     | 
| 
      
 152 
     | 
    
         
            +
            	return C(symx(delim)) * C((P('\\'..delim) +
         
     | 
| 
      
 153 
     | 
    
         
            +
            		"\\\\" +
         
     | 
| 
      
 154 
     | 
    
         
            +
            		(1 - S('\r\n'..delim)))^0) * sym(delim) / mark"string"
         
     | 
| 
      
 155 
     | 
    
         
            +
            end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
            local function wrap_func_arg(value)
         
     | 
| 
      
 158 
     | 
    
         
            +
            	return {"call", {value}}
         
     | 
| 
      
 159 
     | 
    
         
            +
            end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
            -- DOCME
         
     | 
| 
      
 162 
     | 
    
         
            +
            local function flatten_func(callee, args)
         
     | 
| 
      
 163 
     | 
    
         
            +
            	if #args == 0 then return callee end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
            	args = {"call", args}
         
     | 
| 
      
 166 
     | 
    
         
            +
            	if ntype(callee) == "chain" then
         
     | 
| 
      
 167 
     | 
    
         
            +
            		-- check for colon stub that needs arguments
         
     | 
| 
      
 168 
     | 
    
         
            +
            		if ntype(callee[#callee]) == "colon_stub" then
         
     | 
| 
      
 169 
     | 
    
         
            +
            			local stub = callee[#callee]
         
     | 
| 
      
 170 
     | 
    
         
            +
            			stub[1] = "colon"
         
     | 
| 
      
 171 
     | 
    
         
            +
            			table.insert(stub, args)
         
     | 
| 
      
 172 
     | 
    
         
            +
            		else
         
     | 
| 
      
 173 
     | 
    
         
            +
            			table.insert(callee, args)
         
     | 
| 
      
 174 
     | 
    
         
            +
            		end
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            		return callee
         
     | 
| 
      
 177 
     | 
    
         
            +
            	end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            	return {"chain", callee, args}
         
     | 
| 
      
 180 
     | 
    
         
            +
            end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            -- wraps a statement that has a line decorator
         
     | 
| 
      
 183 
     | 
    
         
            +
            local function wrap_decorator(stm, dec)
         
     | 
| 
      
 184 
     | 
    
         
            +
            	if not dec then return stm end
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            	local arg = {stm, dec}
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
            	if dec[1] == "if" then
         
     | 
| 
      
 189 
     | 
    
         
            +
            		local _, cond, fail = unpack(dec)
         
     | 
| 
      
 190 
     | 
    
         
            +
            		if fail then fail = {"else", {fail}} end
         
     | 
| 
      
 191 
     | 
    
         
            +
            		stm = {"if", cond, {stm}, fail}
         
     | 
| 
      
 192 
     | 
    
         
            +
            	elseif dec[1] == "comprehension" then
         
     | 
| 
      
 193 
     | 
    
         
            +
            		local _, clauses = unpack(dec)
         
     | 
| 
      
 194 
     | 
    
         
            +
            		stm = {"comprehension", stm, clauses}
         
     | 
| 
      
 195 
     | 
    
         
            +
            	end
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
            	return stm
         
     | 
| 
      
 198 
     | 
    
         
            +
            end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
            -- wrap if statement if there is a conditional decorator
         
     | 
| 
      
 201 
     | 
    
         
            +
            local function wrap_if(stm, cond)
         
     | 
| 
      
 202 
     | 
    
         
            +
            	if cond then
         
     | 
| 
      
 203 
     | 
    
         
            +
            		local pass, fail = unpack(cond)
         
     | 
| 
      
 204 
     | 
    
         
            +
            		if fail then fail = {"else", {fail}} end
         
     | 
| 
      
 205 
     | 
    
         
            +
            		return {"if", cond[2], {stm}, fail}
         
     | 
| 
      
 206 
     | 
    
         
            +
            	end
         
     | 
| 
      
 207 
     | 
    
         
            +
            	return stm
         
     | 
| 
      
 208 
     | 
    
         
            +
            end
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
            local function check_lua_string(str, pos, right, left)
         
     | 
| 
      
 211 
     | 
    
         
            +
            	return #left == #right
         
     | 
| 
      
 212 
     | 
    
         
            +
            end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
            -- :name in table literal
         
     | 
| 
      
 215 
     | 
    
         
            +
            local function self_assign(name)
         
     | 
| 
      
 216 
     | 
    
         
            +
            	return {name, name}
         
     | 
| 
      
 217 
     | 
    
         
            +
            end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            local err_msg = "Failed to parse:\n [%d] >>    %s (%d)"
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
            local build_grammar = wrap_env(function()
         
     | 
| 
      
 222 
     | 
    
         
            +
            	local _indent = Stack(0) -- current indent
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            	local last_pos = 0 -- used to know where to report error
         
     | 
| 
      
 225 
     | 
    
         
            +
            	local function check_indent(str, pos, indent)
         
     | 
| 
      
 226 
     | 
    
         
            +
            		last_pos = pos
         
     | 
| 
      
 227 
     | 
    
         
            +
            		return _indent:top() == indent
         
     | 
| 
      
 228 
     | 
    
         
            +
            	end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
            	local function advance_indent(str, pos, indent)
         
     | 
| 
      
 231 
     | 
    
         
            +
            		local top = _indent:top()
         
     | 
| 
      
 232 
     | 
    
         
            +
            		if top ~= -1 and indent > _indent:top() then
         
     | 
| 
      
 233 
     | 
    
         
            +
            			_indent:push(indent)
         
     | 
| 
      
 234 
     | 
    
         
            +
            			return true
         
     | 
| 
      
 235 
     | 
    
         
            +
            		end
         
     | 
| 
      
 236 
     | 
    
         
            +
            	end
         
     | 
| 
      
 237 
     | 
    
         
            +
             
     | 
| 
      
 238 
     | 
    
         
            +
            	local function push_indent(str, pos, indent)
         
     | 
| 
      
 239 
     | 
    
         
            +
            		_indent:push(indent)
         
     | 
| 
      
 240 
     | 
    
         
            +
            		return true
         
     | 
| 
      
 241 
     | 
    
         
            +
            	end
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
      
 243 
     | 
    
         
            +
            	local function pop_indent(str, pos)
         
     | 
| 
      
 244 
     | 
    
         
            +
            		if not _indent:pop() then error("unexpected outdent") end
         
     | 
| 
      
 245 
     | 
    
         
            +
            		return true
         
     | 
| 
      
 246 
     | 
    
         
            +
            	end
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
            	local keywords = {}
         
     | 
| 
      
 249 
     | 
    
         
            +
            	local function key(chars)
         
     | 
| 
      
 250 
     | 
    
         
            +
            		keywords[chars] = true
         
     | 
| 
      
 251 
     | 
    
         
            +
            		return Space * chars * -AlphaNum
         
     | 
| 
      
 252 
     | 
    
         
            +
            	end
         
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
            	local function op(word)
         
     | 
| 
      
 255 
     | 
    
         
            +
            		local patt = Space * C(word)
         
     | 
| 
      
 256 
     | 
    
         
            +
            		if word:match("^%w*$") then
         
     | 
| 
      
 257 
     | 
    
         
            +
            			keywords[word] = true
         
     | 
| 
      
 258 
     | 
    
         
            +
            			patt = patt * -AlphaNum
         
     | 
| 
      
 259 
     | 
    
         
            +
            		end
         
     | 
| 
      
 260 
     | 
    
         
            +
            		return patt
         
     | 
| 
      
 261 
     | 
    
         
            +
            	end
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
      
 263 
     | 
    
         
            +
            	local SimpleName = Name -- for table key
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
            	-- make sure name is not a keyword
         
     | 
| 
      
 266 
     | 
    
         
            +
            	local Name = Cmt(Name, function(str, pos, name)
         
     | 
| 
      
 267 
     | 
    
         
            +
            		if keywords[name] then return false end
         
     | 
| 
      
 268 
     | 
    
         
            +
            		return true
         
     | 
| 
      
 269 
     | 
    
         
            +
            	end) / trim
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
            	local Name = sym"@" * Name / mark"self" + Name + Space * "..." / trim
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
            	local g = lpeg.P{
         
     | 
| 
      
 274 
     | 
    
         
            +
            		File,
         
     | 
| 
      
 275 
     | 
    
         
            +
            		File = Shebang^-1 * (Block + Ct""),
         
     | 
| 
      
 276 
     | 
    
         
            +
            		Block = Ct(Line * (Break^1 * Line)^0),
         
     | 
| 
      
 277 
     | 
    
         
            +
            		CheckIndent = Cmt(Indent, check_indent), -- validates line is in correct indent
         
     | 
| 
      
 278 
     | 
    
         
            +
            		Line = (CheckIndent * Statement + Space * #Stop),
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
            		Statement = (Import + While + With + For + ForEach + Switch + Return
         
     | 
| 
      
 281 
     | 
    
         
            +
            			+ ClassDecl + Export + BreakLoop + Ct(ExpList) / flatten_or_mark"explist" * Space) * ((
         
     | 
| 
      
 282 
     | 
    
         
            +
            				-- statement decorators
         
     | 
| 
      
 283 
     | 
    
         
            +
            				key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" +
         
     | 
| 
      
 284 
     | 
    
         
            +
            				CompInner / mark"comprehension"
         
     | 
| 
      
 285 
     | 
    
         
            +
            			) * Space)^-1 / wrap_decorator,
         
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
            		Body = Space^-1 * Break * EmptyLine^0 * InBlock + Ct(Statement), -- either a statement, or an indented block
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
            		Advance = #Cmt(Indent, advance_indent), -- Advances the indent, gives back whitespace for CheckIndent
         
     | 
| 
      
 290 
     | 
    
         
            +
            		PushIndent = Cmt(Indent, push_indent),
         
     | 
| 
      
 291 
     | 
    
         
            +
            		PreventIndent = Cmt(Cc(-1), push_indent),
         
     | 
| 
      
 292 
     | 
    
         
            +
            		PopIndent = Cmt("", pop_indent),
         
     | 
| 
      
 293 
     | 
    
         
            +
            		InBlock = Advance * Block * PopIndent,
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
            		Import = key"import" *  Ct(ImportNameList) * key"from" * Exp / mark"import", 
         
     | 
| 
      
 296 
     | 
    
         
            +
            		ImportName = (sym"\\" * Ct(Cc"colon_stub" * Name) + Name),
         
     | 
| 
      
 297 
     | 
    
         
            +
            		ImportNameList = ImportName * (sym"," * ImportName)^0,
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
      
 299 
     | 
    
         
            +
            		NameList = Name * (sym"," * Name)^0,
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
            		BreakLoop = Ct(key"break"/trim),
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
            		Return = key"return" * (ExpListLow/mark"explist" + C"") / mark"return",
         
     | 
| 
      
 304 
     | 
    
         
            +
             
     | 
| 
      
 305 
     | 
    
         
            +
            		With = key"with" * Exp * key"do"^-1 * Body / mark"with",
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
            		Switch = key"switch" * Exp * key"do"^-1 * Space^-1 * Break * SwitchBlock / mark"switch",
         
     | 
| 
      
 308 
     | 
    
         
            +
             
     | 
| 
      
 309 
     | 
    
         
            +
            		SwitchBlock = EmptyLine^0 * Advance * Ct(SwitchCase * (Break^1 * SwitchCase)^0 * (Break^1 * SwitchElse)^-1) * PopIndent,
         
     | 
| 
      
 310 
     | 
    
         
            +
            		SwitchCase = key"when" * Exp * key"then"^-1 * Body / mark"case",
         
     | 
| 
      
 311 
     | 
    
         
            +
            		SwitchElse = key"else" * Body / mark"else",
         
     | 
| 
      
 312 
     | 
    
         
            +
             
     | 
| 
      
 313 
     | 
    
         
            +
            		If = key"if" * Exp * key"then"^-1 * Body *
         
     | 
| 
      
 314 
     | 
    
         
            +
            			((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * Exp * key"then"^-1 * Body / mark"elseif")^0 *
         
     | 
| 
      
 315 
     | 
    
         
            +
            			((Break * CheckIndent)^-1 * EmptyLine^0 * key"else" * Body / mark"else")^-1 / mark"if",
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
            		While = key"while" * Exp * key"do"^-1 * Body / mark"while",
         
     | 
| 
      
 318 
     | 
    
         
            +
             
     | 
| 
      
 319 
     | 
    
         
            +
            		For = key"for" * (Name * sym"=" * Ct(Exp * sym"," * Exp * (sym"," * Exp)^-1)) *
         
     | 
| 
      
 320 
     | 
    
         
            +
            			key"do"^-1 * Body / mark"for",
         
     | 
| 
      
 321 
     | 
    
         
            +
             
     | 
| 
      
 322 
     | 
    
         
            +
            		ForEach = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) * key"do"^-1 * Body / mark"foreach",
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
            		Comprehension = sym"[" * Exp * CompInner * sym"]" / mark"comprehension",
         
     | 
| 
      
 325 
     | 
    
         
            +
             
     | 
| 
      
 326 
     | 
    
         
            +
            		TblComprehension = sym"{" * Exp * (sym"," * Exp)^-1 * CompInner * sym"}" / mark"tblcomprehension",
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
            		CompInner = Ct(CompFor * CompClause^0),
         
     | 
| 
      
 329 
     | 
    
         
            +
            		CompFor = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"for",
         
     | 
| 
      
 330 
     | 
    
         
            +
            		CompClause = CompFor + key"when" * Exp / mark"when",
         
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
      
 332 
     | 
    
         
            +
            		Assign = Ct(AssignableList) * sym"=" * (Ct(With + If + Switch) + Ct(TableBlock + ExpListLow)) / mark"assign",
         
     | 
| 
      
 333 
     | 
    
         
            +
            		Update = Assignable * ((sym"..=" + sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=")/trim) * Exp / mark"update",
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
            		-- we can ignore precedence for now
         
     | 
| 
      
 336 
     | 
    
         
            +
            		OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">",
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
            		Assignable = Cmt(DotChain + Chain, check_assignable) + Name,
         
     | 
| 
      
 339 
     | 
    
         
            +
            		AssignableList = Assignable * (sym"," * Assignable)^0,
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
            		Exp = Ct(Value * ((OtherOps + FactorOp + TermOp) * Value)^0) / flatten_or_mark"exp",
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
            		-- Exp = Ct(Factor * (OtherOps * Factor)^0) / flatten_or_mark"exp",
         
     | 
| 
      
 344 
     | 
    
         
            +
            		-- Factor = Ct(Term * (FactorOp * Term)^0) / flatten_or_mark"exp",
         
     | 
| 
      
 345 
     | 
    
         
            +
            		-- Term = Ct(Value * (TermOp * Value)^0) / flatten_or_mark"exp",
         
     | 
| 
      
 346 
     | 
    
         
            +
             
     | 
| 
      
 347 
     | 
    
         
            +
            		SimpleValue =
         
     | 
| 
      
 348 
     | 
    
         
            +
            			If +
         
     | 
| 
      
 349 
     | 
    
         
            +
            			Switch +
         
     | 
| 
      
 350 
     | 
    
         
            +
            			With +
         
     | 
| 
      
 351 
     | 
    
         
            +
            			ForEach + For + While +
         
     | 
| 
      
 352 
     | 
    
         
            +
            			sym"-" * -SomeSpace * Exp / mark"minus" +
         
     | 
| 
      
 353 
     | 
    
         
            +
            			sym"#" * Exp / mark"length" +
         
     | 
| 
      
 354 
     | 
    
         
            +
            			key"not" * Exp / mark"not" +
         
     | 
| 
      
 355 
     | 
    
         
            +
            			TblComprehension +
         
     | 
| 
      
 356 
     | 
    
         
            +
            			TableLit +
         
     | 
| 
      
 357 
     | 
    
         
            +
            			Comprehension +
         
     | 
| 
      
 358 
     | 
    
         
            +
            			Assign + Update + FunLit + String +
         
     | 
| 
      
 359 
     | 
    
         
            +
            			Num,
         
     | 
| 
      
 360 
     | 
    
         
            +
             
     | 
| 
      
 361 
     | 
    
         
            +
            		ChainValue = -- a function call or an object access
         
     | 
| 
      
 362 
     | 
    
         
            +
            			((Chain + DotChain + Callable) * Ct(InvokeArgs^-1)) / flatten_func,
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
            		Value = pos(
         
     | 
| 
      
 365 
     | 
    
         
            +
            			SimpleValue +
         
     | 
| 
      
 366 
     | 
    
         
            +
            			Ct(KeyValueList) / mark"table" +
         
     | 
| 
      
 367 
     | 
    
         
            +
            			ChainValue),
         
     | 
| 
      
 368 
     | 
    
         
            +
             
     | 
| 
      
 369 
     | 
    
         
            +
            		SliceValue = SimpleValue + ChainValue,
         
     | 
| 
      
 370 
     | 
    
         
            +
             
     | 
| 
      
 371 
     | 
    
         
            +
            		String = Space * DoubleString + Space * SingleString + LuaString,
         
     | 
| 
      
 372 
     | 
    
         
            +
            		SingleString = simple_string("'"),
         
     | 
| 
      
 373 
     | 
    
         
            +
            		DoubleString = simple_string('"'),
         
     | 
| 
      
 374 
     | 
    
         
            +
             
     | 
| 
      
 375 
     | 
    
         
            +
            		LuaString = Cg(LuaStringOpen, "string_open") * Cb"string_open" * Break^-1 *
         
     | 
| 
      
 376 
     | 
    
         
            +
            			C((1 - Cmt(C(LuaStringClose) * Cb"string_open", check_lua_string))^0) *
         
     | 
| 
      
 377 
     | 
    
         
            +
            			C(LuaStringClose) / mark"string",
         
     | 
| 
      
 378 
     | 
    
         
            +
             
     | 
| 
      
 379 
     | 
    
         
            +
            		LuaStringOpen = sym"[" * P"="^0 * "[" / trim,
         
     | 
| 
      
 380 
     | 
    
         
            +
            		LuaStringClose = "]" * P"="^0 * "]",
         
     | 
| 
      
 381 
     | 
    
         
            +
             
     | 
| 
      
 382 
     | 
    
         
            +
            		Callable = Name + Parens / mark"parens",
         
     | 
| 
      
 383 
     | 
    
         
            +
            		Parens = sym"(" * Exp * sym")",
         
     | 
| 
      
 384 
     | 
    
         
            +
             
     | 
| 
      
 385 
     | 
    
         
            +
            		FnArgs = symx"(" * Ct(ExpList^-1) * sym")" + sym"!" * -P"=" * Ct"",
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
            		ChainTail = (ChainItem^1 * ColonSuffix^-1 + ColonSuffix),
         
     | 
| 
      
 388 
     | 
    
         
            +
             
     | 
| 
      
 389 
     | 
    
         
            +
            		-- a list of funcalls and indexs on a callable
         
     | 
| 
      
 390 
     | 
    
         
            +
            		Chain = Callable * (ChainItem^1 * ColonSuffix^-1 + ColonSuffix) / mark"chain",
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
            		-- shorthand dot call for use in with statement
         
     | 
| 
      
 393 
     | 
    
         
            +
            		DotChain =
         
     | 
| 
      
 394 
     | 
    
         
            +
            			(sym"." * Cc(-1) * (_Name / mark"dot") * ChainTail^-1) / mark"chain" +
         
     | 
| 
      
 395 
     | 
    
         
            +
            			(sym"\\" * Cc(-1) * (
         
     | 
| 
      
 396 
     | 
    
         
            +
            				(_Name * Invoke / mark"colon") * ChainTail^-1 +
         
     | 
| 
      
 397 
     | 
    
         
            +
            				(_Name / mark"colon_stub")
         
     | 
| 
      
 398 
     | 
    
         
            +
            			)) / mark"chain",
         
     | 
| 
      
 399 
     | 
    
         
            +
             
     | 
| 
      
 400 
     | 
    
         
            +
            		ChainItem = 
         
     | 
| 
      
 401 
     | 
    
         
            +
            			Invoke + 
         
     | 
| 
      
 402 
     | 
    
         
            +
            			Slice +
         
     | 
| 
      
 403 
     | 
    
         
            +
            			symx"[" * Exp/mark"index" * sym"]" +
         
     | 
| 
      
 404 
     | 
    
         
            +
            			symx"." * _Name/mark"dot" +
         
     | 
| 
      
 405 
     | 
    
         
            +
            			ColonCall,
         
     | 
| 
      
 406 
     | 
    
         
            +
             
     | 
| 
      
 407 
     | 
    
         
            +
            		Slice = symx"[" * (SliceValue + Cc(1)) * sym"," * (SliceValue + Cc"")  *
         
     | 
| 
      
 408 
     | 
    
         
            +
            			(sym"," * SliceValue)^-1 *sym"]" / mark"slice",
         
     | 
| 
      
 409 
     | 
    
         
            +
             
     | 
| 
      
 410 
     | 
    
         
            +
            		ColonCall = symx"\\" * (_Name * Invoke) / mark"colon",
         
     | 
| 
      
 411 
     | 
    
         
            +
            		ColonSuffix = symx"\\" * _Name / mark"colon_stub",
         
     | 
| 
      
 412 
     | 
    
         
            +
             
     | 
| 
      
 413 
     | 
    
         
            +
            		Invoke = FnArgs/mark"call" +
         
     | 
| 
      
 414 
     | 
    
         
            +
            			SingleString / wrap_func_arg +
         
     | 
| 
      
 415 
     | 
    
         
            +
            			DoubleString / wrap_func_arg,
         
     | 
| 
      
 416 
     | 
    
         
            +
             
     | 
| 
      
 417 
     | 
    
         
            +
            		TableValue = KeyValue + Ct(Exp),
         
     | 
| 
      
 418 
     | 
    
         
            +
             
     | 
| 
      
 419 
     | 
    
         
            +
            		TableLit = sym"{" * Ct(
         
     | 
| 
      
 420 
     | 
    
         
            +
            				TableValueList^-1 * sym","^-1 *
         
     | 
| 
      
 421 
     | 
    
         
            +
            				(SpaceBreak * TableLitLine * (sym","^-1 * SpaceBreak * TableLitLine)^0 * sym","^-1)^-1
         
     | 
| 
      
 422 
     | 
    
         
            +
            			) * White * sym"}" / mark"table",
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
            		TableValueList = TableValue * (sym"," * TableValue)^0,
         
     | 
| 
      
 425 
     | 
    
         
            +
            		TableLitLine = PushIndent * ((TableValueList * PopIndent) + (PopIndent * Cut)) + Space,
         
     | 
| 
      
 426 
     | 
    
         
            +
             
     | 
| 
      
 427 
     | 
    
         
            +
            		-- the unbounded table
         
     | 
| 
      
 428 
     | 
    
         
            +
            		TableBlockInner = Ct(KeyValueLine * (SpaceBreak^1 * KeyValueLine)^0),
         
     | 
| 
      
 429 
     | 
    
         
            +
            		TableBlock = SpaceBreak^1 * Advance * ensure(TableBlockInner, PopIndent) / mark"table",
         
     | 
| 
      
 430 
     | 
    
         
            +
             
     | 
| 
      
 431 
     | 
    
         
            +
            		ClassDecl = key"class" * Name * (key"extends" * PreventIndent * ensure(Exp, PopIndent) + C"")^-1 * ClassBlock / mark"class",
         
     | 
| 
      
 432 
     | 
    
         
            +
             
     | 
| 
      
 433 
     | 
    
         
            +
            		ClassBlock = SpaceBreak^1 * Advance *
         
     | 
| 
      
 434 
     | 
    
         
            +
            			Ct(ClassLine * (SpaceBreak^1 * ClassLine)^0) *  PopIndent,
         
     | 
| 
      
 435 
     | 
    
         
            +
            		ClassLine = CheckIndent * ((
         
     | 
| 
      
 436 
     | 
    
         
            +
            				KeyValueList / mark"props" +
         
     | 
| 
      
 437 
     | 
    
         
            +
            				Exp / mark"stm"
         
     | 
| 
      
 438 
     | 
    
         
            +
            			) * sym","^-1),
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
            		Export = key"export" * (
         
     | 
| 
      
 441 
     | 
    
         
            +
            			Cc"class" * ClassDecl +
         
     | 
| 
      
 442 
     | 
    
         
            +
            			op"*" + op"^" +
         
     | 
| 
      
 443 
     | 
    
         
            +
            			Ct(NameList) * (sym"=" * Ct(ExpListLow))^-1) / mark"export",
         
     | 
| 
      
 444 
     | 
    
         
            +
             
     | 
| 
      
 445 
     | 
    
         
            +
            		KeyValue = (sym":" * Name) / self_assign + Ct((SimpleName + sym"[" * Exp * sym"]") * symx":" * (Exp + TableBlock)),
         
     | 
| 
      
 446 
     | 
    
         
            +
            		KeyValueList = KeyValue * (sym"," * KeyValue)^0,
         
     | 
| 
      
 447 
     | 
    
         
            +
            		KeyValueLine = CheckIndent * KeyValueList * sym","^-1,
         
     | 
| 
      
 448 
     | 
    
         
            +
             
     | 
| 
      
 449 
     | 
    
         
            +
            		FnArgsDef = sym"(" * Ct(FnArgDefList^-1) *
         
     | 
| 
      
 450 
     | 
    
         
            +
            			(key"using" * Ct(NameList + Space * "nil") + Ct"") *
         
     | 
| 
      
 451 
     | 
    
         
            +
            			sym")" + Ct"" * Ct"",
         
     | 
| 
      
 452 
     | 
    
         
            +
             
     | 
| 
      
 453 
     | 
    
         
            +
            		FnArgDefList =  FnArgDef * (sym"," * FnArgDef)^0,
         
     | 
| 
      
 454 
     | 
    
         
            +
            		FnArgDef = Ct(Name * (sym"=" * Exp)^-1),
         
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
      
 456 
     | 
    
         
            +
            		FunLit = FnArgsDef *
         
     | 
| 
      
 457 
     | 
    
         
            +
            			(sym"->" * Cc"slim" + sym"=>" * Cc"fat") *
         
     | 
| 
      
 458 
     | 
    
         
            +
            			(Body + Ct"") / mark"fndef",
         
     | 
| 
      
 459 
     | 
    
         
            +
             
     | 
| 
      
 460 
     | 
    
         
            +
            		NameList = Name * (sym"," * Name)^0,
         
     | 
| 
      
 461 
     | 
    
         
            +
            		ExpList = Exp * (sym"," * Exp)^0,
         
     | 
| 
      
 462 
     | 
    
         
            +
            		ExpListLow = Exp * ((sym"," + sym";") * Exp)^0,
         
     | 
| 
      
 463 
     | 
    
         
            +
             
     | 
| 
      
 464 
     | 
    
         
            +
            		InvokeArgs = ExpList * (sym"," * (TableBlock + SpaceBreak * Advance * ArgBlock * TableBlock^-1) + TableBlock)^-1 + TableBlock,
         
     | 
| 
      
 465 
     | 
    
         
            +
            		ArgBlock = ArgLine * (sym"," * SpaceBreak * ArgLine)^0 * PopIndent,
         
     | 
| 
      
 466 
     | 
    
         
            +
            		ArgLine = CheckIndent * ExpList
         
     | 
| 
      
 467 
     | 
    
         
            +
            	}
         
     | 
| 
      
 468 
     | 
    
         
            +
             
     | 
| 
      
 469 
     | 
    
         
            +
            	return {
         
     | 
| 
      
 470 
     | 
    
         
            +
            		_g = White * g * White * -1,
         
     | 
| 
      
 471 
     | 
    
         
            +
            		match = function(self, str, ...)
         
     | 
| 
      
 472 
     | 
    
         
            +
             
     | 
| 
      
 473 
     | 
    
         
            +
            			local pos_to_line = function(pos)
         
     | 
| 
      
 474 
     | 
    
         
            +
            				return util.pos_to_line(str, pos)
         
     | 
| 
      
 475 
     | 
    
         
            +
            			end
         
     | 
| 
      
 476 
     | 
    
         
            +
             
     | 
| 
      
 477 
     | 
    
         
            +
            			local get_line = function(num)
         
     | 
| 
      
 478 
     | 
    
         
            +
            				return util.get_line(str, num)
         
     | 
| 
      
 479 
     | 
    
         
            +
            			end
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
      
 481 
     | 
    
         
            +
            			local tree
         
     | 
| 
      
 482 
     | 
    
         
            +
            			local args = {...}
         
     | 
| 
      
 483 
     | 
    
         
            +
            			local pass, err = assert(pcall(function()
         
     | 
| 
      
 484 
     | 
    
         
            +
            				tree = self._g:match(str, unpack(args))
         
     | 
| 
      
 485 
     | 
    
         
            +
            			end))
         
     | 
| 
      
 486 
     | 
    
         
            +
             
     | 
| 
      
 487 
     | 
    
         
            +
            			if not tree then
         
     | 
| 
      
 488 
     | 
    
         
            +
            				local line_no = pos_to_line(last_pos)
         
     | 
| 
      
 489 
     | 
    
         
            +
            				local line_str = get_line(line_no) or ""
         
     | 
| 
      
 490 
     | 
    
         
            +
            				
         
     | 
| 
      
 491 
     | 
    
         
            +
            				return nil, err_msg:format(line_no, trim(line_str), _indent:top())
         
     | 
| 
      
 492 
     | 
    
         
            +
            			end
         
     | 
| 
      
 493 
     | 
    
         
            +
            			return tree
         
     | 
| 
      
 494 
     | 
    
         
            +
            		end
         
     | 
| 
      
 495 
     | 
    
         
            +
            	}
         
     | 
| 
      
 496 
     | 
    
         
            +
            	
         
     | 
| 
      
 497 
     | 
    
         
            +
            end)
         
     | 
| 
      
 498 
     | 
    
         
            +
             
     | 
| 
      
 499 
     | 
    
         
            +
            -- parse a string
         
     | 
| 
      
 500 
     | 
    
         
            +
            -- returns tree, or nil and error message
         
     | 
| 
      
 501 
     | 
    
         
            +
            function string(str)
         
     | 
| 
      
 502 
     | 
    
         
            +
            	local g = build_grammar()
         
     | 
| 
      
 503 
     | 
    
         
            +
            	return g:match(str)
         
     | 
| 
      
 504 
     | 
    
         
            +
            end
         
     | 
| 
      
 505 
     | 
    
         
            +
             
     |