aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--files.lua42
-rw-r--r--files.moon34
-rw-r--r--nomsu_compiler.lua58
-rw-r--r--nomsu_compiler.moon51
-rw-r--r--parser.lua4
-rw-r--r--parser.moon2
6 files changed, 95 insertions, 96 deletions
diff --git a/files.lua b/files.lua
index 365cb96..ded403a 100644
--- a/files.lua
+++ b/files.lua
@@ -1,3 +1,5 @@
+local lpeg = require('lpeg')
+local re = require('re')
local files = { }
local _FILE_CACHE = { }
files.spoof = function(filename, contents)
@@ -48,7 +50,7 @@ iterate_single = function(item, prev)
end
end
local ok, lfs = pcall(require, "lfs")
-if ok and false then
+if ok then
files.walk = function(path)
local browse
browse = function(filename)
@@ -121,4 +123,42 @@ else
end)
end
end
+local line_counter = re.compile([[ lines <- {| line (%nl line)* |}
+ line <- {} (!%nl .)*
+]], {
+ nl = lpeg.P("\r") ^ -1 * lpeg.P("\n")
+})
+local get_lines = re.compile([[ lines <- {| line (%nl line)* |}
+ line <- {[^%nl]*}
+]], {
+ nl = lpeg.P("\r") ^ -1 * lpeg.P("\n")
+})
+local _LINE_STARTS = { }
+files.get_line_starts = function(str)
+ if type(str) ~= 'string' then
+ str = tostring(str)
+ end
+ do
+ local starts = _LINE_STARTS[str]
+ if starts then
+ return starts
+ end
+ end
+ local line_starts = line_counter:match(str)
+ _LINE_STARTS[str] = line_starts
+ return line_starts
+end
+files.get_line_number = function(str, pos)
+ local line_starts = files.get_line_starts(str)
+ local lo, hi = 1, #line_starts
+ while lo <= hi do
+ local mid = math.floor((lo + hi) / 2)
+ if line_starts[mid] > pos then
+ hi = mid - 1
+ else
+ lo = mid + 1
+ end
+ end
+ return hi
+end
return files
diff --git a/files.moon b/files.moon
index 5422651..1d28e5c 100644
--- a/files.moon
+++ b/files.moon
@@ -1,4 +1,6 @@
-- Some file utilities for searching for files recursively and using package.nomsupath
+lpeg = require 'lpeg'
+re = require 're'
files = {}
_FILE_CACHE = {}
@@ -83,4 +85,36 @@ else
unless found
error("Invalid file path: "..tostring(path))
+line_counter = re.compile([[
+ lines <- {| line (%nl line)* |}
+ line <- {} (!%nl .)*
+]], nl:lpeg.P("\r")^-1 * lpeg.P("\n"))
+
+get_lines = re.compile([[
+ lines <- {| line (%nl line)* |}
+ line <- {[^%nl]*}
+]], nl:lpeg.P("\r")^-1 * lpeg.P("\n"))
+
+-- LINE_STARTS is a mapping from strings to a table that maps line number to character positions
+_LINE_STARTS = {}
+files.get_line_starts = (str)->
+ if type(str) != 'string'
+ str = tostring(str)
+ if starts = _LINE_STARTS[str]
+ return starts
+ line_starts = line_counter\match(str)
+ _LINE_STARTS[str] = line_starts
+ return line_starts
+
+files.get_line_number = (str, pos)->
+ line_starts = files.get_line_starts(str)
+ -- Binary search for line number of position
+ lo, hi = 1, #line_starts
+ while lo <= hi
+ mid = math.floor((lo+hi)/2)
+ if line_starts[mid] > pos
+ hi = mid-1
+ else lo = mid+1
+ return hi
+
return files
diff --git a/nomsu_compiler.lua b/nomsu_compiler.lua
index 200f0f7..137df2e 100644
--- a/nomsu_compiler.lua
+++ b/nomsu_compiler.lua
@@ -1,6 +1,5 @@
local lpeg = require('lpeg')
local re = require('re')
-lpeg.setmaxstack(10000)
local utils = require('utils')
local files = require('files')
local repr, stringify, equivalent
@@ -19,10 +18,10 @@ do
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end
local unpack = unpack or table.unpack
-local match, sub, rep, gsub, format, byte, find
+local match, sub, gsub, format, byte, find
do
local _obj_0 = string
- match, sub, rep, gsub, format, byte, match, find = _obj_0.match, _obj_0.sub, _obj_0.rep, _obj_0.gsub, _obj_0.format, _obj_0.byte, _obj_0.match, _obj_0.find
+ match, sub, gsub, format, byte, find = _obj_0.match, _obj_0.sub, _obj_0.gsub, _obj_0.format, _obj_0.byte, _obj_0.find
end
local NomsuCode, LuaCode, Source
do
@@ -61,46 +60,6 @@ table.fork = function(t, values)
__index = t
})
end
-local line_counter = re.compile([[ lines <- {| line (%nl line)* |}
- line <- {} (!%nl .)*
-]], {
- nl = lpeg.P("\r") ^ -1 * lpeg.P("\n")
-})
-local get_lines = re.compile([[ lines <- {| line (%nl line)* |}
- line <- {[^%nl]*}
-]], {
- nl = lpeg.P("\r") ^ -1 * lpeg.P("\n")
-})
-LINE_STARTS = setmetatable({ }, {
- __mode = "k",
- __index = function(self, k)
- if type(k) ~= 'string' then
- k = tostring(k)
- do
- local v = rawget(self, k)
- if v then
- return v
- end
- end
- end
- local line_starts = line_counter:match(k)
- self[k] = line_starts
- return line_starts
- end
-})
-pos_to_line = function(str, pos)
- local line_starts = LINE_STARTS[str]
- local lo, hi = 1, #line_starts
- while lo <= hi do
- local mid = math.floor((lo + hi) / 2)
- if line_starts[mid] > pos then
- hi = mid - 1
- else
- lo = mid + 1
- end
- end
- return hi
-end
do
local STRING_METATABLE = getmetatable("")
STRING_METATABLE.__add = function(self, other)
@@ -262,11 +221,12 @@ do
NomsuCompiler.AST = AST
NomsuCompiler.compile_error = function(self, tok, err_format_string, ...)
local file = files.read(tok.source.filename)
- local line_no = pos_to_line(file, tok.source.start)
- local line_start = LINE_STARTS[file][line_no]
+ local line_starts = files.get_line_starts(file)
+ local line_no = files.get_line_number(file, tok.source.start)
+ local line_start = line_starts[line_no]
local src = colored.dim(file:sub(line_start, tok.source.start - 1))
src = src .. colored.underscore(colored.bright(colored.red(file:sub(tok.source.start, tok.source.stop - 1))))
- local end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
+ local end_of_line = (line_starts[files.get_line_number(file, tok.source.stop) + 1] or 0) - 1
src = src .. colored.dim(file:sub(tok.source.stop, end_of_line - 1))
src = ' ' .. src:gsub('\n', '\n ')
local err_msg = err_format_string:format(src, ...)
@@ -498,7 +458,7 @@ do
end
local nomsu_str = tostring(file:sub(source.start, source.stop))
local lua_line = 1
- local nomsu_line = pos_to_line(nomsu_str, source.start)
+ local nomsu_line = files.get_line_number(nomsu_str, source.start)
local fn
fn = function(s)
if type(s) == 'string' then
@@ -509,7 +469,7 @@ do
else
local old_line = nomsu_line
if s.source then
- nomsu_line = pos_to_line(nomsu_str, s.source.start)
+ nomsu_line = files.get_line_number(nomsu_str, s.source.start)
end
local _list_0 = s.bits
for _index_0 = 1, #_list_0 do
@@ -629,7 +589,7 @@ do
local bit_lua = self:compile(bit)
if not (bit_lua.is_value) then
local src = ' ' .. gsub(tostring(self:tree_to_nomsu(bit)), '\n', '\n ')
- local line = tostring(bit.source.filename) .. ":" .. tostring(pos_to_line(files.read(bit.source.filename), bit.source.start))
+ local line = tostring(bit.source.filename) .. ":" .. tostring(files.get_line_number(files.read(bit.source.filename), bit.source.start))
self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end
if #lua.bits > 0 then
diff --git a/nomsu_compiler.moon b/nomsu_compiler.moon
index 99cfce7..c7105f3 100644
--- a/nomsu_compiler.moon
+++ b/nomsu_compiler.moon
@@ -11,7 +11,6 @@
-- lua nomsu.lua your_file.nom
lpeg = require 'lpeg'
re = require 're'
-lpeg.setmaxstack 10000
utils = require 'utils'
files = require 'files'
{:repr, :stringify, :equivalent} = utils
@@ -20,7 +19,7 @@ colors = require 'consolecolors'
colored = setmetatable({}, {__index:(_,color)-> ((msg)-> colors[color]..tostring(msg or '')..colors.reset)})
{:insert, :remove, :concat} = table
unpack or= table.unpack
-{:match, :sub, :rep, :gsub, :format, :byte, :match, :find} = string
+{:match, :sub, :gsub, :format, :byte, :find} = string
{:NomsuCode, :LuaCode, :Source} = require "code_obj"
AST = require "nomsu_tree"
Parser = require("parser")
@@ -50,41 +49,6 @@ table.fork = (t, values)-> setmetatable(values or {}, {__index:t})
-- Add a ((%x foo %y) where {x:"asdf", y:"fdsa"}) compile-time action for substitution
-- Re-implement nomsu-to-lua comment translation?
-line_counter = re.compile([[
- lines <- {| line (%nl line)* |}
- line <- {} (!%nl .)*
-]], nl:lpeg.P("\r")^-1 * lpeg.P("\n"))
-get_lines = re.compile([[
- lines <- {| line (%nl line)* |}
- line <- {[^%nl]*}
-]], nl:lpeg.P("\r")^-1 * lpeg.P("\n"))
--- Mapping from line number -> character offset
-export LINE_STARTS
--- LINE_STARTS is a mapping from strings to a table that maps line number to character positions
-LINE_STARTS = setmetatable {}, {
- __mode:"k"
- __index: (k)=>
- -- Implicitly convert Lua and Nomsu objects to strings
- if type(k) != 'string'
- k = tostring(k)
- if v = rawget(self, k)
- return v
- line_starts = line_counter\match(k)
- self[k] = line_starts
- return line_starts
-}
-export pos_to_line
-pos_to_line = (str, pos)->
- line_starts = LINE_STARTS[str]
- -- Binary search for line number of position
- lo, hi = 1, #line_starts
- while lo <= hi
- mid = math.floor((lo+hi)/2)
- if line_starts[mid] > pos
- hi = mid-1
- else lo = mid+1
- return hi
-
-- Use + operator for string coercive concatenation (note: "asdf" + 3 == "asdf3")
-- Use [] for accessing string characters, or s[{3,4}] for s:sub(3,4)
-- Note: This globally affects all strings in this instance of Lua!
@@ -158,11 +122,12 @@ with NomsuCompiler
.compile_error = (tok, err_format_string, ...)=>
file = files.read(tok.source.filename)
- line_no = pos_to_line(file, tok.source.start)
- line_start = LINE_STARTS[file][line_no]
+ line_starts = files.get_line_starts(file)
+ line_no = files.get_line_number(file, tok.source.start)
+ line_start = line_starts[line_no]
src = colored.dim(file\sub(line_start, tok.source.start-1))
src ..= colored.underscore colored.bright colored.red(file\sub(tok.source.start, tok.source.stop-1))
- end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
+ end_of_line = (line_starts[files.get_line_number(file, tok.source.stop) + 1] or 0) - 1
src ..= colored.dim(file\sub(tok.source.stop, end_of_line-1))
src = ' '..src\gsub('\n', '\n ')
err_msg = err_format_string\format(src, ...)
@@ -336,7 +301,7 @@ with NomsuCompiler
error "Failed to find file: #{source.filename}"
nomsu_str = tostring(file\sub(source.start, source.stop))
lua_line = 1
- nomsu_line = pos_to_line(nomsu_str, source.start)
+ nomsu_line = files.get_line_number(nomsu_str, source.start)
fn = (s)->
if type(s) == 'string'
for nl in s\gmatch("\n")
@@ -345,7 +310,7 @@ with NomsuCompiler
else
old_line = nomsu_line
if s.source
- nomsu_line = pos_to_line(nomsu_str, s.source.start)
+ nomsu_line = files.get_line_number(nomsu_str, s.source.start)
for b in *s.bits do fn(b)
fn(lua)
map[lua_line] or= nomsu_line
@@ -410,7 +375,7 @@ with NomsuCompiler
bit_lua = @compile(bit)
unless bit_lua.is_value
src = ' '..gsub(tostring(@tree_to_nomsu(bit)), '\n','\n ')
- line = "#{bit.source.filename}:#{pos_to_line(files.read(bit.source.filename), bit.source.start)}"
+ line = "#{bit.source.filename}:#{files.get_line_number(files.read(bit.source.filename), bit.source.start)}"
@compile_error bit,
"Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
if #lua.bits > 0 then lua\append ".."
diff --git a/parser.lua b/parser.lua
index ad81252..e54ad6b 100644
--- a/parser.lua
+++ b/parser.lua
@@ -4,10 +4,10 @@ lpeg.setmaxstack(10000)
local P, R, V, S, Cg, C, Cp, B, Cmt, Carg
P, R, V, S, Cg, C, Cp, B, Cmt, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.S, lpeg.Cg, lpeg.C, lpeg.Cp, lpeg.B, lpeg.Cmt, lpeg.Carg
local utils = require('utils')
-local match, sub, rep, gsub, format, byte, find
+local match, sub
do
local _obj_0 = string
- match, sub, rep, gsub, format, byte, match, find = _obj_0.match, _obj_0.sub, _obj_0.rep, _obj_0.gsub, _obj_0.format, _obj_0.byte, _obj_0.match, _obj_0.find
+ match, sub = _obj_0.match, _obj_0.sub
end
local NomsuCode, LuaCode, Source
do
diff --git a/parser.moon b/parser.moon
index 6fe54e6..e7ee809 100644
--- a/parser.moon
+++ b/parser.moon
@@ -4,7 +4,7 @@ re = require 're'
lpeg.setmaxstack 10000
{:P,:R,:V,:S,:Cg,:C,:Cp,:B,:Cmt,:Carg} = lpeg
utils = require 'utils'
-{:match, :sub, :rep, :gsub, :format, :byte, :match, :find} = string
+{:match, :sub} = string
{:NomsuCode, :LuaCode, :Source} = require "code_obj"
AST = require "nomsu_tree"