Cleaning up code and shuffling things around.

This commit is contained in:
Bruce Hill 2018-06-24 23:18:32 -07:00
parent b09db8f7df
commit 2db2c68ac3
6 changed files with 95 additions and 96 deletions

View File

@ -1,3 +1,5 @@
local lpeg = require('lpeg')
local re = require('re')
local files = { } local files = { }
local _FILE_CACHE = { } local _FILE_CACHE = { }
files.spoof = function(filename, contents) files.spoof = function(filename, contents)
@ -48,7 +50,7 @@ iterate_single = function(item, prev)
end end
end end
local ok, lfs = pcall(require, "lfs") local ok, lfs = pcall(require, "lfs")
if ok and false then if ok then
files.walk = function(path) files.walk = function(path)
local browse local browse
browse = function(filename) browse = function(filename)
@ -121,4 +123,42 @@ else
end) end)
end 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 return files

View File

@ -1,4 +1,6 @@
-- Some file utilities for searching for files recursively and using package.nomsupath -- Some file utilities for searching for files recursively and using package.nomsupath
lpeg = require 'lpeg'
re = require 're'
files = {} files = {}
_FILE_CACHE = {} _FILE_CACHE = {}
@ -83,4 +85,36 @@ else
unless found unless found
error("Invalid file path: "..tostring(path)) 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 return files

View File

@ -1,6 +1,5 @@
local lpeg = require('lpeg') local lpeg = require('lpeg')
local re = require('re') local re = require('re')
lpeg.setmaxstack(10000)
local utils = require('utils') local utils = require('utils')
local files = require('files') local files = require('files')
local repr, stringify, equivalent local repr, stringify, equivalent
@ -19,10 +18,10 @@ do
insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
end end
local unpack = unpack or table.unpack local unpack = unpack or table.unpack
local match, sub, rep, gsub, format, byte, find local match, sub, gsub, format, byte, find
do do
local _obj_0 = string 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 end
local NomsuCode, LuaCode, Source local NomsuCode, LuaCode, Source
do do
@ -61,46 +60,6 @@ table.fork = function(t, values)
__index = t __index = t
}) })
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")
})
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 do
local STRING_METATABLE = getmetatable("") local STRING_METATABLE = getmetatable("")
STRING_METATABLE.__add = function(self, other) STRING_METATABLE.__add = function(self, other)
@ -262,11 +221,12 @@ do
NomsuCompiler.AST = AST NomsuCompiler.AST = AST
NomsuCompiler.compile_error = function(self, tok, err_format_string, ...) NomsuCompiler.compile_error = function(self, tok, err_format_string, ...)
local file = files.read(tok.source.filename) local file = files.read(tok.source.filename)
local line_no = pos_to_line(file, tok.source.start) local line_starts = files.get_line_starts(file)
local line_start = LINE_STARTS[file][line_no] 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)) 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)))) 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 .. colored.dim(file:sub(tok.source.stop, end_of_line - 1))
src = ' ' .. src:gsub('\n', '\n ') src = ' ' .. src:gsub('\n', '\n ')
local err_msg = err_format_string:format(src, ...) local err_msg = err_format_string:format(src, ...)
@ -498,7 +458,7 @@ do
end end
local nomsu_str = tostring(file:sub(source.start, source.stop)) local nomsu_str = tostring(file:sub(source.start, source.stop))
local lua_line = 1 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 local fn
fn = function(s) fn = function(s)
if type(s) == 'string' then if type(s) == 'string' then
@ -509,7 +469,7 @@ do
else else
local old_line = nomsu_line local old_line = nomsu_line
if s.source then 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 end
local _list_0 = s.bits local _list_0 = s.bits
for _index_0 = 1, #_list_0 do for _index_0 = 1, #_list_0 do
@ -629,7 +589,7 @@ do
local bit_lua = self:compile(bit) local bit_lua = self:compile(bit)
if not (bit_lua.is_value) then if not (bit_lua.is_value) then
local src = ' ' .. gsub(tostring(self:tree_to_nomsu(bit)), '\n', '\n ') 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.") self:compile_error(bit, "Cannot use:\n%s\nas a string interpolation value, since it's not an expression.")
end end
if #lua.bits > 0 then if #lua.bits > 0 then

View File

