Added tentative support for luajit (depends on pure-lua LPEG
implementation).
This commit is contained in:
parent
126f51f955
commit
1a755ddee8
@ -163,7 +163,7 @@ do
|
||||
if start or stop then
|
||||
self.source = Source(filename, tonumber(start), tonumber(stop))
|
||||
else
|
||||
self.source = Source(self.source, 1, #self + 1)
|
||||
self.source = Source(self.source, 1, #tostring(self) + 1)
|
||||
end
|
||||
end
|
||||
assert(self.source == nil or Source:is_instance(self.source))
|
||||
@ -346,7 +346,7 @@ do
|
||||
else
|
||||
walk(b, pos)
|
||||
end
|
||||
pos = pos + #b
|
||||
pos = pos + #tostring(b)
|
||||
end
|
||||
end
|
||||
walk(self, 1)
|
||||
|
@ -71,7 +71,7 @@ class Code
|
||||
if start or stop
|
||||
@source = Source(filename, tonumber(start), tonumber(stop))
|
||||
else
|
||||
@source = Source(@source, 1, #self+1)
|
||||
@source = Source(@source, 1, #tostring(self)+1)
|
||||
assert(@source == nil or Source\is_instance(@source))
|
||||
indent = 0
|
||||
for i,b in ipairs @bits
|
||||
@ -219,7 +219,7 @@ class Lua extends Code
|
||||
nomsu_to_lua[lua.source.start] = pos
|
||||
else
|
||||
walk b, pos
|
||||
pos += #b
|
||||
pos += #tostring(b)
|
||||
walk self, 1
|
||||
return {
|
||||
nomsu_filename:@source.filename
|
||||
|
@ -159,19 +159,6 @@ immediately
|
||||
compile [nomsu] to: Lua value "nomsu"
|
||||
compile [%var as lua identifier] to: Lua value "nomsu:var_to_lua_identifier(\(%var as lua expr))"
|
||||
|
||||
action [action %names metadata]
|
||||
=lua "nomsu.action_metadata[ACTIONS[\%names]]"
|
||||
|
||||
# Get the source code for a function
|
||||
action [help %action]
|
||||
lua> ".."
|
||||
local metadata = \(action %action metadata);
|
||||
if not metadata then
|
||||
print("Action not found: "..repr(\%action));
|
||||
else
|
||||
print(metadata.src or "<unknown source code>");
|
||||
end
|
||||
|
||||
# Compiler tools
|
||||
immediately
|
||||
compile [run %code] to
|
||||
|
@ -163,7 +163,14 @@ immediately
|
||||
# Unary operators
|
||||
compile [- %] to: Lua value "(- \(% as lua expr))"
|
||||
compile [not %] to: Lua value "(not \(% as lua expr))"
|
||||
compile [length of %list] to: Lua value "(#\(%list as lua expr))"
|
||||
compile [length of %list] to
|
||||
# A bit of a hack so that luajit works properly.
|
||||
Lua value ".."
|
||||
(function(l)
|
||||
local mt = getmetatable(l);
|
||||
if mt and mt.__len then return mt.__len(l) end
|
||||
return #l
|
||||
end)(\(%list as lua expr))
|
||||
|
||||
# Update operators
|
||||
immediately
|
||||
|
@ -83,34 +83,36 @@ compile [define object %classname %class_body] to
|
||||
%actions <- %line.value.2
|
||||
%body <- %line.value.3
|
||||
lua> ".."
|
||||
local stubs = {};
|
||||
for i, action in ipairs(\%actions.value) do
|
||||
stubs[i] = nomsu:tree_to_named_stub(action);
|
||||
end
|
||||
local args = {};
|
||||
for i,tok in ipairs(\%actions.value[1].value) do
|
||||
if tok.type == "Var" then args[#args+1] = nomsu:var_to_lua_identifier(tok.value); end
|
||||
end
|
||||
local arg_set = {};
|
||||
for i, arg in ipairs(args) do arg_set[arg] = true; end
|
||||
local body_lua = nomsu:tree_to_lua(\%body);
|
||||
body_lua:convert_to_statements();
|
||||
body_lua:declare_locals();
|
||||
local lua_fn_args = table.concat({"self", unpack(args)}, ", ");
|
||||
local def_tree = nomsu.compilestack[#nomsu.compilestack];
|
||||
|
||||
local compiled_args = {};
|
||||
for i, arg in ipairs(args) do
|
||||
compiled_args[i] = "nomsu:tree_to_lua("..arg..")";
|
||||
end
|
||||
compiled_args = table.concat(compiled_args, "..', '..");
|
||||
table.insert(\%methods, ([==[
|
||||
%s[ %s] = function(%s)
|
||||
%s
|
||||
do
|
||||
local stubs = {};
|
||||
for i, action in ipairs(\%actions.value) do
|
||||
stubs[i] = nomsu:tree_to_named_stub(action);
|
||||
end
|
||||
]==]):format(
|
||||
\%class_identifier, repr(stubs[1]), lua_fn_args,
|
||||
body_lua));
|
||||
local args = {};
|
||||
for i,tok in ipairs(\%actions.value[1].value) do
|
||||
if tok.type == "Var" then args[#args+1] = nomsu:var_to_lua_identifier(tok.value); end
|
||||
end
|
||||
local arg_set = {};
|
||||
for i, arg in ipairs(args) do arg_set[arg] = true; end
|
||||
local body_lua = nomsu:tree_to_lua(\%body);
|
||||
body_lua:convert_to_statements();
|
||||
body_lua:declare_locals();
|
||||
local lua_fn_args = table.concat({"self", unpack(args)}, ", ");
|
||||
local def_tree = nomsu.compilestack[#nomsu.compilestack];
|
||||
|
||||
local compiled_args = {};
|
||||
for i, arg in ipairs(args) do
|
||||
compiled_args[i] = "nomsu:tree_to_lua("..arg..")";
|
||||
end
|
||||
compiled_args = table.concat(compiled_args, "..', '..");
|
||||
table.insert(\%methods, ([==[
|
||||
%s[ %s] = function(%s)
|
||||
%s
|
||||
end
|
||||
]==]):format(
|
||||
\%class_identifier, repr(stubs[1]), lua_fn_args,
|
||||
body_lua));
|
||||
end
|
||||
|
||||
return
|
||||
Lua ".."
|
||||
|
120
nomsu.lua
120
nomsu.lua
@ -1,5 +1,35 @@
|
||||
local re = require('re')
|
||||
local lpeg = require('lpeg')
|
||||
if jit then
|
||||
package.path = "LPegLJ/src/?.lua;" .. tostring(package.path)
|
||||
lpeg = require('lpeglj')
|
||||
re = require('re')
|
||||
bit32 = require('bit')
|
||||
local _pairs, _ipairs = pairs, ipairs
|
||||
pairs = function(x)
|
||||
do
|
||||
local mt = getmetatable(x)
|
||||
if mt then
|
||||
if mt.__pairs then
|
||||
return mt.__pairs(x)
|
||||
end
|
||||
end
|
||||
end
|
||||
return _pairs(x)
|
||||
end
|
||||
ipairs = function(x)
|
||||
do
|
||||
local mt = getmetatable(x)
|
||||
if mt then
|
||||
if mt.__ipairs then
|
||||
return mt.__ipairs(x)
|
||||
end
|
||||
end
|
||||
end
|
||||
return _ipairs(x)
|
||||
end
|
||||
else
|
||||
re = require('re')
|
||||
lpeg = require('lpeg')
|
||||
end
|
||||
lpeg.setmaxstack(10000)
|
||||
local P, R, V, S, Cg, C, Cp, B, Cmt
|
||||
P, R, V, S, Cg, C, Cp, B, Cmt = lpeg.P, lpeg.R, lpeg.V, lpeg.S, lpeg.Cg, lpeg.C, lpeg.Cp, lpeg.B, lpeg.Cmt
|
||||
@ -41,7 +71,7 @@ FILE_CACHE = setmetatable({ }, {
|
||||
if not (file) then
|
||||
return nil
|
||||
end
|
||||
local contents = file:read("a")
|
||||
local contents = file:read("*a")
|
||||
file:close()
|
||||
self[filename] = contents
|
||||
return contents
|
||||
@ -118,7 +148,7 @@ local NOMSU_DEFS
|
||||
do
|
||||
local _with_0 = { }
|
||||
_with_0.Tuple = function(values)
|
||||
return Tuple(table.unpack(values))
|
||||
return Tuple(unpack(values))
|
||||
end
|
||||
_with_0.DictEntry = function(k, v)
|
||||
return Types.DictEntry(k, v)
|
||||
@ -343,7 +373,7 @@ do
|
||||
if compile_fn == nil then
|
||||
compile_fn = nil
|
||||
end
|
||||
if #nomsu_code == 0 then
|
||||
if #tostring(nomsu_code) == 0 then
|
||||
return nil
|
||||
end
|
||||
local tree = self:parse(nomsu_code)
|
||||
@ -884,46 +914,35 @@ OPTIONS
|
||||
break
|
||||
end
|
||||
local line = nil
|
||||
do
|
||||
local metadata = nomsu.action_metadata[calling_fn.func]
|
||||
if metadata then
|
||||
local filename, start, stop = metadata.source:match("([^:]*):([0-9]*),([0-9]*)")
|
||||
if filename then
|
||||
local file = FILE_CACHE[filename]
|
||||
local line_no = 1
|
||||
for _ in file:sub(1, tonumber(start)):gmatch("\n") do
|
||||
line_no = line_no + 1
|
||||
end
|
||||
local offending_statement = file:sub(tonumber(start), tonumber(stop))
|
||||
if #offending_statement > 50 then
|
||||
offending_statement = offending_statement:sub(1, 50) .. "..."
|
||||
end
|
||||
offending_statement = colored.red(offending_statement)
|
||||
line = colored.yellow(filename .. ":" .. tostring(line_no) .. "\n " .. offending_statement)
|
||||
_ = [=[ if metadata = nomsu.action_metadata[calling_fn.func]
|
||||
filename, start, stop = metadata.source\match("([^:]*):([0-9]*),([0-9]*)")
|
||||
if filename
|
||||
file = FILE_CACHE[filename]
|
||||
line_no = 1
|
||||
for _ in file\sub(1,tonumber(start))\gmatch("\n") do line_no += 1
|
||||
offending_statement = file\sub(tonumber(start),tonumber(stop))
|
||||
if #offending_statement > 50
|
||||
offending_statement = offending_statement\sub(1,50).."..."
|
||||
offending_statement = colored.red(offending_statement)
|
||||
line = colored.yellow(filename..":"..tostring(line_no).."\n "..offending_statement)
|
||||
else
|
||||
line = colored.yellow(metadata.source)
|
||||
name = colored.bright(colored.yellow(metadata.aliases[1]))
|
||||
else
|
||||
line = colored.yellow(metadata.source)
|
||||
end
|
||||
name = colored.bright(colored.yellow(metadata.aliases[1]))
|
||||
else
|
||||
if calling_fn.istailcall and not name then
|
||||
name = "<tail call>"
|
||||
end
|
||||
if calling_fn.short_src == "./nomsu.moon" and line_table then
|
||||
local char = line_table[calling_fn.currentline]
|
||||
local line_num = 1
|
||||
for _ in nomsu_source:sub(1, char):gmatch("\n") do
|
||||
line_num = line_num + 1
|
||||
end
|
||||
line = colored.cyan(tostring(calling_fn.short_src) .. ":" .. tostring(line_num))
|
||||
name = colored.bright(colored.cyan(name or "???"))
|
||||
else
|
||||
line = colored.blue(tostring(calling_fn.short_src) .. ":" .. tostring(calling_fn.currentline))
|
||||
name = colored.bright(colored.blue(name or "???"))
|
||||
end
|
||||
end
|
||||
end
|
||||
local _from = colored.dim(colored.white("|"))
|
||||
io.stderr:write(("%32s %s %s\n"):format(name, _from, line))
|
||||
if calling_fn.istailcall and not name
|
||||
name = "<tail call>"
|
||||
if calling_fn.short_src == "./nomsu.moon" and line_table
|
||||
char = line_table[calling_fn.currentline]
|
||||
line_num = 1
|
||||
for _ in nomsu_source\sub(1,char)\gmatch("\n") do line_num += 1
|
||||
line = colored.cyan("#{calling_fn.short_src}:#{line_num}")
|
||||
name = colored.bright(colored.cyan(name or "???"))
|
||||
else
|
||||
line = colored.blue("#{calling_fn.short_src}:#{calling_fn.currentline}")
|
||||
name = colored.bright(colored.blue(name or "???"))
|
||||
_from = colored.dim colored.white "|"
|
||||
io.stderr\write(("%32s %s %s\n")\format(name, _from, line))
|
||||
]=]
|
||||
_continue_0 = true
|
||||
until true
|
||||
if not _continue_0 then
|
||||
@ -1064,13 +1083,12 @@ OPTIONS
|
||||
print_err_msg(error_message)
|
||||
return os.exit(false, true)
|
||||
end
|
||||
do
|
||||
local ldt = require('ldt')
|
||||
if ldt then
|
||||
ldt.guard(run)
|
||||
else
|
||||
xpcall(run, err_hand)
|
||||
end
|
||||
local ldt
|
||||
ok, ldt = pcall(require, 'ldt')
|
||||
if ok then
|
||||
ldt.guard(run)
|
||||
else
|
||||
xpcall(run, err_hand)
|
||||
end
|
||||
end
|
||||
return NomsuCompiler
|
||||
|
37
nomsu.moon
37
nomsu.moon
@ -10,8 +10,30 @@
|
||||
-- nomsu:run(your_nomsu_code)
|
||||
-- Or from the command line:
|
||||
-- lua nomsu.lua [input_file [output_file or -]]
|
||||
re = require 're'
|
||||
lpeg = require 'lpeg'
|
||||
export lpeg, re
|
||||
if jit
|
||||
package.path = "LPegLJ/src/?.lua;#{package.path}"
|
||||
lpeg = require 'lpeglj'
|
||||
re = require 're'
|
||||
|
||||
export bit32
|
||||
bit32 = require('bit')
|
||||
|
||||
_pairs, _ipairs = pairs, ipairs
|
||||
export pairs, ipairs
|
||||
pairs = (x)->
|
||||
if mt = getmetatable(x)
|
||||
if mt.__pairs
|
||||
return mt.__pairs(x)
|
||||
return _pairs(x)
|
||||
ipairs = (x)->
|
||||
if mt = getmetatable(x)
|
||||
if mt.__ipairs
|
||||
return mt.__ipairs(x)
|
||||
return _ipairs(x)
|
||||
else
|
||||
re = require 're'
|
||||
lpeg = require 'lpeg'
|
||||
lpeg.setmaxstack 10000
|
||||
{:P,:R,:V,:S,:Cg,:C,:Cp,:B,:Cmt} = lpeg
|
||||
utils = require 'utils'
|
||||
@ -44,7 +66,7 @@ FILE_CACHE = setmetatable {}, {
|
||||
__index: (filename)=>
|
||||
file = io.open(filename)
|
||||
return nil unless file
|
||||
contents = file\read("a")
|
||||
contents = file\read("*a")
|
||||
file\close!
|
||||
self[filename] = contents
|
||||
return contents
|
||||
@ -111,7 +133,7 @@ Types = require "nomsu_tree"
|
||||
NOMSU_DEFS = with {}
|
||||
-- Newline supports either windows-style CR+LF or unix-style LF
|
||||
.Tuple = (values)->
|
||||
return Tuple(table.unpack(values))
|
||||
return Tuple(unpack(values))
|
||||
.DictEntry = (k,v) -> Types.DictEntry(k,v)
|
||||
.nl = P("\r")^-1 * P("\n")
|
||||
.ws = S(" \t")
|
||||
@ -308,7 +330,7 @@ class NomsuCompiler
|
||||
|
||||
_nomsu_chunk_counter = 0
|
||||
run: (nomsu_code, compile_fn=nil)=>
|
||||
if #nomsu_code == 0 then return nil
|
||||
if #tostring(nomsu_code) == 0 then return nil
|
||||
tree = @parse(nomsu_code)
|
||||
assert tree, "Failed to parse: #{nomsu_code}"
|
||||
assert tree.type == "File", "Attempt to run non-file: #{tree.type}"
|
||||
@ -629,6 +651,7 @@ OPTIONS
|
||||
name = calling_fn.name
|
||||
if name == "run_lua_fn" then continue
|
||||
line = nil
|
||||
[=[
|
||||
if metadata = nomsu.action_metadata[calling_fn.func]
|
||||
filename, start, stop = metadata.source\match("([^:]*):([0-9]*),([0-9]*)")
|
||||
if filename
|
||||
@ -657,6 +680,7 @@ OPTIONS
|
||||
name = colored.bright(colored.blue(name or "???"))
|
||||
_from = colored.dim colored.white "|"
|
||||
io.stderr\write(("%32s %s %s\n")\format(name, _from, line))
|
||||
]=]
|
||||
io.stderr\flush!
|
||||
|
||||
run = ->
|
||||
@ -763,7 +787,8 @@ OPTIONS
|
||||
|
||||
--ProFi = require 'ProFi'
|
||||
--ProFi\start()
|
||||
if ldt = require('ldt')
|
||||
ok, ldt = pcall(require,'ldt')
|
||||
if ok
|
||||
ldt.guard run
|
||||
else xpcall(run, err_hand)
|
||||
--ProFi\stop()
|
||||
|
@ -1,6 +1,4 @@
|
||||
local utils = require('utils')
|
||||
local re = require('re')
|
||||
local lpeg = require('lpeg')
|
||||
local repr, stringify, min, max, equivalent, set, is_list, sum
|
||||
repr, stringify, min, max, equivalent, set, is_list, sum = utils.repr, utils.stringify, utils.min, utils.max, utils.equivalent, utils.set, utils.is_list, utils.sum
|
||||
local immutable = require('immutable')
|
||||
|
@ -1,8 +1,6 @@
|
||||
-- This file contains the datastructures used to represent parsed Nomsu syntax trees,
|
||||
-- as well as the logic for converting them to Lua code.
|
||||
utils = require 'utils'
|
||||
re = require 're'
|
||||
lpeg = require 'lpeg'
|
||||
{:repr, :stringify, :min, :max, :equivalent, :set, :is_list, :sum} = utils
|
||||
immutable = require 'immutable'
|
||||
{:insert, :remove, :concat} = table
|
||||
|
@ -1,8 +1,5 @@
|
||||
--
|
||||
-- A collection of helper utility functions
|
||||
--
|
||||
local lpeg, re = require("lpeg"), require("re")
|
||||
|
||||
local function is_list(t)
|
||||
if type(t) ~= 'table' then
|
||||
return false
|
||||
|
4
uuid.lua
4
uuid.lua
@ -13,10 +13,10 @@ local function uuid()
|
||||
-- Set the four most significant bits (bits 12 through 15) of the
|
||||
-- time_hi_and_version field to the 4-bit version number from
|
||||
-- Section 4.1.3.
|
||||
bytes[3] = bit32.bor(bytes[3], 0x4000)
|
||||
bytes[3] = bytes[3] + 0x4000
|
||||
-- Set the two most significant bits (bits 6 and 7) of the
|
||||
-- clock_seq_hi_and_reserved to zero and one, respectively.
|
||||
bytes[4] = bit32.bor(bytes[4], 0xC0)
|
||||
bytes[4] = bytes[4] + 0xC0
|
||||
return ("%08x-%04x-%04x-%02x%02x-%6x%6x"):format(unpack(bytes))
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user