Changed stub convention to (foo 1 baz 2) -> foo_1_baz instead of
foo_1_baz_2, removed "smext", made some cleanup changes.
This commit is contained in:
parent
d0c3c57f7b
commit
307dea1881
25
code_obj.lua
25
code_obj.lua
@ -78,7 +78,7 @@ do
|
||||
local _class_0
|
||||
local _base_0 = {
|
||||
is_code = true,
|
||||
as_smext = function(self)
|
||||
text = function(self)
|
||||
if self.__str == nil then
|
||||
local buff, indent = { }, 0
|
||||
local match, gsub, rep
|
||||
@ -95,7 +95,7 @@ do
|
||||
end
|
||||
end
|
||||
else
|
||||
b = b:as_smext()
|
||||
b = b:text()
|
||||
if indent > 0 then
|
||||
b = gsub(b, "\n", "\n" .. rep(" ", indent))
|
||||
end
|
||||
@ -107,7 +107,7 @@ do
|
||||
return self.__str
|
||||
end,
|
||||
__tostring = function(self)
|
||||
return self:as_smext()
|
||||
return self:text()
|
||||
end,
|
||||
as_lua = function(self)
|
||||
return tostring(self.__class.__name) .. "(" .. tostring(concat({
|
||||
@ -126,13 +126,13 @@ do
|
||||
}, ", ")) .. ")"
|
||||
end,
|
||||
__len = function(self)
|
||||
return #self:as_smext()
|
||||
return #self:text()
|
||||
end,
|
||||
match = function(self, ...)
|
||||
return self:as_smext():match(...)
|
||||
return self:text():match(...)
|
||||
end,
|
||||
gmatch = function(self, ...)
|
||||
return self:as_smext():gmatch(...)
|
||||
return self:text():gmatch(...)
|
||||
end,
|
||||
dirty = function(self)
|
||||
self.__str = nil
|
||||
@ -169,7 +169,7 @@ do
|
||||
end,
|
||||
trailing_line_len = function(self)
|
||||
if self._trailing_line_len == nil then
|
||||
self._trailing_line_len = #self:as_smext():match("[^\n]*$")
|
||||
self._trailing_line_len = #self:text():match("[^\n]*$")
|
||||
end
|
||||
return self._trailing_line_len
|
||||
end,
|
||||
@ -213,7 +213,7 @@ do
|
||||
b.dirty = error
|
||||
end
|
||||
if not (type(b) == 'string') then
|
||||
b = b:as_smext()
|
||||
b = b:text()
|
||||
end
|
||||
local line = match(b, "\n([^\n]*)$")
|
||||
if line then
|
||||
@ -400,7 +400,7 @@ do
|
||||
end
|
||||
else
|
||||
walk(b, pos)
|
||||
b = b:as_smext()
|
||||
b = b:text()
|
||||
end
|
||||
pos = pos + #b
|
||||
end
|
||||
@ -502,12 +502,7 @@ do
|
||||
end
|
||||
NomsuCode = _class_0
|
||||
end
|
||||
Code.__base.append_1 = assert(Code.__base.append)
|
||||
Code.__base.append_1_joined_by_2 = assert(Code.__base.concat_append)
|
||||
Code.__base.prepend_1 = assert(Code.__base.prepend)
|
||||
LuaCode.__base.declare_locals_1 = assert(LuaCode.__base.declare_locals)
|
||||
LuaCode.__base.remove_free_vars_1 = assert(LuaCode.__base.remove_free_vars)
|
||||
LuaCode.__base.add_free_vars_1 = assert(LuaCode.__base.add_free_vars)
|
||||
Code.__base.add_1_joined_with = assert(Code.__base.concat_append)
|
||||
return {
|
||||
Code = Code,
|
||||
NomsuCode = NomsuCode,
|
||||
|
@ -50,7 +50,7 @@ class Code
|
||||
--assert(@source and Source\is_instance(@source), "Source has the wrong type")
|
||||
@append(...)
|
||||
|
||||
as_smext: =>
|
||||
text: =>
|
||||
if @__str == nil
|
||||
buff, indent = {}, 0
|
||||
{:match, :gsub, :rep} = string
|
||||
@ -59,23 +59,23 @@ class Code
|
||||
if spaces = match(b, "\n([ ]*)[^\n]*$")
|
||||
indent = #spaces
|
||||
else
|
||||
b = b\as_smext!
|
||||
b = b\text!
|
||||
if indent > 0
|
||||
b = gsub(b, "\n", "\n"..rep(" ", indent))
|
||||
buff[#buff+1] = b
|
||||
@__str = concat(buff, "")
|
||||
return @__str
|
||||
|
||||
__tostring: => @as_smext!
|
||||
__tostring: => @text!
|
||||
|
||||
as_lua: =>
|
||||
"#{@__class.__name}(#{concat {tostring(@source)\as_lua!, unpack([b\as_lua! for b in *@bits])}, ", "})"
|
||||
|
||||
__len: => #@as_smext!
|
||||
__len: => #@text!
|
||||
|
||||
match: (...)=> @as_smext!\match(...)
|
||||
match: (...)=> @text!\match(...)
|
||||
|
||||
gmatch: (...)=> @as_smext!\gmatch(...)
|
||||
gmatch: (...)=> @text!\gmatch(...)
|
||||
|
||||
dirty: =>
|
||||
@__str = nil
|
||||
@ -100,7 +100,7 @@ class Code
|
||||
|
||||
trailing_line_len: =>
|
||||
if @_trailing_line_len == nil
|
||||
@_trailing_line_len = #@as_smext!\match("[^\n]*$")
|
||||
@_trailing_line_len = #@text!\match("[^\n]*$")
|
||||
return @_trailing_line_len
|
||||
|
||||
is_multiline: =>
|
||||
@ -133,7 +133,7 @@ class Code
|
||||
bits[#bits+1] = b
|
||||
b.dirty = error if b.is_code
|
||||
unless type(b) == 'string'
|
||||
b = b\as_smext!
|
||||
b = b\text!
|
||||
line = match(b, "\n([^\n]*)$")
|
||||
if line
|
||||
line_len = #line
|
||||
@ -240,7 +240,7 @@ class LuaCode extends Code
|
||||
nomsu_to_lua[lua.source.start] = pos
|
||||
else
|
||||
walk b, pos
|
||||
b = b\as_smext!
|
||||
b = b\text!
|
||||
pos += #b
|
||||
walk self, 1
|
||||
return {
|
||||
@ -259,11 +259,6 @@ class NomsuCode extends Code
|
||||
as_lua: Code.as_lua
|
||||
__len: Code.__len
|
||||
|
||||
Code.__base.append_1 = assert Code.__base.append
|
||||
Code.__base.append_1_joined_by_2 = assert Code.__base.concat_append
|
||||
Code.__base.prepend_1 = assert Code.__base.prepend
|
||||
LuaCode.__base.declare_locals_1 = assert LuaCode.__base.declare_locals
|
||||
LuaCode.__base.remove_free_vars_1 = assert LuaCode.__base.remove_free_vars
|
||||
LuaCode.__base.add_free_vars_1 = assert LuaCode.__base.add_free_vars
|
||||
Code.__base.add_1_joined_with = assert Code.__base.concat_append
|
||||
|
||||
return {:Code, :NomsuCode, :LuaCode, :Source}
|
||||
|
@ -57,3 +57,4 @@ upgrade action "parse 1 as 2" to "4.8.10" via (..)
|
||||
|
||||
upgrade action (compile as %) to "4.8.10" as (what % compiles to)
|
||||
upgrade action (action %) to "4.8.10" as (%'s meaning)
|
||||
upgrade action (remove action %) to "4.8.10" as ((%'s meaning) = (nil))
|
||||
|
@ -52,7 +52,7 @@ externally (upgrade action %stub to %version via %upgrade_fn) means:
|
||||
%retval = (make tree %body)
|
||||
%lua::append (..)
|
||||
Lua "\
|
||||
..upgrade_action_1_to_2_via_3(\(quote %action.stub), \(%version as lua expr), function(\(..)
|
||||
..upgrade_action_1_to_2_via(\(quote %action.stub), \(%version as lua expr), function(\(..)
|
||||
\%tree as lua id
|
||||
..)
|
||||
return \%retval
|
||||
|
@ -134,15 +134,15 @@ local _list_mt = {
|
||||
return ret
|
||||
end,
|
||||
__index = {
|
||||
add_1 = insert,
|
||||
append_1 = insert,
|
||||
add_1_at_index_2 = function(t, x, i)
|
||||
add = insert,
|
||||
append = insert,
|
||||
add_1_at_index = function(t, x, i)
|
||||
return insert(t, i, x)
|
||||
end,
|
||||
at_index_1_add_2 = insert,
|
||||
at_index_1_add = insert,
|
||||
pop = remove,
|
||||
remove_last = remove,
|
||||
remove_index_1 = remove,
|
||||
remove_index = remove,
|
||||
last = (function(self)
|
||||
return self[#self]
|
||||
end),
|
||||
@ -165,7 +165,7 @@ local _list_mt = {
|
||||
return _accum_0
|
||||
end)())
|
||||
end,
|
||||
joined_with_1 = function(self, glue)
|
||||
joined_with = function(self, glue)
|
||||
return table.concat((function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 1
|
||||
@ -177,7 +177,7 @@ local _list_mt = {
|
||||
return _accum_0
|
||||
end)(), glue)
|
||||
end,
|
||||
has_1 = function(self, item)
|
||||
has = function(self, item)
|
||||
for _index_0 = 1, #self do
|
||||
local x = self[_index_0]
|
||||
if x == item then
|
||||
@ -186,14 +186,14 @@ local _list_mt = {
|
||||
end
|
||||
return false
|
||||
end,
|
||||
remove_1 = function(self, item)
|
||||
remove = function(self, item)
|
||||
for i, x in ipairs(self) do
|
||||
if x == item then
|
||||
remove(self, i)
|
||||
end
|
||||
end
|
||||
end,
|
||||
index_of_1 = function(self, item)
|
||||
index_of = function(self, item)
|
||||
for i, x in ipairs(self) do
|
||||
if x == item then
|
||||
return i
|
||||
@ -201,7 +201,7 @@ local _list_mt = {
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
from_1_to_2 = function(self, start, stop)
|
||||
from_1_to = function(self, start, stop)
|
||||
local n = #self
|
||||
if n < 0 then
|
||||
start = (n + 1 - start)
|
||||
@ -383,20 +383,20 @@ do
|
||||
local lines, line, line_at, as_lua_id, is_lua_id
|
||||
lines, line, line_at, as_lua_id, is_lua_id = string2.lines, string2.line, string2.line_at, string2.as_lua_id, string2.is_lua_id
|
||||
local text_methods = {
|
||||
formatted_with_1 = format,
|
||||
byte_1 = byte,
|
||||
position_of_1 = find,
|
||||
position_of_1_after_2 = find,
|
||||
formatted_with = format,
|
||||
byte = byte,
|
||||
position_of = find,
|
||||
position_of_1_after = find,
|
||||
as_a_lua_identifier = as_lua_id,
|
||||
is_a_lua_identifier = is_lua_id,
|
||||
as_a_lua_id = as_lua_id,
|
||||
is_a_lua_id = is_lua_id,
|
||||
bytes_1_to_2 = function(self, start, stop)
|
||||
bytes_1_to = function(self, start, stop)
|
||||
return List({
|
||||
byte(tostring(self), start, stop)
|
||||
})
|
||||
end,
|
||||
[as_lua_id("with 1 -> 2")] = gsub,
|
||||
[as_lua_id("with 1 ->")] = gsub,
|
||||
bytes = function(self)
|
||||
return List({
|
||||
byte(tostring(self), 1, -1)
|
||||
@ -405,8 +405,8 @@ do
|
||||
lines = function(self)
|
||||
return List(lines(self))
|
||||
end,
|
||||
line_1 = line,
|
||||
wrapped_to_1 = function(self, maxlen)
|
||||
line = line,
|
||||
wrapped_to = function(self, maxlen)
|
||||
local _lines = { }
|
||||
local _list_0 = self:lines()
|
||||
for _index_0 = 1, #_list_0 do
|
||||
@ -422,22 +422,22 @@ do
|
||||
end
|
||||
return table.concat(_lines, "\n")
|
||||
end,
|
||||
line_at_1 = function(self, i)
|
||||
line_at = function(self, i)
|
||||
return (line_at(self, i))
|
||||
end,
|
||||
line_number_at_1 = function(self, i)
|
||||
line_number_at = function(self, i)
|
||||
return select(2, line_at(self, i))
|
||||
end,
|
||||
line_position_at_1 = function(self, i)
|
||||
line_position_at = function(self, i)
|
||||
return select(3, line_at(self, i))
|
||||
end,
|
||||
matches_1 = function(self, patt)
|
||||
matches = function(self, patt)
|
||||
return match(self, patt) and true or false
|
||||
end,
|
||||
matching_1 = function(self, patt)
|
||||
matching = function(self, patt)
|
||||
return (match(self, patt))
|
||||
end,
|
||||
matching_groups_1 = function(self, patt)
|
||||
matching_groups = function(self, patt)
|
||||
return {
|
||||
match(self, patt)
|
||||
}
|
||||
@ -445,7 +445,7 @@ do
|
||||
[as_lua_id("* 1")] = function(self, n)
|
||||
return rep(self, n)
|
||||
end,
|
||||
all_matches_of_1 = function(self, patt)
|
||||
all_matches_of = function(self, patt)
|
||||
local result = { }
|
||||
local stepper, x, i = gmatch(self, patt)
|
||||
while true do
|
||||
|
@ -58,31 +58,31 @@ _list_mt =
|
||||
insert(ret, x)
|
||||
return ret
|
||||
__index:
|
||||
add_1: insert, append_1: insert
|
||||
add_1_at_index_2: (t,x,i)-> insert(t,i,x)
|
||||
at_index_1_add_2: insert
|
||||
pop: remove, remove_last: remove, remove_index_1: remove
|
||||
add: insert, append: insert
|
||||
add_1_at_index: (t,x,i)-> insert(t,i,x)
|
||||
at_index_1_add: insert
|
||||
pop: remove, remove_last: remove, remove_index: remove
|
||||
last: (=> @[#@]), first: (=> @[1])
|
||||
_1_st_to_last:nth_to_last, _1_nd_to_last:nth_to_last
|
||||
_1_rd_to_last:nth_to_last, _1_th_to_last:nth_to_last
|
||||
-- TODO: use stringify() to allow joining misc. objects?
|
||||
joined: => table.concat([tostring(x) for x in *@]),
|
||||
joined_with_1: (glue)=> table.concat([tostring(x) for x in *@], glue),
|
||||
has_1: (item)=>
|
||||
joined_with: (glue)=> table.concat([tostring(x) for x in *@], glue),
|
||||
has: (item)=>
|
||||
for x in *@
|
||||
if x == item
|
||||
return true
|
||||
return false
|
||||
remove_1: (item)=>
|
||||
remove: (item)=>
|
||||
for i,x in ipairs @
|
||||
if x == item
|
||||
remove(@, i)
|
||||
index_of_1: (item)=>
|
||||
index_of: (item)=>
|
||||
for i,x in ipairs @
|
||||
if x == item
|
||||
return i
|
||||
return nil
|
||||
from_1_to_2: (start, stop)=>
|
||||
from_1_to: (start, stop)=>
|
||||
n = #@
|
||||
start = (n+1-start) if n < 0
|
||||
stop = (n+1-stop) if n < 0
|
||||
@ -149,15 +149,15 @@ do
|
||||
string2 = require 'string2'
|
||||
{:lines, :line, :line_at, :as_lua_id, :is_lua_id} = string2
|
||||
text_methods =
|
||||
formatted_with_1:format, byte_1:byte, position_of_1:find, position_of_1_after_2:find,
|
||||
formatted_with:format, byte:byte, position_of:find, position_of_1_after:find,
|
||||
as_a_lua_identifier: as_lua_id, is_a_lua_identifier: is_lua_id,
|
||||
as_a_lua_id: as_lua_id, is_a_lua_id: is_lua_id,
|
||||
bytes_1_to_2: (start, stop)=> List{byte(tostring(@), start, stop)}
|
||||
[as_lua_id "with 1 -> 2"]: gsub
|
||||
bytes_1_to: (start, stop)=> List{byte(tostring(@), start, stop)}
|
||||
[as_lua_id "with 1 ->"]: gsub
|
||||
bytes: => List{byte(tostring(@), 1, -1)},
|
||||
lines: => List(lines(@))
|
||||
line_1: line
|
||||
wrapped_to_1: (maxlen)=>
|
||||
line: line
|
||||
wrapped_to: (maxlen)=>
|
||||
_lines = {}
|
||||
for line in *@lines!
|
||||
while #line > maxlen
|
||||
@ -169,14 +169,14 @@ do
|
||||
_lines[#_lines+1] = line
|
||||
return table.concat(_lines, "\n")
|
||||
|
||||
line_at_1: (i)=> (line_at(@, i))
|
||||
line_number_at_1: (i)=> select(2, line_at(@, i))
|
||||
line_position_at_1: (i)=> select(3, line_at(@, i))
|
||||
matches_1: (patt)=> match(@, patt) and true or false
|
||||
matching_1: (patt)=> (match(@, patt))
|
||||
matching_groups_1: (patt)=> {match(@, patt)}
|
||||
line_at: (i)=> (line_at(@, i))
|
||||
line_number_at: (i)=> select(2, line_at(@, i))
|
||||
line_position_at: (i)=> select(3, line_at(@, i))
|
||||
matches: (patt)=> match(@, patt) and true or false
|
||||
matching: (patt)=> (match(@, patt))
|
||||
matching_groups: (patt)=> {match(@, patt)}
|
||||
[as_lua_id "* 1"]: (n)=> rep(@, n)
|
||||
all_matches_of_1: (patt)=>
|
||||
all_matches_of: (patt)=>
|
||||
result = {}
|
||||
stepper,x,i = gmatch(@, patt)
|
||||
while true
|
||||
|
@ -102,8 +102,20 @@ test:
|
||||
.."
|
||||
|
||||
# Basic loop control
|
||||
(do next) compiles to (Lua "goto continue")
|
||||
(stop) compiles to (Lua "break")
|
||||
(stop %var) compiles to:
|
||||
if %var:
|
||||
return (..)
|
||||
Lua "goto stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)"
|
||||
..else: return (Lua "break")
|
||||
(do next %var) compiles to:
|
||||
if %var:
|
||||
return (..)
|
||||
Lua "goto continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)"
|
||||
..else: return (Lua "goto continue")
|
||||
[===stop %var ===, ---stop %var ---, ***stop %var ***] all compile to (..)
|
||||
Lua "::stop_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::"
|
||||
[===next %var ===, ---next %var ---, ***next %var ***] all compile to (..)
|
||||
Lua "::continue_\((%var.stub if (%var.type == "action") else %var) as lua identifier)::"
|
||||
|
||||
# While loops
|
||||
test:
|
||||
@ -177,16 +189,6 @@ test:
|
||||
|
||||
return %lua
|
||||
|
||||
# For loop control flow
|
||||
(stop %var) compiles to (..)
|
||||
Lua "goto stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)"
|
||||
(do next %var) compiles to (..)
|
||||
Lua "goto continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)"
|
||||
[===stop %var ===, ---stop %var ---, ***stop %var ***] all compile to (..)
|
||||
Lua "::stop_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::"
|
||||
[===next %var ===, ---next %var ---, ***next %var ***] all compile to (..)
|
||||
Lua "::continue_\((%var.stub if (%var.type == "Action") else %var) as lua identifier)::"
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
test:
|
||||
@ -365,7 +367,7 @@ test:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
test:
|
||||
if:
|
||||
when:
|
||||
(1 == 2) (100 < 0):
|
||||
barf "bad conditional"
|
||||
(1 == 0) (1 == 1) %not_a_variable.x: do nothing
|
||||
@ -377,7 +379,7 @@ test:
|
||||
barf "bad conditional"
|
||||
|
||||
# Multi-branch conditional (if..elseif..else)
|
||||
[if %body, when %body] all compile to:
|
||||
(when %body) compiles to:
|
||||
%code = (Lua "")
|
||||
%clause = "if"
|
||||
%else_allowed = (yes)
|
||||
@ -512,8 +514,6 @@ test:
|
||||
%d.x = "bad"
|
||||
barf
|
||||
..then always: %d.x = "good"
|
||||
..and if it barfs: do nothing
|
||||
|
||||
assume (%d.x == "good")
|
||||
(do %action then always %final_action) compiles to:
|
||||
define mangler
|
||||
|
@ -4,8 +4,7 @@
|
||||
|
||||
use "core/metaprogramming.nom"
|
||||
|
||||
(barf) compiles to (Lua "error(nil, 0);")
|
||||
(barf %msg) compiles to (Lua "error(\(%msg as lua expr), 0);")
|
||||
(barf %msg) compiles to (Lua "error(\(=lua "\%msg and \(%msg as lua expr) or 'nil'"), 0);")
|
||||
(compile error at %tree %msg) compiles to (..)
|
||||
Lua "nomsu:compile_error(\(%tree as lua expr), \(%msg as lua expr))"
|
||||
(compile error at %tree %msg hint %hint) compiles to (..)
|
||||
@ -66,9 +65,9 @@ test:
|
||||
local ok, ret = xpcall(function()
|
||||
\(%action as lua statements)
|
||||
fell_through = true
|
||||
end, function(\(%msg as lua expr))
|
||||
end, function(\(=lua "\%fallback and \(%msg as lua expr) or ''"))
|
||||
local ok, ret = pcall(function()
|
||||
\(%fallback as lua statements)
|
||||
\((=lua "\%fallback or \%msg") as lua statements)
|
||||
end)
|
||||
if not ok then err, erred = ret, true end
|
||||
end)
|
||||
@ -84,18 +83,19 @@ test:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
[..]
|
||||
try %action and if it succeeds %success or if it barfs %fallback
|
||||
try %action and if it barfs %fallback or if it succeeds %success
|
||||
..all parse as (..)
|
||||
try %action and if it succeeds %success or if it barfs (=lua "") %fallback
|
||||
#
|
||||
[..]
|
||||
try %action and if it succeeds %success or if it barfs %fallback
|
||||
try %action and if it barfs %fallback or if it succeeds %success
|
||||
..all parse as (..)
|
||||
try %action and if it succeeds %success or if it barfs (=lua "") %fallback
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
(try %action) parses as (..)
|
||||
try %action and if it succeeds (do nothing) or if it barfs (do nothing)
|
||||
|
||||
(try %action and if it barfs %fallback) parses as (..)
|
||||
#(try %action and if it barfs %fallback) parses as (..)
|
||||
try %action and if it succeeds (do nothing) or if it barfs %fallback
|
||||
|
||||
(try %action and if it barfs %msg %fallback) parses as (..)
|
||||
|
@ -80,21 +80,21 @@ externally (%n to the nearest %rounder) means (..)
|
||||
[all of %items, all %items] all compile to:
|
||||
unless (%items.type is "List"):
|
||||
return (Lua value "utils.all(\(%items as lua expr))")
|
||||
%clauses = (((% as lua expr)::as smext) for % in %items)
|
||||
%clauses = (((% as lua expr)::text) for % in %items)
|
||||
return (Lua value "(\(%clauses::joined with " and "))")
|
||||
|
||||
[not all of %items, not all %items] all parse as (not (all of %items))
|
||||
[any of %items, any %items] all compile to:
|
||||
unless (%items.type is "List"):
|
||||
return (Lua value "utils.any(\(%items as lua expr))")
|
||||
%clauses = (((% as lua expr)::as smext) for % in %items)
|
||||
%clauses = (((% as lua expr)::text) for % in %items)
|
||||
return (Lua value "(\(%clauses::joined with " or "))")
|
||||
|
||||
[none of %items, none %items] all parse as (not (any of %items))
|
||||
[sum of %items, sum %items] all compile to:
|
||||
unless (%items.type is "List"):
|
||||
return (Lua value "utils.sum(\(%items as lua expr))")
|
||||
%clauses = (((% as lua expr)::as smext) for % in %items)
|
||||
%clauses = (((% as lua expr)::text) for % in %items)
|
||||
return (Lua value "(\(%clauses::joined with " + "))")
|
||||
|
||||
[if all of %items %body, if all of %items then %body] all parse as (..)
|
||||
@ -139,7 +139,7 @@ externally (%n to the nearest %rounder) means (..)
|
||||
[product of %items, product %items] all compile to:
|
||||
unless (%items.type is "List"):
|
||||
return (Lua value "utils.product(\(%items as lua expr))")
|
||||
%clauses = (((% as lua expr)::as smext) for % in %items)
|
||||
%clauses = (((% as lua expr)::text) for % in %items)
|
||||
return (Lua value "(\(%clauses::joined with " * "))")
|
||||
|
||||
externally [avg of %items, average of %items] all mean (..)
|
||||
|
@ -3,7 +3,7 @@
|
||||
This File contains actions for making actions and compile-time actions and some helper
|
||||
functions to make that easier.
|
||||
|
||||
lua> "NOMSU_CORE_VERSION = 8"
|
||||
lua> "NOMSU_CORE_VERSION = 9"
|
||||
lua> "\
|
||||
..do
|
||||
local mangle_index = 0
|
||||
@ -16,14 +16,14 @@ lua> "\
|
||||
end
|
||||
end
|
||||
COMPILE_ACTIONS["define mangler"] = function(nomsu, tree)
|
||||
return LuaCode(tree.source, "local mangle_1 = mangler()")
|
||||
return LuaCode(tree.source, "local mangle = mangler()")
|
||||
end"
|
||||
|
||||
lua> "\
|
||||
..COMPILE_ACTIONS["1 -> 2"] = function(nomsu, tree, \%args, \%body)
|
||||
..COMPILE_ACTIONS["1 ->"] = function(nomsu, tree, \%args, \%body)
|
||||
local lua = LuaCode.Value(tree.source, "(function(")
|
||||
if SyntaxTree:is_instance(\%args) and \%args.type == "Action" then \%args = \%args:get_args() end
|
||||
local lua_args = table.map(\%args, function(a) return SyntaxTree:is_instance(a) and nomsu:compile(a):as_smext() or a end)
|
||||
local lua_args = table.map(\%args, function(a) return SyntaxTree:is_instance(a) and nomsu:compile(a):text() or a end)
|
||||
lua:concat_append(lua_args, ", ")
|
||||
local body_lua = SyntaxTree:is_instance(\%body) and nomsu:compile(\%body):as_statements("return ") or \%body
|
||||
body_lua:remove_free_vars(lua_args)
|
||||
@ -63,15 +63,15 @@ test:
|
||||
asdf
|
||||
assume (%tmp is (nil)) or barf "compile to is leaking variables"
|
||||
lua> "\
|
||||
..COMPILE_ACTIONS["1 compiles to 2"] = function(nomsu, tree, \%actions, \%body)
|
||||
..COMPILE_ACTIONS["1 compiles to"] = function(nomsu, tree, \%actions, \%body)
|
||||
if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
|
||||
local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):as_smext() end))}
|
||||
local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):text() end))}
|
||||
local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", \%actions[1].stub:as_lua(),
|
||||
"] = ", \(what (%args -> %body) compiles to))
|
||||
for i=2,#\%actions do
|
||||
local alias = \%actions[i]
|
||||
local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return nomsu:compile(a):as_\
|
||||
..smext() end))}
|
||||
local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return nomsu:compile(a):text() \
|
||||
..end))}
|
||||
lua:append("\\nCOMPILE_ACTIONS[", alias.stub:as_lua(), "] = ")
|
||||
if utils.equivalent(\%args, \%alias_args) then
|
||||
lua:append("COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "]")
|
||||
@ -85,7 +85,7 @@ lua> "\
|
||||
end
|
||||
return lua
|
||||
end
|
||||
COMPILE_ACTIONS["1 all compile to 2"] = COMPILE_ACTIONS["1 compiles to 2"]"
|
||||
COMPILE_ACTIONS["1 all compile to"] = COMPILE_ACTIONS["1 compiles to"]"
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -116,14 +116,14 @@ test:
|
||||
lua> "\
|
||||
..if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
|
||||
local fn_name = \%actions[1].stub:as_lua_id()
|
||||
local \%args = table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):as_smext() end)
|
||||
local \%args = table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):text() end)
|
||||
local lua = LuaCode(tree.source, fn_name, " = ", \(what (%args -> %body) compiles to))
|
||||
lua:add_free_vars({fn_name})
|
||||
for i=2,#\%actions do
|
||||
local alias = \%actions[i]
|
||||
local alias_name = alias.stub:as_lua_id()
|
||||
lua:add_free_vars({alias_name})
|
||||
local \%alias_args = table.map(alias:get_args(), function(a) return nomsu:compile(a):as_smext() end)
|
||||
local \%alias_args = table.map(alias:get_args(), function(a) return nomsu:compile(a):text() end)
|
||||
lua:append("\\n", alias_name, " = ")
|
||||
if utils.equivalent(\%args, \%alias_args) then
|
||||
lua:append(fn_name)
|
||||
@ -151,7 +151,7 @@ test:
|
||||
return lua"
|
||||
|
||||
test:
|
||||
assume (((say %)'s meaning) == (=lua "say_1"))
|
||||
assume (((say %)'s meaning) == (=lua "say"))
|
||||
(%action's meaning) compiles to (Lua value (%action.stub as lua id))
|
||||
|
||||
test:
|
||||
@ -174,7 +174,7 @@ test:
|
||||
..local replacements = {}
|
||||
if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
|
||||
for i,arg in ipairs(\%actions[1]:get_args()) do
|
||||
replacements[arg[1]] = nomsu:compile(arg):as_smext()
|
||||
replacements[arg[1]] = nomsu:compile(arg):text()
|
||||
end
|
||||
local function make_tree(t)
|
||||
if SyntaxTree:is_instance(t) and t.type == "Var" then
|
||||
@ -192,14 +192,14 @@ test:
|
||||
i = i + 1
|
||||
elseif k == "source" then
|
||||
ret[#ret+1] = k.."= "..tostring(v):as_lua()
|
||||
elseif lua_type_of_1(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
|
||||
elseif lua_type_of(k) == 'string' and k:match("[_a-zA-Z][_a-zA-Z0-9]*") then
|
||||
ret[#ret+1] = k.."= "..make_tree(v)
|
||||
else
|
||||
ret[#ret+1] = "["..make_tree(k).."]= "..make_tree(v)
|
||||
end
|
||||
end
|
||||
return "SyntaxTree{"..table.concat(ret, ", ").."}"
|
||||
elseif lua_type_of_1(t) == 'number' then
|
||||
elseif lua_type_of(t) == 'number' then
|
||||
return tostring(t)
|
||||
else
|
||||
return t:as_lua()
|
||||
@ -226,9 +226,6 @@ test:
|
||||
(%tree as lua return) compiles to (..)
|
||||
Lua value "nomsu:compile(\(%tree as lua expr)):as_statements('return ')"
|
||||
|
||||
(remove action %action) compiles to (..)
|
||||
Lua "\(=lua "(\(%action.stub)):as_lua_id()") = nil"
|
||||
|
||||
test:
|
||||
assume ("\(\(foo \%x) as nomsu)" == "foo %x") or barf "\
|
||||
..action source code failed."
|
||||
@ -240,11 +237,11 @@ test:
|
||||
|
||||
externally [%var as lua identifier, %var as lua id] all mean:
|
||||
lua> "\
|
||||
..if lua_type_of_1(\%var) == 'string' then return \%var:as_lua_id()
|
||||
..if lua_type_of(\%var) == 'string' then return \%var:as_lua_id()
|
||||
elseif SyntaxTree:is_instance(\%var, 'Var') then return \%var[1]:as_lua_id()
|
||||
elseif SyntaxTree:is_instance(\%var) then
|
||||
local lua = \(%var as lua expr)
|
||||
if not lua:as_smext():match("^[_a-zA-Z][_a-zA-Z0-9]*$") then
|
||||
if not lua:text():match("^[_a-zA-Z][_a-zA-Z0-9]*$") then
|
||||
nomsu:compile_error(\%var, "This is not a valid Lua identifier.")
|
||||
end
|
||||
return lua
|
||||
|
@ -34,7 +34,7 @@ test:
|
||||
lua> "\
|
||||
..local lua = LuaCode(tree.source, \%var_lua, ' = ', \%value_lua, ';')
|
||||
if \%var.type == 'Var' then
|
||||
lua:add_free_vars({nomsu:compile(\%var):as_smext()})
|
||||
lua:add_free_vars({nomsu:compile(\%var):text()})
|
||||
end
|
||||
return lua"
|
||||
|
||||
@ -66,7 +66,7 @@ test:
|
||||
%value as text
|
||||
..) end
|
||||
if \%target.type == "Var" then
|
||||
lhs:add_free_vars({target_lua:as_smext()})
|
||||
lhs:add_free_vars({target_lua:text()})
|
||||
end
|
||||
if i > 1 then
|
||||
lhs:append(", ")
|
||||
@ -107,7 +107,7 @@ test:
|
||||
(with external %externs %body) compiles to:
|
||||
%body_lua = (%body as lua statements)
|
||||
lua> "\
|
||||
..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return nomsu:compile(v):as_smext() end))"
|
||||
..\%body_lua:remove_free_vars(table.map(\%externs, function(v) return nomsu:compile(v):text() end))"
|
||||
return %body_lua
|
||||
|
||||
test:
|
||||
@ -141,7 +141,7 @@ test:
|
||||
lhs:append(target_lua)
|
||||
rhs:append(value_lua)
|
||||
if \%target.type == "Var" then
|
||||
vars[i] = target_lua:as_smext()
|
||||
vars[i] = target_lua:text()
|
||||
end
|
||||
end
|
||||
\%lua:remove_free_vars(vars)
|
||||
|
@ -181,6 +181,8 @@ Files.walk = function(path, flush_cache)
|
||||
files = {
|
||||
path
|
||||
}
|
||||
elseif path:match("^[~/]") or path:match("^%./") or path:match("^%.%./") then
|
||||
files = browse(path)
|
||||
else
|
||||
for nomsupath in package.nomsupath:gmatch("[^;]+") do
|
||||
do
|
||||
|
@ -104,6 +104,8 @@ Files.walk = (path, flush_cache=false)->
|
||||
local files
|
||||
if path == 'stdin' or _SPOOFED_FILES[path]
|
||||
files = {path}
|
||||
elseif path\match("^[~/]") or path\match("^%./") or path\match("^%.%./")
|
||||
files = browse(path)
|
||||
else
|
||||
for nomsupath in package.nomsupath\gmatch("[^;]+")
|
||||
if files = browse(nomsupath.."/"..path) then break
|
||||
|
@ -14,8 +14,10 @@ test:
|
||||
|
||||
for %name = %colornum in %colors:
|
||||
%colornum = "\%colornum"
|
||||
(=lua "COMPILE_ACTIONS").%name = (..)
|
||||
#(=lua "COMPILE_ACTIONS").%name = (..)
|
||||
[%nomsu, %tree] -> (Lua value "'\\027[\(%colornum)m'")
|
||||
(=lua "COMPILE_ACTIONS")."\%name 1" = (..)
|
||||
[%nomsu, %tree, %text] -> (..)
|
||||
Lua value "('\\027[\(%colornum)m'..\(%text as lua expr)..'\\027[0m')"
|
||||
(=lua "COMPILE_ACTIONS")."\%name" = (..)
|
||||
[%nomsu, %tree, %text] ->:
|
||||
if %text:
|
||||
return (Lua value "('\\027[\(%colornum)m'..\(%text as lua expr)..'\\027[0m')")
|
||||
..else: return (Lua value "'\\027[\(%colornum)m'")
|
||||
|
@ -93,13 +93,13 @@ test:
|
||||
__index=\(%parent as lua expr),
|
||||
__tostring=function(cls) return cls.name end,
|
||||
__call=function(cls, inst)
|
||||
inst = setmetatable(inst or {}, cls)
|
||||
if inst == nil then return cls end
|
||||
inst = setmetatable(inst, cls)
|
||||
if inst.set_up then inst:set_up() end
|
||||
return inst
|
||||
end,
|
||||
})
|
||||
nomsu.environment[(class.name.." 1"):as_lua_id()] = class
|
||||
nomsu.environment[class.name:as_lua_id()] = function() return class end
|
||||
nomsu.environment[class.name:as_lua_id()] = class
|
||||
class.__index = class
|
||||
class.class = class
|
||||
class.__tostring = function(inst)
|
||||
|
@ -32,7 +32,7 @@ object (Syntax Tree):
|
||||
return %children
|
||||
|
||||
my action [as lua] "\
|
||||
..a_Syntax_Tree_with_1(\(call ({} 's metatable).as_lua with [%me]))"
|
||||
..a_Syntax_Tree_with(\(call ({} 's metatable).as_lua with [%me]))"
|
||||
my action [as nomsu] "\
|
||||
..(a Syntax Tree with \(call ({} 's metatable).as_nomsu with [%me]))"
|
||||
my action [as text] "\
|
||||
@ -86,4 +86,3 @@ object (Syntax Tree):
|
||||
unless ((% is text) or (%.type == "Comment")): %args::add %
|
||||
return %args
|
||||
|
||||
(Syntax Tree).map = (Syntax Tree).map_1
|
||||
|
@ -2,103 +2,89 @@
|
||||
# This file contains objects that are used to track code positions and incrementally
|
||||
build up generated code, while keeping track of where it came from, and managing
|
||||
indentation levels.
|
||||
use "lib/object.nom"
|
||||
use "lib/things.nom"
|
||||
|
||||
object (Hole):
|
||||
externally (Hole from %lua) means:
|
||||
return (Hole {lua:%lua})
|
||||
my action [as lua]: return %me.lua
|
||||
my action [as nomsu]:
|
||||
return "(Hole {lua:\(%me.lua)})"
|
||||
my action [as text]:
|
||||
barf "Not implemented"
|
||||
my action [as smext]:
|
||||
barf "Must fill in holes before smexting"
|
||||
a (Code Buffer) is a thing:
|
||||
that can (set up) by:
|
||||
assume %its.source
|
||||
%old_bits = (%its.bits if (%its.bits is a "List") else [%its.bits])
|
||||
%its.bits = []
|
||||
if (type of %its.source) is:
|
||||
"Text":
|
||||
%its.source = (Source from text %its.source)
|
||||
"Syntax Tree":
|
||||
%its.source = %its.source.source
|
||||
|
||||
object (Code):
|
||||
my action [set up]:
|
||||
assume %me.source
|
||||
%old_bits = (%me.bits if (%me.bits is a "List") else [%me.bits])
|
||||
%me.bits = []
|
||||
if (%me.source is text):
|
||||
%me.source = (Source from text %me.source)
|
||||
for % in %old_bits: %me::add %
|
||||
for % in %old_bits: %its::add %
|
||||
|
||||
my action [as text]:
|
||||
barf "Not implemented"
|
||||
my action [as smext]:
|
||||
if (%me.__str == (nil)):
|
||||
set {%buff:[], %indent:0}
|
||||
for %bit in %me.bits:
|
||||
whose (text) means:
|
||||
if (%its._text == (nil)):
|
||||
%buff = []
|
||||
%indent = 0
|
||||
for %bit in %its.bits:
|
||||
if (%bit is text):
|
||||
%spaces = (%bit::matching "\n([ ]*)[^\n]*$")
|
||||
if %spaces: %indent = (size of %spaces.1)
|
||||
..else:
|
||||
%bit = (%bit::as smext)
|
||||
%bit = (%bit::text)
|
||||
if (%indent > 0):
|
||||
%bit = (%bit::with "\n" -> "\n\(" "::* %indent)")
|
||||
|
||||
%buff::add %bit
|
||||
|
||||
%me.__str = (%buff::joined)
|
||||
|
||||
return %me.__str
|
||||
%its._text = (%buff::joined)
|
||||
return %its._text
|
||||
|
||||
my action [as lua]:
|
||||
barf
|
||||
return "\
|
||||
..\(%me.class.name::as lua id)_from_1_2(\(..)
|
||||
(%me.source::as lua) if %me.source else "nil"
|
||||
.., \(%me.bits::as lua))"
|
||||
whose (lua code) means "\
|
||||
..a_\(%its.class.name::as lua id)_with{source=\(..)
|
||||
(%its.source::as lua) if %its.source else "nil"
|
||||
.., \(%its.bits::as lua)}"
|
||||
|
||||
my action [as nomsu] "\
|
||||
..(\(%me.class.name) \((%me.source::as nomsu) if %me.source else "(nil)") \(..)
|
||||
%me.bits::as nomsu
|
||||
..)"
|
||||
whose (nomsu code) means "\
|
||||
..(a \(%its.class.name) with {source: \((%its.source::as nomsu) if %its.source else "(nil)"), bits: \(..)
|
||||
%its.bits::as nomsu
|
||||
..})"
|
||||
|
||||
my action [size] (size of (%me::as smext))
|
||||
my action [mark as dirty]:
|
||||
%me.__str = (nil)
|
||||
%me._trailing_line_len = (nil)
|
||||
%me._num_lines = (nil)
|
||||
whose (size) means (size of (%its::text))
|
||||
|
||||
that can (mark as dirty) by:
|
||||
%its._text = (nil)
|
||||
%its._trailing_line_len = (nil)
|
||||
%its._num_lines = (nil)
|
||||
|
||||
my action [add %new_bits]:
|
||||
that can (add %new_bits) by:
|
||||
unless (%new_bits is a "List"):
|
||||
%new_bits = [%new_bits]
|
||||
for % in %new_bits:
|
||||
if (% == ""): do next %
|
||||
|
||||
#if ((% isn't text) and (% isn't a (Code))):
|
||||
% = (%::as lua)
|
||||
%me.bits::add %
|
||||
|
||||
%me::mark as dirty
|
||||
%its.bits::add %
|
||||
%its::mark as dirty
|
||||
|
||||
my action [trailing line length]:
|
||||
if (%me._trailing_line_len == (nil)):
|
||||
%me._trailing_line_len = (size of ((%me::as smext)::matching "[^\n]*$"))
|
||||
return %me._trailing_line_len
|
||||
whose (trailing line length) means:
|
||||
if (%its._trailing_line_len == (nil)):
|
||||
%its._trailing_line_len = (size of ((%its::text)::matching "[^\n]*$"))
|
||||
return %its._trailing_line_len
|
||||
|
||||
my action [number of lines]:
|
||||
unless %me._num_lines:
|
||||
whose (number of lines) means:
|
||||
unless %its._num_lines:
|
||||
%num_lines = 1
|
||||
for % in %me:
|
||||
for % in %its:
|
||||
if (% is text):
|
||||
%num_lines += (size of (%::all matches of "\n"))
|
||||
..else:
|
||||
%num_lines += ((%::number of lines) - 1)
|
||||
|
||||
%me._num_lines = %num_lines
|
||||
%its._num_lines = %num_lines
|
||||
|
||||
return %me._num_lines
|
||||
return %its._num_lines
|
||||
|
||||
my action [is multiline, is multi-line] ((%me::number of lines) > 1)
|
||||
my action [is one line, is single line] ((%me::number of lines) == 1)
|
||||
my action [add %values joined with %joiner]:
|
||||
%me::add %values joined with %joiner or %joiner
|
||||
my action [add %values joined with %joiner or %wrapping_joiner]:
|
||||
whose [is multiline, is multi-line] all mean ((%its::number of lines) > 1)
|
||||
whose [is one line, is single line] all mean ((%its::number of lines) == 1)
|
||||
that can (add %values joined with %joiner) by:
|
||||
%its::add %values joined with %joiner or %joiner
|
||||
that can [add %values joined with %joiner or %wrapping_joiner] by:
|
||||
%line_len = 0
|
||||
%bits = %me.bits
|
||||
%bits = %its.bits
|
||||
for %value in %values at %i:
|
||||
if (%i > 1):
|
||||
if (%line_len > 80):
|
||||
@ -108,65 +94,71 @@ object (Code):
|
||||
|
||||
%bits::add %value
|
||||
unless (%value is text):
|
||||
%value = (%value::as smext)
|
||||
%value = (%value::text)
|
||||
%line = (%value::matching "\n([^\n]*)$")
|
||||
if %line:
|
||||
%line_len = (size of %line)
|
||||
..else:
|
||||
%line_len += (size of %value)
|
||||
|
||||
%me::mark as dirty
|
||||
%its::mark as dirty
|
||||
|
||||
my action [prepend %]:
|
||||
#if ((% isn't text) and (% isn't a %me.__type)):
|
||||
that can (prepend %) by:
|
||||
#if ((% isn't text) and (% isn't a %its.__type)):
|
||||
% = (%::as lua)
|
||||
%me.bits::add % at index 1
|
||||
%me::mark as dirty
|
||||
%its.bits::add % at index 1
|
||||
%its::mark as dirty
|
||||
|
||||
my action [parenthesize]:
|
||||
%me.bits::add "(" at index 1
|
||||
%me.bits::add ")"
|
||||
%me::mark as dirty
|
||||
that can (parenthesize) by:
|
||||
%its.bits::add "(" at index 1
|
||||
%its.bits::add ")"
|
||||
%its::mark as dirty
|
||||
|
||||
object (Lua Code) extends (Code):
|
||||
my action [add free vars %vars]:
|
||||
a (Lua Buffer) is a thing:
|
||||
that has [..]
|
||||
text, lua code, nomsu code, trailing line length, size, number of lines,
|
||||
is multiline, is multi-line, is one line, is single line,
|
||||
..like a (Code Buffer)
|
||||
that can [..]
|
||||
set up, mark as dirty, add %, prepend %, parenthesize,
|
||||
add % joined with %, add % joined with % or %,
|
||||
..like a (Code Buffer)
|
||||
|
||||
that can (add free vars %vars) by:
|
||||
if ((size of %vars) == 0): return
|
||||
%seen = (%v = (yes) for %v in %me.free_vars)
|
||||
%seen = (%v = (yes) for %v in %its.free_vars)
|
||||
for %var in %vars:
|
||||
assume (%var is text)
|
||||
unless %seen.%var:
|
||||
%me.free_vars::add %var
|
||||
%its.free_vars::add %var
|
||||
%seen.%var = (yes)
|
||||
|
||||
%me::mark as dirty
|
||||
%its::mark as dirty
|
||||
|
||||
my action [remove free vars %vars]:
|
||||
that can (remove free vars %vars) by:
|
||||
if ((size of %vars) == 0): return
|
||||
%removals = {}
|
||||
for %var in %vars:
|
||||
assume (%var is text)
|
||||
%removals.%var = (yes)
|
||||
|
||||
%stack = [%me]
|
||||
%stack = [%its]
|
||||
repeat while ((size of %stack) > 0):
|
||||
%lua = (%stack::pop)
|
||||
for %i in (size of %lua.free_vars) to 1 by -1:
|
||||
if %removals.(%lua.free_vars.%i):
|
||||
lua> "table.remove(\%lua.free_vars, \%i)"
|
||||
#TODO: reinstate this
|
||||
#%lua.free_vars::remove at index %i
|
||||
|
||||
%lua.free_vars::remove at index %i
|
||||
|
||||
for % in %lua.bits:
|
||||
unless (% is text): %stack::add %
|
||||
|
||||
%me::mark as dirty
|
||||
%its::mark as dirty
|
||||
|
||||
my action [declare locals] (%me::declare locals (nil))
|
||||
my action [declare locals %to_declare]:
|
||||
that can (declare locals) by (%its::declare locals (nil))
|
||||
that can (declare locals %to_declare) by:
|
||||
unless %to_declare:
|
||||
set {%to_declare:[], %seen:{}}
|
||||
for %lua in recursive %me:
|
||||
%to_declare = []
|
||||
%seen = {}
|
||||
for %lua in recursive %its:
|
||||
for %var in %lua.free_vars:
|
||||
unless %seen.%var:
|
||||
%seen.%var = (yes)
|
||||
@ -176,70 +168,43 @@ object (Lua Code) extends (Code):
|
||||
unless (% is text): recurse %lua on %
|
||||
|
||||
if ((size of %to_declare) > 0):
|
||||
%me::remove free vars %to_declare
|
||||
%me::prepend "local \(%to_declare::joined with ", ");\n"
|
||||
%its::remove free vars %to_declare
|
||||
%its::prepend "local \(%to_declare::joined with ", ");\n"
|
||||
return %to_declare
|
||||
|
||||
my action [as statements] (%me::as statements "" ";")
|
||||
my action [as statements %prefix] (%me::as statements %prefix ";")
|
||||
my action [as statements %prefix %suffix]:
|
||||
unless %me.is_value: return %me
|
||||
%statements = (Lua Code from %me.source [])
|
||||
whose (as statements) means (%its::as statements with "")
|
||||
whose (as statements with %prefix) means:
|
||||
unless %its.is_value: return %its
|
||||
%statements = (a Lua Buffer with {source:%its.source})
|
||||
if ((%prefix or "") != ""):
|
||||
%statements::add %prefix
|
||||
%statements::add %me
|
||||
if (%suffix != ""):
|
||||
%statements::add (%suffix or ";")
|
||||
%statements::add %its
|
||||
%statements::add ";"
|
||||
return %statements
|
||||
|
||||
my action [variables]:
|
||||
that can (mark as value) by:
|
||||
%its.is_value = (yes)
|
||||
|
||||
that can (mark as variable) by:
|
||||
%its.is_variable = (yes)
|
||||
%its.is_value = (yes)
|
||||
|
||||
that can (variables) by:
|
||||
%vars = []
|
||||
for %code in recursive %me:
|
||||
for %code in recursive %its:
|
||||
if %code.is_variable:
|
||||
%vars::add (%code::as smext)
|
||||
%vars::add (%code::text)
|
||||
for % in %code.bits:
|
||||
unless (% is text): recurse %code on %
|
||||
|
||||
return %vars
|
||||
|
||||
externally (Lua Code from %source %bits) means:
|
||||
assume %source
|
||||
unless (%bits is a "List"): %bits = [%bits]
|
||||
if (%source is a "Syntax Tree"):
|
||||
%source = %source.source
|
||||
return (Lua Code {source:%source, bits:%bits, is_value:no, free_vars:[]})
|
||||
|
||||
externally (Lua Code from %source) means (Lua Code from %source [])
|
||||
externally (Lua Value from %source %bits) means:
|
||||
assume %source
|
||||
unless (%bits is a "List"): %bits = [%bits]
|
||||
if (%source is a "Syntax Tree"):
|
||||
%source = %source.source
|
||||
return (Lua Code {source:%source, bits:%bits, is_value:yes, free_vars:[]})
|
||||
|
||||
externally (Lua Value from %source) means (Lua Value from %source [])
|
||||
externally (Lua Variable from %source) means (Lua Variable from %source [])
|
||||
externally (Lua Variable from %source %bits) means:
|
||||
assume %source
|
||||
unless (%bits is a "List"): %bits = [%bits]
|
||||
if (%source is a "Syntax Tree"):
|
||||
%source = %source.source
|
||||
return (..)
|
||||
Lua Code {..}
|
||||
source:%source, bits:%bits, is_value:yes, is_variable:yes, free_vars:[]
|
||||
|
||||
# TODO: remove this shim
|
||||
(Lua Code).add_free_vars = (Lua Code).add_free_vars_1
|
||||
(Lua Code).remove_free_vars = (Lua Code).remove_free_vars_1
|
||||
(Lua Code).declare_locals = (Lua Code).declare_locals_1
|
||||
(Lua Code).as_statements = (Lua Code).as_statements_1_2
|
||||
object (Nomsu Code) extends (Code):
|
||||
externally (Nomsu Code from %source %bits) means:
|
||||
if (%bits is text): %bits = [%bits]
|
||||
if (%source is a "Syntax Tree"):
|
||||
%source = %source.source
|
||||
return (Nomsu Code {source:%source, bits:%bits})
|
||||
|
||||
externally (Nomsu Code from %source) means (Nomsu Code from %source [])
|
||||
externally (Nomsu Code %bits) means (Nomsu Code from (nil) %bits)
|
||||
externally (Nomsu Code) means (Nomsu Code from (nil) [])
|
||||
a (Nomsu Buffer) is a thing:
|
||||
that has [..]
|
||||
text, lua code, nomsu code, trailing line length, size, number of lines,
|
||||
is multiline, is multi-line, is one line, is single line,
|
||||
..like a (Code Buffer)
|
||||
that can [..]
|
||||
set up, mark as dirty, add %, prepend %, parenthesize,
|
||||
add % joined with %, add % joined with % or %,
|
||||
..like a (Code Buffer)
|
||||
|
@ -45,7 +45,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
# TODO: restore this:
|
||||
#%args = [%tree, %compile_actions]
|
||||
%args = [%nomsu, %tree]
|
||||
for % in (%tree::get args): %args::add %
|
||||
for % in (%tree::arguments): %args::add %
|
||||
%result = (call %compile_action with %args)
|
||||
if (%result == (nil)):
|
||||
report compile error at %tree "\
|
||||
@ -64,13 +64,13 @@ externally (%tree compiled with %compile_actions) means:
|
||||
|
||||
return %result
|
||||
|
||||
%lua = (Lua Value from %tree)
|
||||
%lua = (a Lua Buffer with {source:%tree})
|
||||
if %tree.target:
|
||||
# Method call
|
||||
%target_lua = (%tree.target compiled with %compile_actions)
|
||||
if (..)
|
||||
((%target_lua::as smext)::matches "^%(.*%)$") or (..)
|
||||
(%target_lua::as smext)::matches "^[_a-zA-Z][_a-zA-Z0-9]*$"
|
||||
((%target_lua::text)::matches "^%(.*%)$") or (..)
|
||||
(%target_lua::text)::matches "^[_a-zA-Z][_a-zA-Z0-9]*$"
|
||||
..:
|
||||
%lua::add [%target_lua, ":"]
|
||||
..else:
|
||||
@ -93,14 +93,14 @@ externally (%tree compiled with %compile_actions) means:
|
||||
if ((size of %values) == 1):
|
||||
%arg_lua = %values.1
|
||||
..else:
|
||||
%arg_lua = (Lua Value from %tok ["("])
|
||||
%arg_lua = (a Lua Buffer with {source:%tok, is_value:yes, bits:["("]})
|
||||
%arg_lua::add %values joined with " and nil or "
|
||||
%arg_lua::add ")"
|
||||
..else:
|
||||
%arg_lua = (Lua Value from %tok ["((function()"])
|
||||
%arg_lua = (a Lua Buffer with {source:%tok, is_value:yes, bits:["((function()"]})
|
||||
for %v in %values at %i:
|
||||
if %v.is_value:
|
||||
%v = (%v::as statements ("return " if (%i == (size of %values) else "")))
|
||||
%v = (%v::as statements with ("return " if (%i == (size of %values) else "")))
|
||||
%arg_lua::add ["\n ", %v]
|
||||
|
||||
%arg_lua::add "\nend)())"
|
||||
@ -124,8 +124,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
return %lua
|
||||
|
||||
"EscapedNomsu":
|
||||
#return (Lua Value from %tree ((%tree.1)::as lua))
|
||||
%lua = (Lua Value from %tree ["a_Syntax_Tree_with_1{type=", quote %tree.(1).type])
|
||||
%lua = (a Lua Buffer with {source:%tree, is_value:yes, bits:["a_Syntax_Tree_with{type=", quote %tree.(1).type]})
|
||||
set {%needs_comma:no, %i:1}
|
||||
(% as shmua) means:
|
||||
if (% is a "Lua number"): return "\%"
|
||||
@ -152,7 +151,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
return %lua
|
||||
|
||||
"Block":
|
||||
%lua = (Lua Code from %tree)
|
||||
%lua = (a Lua Buffer with {source:%tree})
|
||||
%lua::add (..)
|
||||
((%line compiled with %compile_actions)::as statements) for %line in %tree
|
||||
..joined with "\n"
|
||||
@ -160,7 +159,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
return %lua
|
||||
|
||||
"Text":
|
||||
%lua = (Lua Value from %tree)
|
||||
%lua = (a Lua Buffer with {source:%tree})
|
||||
%lua_bits = []
|
||||
%string_buffer = ""
|
||||
for % in %tree:
|
||||
@ -178,7 +177,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
..Can't use this as a string interpolation value, since it doesn't have a value."
|
||||
|
||||
if (%.type != "Text"):
|
||||
%bit_lua = (Lua Value from % ["tostring(", %bit_lua, ")"])
|
||||
%bit_lua = (a Lua Buffer with {source:%, is_value:yes, bits:["tostring(", %bit_lua, ")"]})
|
||||
%lua_bits::add %bit_lua
|
||||
|
||||
if ((%string_buffer != "") or ((size of %lua_bits) == 0)):
|
||||
@ -188,13 +187,13 @@ externally (%tree compiled with %compile_actions) means:
|
||||
return %lua
|
||||
|
||||
"List":
|
||||
%lua = (Lua Value from %tree ["List{"])
|
||||
%lua = (a Lua Buffer with {source:%tree, is_value:yes, bits:["List{"]})
|
||||
%lua::add ((% compiled with %compile_actions) for % in %tree) joined with ", " or ",\n "
|
||||
%lua::add "}"
|
||||
return %lua
|
||||
|
||||
"Dict":
|
||||
%lua = (Lua Value from %tree ["Dict{"])
|
||||
%lua = (a Lua Buffer with {source:%tree, is_value:yes, bits:["Dict{"]})
|
||||
%lua::add ((% compiled with %compile_actions) for % in %tree) joined with ", " or ",\n "
|
||||
%lua::add "}"
|
||||
return %lua
|
||||
@ -208,24 +207,24 @@ externally (%tree compiled with %compile_actions) means:
|
||||
|
||||
%value_lua = (..)
|
||||
(%value compiled with %compile_actions) if %value else (..)
|
||||
Lua Value from %key ["true"]
|
||||
a Lua Buffer with {source:%key, is_value:yes, bits:["true"]}
|
||||
|
||||
unless %value_lua.is_value:
|
||||
report compile error at %tree.2 "\
|
||||
..Can't use this as a dict value, since it's not an expression."
|
||||
|
||||
%key_str = ((%key_lua::as smext)::matching "^[\"']([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
|
||||
%key_str = ((%key_lua::text)::matching "^[\"']([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
|
||||
if:
|
||||
%key_str:
|
||||
return (Lua Code from %tree [%key_str, "=", %value_lua])
|
||||
((%key_lua::as smext).1 == "["):
|
||||
return (a Lua Buffer with {source:%tree, bits:[%key_str, "=", %value_lua]})
|
||||
((%key_lua::text).1 == "["):
|
||||
# NOTE: this *must* use a space after the [ to avoid freaking out
|
||||
Lua's parser if the inner expression is a long string. Lua
|
||||
parses x[[[y]]] as x("[y]"), not as x["y"]
|
||||
return (Lua Code from %tree ["[ ", %key_lua, "]=", %value_lua])
|
||||
return (a Lua Buffer with {source:%tree, bits:["[ ", %key_lua, "]=", %value_lua]})
|
||||
|
||||
else:
|
||||
return (Lua Code from %tree ["[", %key_lua, "]=", %value_lua])
|
||||
return (a Lua Buffer with {source:%tree, bits:["[", %key_lua, "]=", %value_lua]})
|
||||
|
||||
"IndexChain":
|
||||
%lua = (%tree.1 compiled with %compile_actions)
|
||||
@ -233,7 +232,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
report compile error at %tree.1 "\
|
||||
..Can't index into this, since it's not an expression."
|
||||
|
||||
%first_char = (%lua::as smext).1
|
||||
%first_char = (%lua::text).1
|
||||
if (any of [%first_char == "{", %first_char == "\"", %first_char == "["]):
|
||||
%lua::parenthesize
|
||||
for %i in 2 to (size of %tree):
|
||||
@ -243,7 +242,7 @@ externally (%tree compiled with %compile_actions) means:
|
||||
report compile error at %key "\
|
||||
..Can't use this as an index, since it's not an expression."
|
||||
|
||||
%key_lua_str = (%key_lua::as smext)
|
||||
%key_lua_str = (%key_lua::text)
|
||||
%lua_id = (%key_lua_str::matching "^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
|
||||
if:
|
||||
%lua_id:
|
||||
@ -260,16 +259,16 @@ externally (%tree compiled with %compile_actions) means:
|
||||
return %lua
|
||||
|
||||
"Number":
|
||||
return (Lua Value from %tree ["\(%tree.1)"])
|
||||
return (a Lua Buffer with {source:%tree, is_value:yes, bits:["\(%tree.1)"]})
|
||||
"Var":
|
||||
return (Lua Variable from %tree [%tree.1::as lua id])
|
||||
return (a Lua Buffer with {source:%tree, is_value:yes, is_variable:yes, bits:[%tree.1::as lua id]})
|
||||
"FileChunks":
|
||||
barf "\
|
||||
..Can't convert FileChunks to a single block of lua, since each chunk's compilation depends on the earlier chunks"
|
||||
|
||||
"Comment":
|
||||
# TODO: de-implement?
|
||||
return (Lua Code from %tree "-- \(%tree.1::with "\n" -> "\n-- ")")
|
||||
return (a Lua Buffer with {source:%tree, bits:["-- \(%tree.1::with "\n" -> "\n-- ")"]})
|
||||
|
||||
"Error":
|
||||
barf (%tree as a pretty error)
|
||||
|
@ -8,7 +8,7 @@ externally (%tree decompiled inline) means:
|
||||
assume (%tree is a "Syntax Tree")
|
||||
if %tree.type is:
|
||||
"Action":
|
||||
%nomsu = (Nomsu Code from %tree)
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree})
|
||||
if %tree.target:
|
||||
%target_nomsu = (%tree.target decompiled inline)
|
||||
if %tree.target.type is:
|
||||
@ -44,17 +44,17 @@ externally (%tree decompiled inline) means:
|
||||
..:
|
||||
%inner_nomsu::parenthesize
|
||||
|
||||
%nomsu = (Nomsu Code from %tree ["\\", %inner_nomsu])
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree, bits: ["\\", %inner_nomsu]})
|
||||
return %nomsu
|
||||
|
||||
"Block":
|
||||
%nomsu = (Nomsu Code from %tree [":"])
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree, bits: [":"]})
|
||||
for %line in %tree at %i:
|
||||
%nomsu::add [" " if (%i == 1) else "; ", %line decompiled inline]
|
||||
return %nomsu
|
||||
|
||||
"Text":
|
||||
%nomsu = (Nomsu Code from %tree [])
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree, bits: []})
|
||||
for %text in recursive %tree:
|
||||
for %bit in %text at %i:
|
||||
if (%bit is text): %nomsu::add %bit
|
||||
@ -78,10 +78,10 @@ externally (%tree decompiled inline) means:
|
||||
else:
|
||||
%nomsu::add ["\\(", %bit decompiled inline, ")"]
|
||||
|
||||
return (Nomsu Code from %tree ["\"", %nomsu, "\""])
|
||||
return (a Nomsu Buffer with {source: %tree, bits: ["\"", %nomsu, "\""]})
|
||||
|
||||
"List" "Dict":
|
||||
%nomsu = (Nomsu Code from %tree ["[" if (%tree.type == "List") else "{"])
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree, bits: ["[" if (%tree.type == "List") else "{"]})
|
||||
for %item in %tree at %i:
|
||||
if (%i > 1): %nomsu::add ", "
|
||||
%nomsu::add (%item decompiled inline)
|
||||
@ -94,7 +94,7 @@ externally (%tree decompiled inline) means:
|
||||
if (..)
|
||||
all of [%key.type == "Text", (size of %key) == 1, %key.1 is a nomsu identifier]
|
||||
..:
|
||||
%nomsu = (Nomsu Code from %key [%key.1])
|
||||
%nomsu = (a Nomsu Buffer with {source: %key, bits: [%key.1]})
|
||||
..else:
|
||||
%nomsu = (%key decompiled inline)
|
||||
|
||||
@ -107,7 +107,7 @@ externally (%tree decompiled inline) means:
|
||||
return %nomsu
|
||||
|
||||
"IndexChain":
|
||||
%nomsu = (Nomsu Code from %tree)
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree})
|
||||
for %bit in %tree at %i:
|
||||
if (%i > 1): %nomsu::add "."
|
||||
if (..)
|
||||
@ -128,9 +128,9 @@ externally (%tree decompiled inline) means:
|
||||
return %nomsu
|
||||
|
||||
"Number":
|
||||
return (Nomsu Code from %tree [(%tree.1 as hex) if %tree.hex else "\(%tree.1)"])
|
||||
return (a Nomsu Buffer with {source: %tree, bits: [(%tree.1 as hex) if %tree.hex else "\(%tree.1)"]})
|
||||
"Var":
|
||||
return (Nomsu Code from %tree ["%\(%tree.1)"])
|
||||
return (a Nomsu Buffer with {source: %tree, bits: ["%\(%tree.1)"]})
|
||||
"Comment": return (nil)
|
||||
"FileChunks":
|
||||
barf "Can't inline a FileChunks"
|
||||
@ -141,7 +141,7 @@ externally (%tree decompiled inline) means:
|
||||
|
||||
%MAX_LINE = 90
|
||||
externally (%tree decompiled) means:
|
||||
%nomsu = (Nomsu Code from %tree)
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree})
|
||||
|
||||
# For concision:
|
||||
(recurse on %t) means:
|
||||
@ -167,8 +167,7 @@ externally (%tree decompiled) means:
|
||||
%indented = (%t decompiled)
|
||||
if (%t.type == "Action"):
|
||||
%indented = (..)
|
||||
Nomsu Code from %t [..]
|
||||
"(..)\n ", %indented
|
||||
a Nomsu Buffer with {source: %t, bits: ["(..)\n ", %indented]}
|
||||
|
||||
return %indented
|
||||
|
||||
@ -253,13 +252,12 @@ externally (%tree decompiled) means:
|
||||
..else: %nomsu::add "\n"
|
||||
|
||||
return (..)
|
||||
Nomsu Code from %tree [..]
|
||||
":\n ", %nomsu
|
||||
a Nomsu Buffer with {source: %tree, bits: [":\n ", %nomsu]}
|
||||
|
||||
"Text":
|
||||
# Multi-line text has more generous wrap margins
|
||||
%max_line = ((1.5 * %MAX_LINE) rounded down)
|
||||
%nomsu = (Nomsu Code from %tree)
|
||||
%nomsu = (a Nomsu Buffer with {source: %tree})
|
||||
(add text from %tree) means:
|
||||
for %bit in %tree at %i:
|
||||
if (%bit is text):
|
||||
@ -301,8 +299,7 @@ externally (%tree decompiled) means:
|
||||
|
||||
add text from %tree
|
||||
return (..)
|
||||
Nomsu Code from %tree [..]
|
||||
"\"\\\n ..", %nomsu, "\""
|
||||
a Nomsu Buffer with {source: %tree, bits: ["\"\\\n ..", %nomsu, "\""]}
|
||||
|
||||
"List" "Dict":
|
||||
if ((size of %tree) == 0):
|
||||
@ -321,9 +318,9 @@ externally (%tree decompiled) means:
|
||||
..else: %nomsu::add ", "
|
||||
|
||||
return (..)
|
||||
Nomsu Code from %tree [..]
|
||||
"[..]\n " if (%tree.type == "List") else "{..}\n "
|
||||
%nomsu
|
||||
a Nomsu Buffer with {..}
|
||||
source: %tree, bits: [..]
|
||||
"[..]\n " if (%tree.type == "List") else "{..}\n ", %nomsu
|
||||
|
||||
"DictEntry":
|
||||
set {%key:%tree.1, %value:%tree.2}
|
||||
|
@ -32,7 +32,7 @@ set {..}
|
||||
%source = (..)
|
||||
Source {filename:%userdata.filename, start:%t.start, stop:%t.stop}
|
||||
set {%t.start: nil, %t.stop: nil, %t.source: %source}
|
||||
%t = (Syntax Tree %t)
|
||||
%t = (a Syntax Tree with %t)
|
||||
(Syntax Tree).source_code_for_tree.%t = %userdata.source
|
||||
return %t
|
||||
..with fallback %key ->:
|
||||
|
@ -212,6 +212,7 @@ say "\
|
||||
|
||||
buff = table.concat(buff)
|
||||
|
||||
-- TODO: support local variables
|
||||
pseudo_filename = "user input #"..repl_line
|
||||
Files.spoof(pseudo_filename, buff)
|
||||
err_hand = (error_message)->
|
||||
|
@ -151,7 +151,7 @@ do
|
||||
return false
|
||||
end
|
||||
NomsuCompiler.environment = {
|
||||
NOMSU_COMPILER_VERSION = 10,
|
||||
NOMSU_COMPILER_VERSION = 11,
|
||||
NOMSU_SYNTAX_VERSION = max_parser_version,
|
||||
next = next,
|
||||
unpack = unpack,
|
||||
@ -180,7 +180,7 @@ do
|
||||
assert = assert,
|
||||
dofile = dofile,
|
||||
loadstring = loadstring,
|
||||
lua_type_of_1 = type,
|
||||
lua_type_of = type,
|
||||
select = select,
|
||||
math = math,
|
||||
io = io,
|
||||
@ -406,7 +406,7 @@ do
|
||||
end
|
||||
return operate_on_text(code)
|
||||
end
|
||||
local math_expression = re.compile([[ ([+-] " ")* [0-9]+ (" " [*/^+-] (" " [+-])* " " [0-9]+)+ !. ]])
|
||||
local math_expression = re.compile([[ (([*/^+-] / [0-9]+) " ")* [*/^+-] !. ]])
|
||||
local compile_math_expression
|
||||
compile_math_expression = function(self, tree, ...)
|
||||
local lua = LuaCode.Value(tree.source)
|
||||
@ -431,34 +431,36 @@ do
|
||||
end
|
||||
NomsuCompiler.environment.COMPILE_ACTIONS = setmetatable({
|
||||
__imported = Dict({ }),
|
||||
["Lua 1"] = function(self, tree, code)
|
||||
["Lua"] = function(self, tree, code)
|
||||
return add_lua_string_bits(self, 'statements', code)
|
||||
end,
|
||||
["Lua value 1"] = function(self, tree, code)
|
||||
["Lua value"] = function(self, tree, code)
|
||||
return add_lua_string_bits(self, 'value', code)
|
||||
end,
|
||||
["lua > 1"] = function(self, tree, code)
|
||||
["lua >"] = function(self, tree, code)
|
||||
if code.type ~= "Text" then
|
||||
return LuaCode(tree.source, "nomsu:run_lua(", self:compile(code), ", nomsu);")
|
||||
end
|
||||
return add_lua_bits(self, "statements", code)
|
||||
end,
|
||||
["= lua 1"] = function(self, tree, code)
|
||||
["= lua"] = function(self, tree, code)
|
||||
if code.type ~= "Text" then
|
||||
return LuaCode.Value(tree.source, "nomsu:run_lua(", self:compile(code), ":as_statements('return '), nomsu)")
|
||||
end
|
||||
return add_lua_bits(self, "value", code)
|
||||
end,
|
||||
["use 1"] = function(self, tree, path)
|
||||
["use"] = function(self, tree, path)
|
||||
if path.type == 'Text' and #path == 1 and type(path[1]) == 'string' then
|
||||
self:import_file(path[1])
|
||||
if not (self:import_file(path[1])) then
|
||||
self:compile_error(tree, "Could not find anything to import for " .. tostring(path))
|
||||
end
|
||||
end
|
||||
return LuaCode(tree.source, "nomsu:import_file(" .. tostring(self:compile(path)) .. ")")
|
||||
end,
|
||||
["tests"] = function(self, tree)
|
||||
return LuaCode.Value(tree.source, "TESTS")
|
||||
end,
|
||||
["test 1"] = function(self, tree, body)
|
||||
["test"] = function(self, tree, body)
|
||||
local test_str = table.concat((function()
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 1
|
||||
@ -516,11 +518,14 @@ do
|
||||
end
|
||||
end
|
||||
NomsuCompiler.import_file = function(self, path)
|
||||
local found = false
|
||||
for _, f in Files.walk(path) do
|
||||
if match(f, "%.lua$") or match(f, "%.nom$") or match(f, "^/dev/fd/[012]$") then
|
||||
found = true
|
||||
self:import(self:run_file(f))
|
||||
end
|
||||
end
|
||||
return found
|
||||
end
|
||||
NomsuCompiler.run = function(self, to_run, compile_actions)
|
||||
local source = to_run.source or Source(to_run, 1, #to_run)
|
||||
@ -673,7 +678,7 @@ do
|
||||
local get_version = self[("Nomsu version"):as_lua_id()]
|
||||
if get_version then
|
||||
do
|
||||
local upgrade = self[("1 upgraded from 2 to 3"):as_lua_id()]
|
||||
local upgrade = self[("1 upgraded from 2 to"):as_lua_id()]
|
||||
if upgrade then
|
||||
tree = upgrade(tree, tree.version, get_version())
|
||||
end
|
||||
@ -1273,13 +1278,13 @@ do
|
||||
local should_clump
|
||||
should_clump = function(prev_line, line)
|
||||
if prev_line.type == "Action" and line.type == "Action" then
|
||||
if prev_line.stub == "use 1" then
|
||||
return line.stub == "use 1"
|
||||
if prev_line.stub == "use" then
|
||||
return line.stub == "use"
|
||||
end
|
||||
if prev_line.stub == "test 1" then
|
||||
if prev_line.stub == "test" then
|
||||
return true
|
||||
end
|
||||
if line.stub == "test 1" then
|
||||
if line.stub == "test" then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
@ -93,12 +93,12 @@ with NomsuCompiler
|
||||
|
||||
-- Discretionary/convenience stuff
|
||||
.environment = {
|
||||
NOMSU_COMPILER_VERSION: 10, NOMSU_SYNTAX_VERSION: max_parser_version
|
||||
NOMSU_COMPILER_VERSION: 11, NOMSU_SYNTAX_VERSION: max_parser_version
|
||||
-- Lua stuff:
|
||||
:next, :unpack, :setmetatable, :coroutine, :rawequal, :getmetatable, :pcall,
|
||||
:error, :package, :os, :require, :tonumber, :tostring, :string, :xpcall, :module,
|
||||
:print, :loadfile, :rawset, :_VERSION, :collectgarbage, :rawget, :rawlen,
|
||||
:table, :assert, :dofile, :loadstring, lua_type_of_1:type, :select, :math, :io, :load,
|
||||
:table, :assert, :dofile, :loadstring, lua_type_of:type, :select, :math, :io, :load,
|
||||
:pairs, :ipairs,
|
||||
-- Nomsu types:
|
||||
_List:List, _Dict:Dict,
|
||||
@ -225,7 +225,7 @@ with NomsuCompiler
|
||||
-- This is a bit of a hack, but this code handles arbitrarily complex
|
||||
-- math expressions like 2*x + 3^2 without having to define a single
|
||||
-- action for every possibility.
|
||||
math_expression = re.compile [[ ([+-] " ")* [0-9]+ (" " [*/^+-] (" " [+-])* " " [0-9]+)+ !. ]]
|
||||
math_expression = re.compile [[ (([*/^+-] / [0-9]+) " ")* [*/^+-] !. ]]
|
||||
compile_math_expression = (tree, ...)=>
|
||||
lua = LuaCode.Value(tree.source)
|
||||
for i,tok in ipairs tree
|
||||
@ -242,29 +242,30 @@ with NomsuCompiler
|
||||
return lua
|
||||
.environment.COMPILE_ACTIONS = setmetatable({
|
||||
__imported: Dict{}
|
||||
["Lua 1"]: (tree, code)=>
|
||||
["Lua"]: (tree, code)=>
|
||||
return add_lua_string_bits(@, 'statements', code)
|
||||
|
||||
["Lua value 1"]: (tree, code)=>
|
||||
["Lua value"]: (tree, code)=>
|
||||
return add_lua_string_bits(@, 'value', code)
|
||||
|
||||
["lua > 1"]: (tree, code)=>
|
||||
["lua >"]: (tree, code)=>
|
||||
if code.type != "Text"
|
||||
return LuaCode tree.source, "nomsu:run_lua(", @compile(code), ", nomsu);"
|
||||
return add_lua_bits(@, "statements", code)
|
||||
|
||||
["= lua 1"]: (tree, code)=>
|
||||
["= lua"]: (tree, code)=>
|
||||
if code.type != "Text"
|
||||
return LuaCode.Value tree.source, "nomsu:run_lua(", @compile(code), ":as_statements('return '), nomsu)"
|
||||
return add_lua_bits(@, "value", code)
|
||||
|
||||
["use 1"]: (tree, path)=>
|
||||
["use"]: (tree, path)=>
|
||||
if path.type == 'Text' and #path == 1 and type(path[1]) == 'string'
|
||||
@import_file(path[1])
|
||||
unless @import_file(path[1])
|
||||
@compile_error tree, "Could not find anything to import for #{path}"
|
||||
return LuaCode(tree.source, "nomsu:import_file(#{@compile(path)})")
|
||||
|
||||
["tests"]: (tree)=> LuaCode.Value(tree.source, "TESTS")
|
||||
["test 1"]: (tree, body)=>
|
||||
["test"]: (tree, body)=>
|
||||
test_str = table.concat [tostring(@tree_to_nomsu(line)) for line in *body], "\n"
|
||||
LuaCode tree.source, "TESTS[#{tostring(tree.source)\as_lua!}] = ", test_str\as_lua!
|
||||
|
||||
@ -290,9 +291,12 @@ with NomsuCompiler
|
||||
@environment.COMPILE_ACTIONS.__imported[k] or= v
|
||||
|
||||
.import_file = (path)=>
|
||||
found = false
|
||||
for _,f in Files.walk(path)
|
||||
if match(f, "%.lua$") or match(f, "%.nom$") or match(f, "^/dev/fd/[012]$")
|
||||
found = true
|
||||
@import(@run_file(f))
|
||||
return found
|
||||
|
||||
.run = (to_run, compile_actions)=>
|
||||
source = to_run.source or Source(to_run, 1, #to_run)
|
||||
@ -394,7 +398,7 @@ with NomsuCompiler
|
||||
compile_actions or= @environment.COMPILE_ACTIONS
|
||||
if tree.version
|
||||
if get_version = @[("Nomsu version")\as_lua_id!]
|
||||
if upgrade = @[("1 upgraded from 2 to 3")\as_lua_id!]
|
||||
if upgrade = @[("1 upgraded from 2 to")\as_lua_id!]
|
||||
tree = upgrade(tree, tree.version, get_version!)
|
||||
switch tree.type
|
||||
when "Action"
|
||||
@ -787,9 +791,9 @@ with NomsuCompiler
|
||||
nomsu = NomsuCode(tree.source, pop_comments(tree.source.start))
|
||||
should_clump = (prev_line, line)->
|
||||
if prev_line.type == "Action" and line.type == "Action"
|
||||
if prev_line.stub == "use 1" then return line.stub == "use 1"
|
||||
if prev_line.stub == "test 1" then return true
|
||||
if line.stub == "test 1" then return false
|
||||
if prev_line.stub == "use" then return line.stub == "use"
|
||||
if prev_line.stub == "test" then return true
|
||||
if line.stub == "test" then return false
|
||||
return not recurse(prev_line)\is_multiline!
|
||||
for chunk_no, chunk in ipairs tree
|
||||
nomsu\append "\n\n#{("~")\rep(80)}\n\n" if chunk_no > 1
|
||||
|
17
string2.lua
17
string2.lua
@ -78,6 +78,9 @@ local string2 = {
|
||||
end
|
||||
return _accum_0
|
||||
end,
|
||||
starts_with = function(self, s)
|
||||
return sub(self, 1, #s) == s
|
||||
end,
|
||||
lines = function(self)
|
||||
local _accum_0 = { }
|
||||
local _len_0 = 1
|
||||
@ -114,10 +117,10 @@ local string2 = {
|
||||
for _index_0 = 1, #_list_0 do
|
||||
local line = _list_0[_index_0]
|
||||
while #line > maxlen do
|
||||
local chunk = line:sub(1, maxlen)
|
||||
local split = chunk:find(' ', maxlen - buffer, true) or maxlen
|
||||
chunk = line:sub(1, split)
|
||||
line = line:sub(split + 1, -1)
|
||||
local chunk = sub(line, 1, maxlen)
|
||||
local split = find(chunk, ' ', maxlen - buffer, true) or maxlen
|
||||
chunk = sub(line, 1, split)
|
||||
line = sub(line, split + 1, -1)
|
||||
lines[#lines + 1] = chunk
|
||||
end
|
||||
lines[#lines + 1] = line
|
||||
@ -151,14 +154,14 @@ local string2 = {
|
||||
return format("x%02X", byte(c))
|
||||
end
|
||||
end)
|
||||
if not (is_lua_id(str:match("^_*(.*)$"))) then
|
||||
if not (is_lua_id(match(str, "^_*(.*)$"))) then
|
||||
str = "_" .. str
|
||||
end
|
||||
return str
|
||||
end,
|
||||
from_lua_id = function(str)
|
||||
if not (is_lua_id(str:match("^_*(.*)$"))) then
|
||||
str = str:sub(2, -1)
|
||||
if not (is_lua_id(match(str, "^_*(.*)$"))) then
|
||||
str = sub(str, 2, -1)
|
||||
end
|
||||
str = gsub(str, "_", " ")
|
||||
str = gsub(str, "x([0-9A-F][0-9A-F])", function(hex)
|
||||
|
15
string2.moon
15
string2.moon
@ -26,6 +26,7 @@ string2 = {
|
||||
capitalized: => gsub(@, '%l', upper, 1)
|
||||
byte: byte, bytes: (i, j)=> {byte(@, i or 1, j or -1)}
|
||||
split: (sep)=> [chunk for i,chunk in isplit(@, sep)]
|
||||
starts_with: (s)=> sub(@, 1, #s) == s
|
||||
lines: => [line for i,line in isplit(@, '\n')]
|
||||
line: (line_num)=>
|
||||
for i, line, start in isplit(@, '\n')
|
||||
@ -41,10 +42,10 @@ string2 = {
|
||||
lines = {}
|
||||
for line in *@lines!
|
||||
while #line > maxlen
|
||||
chunk = line\sub(1, maxlen)
|
||||
split = chunk\find(' ', maxlen-buffer, true) or maxlen
|
||||
chunk = line\sub(1, split)
|
||||
line = line\sub(split+1, -1)
|
||||
chunk = sub(line, 1, maxlen)
|
||||
split = find(chunk, ' ', maxlen-buffer, true) or maxlen
|
||||
chunk = sub(line, 1, split)
|
||||
line = sub(line, split+1, -1)
|
||||
lines[#lines+1] = chunk
|
||||
lines[#lines+1] = line
|
||||
return table.concat(lines, "\n")
|
||||
@ -77,15 +78,15 @@ string2 = {
|
||||
if c == ' ' then '_'
|
||||
else format("x%02X", byte(c))
|
||||
|
||||
unless is_lua_id(str\match("^_*(.*)$"))
|
||||
unless is_lua_id(match(str, "^_*(.*)$"))
|
||||
str = "_"..str
|
||||
return str
|
||||
|
||||
-- from_lua_id(as_lua_id(str)) == str, but behavior is unspecified for inputs that
|
||||
-- did not come from as_lua_id()
|
||||
from_lua_id: (str)->
|
||||
unless is_lua_id(str\match("^_*(.*)$"))
|
||||
str = str\sub(2,-1)
|
||||
unless is_lua_id(match(str, "^_*(.*)$"))
|
||||
str = sub(str,2,-1)
|
||||
str = gsub(str, "_", " ")
|
||||
str = gsub(str, "x([0-9A-F][0-9A-F])", (hex)-> char(tonumber(hex, 16)))
|
||||
return str
|
||||
|
@ -160,10 +160,13 @@ do
|
||||
if type(a) == 'string' then
|
||||
stub_bits[#stub_bits + 1] = a
|
||||
else
|
||||
stub_bits[#stub_bits + 1] = tostring(arg_i)
|
||||
stub_bits[#stub_bits + 1] = arg_i
|
||||
arg_i = arg_i + 1
|
||||
end
|
||||
end
|
||||
while type(stub_bits[#stub_bits]) == 'number' do
|
||||
stub_bits[#stub_bits] = nil
|
||||
end
|
||||
return concat(stub_bits, " ")
|
||||
end
|
||||
}
|
||||
|
@ -80,8 +80,10 @@ class SyntaxTree
|
||||
if type(a) == 'string'
|
||||
stub_bits[#stub_bits+1] = a
|
||||
else
|
||||
stub_bits[#stub_bits+1] = tostring(arg_i)
|
||||
stub_bits[#stub_bits+1] = arg_i
|
||||
arg_i += 1
|
||||
while type(stub_bits[#stub_bits]) == 'number'
|
||||
stub_bits[#stub_bits] = nil
|
||||
return concat stub_bits, " "
|
||||
|
||||
@is_instance: (t)=>
|
||||
|
@ -14,7 +14,12 @@ for %path in %files:
|
||||
for file %filename in %path:
|
||||
unless (%filename::matches "%.nom$") (do next %filename)
|
||||
%file = (read file %filename)
|
||||
%tree = (parse %file from %filename)
|
||||
try:
|
||||
%tree = (parse %file from %filename)
|
||||
..and if it barfs:
|
||||
say (red "\%filename failed to parse")
|
||||
%tree = (nil)
|
||||
unless %tree: do next %filename
|
||||
%results = []
|
||||
for %t in recursive %tree:
|
||||
if (%t is "Action" syntax tree):
|
||||
|
Loading…
Reference in New Issue
Block a user