@ -11,7 +11,6 @@
-- lua nomsu.lua your_file.nom -- lua nomsu.lua your_file.nom
lpeg = require 'lpeg' lpeg = require 'lpeg'
re = require 're' re = require 're'
lpeg.setmaxstack 10000
utils = require 'utils' utils = require 'utils'
files = require 'files' files = require 'files'
{:repr, :stringify, :equivalent} = utils {:repr, :stringify, :equivalent} = utils
@ -20,7 +19,7 @@ colors = require 'consolecolors'
colored = setmetatable({}, {__index:(_,color)-> ((msg)-> colors[color]..tostring(msg or '')..colors.reset)}) colored = setmetatable({}, {__index:(_,color)-> ((msg)-> colors[color]..tostring(msg or '')..colors.reset)})
{:insert, :remove, :concat} = table {:insert, :remove, :concat} = table
unpack or= table.unpack 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" {:NomsuCode, :LuaCode, :Source} = require "code_obj"
AST = require "nomsu_tree" AST = require "nomsu_tree"
Parser = require("parser") 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 -- Add a ((%x foo %y) where {x:"asdf", y:"fdsa"}) compile-time action for substitution
-- Re-implement nomsu-to-lua comment translation? -- 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 + operator for string coercive concatenation (note: "asdf" + 3 == "asdf3")
-- Use [] for accessing string characters, or s[{3,4}] for s:sub(3,4) -- 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! -- Note: This globally affects all strings in this instance of Lua!
@ -158,11 +122,12 @@ with NomsuCompiler
.compile_error = (tok, err_format_string, ...)=> .compile_error = (tok, err_format_string, ...)=>
file = files.read(tok.source.filename) file = files.read(tok.source.filename)
line_no = pos_to_line(file, tok.source.start) line_starts = files.get_line_starts(file)
line_start = LINE_STARTS[file][line_no] 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.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)) 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 ..= colored.dim(file\sub(tok.source.stop, end_of_line-1))
src = ' '..src\gsub('\n', '\n ') src = ' '..src\gsub('\n', '\n ')
err_msg = err_format_string\format(src, ...) err_msg = err_format_string\format(src, ...)
@ -336,7 +301,7 @@ with NomsuCompiler
error "Failed to find file: #{source.filename}" error "Failed to find file: #{source.filename}"
nomsu_str = tostring(file\sub(source.start, source.stop)) nomsu_str = tostring(file\sub(source.start, source.stop))
lua_line = 1 lua_line = 1
nomsu_line = pos_to_line(nomsu_str, source.start) nomsu_line = files.get_line_number(nomsu_str, source.start)
fn = (s)-> fn = (s)->
if type(s) == 'string' if type(s) == 'string'
for nl in s\gmatch("\n") for nl in s\gmatch("\n")
@ -345,7 +310,7 @@ with NomsuCompiler
else else
old_line = nomsu_line old_line = nomsu_line
if s.source 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) for b in *s.bits do fn(b)
fn(lua) fn(lua)
map[lua_line] or= nomsu_line map[lua_line] or= nomsu_line
@ -410,7 +375,7 @@ with NomsuCompiler
bit_lua = @compile(bit) bit_lua = @compile(bit)
unless bit_lua.is_value unless bit_lua.is_value
src = ' '..gsub(tostring(@tree_to_nomsu(bit)), '\n','\n ') 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, @compile_error bit,
"Cannot use:\n%s\nas a string interpolation value, since it's not an expression." "Cannot use:\n%s\nas a string interpolation value, since it's not an expression."
if #lua.bits > 0 then lua\append ".." if #lua.bits > 0 then lua\append ".."

View File

@ -4,10 +4,10 @@ lpeg.setmaxstack(10000)
local P, R, V, S, Cg, C, Cp, B, Cmt, Carg 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 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 utils = require('utils')
local match, sub, rep, gsub, format, byte, find local match, sub
do do
local _obj_0 = string 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 end
local NomsuCode, LuaCode, Source local NomsuCode, LuaCode, Source
do do

View File

@ -4,7 +4,7 @@ re = require 're'
lpeg.setmaxstack 10000 lpeg.setmaxstack 10000
{:P,:R,:V,:S,:Cg,:C,:Cp,:B,:Cmt,:Carg} = lpeg {:P,:R,:V,:S,:Cg,:C,:Cp,:B,:Cmt,:Carg} = lpeg
utils = require 'utils' utils = require 'utils'
{:match, :sub, :rep, :gsub, :format, :byte, :match, :find} = string {:match, :sub} = string
{:NomsuCode, :LuaCode, :Source} = require "code_obj" {:NomsuCode, :LuaCode, :Source} = require "code_obj"
AST = require "nomsu_tree" AST = require "nomsu_tree"