lua-scaffold.nv
· 13 KiB · Text
Bruto
Playground
|- lowky, kind forget what all this does -|
||
:stacks: (
.arity .1
@stdio.arity @stdio.1 @stdio.2
@jet.arity @jet.1
)
:rule: (
.arity 1 pushsym .1 10 pushsym
.arity 1 pushsym .1 33 pushsym
.arity 1 pushsym .1 100 pushsym
.arity 1 pushsym .1 108 pushsym
.arity 1 pushsym .1 114 pushsym
.arity 1 pushsym .1 111 pushsym
.arity 1 pushsym .1 87 pushsym
.arity 1 pushsym .1 32 pushsym
.arity 1 pushsym .1 44 pushsym
.arity 1 pushsym .1 111 pushsym
.arity 1 pushsym .1 108 pushsym
.arity 1 pushsym .1 108 pushsym
.arity 1 pushsym .1 101 pushsym
.arity 1 pushsym .1 72 pushsym
.arity 1 pushsym .1 print pushsym
done
@stdio.arity 2 0 match @stdio.1 write 0 match @stdio.2 $char 0 bind
@stdio.arity pop @stdio.1 pop @stdio.2 pop
@jet.arity 1 pushsym @jet.1 9 pushsym
@jet.arity 1 pushsym @jet.1 105 pushsym
@jet.arity 1 pushsym @jet.1 111 pushsym
@jet.arity 1 pushsym @jet.1 46 pushsym
@jet.arity 1 pushsym @jet.1 119 pushsym
@jet.arity 1 pushsym @jet.1 114 pushsym
@jet.arity 1 pushsym @jet.1 105 pushsym
@jet.arity 1 pushsym @jet.1 116 pushsym
@jet.arity 1 pushsym @jet.1 101 pushsym
@jet.arity 1 pushsym @jet.1 40 pushsym
@jet.arity 1 pushsym @jet.1 115 pushsym
@jet.arity 1 pushsym @jet.1 116 pushsym
@jet.arity 1 pushsym @jet.1 114 pushsym
@jet.arity 1 pushsym @jet.1 105 pushsym
@jet.arity 1 pushsym @jet.1 110 pushsym
@jet.arity 1 pushsym @jet.1 103 pushsym
@jet.arity 1 pushsym @jet.1 46 pushsym
@jet.arity 1 pushsym @jet.1 99 pushsym
@jet.arity 1 pushsym @jet.1 104 pushsym
@jet.arity 1 pushsym @jet.1 97 pushsym
@jet.arity 1 pushsym @jet.1 114 pushsym
@jet.arity 1 pushsym @jet.1 40 pushsym
@jet.arity 1 pushsym @jet.1 116 pushsym
@jet.arity 1 pushsym @jet.1 111 pushsym
@jet.arity 1 pushsym @jet.1 110 pushsym
@jet.arity 1 pushsym @jet.1 117 pushsym
@jet.arity 1 pushsym @jet.1 109 pushsym
@jet.arity 1 pushsym @jet.1 98 pushsym
@jet.arity 1 pushsym @jet.1 101 pushsym
@jet.arity 1 pushsym @jet.1 114 pushsym
@jet.arity 1 pushsym @jet.1 40 pushsym
@jet.arity 1 pushsym @jet.1 122 pushsym
@jet.arity 1 pushsym @jet.1 100 pushsym
@jet.arity 1 pushsym @jet.1 99 pushsym
@jet.arity 1 pushsym @jet.1 104 pushsym
@jet.arity 1 pushsym @jet.1 97 pushsym
@jet.arity 1 pushsym @jet.1 114 pushsym
@jet.arity 1 pushsym @jet.1 41 pushsym
@jet.arity 1 pushsym @jet.1 41 pushsym
@jet.arity 1 pushsym @jet.1 41 pushsym
@jet.arity 1 pushsym @jet.1 10 pushsym
done
.arity 1 0 match .1 print 0 match
.arity 1 1 match .1 $char 1 bind
.arity pop .1 pop .arity pop .1 pop
.arity 1 pushsym .1 print pushsym
@stdio.arity 2 pushsym @stdio.1 write pushsym @stdio.2 $char pushvar
done
.arity 1 0 match .1 print 0 match
.arity pop .1 pop
done
)
||
:: compile module header
:: compile stacks
:: compile rules :rule id: 0
:: compile run function
|:@symbols stacks:| :@symbol as string: $1
|:@symbols: explode $symbol|
:@jet: "
self\:ensure_stack("@symbol as string")
self\:push_string("@symbol as string", $symbol)
"
|:: get $symbol as string|
:@symbols: explode $symbol
|:: push to arguments|
:arguments: :: move to arguments
|:: move to arguments? :@symbol as string: $char|
:reversed string: $char
|:: move to arguments? :reversed string: $char|
:arguments: $char
|:: move to arguments|
|:: move $depth to arguments|
:arguments: $depth :arguments:
|:: next rule id? :rule id: $id|
:@math: add $id 1
|:: next rule id :@math: $z|
:rule id: $z
|:: compile stacks :stacks: $stack|
:: get $stack as string :: push to arguments
:: compile empty stack
:: compile stacks
|:: compile stacks|
|:: compile rules :rule: $more-op-codes?|
:: compile header for current rule
:: compile bytecode for current rule
:: compile footer for current rule
:: next rule id
:: compile rules
|:: compile rules|
|:: compile run function|
:: compile run header :rule index: 1
:: compile rule tree
:: compile run footer
|:: compile header for current rule :rule id: $id?|
:: print (formatted) :message: "function nova_core\:rule_{%d}()\n"
:arguments: $id :arguments:
|:: compile bytecode for current rule :rule: ($stack $symbol $depth match)|
:: get $symbol as string :: push to arguments
:: move $depth to arguments
:: get $stack as string :: push to arguments
:: compile match operation
:: compile bytecode for current rule :compiled rules: (match $depth $symbol $stack)
|:: compile bytecode for current rule :rule: ($stack $var $depth bind)|
:: get $var as string :: z-encode string :: push to arguments
:: move $depth to arguments
:: get $stack as string :: push to arguments
:: get $var as string :: z-encode string :: push to arguments
:: compile bind operation
:: compile bytecode for current rule :compiled rules: (bind $depth $var $stack)
|:: compile bytecode for current rule :rule: ($stack pop)|
:: get $stack as string :: push to arguments
:: compile pop operation
:: compile bytecode for current rule :compiled rules: (pop $stack)
|:: compile bytecode for current rule? :rule: (@jet.arity 1 pushsym @jet.1 $char pushsym)|
:@stdio: write $char
|:: compile bytecode for current rule :rule: ($stack $symbol pushsym)|
:: get $symbol as string :: push to arguments
:: get $stack as string :: push to arguments
:: compile pushsym operation
:: compile bytecode for current rule :compiled rules: (pushsym $symbol $stack)
|:: compile bytecode for current rule :rule: ($stack $symbol pushvar)|
:: get $symbol as string :: z-encode string :: push to arguments
:: get $stack as string :: push to arguments
:: compile pushvar operation
:: compile bytecode for current rule :compiled rules: (pushvar $symbol $stack)
|:: compile bytecode for current rule :rule: done|
:: compile done operation
|:: compile footer for current rule|
:: print (formatted)
:message: "end\n"
|:: compile empty stack|
:: print (formatted) :message: "nova_core.stacks["{}"] = { n = 0 ; }\n"
|:: compile match operation|
:: print (formatted)
:message: "\tif not match(self.stacks["{}"], {%d}, "{}") then return false end\n"
|:: compile bind operation|
:: print (formatted)
:message: "\tlocal {} = peek(self.stacks["{}"], {%d})\n\tif not {} then return false end\n"
|:: compile pop operation|
:: print (formatted)
:message: "\tpop(self.stacks["{}"])\n"
|:: compile pushsym operation|
:: print (formatted)
:message: "\tpush(self.stacks["{}"], "{}")\n"
|:: compile pushvar operation|
:: print (formatted)
:message: "\tpush(self.stacks["{}"], {})\n"
|:: compile done operation|
:: print (formatted)
:message: "\treturn true\n"
|:: compile run header|
:: print (formatted) :message: "
function nova_core\:run()
\tlocal run_rules = true
\tself\:rule_0()
\twhile run_rules do
\t\trun_rules = false
"
|:: compile rule tree :rule index: 0 :rule id: 0?|
|:: compile rule tree :rule index: $index :rule id: $index?|
:: end rule tree
|:: compile rule tree :rule index: $index?|
:: compile rule $index
:: next rule index
:: compile rule tree
|:: compile rule 1|
:: print (formatted) :message: "\t\tif self\:rule_1() then\n\t\t\trun_rules = true\n"
|:: compile rule $n|
:: print (formatted) :message: "\t\telseif self\:rule_{%d}() then\n\t\t\trun_rules = true\n"
:arguments: $n :arguments:
|:: next rule index? :rule index: $index|
:@math: add $index 1
|:: next rule index :@math: $z|
:rule index: $z
|:: end rule tree|
:: print (formatted) :message: "\t\tend\n"
|:: compile run footer|
:: print (formatted) :message: "\tend\nend\nnova_core\:run()\n"
|:: z-encode string? :@symbol as string: "!" | :reversed string: "nz"
|:: z-encode string? :@symbol as string: """ | :reversed string: "Qz"
|:: z-encode string? :@symbol as string: "#" | :reversed string: "hz"
|:: z-encode string? :@symbol as string: "$" | :reversed string: "dz"
|:: z-encode string? :@symbol as string: "%" | :reversed string: "vz"
|:: z-encode string? :@symbol as string: "&" | :reversed string: "az"
|:: z-encode string? :@symbol as string: """ | :reversed string: "qz"
|:: z-encode string? :@symbol as string: "(" | :reversed string: "LZ"
|:: z-encode string? :@symbol as string: ")" | :reversed string: "RZ"
|:: z-encode string? :@symbol as string: "*" | :reversed string: "tz"
|:: z-encode string? :@symbol as string: "+" | :reversed string: "pz"
|:: z-encode string? :@symbol as string: "," | :reversed string: "Cz"
|:: z-encode string? :@symbol as string: "-" | :reversed string: "mz"
|:: z-encode string? :@symbol as string: "." | :reversed string: "iz"
|:: z-encode string? :@symbol as string: "/" | :reversed string: "sz"
|:: z-encode string? :@symbol as string: "\:"| :reversed string: "CZ"
|:: z-encode string? :@symbol as string: ";" | :reversed string: "SZ"
|:: z-encode string? :@symbol as string: ">" | :reversed string: "gz"
|:: z-encode string? :@symbol as string: "=" | :reversed string: "ez"
|:: z-encode string? :@symbol as string: "<" | :reversed string: "lz"
|:: z-encode string? :@symbol as string: "?" | :reversed string: "Iz"
|:: z-encode string? :@symbol as string: "@" | :reversed string: "Az"
|:: z-encode string? :@symbol as string: "Z" | :reversed string: "ZZ"
|:: z-encode string? :@symbol as string: "[" | :reversed string: "MZ"
|:: z-encode string? :@symbol as string: "\" | :reversed string: "rz"
|:: z-encode string? :@symbol as string: "]" | :reversed string: "NZ"
|:: z-encode string? :@symbol as string: "^" | :reversed string: "cz"
|:: z-encode string? :@symbol as string: "_" | :reversed string: "uz"
|:: z-encode string? :@symbol as string: "`" | :reversed string: "Bz"
|:: z-encode string? :@symbol as string: "z" | :reversed string: "zz"
|:: z-encode string? :@symbol as string: "{" | :reversed string: "OZ"
|:: z-encode string? :@symbol as string: "\|"| :reversed string: "bz"
|:: z-encode string? :@symbol as string: "}" | :reversed string: "PZ"
|:: z-encode string? :@symbol as string: "~" | :reversed string: "Tz"
|:: z-encode string? :@symbol as string: $ch | :reversed string: $ch
|:: z-encode string|
|:: compile module header|
:: print (formatted) :message: "
local nova_core = { }
nova_core.stacks = { }
local function push(stack, value)
table.insert(stack, value)
stack.n = stack.n + 1
end
local function match(stack, depth, value)
local index = stack.n - depth
if index <= 0 then return false end
local tuple = stack[index]
if not tuple then return false end
return tuple == value
end
local function peek(stack, depth)
local index = stack.n - depth
if index <= 0 then return nil end
local tuple = stack[index]
if not tuple then return nil end
return tuple
end
local function pop(stack)
stack.n = stack.n - 1
table.remove(stack)
end
function nova_core\:fact(stack, ...)
local tuple, arity, arity_label, symbol_label_template = {...}, tostring(select("#", ...)), stack .. ".arity", stack .. ".%d"
push(self.stacks[arity_label], arity)
for i, symbol in ipairs(tuple) do
push(self.stacks[symbol_label_template\:format(i)], symbol)
end
end
function nova_core\:take(stack)
local tuple = { }
local arity_label, symbol_label_template = stack .. ".arity", stack .. ".%d"
local arity_stack = self.stacks[arity_label]
if arity_stack.n == 0 then return nil end
for arity = 1, tonumber(peek(arity_stack, 0)) do
local stack = self.stacks[symbol_label_template\:format(arity)]
table.insert(tuple, peek(stack, 0))
pop(stack)
end
pop(self.stacks[arity_label])
return tuple
end
function nova_core\:take_string(stack)
local str = { }
local fact = self\:take(stack)
while fact do
table.insert(str, string.char(tonumber(fact[1])))
fact = self\:take(stack)
end
return table.concat(str)
end
function nova_core\:push_string(stack, string)
for i = #string, 1, -1 do
self\:fact(stack, tostring(string.byte(string\:sub(i, i))))
end
end
function nova_core\:ensure_stack(stack)
if not self.stacks[stack] then
self.stacks[stack] = { n = 0 }
end
end
function nova_core\:print_stacks()
local stack_names = {}
local longest_name = -math.huge
for key, _ in pairs(self.stacks) do
table.insert(stack_names, key)
longest_name = math.max(#key, longest_name)
end
table.sort(stack_names)
for _, stack_name in ipairs(stack_names) do
local tuples = {
string.rep(" ", longest_name - #stack_name) .. stack_name .. "\:"
}
local stack = self.stacks[stack_name]
for i = stack.n, 1, -1 do
table.insert(tuples, "(" .. stack[i] .. ")")
end
io.stderr\:write(table.concat(tuples, " "))
io.stderr\:write("%\n")
end
end
"
| 1 | |- lowky, kind forget what all this does -| |
| 2 | || |
| 3 | :stacks: ( |
| 4 | .arity .1 |
| 5 | @stdio.arity @stdio.1 @stdio.2 |
| 6 | @jet.arity @jet.1 |
| 7 | ) |
| 8 | :rule: ( |
| 9 | .arity 1 pushsym .1 10 pushsym |
| 10 | .arity 1 pushsym .1 33 pushsym |
| 11 | .arity 1 pushsym .1 100 pushsym |
| 12 | .arity 1 pushsym .1 108 pushsym |
| 13 | .arity 1 pushsym .1 114 pushsym |
| 14 | .arity 1 pushsym .1 111 pushsym |
| 15 | .arity 1 pushsym .1 87 pushsym |
| 16 | .arity 1 pushsym .1 32 pushsym |
| 17 | .arity 1 pushsym .1 44 pushsym |
| 18 | .arity 1 pushsym .1 111 pushsym |
| 19 | .arity 1 pushsym .1 108 pushsym |
| 20 | .arity 1 pushsym .1 108 pushsym |
| 21 | .arity 1 pushsym .1 101 pushsym |
| 22 | .arity 1 pushsym .1 72 pushsym |
| 23 | .arity 1 pushsym .1 print pushsym |
| 24 | done |
| 25 | |
| 26 | @stdio.arity 2 0 match @stdio.1 write 0 match @stdio.2 $char 0 bind |
| 27 | @stdio.arity pop @stdio.1 pop @stdio.2 pop |
| 28 | @jet.arity 1 pushsym @jet.1 9 pushsym |
| 29 | @jet.arity 1 pushsym @jet.1 105 pushsym |
| 30 | @jet.arity 1 pushsym @jet.1 111 pushsym |
| 31 | @jet.arity 1 pushsym @jet.1 46 pushsym |
| 32 | @jet.arity 1 pushsym @jet.1 119 pushsym |
| 33 | @jet.arity 1 pushsym @jet.1 114 pushsym |
| 34 | @jet.arity 1 pushsym @jet.1 105 pushsym |
| 35 | @jet.arity 1 pushsym @jet.1 116 pushsym |
| 36 | @jet.arity 1 pushsym @jet.1 101 pushsym |
| 37 | @jet.arity 1 pushsym @jet.1 40 pushsym |
| 38 | @jet.arity 1 pushsym @jet.1 115 pushsym |
| 39 | @jet.arity 1 pushsym @jet.1 116 pushsym |
| 40 | @jet.arity 1 pushsym @jet.1 114 pushsym |
| 41 | @jet.arity 1 pushsym @jet.1 105 pushsym |
| 42 | @jet.arity 1 pushsym @jet.1 110 pushsym |
| 43 | @jet.arity 1 pushsym @jet.1 103 pushsym |
| 44 | @jet.arity 1 pushsym @jet.1 46 pushsym |
| 45 | @jet.arity 1 pushsym @jet.1 99 pushsym |
| 46 | @jet.arity 1 pushsym @jet.1 104 pushsym |
| 47 | @jet.arity 1 pushsym @jet.1 97 pushsym |
| 48 | @jet.arity 1 pushsym @jet.1 114 pushsym |
| 49 | @jet.arity 1 pushsym @jet.1 40 pushsym |
| 50 | @jet.arity 1 pushsym @jet.1 116 pushsym |
| 51 | @jet.arity 1 pushsym @jet.1 111 pushsym |
| 52 | @jet.arity 1 pushsym @jet.1 110 pushsym |
| 53 | @jet.arity 1 pushsym @jet.1 117 pushsym |
| 54 | @jet.arity 1 pushsym @jet.1 109 pushsym |
| 55 | @jet.arity 1 pushsym @jet.1 98 pushsym |
| 56 | @jet.arity 1 pushsym @jet.1 101 pushsym |
| 57 | @jet.arity 1 pushsym @jet.1 114 pushsym |
| 58 | @jet.arity 1 pushsym @jet.1 40 pushsym |
| 59 | @jet.arity 1 pushsym @jet.1 122 pushsym |
| 60 | @jet.arity 1 pushsym @jet.1 100 pushsym |
| 61 | @jet.arity 1 pushsym @jet.1 99 pushsym |
| 62 | @jet.arity 1 pushsym @jet.1 104 pushsym |
| 63 | @jet.arity 1 pushsym @jet.1 97 pushsym |
| 64 | @jet.arity 1 pushsym @jet.1 114 pushsym |
| 65 | @jet.arity 1 pushsym @jet.1 41 pushsym |
| 66 | @jet.arity 1 pushsym @jet.1 41 pushsym |
| 67 | @jet.arity 1 pushsym @jet.1 41 pushsym |
| 68 | @jet.arity 1 pushsym @jet.1 10 pushsym |
| 69 | done |
| 70 | |
| 71 | .arity 1 0 match .1 print 0 match |
| 72 | .arity 1 1 match .1 $char 1 bind |
| 73 | .arity pop .1 pop .arity pop .1 pop |
| 74 | .arity 1 pushsym .1 print pushsym |
| 75 | @stdio.arity 2 pushsym @stdio.1 write pushsym @stdio.2 $char pushvar |
| 76 | done |
| 77 | |
| 78 | .arity 1 0 match .1 print 0 match |
| 79 | .arity pop .1 pop |
| 80 | done |
| 81 | ) |
| 82 | |
| 83 | || |
| 84 | :: compile module header |
| 85 | :: compile stacks |
| 86 | :: compile rules :rule id: 0 |
| 87 | :: compile run function |
| 88 | |
| 89 | |:@symbols stacks:| :@symbol as string: $1 |
| 90 | |:@symbols: explode $symbol| |
| 91 | :@jet: " |
| 92 | self\:ensure_stack("@symbol as string") |
| 93 | self\:push_string("@symbol as string", $symbol) |
| 94 | " |
| 95 | |
| 96 | |:: get $symbol as string| |
| 97 | :@symbols: explode $symbol |
| 98 | |
| 99 | |:: push to arguments| |
| 100 | :arguments: :: move to arguments |
| 101 | |
| 102 | |:: move to arguments? :@symbol as string: $char| |
| 103 | :reversed string: $char |
| 104 | |:: move to arguments? :reversed string: $char| |
| 105 | :arguments: $char |
| 106 | |:: move to arguments| |
| 107 | |
| 108 | |:: move $depth to arguments| |
| 109 | :arguments: $depth :arguments: |
| 110 | |
| 111 | |:: next rule id? :rule id: $id| |
| 112 | :@math: add $id 1 |
| 113 | |:: next rule id :@math: $z| |
| 114 | :rule id: $z |
| 115 | |
| 116 | |:: compile stacks :stacks: $stack| |
| 117 | :: get $stack as string :: push to arguments |
| 118 | :: compile empty stack |
| 119 | :: compile stacks |
| 120 | |:: compile stacks| |
| 121 | |
| 122 | |:: compile rules :rule: $more-op-codes?| |
| 123 | :: compile header for current rule |
| 124 | :: compile bytecode for current rule |
| 125 | :: compile footer for current rule |
| 126 | :: next rule id |
| 127 | :: compile rules |
| 128 | |:: compile rules| |
| 129 | |
| 130 | |:: compile run function| |
| 131 | :: compile run header :rule index: 1 |
| 132 | :: compile rule tree |
| 133 | :: compile run footer |
| 134 | |
| 135 | |
| 136 | |:: compile header for current rule :rule id: $id?| |
| 137 | :: print (formatted) :message: "function nova_core\:rule_{%d}()\n" |
| 138 | :arguments: $id :arguments: |
| 139 | |
| 140 | |:: compile bytecode for current rule :rule: ($stack $symbol $depth match)| |
| 141 | :: get $symbol as string :: push to arguments |
| 142 | :: move $depth to arguments |
| 143 | :: get $stack as string :: push to arguments |
| 144 | :: compile match operation |
| 145 | :: compile bytecode for current rule :compiled rules: (match $depth $symbol $stack) |
| 146 | |
| 147 | |:: compile bytecode for current rule :rule: ($stack $var $depth bind)| |
| 148 | :: get $var as string :: z-encode string :: push to arguments |
| 149 | :: move $depth to arguments |
| 150 | :: get $stack as string :: push to arguments |
| 151 | :: get $var as string :: z-encode string :: push to arguments |
| 152 | :: compile bind operation |
| 153 | :: compile bytecode for current rule :compiled rules: (bind $depth $var $stack) |
| 154 | |
| 155 | |:: compile bytecode for current rule :rule: ($stack pop)| |
| 156 | :: get $stack as string :: push to arguments |
| 157 | :: compile pop operation |
| 158 | :: compile bytecode for current rule :compiled rules: (pop $stack) |
| 159 | |
| 160 | |:: compile bytecode for current rule? :rule: (@jet.arity 1 pushsym @jet.1 $char pushsym)| |
| 161 | :@stdio: write $char |
| 162 | |
| 163 | |:: compile bytecode for current rule :rule: ($stack $symbol pushsym)| |
| 164 | :: get $symbol as string :: push to arguments |
| 165 | :: get $stack as string :: push to arguments |
| 166 | :: compile pushsym operation |
| 167 | :: compile bytecode for current rule :compiled rules: (pushsym $symbol $stack) |
| 168 | |
| 169 | |:: compile bytecode for current rule :rule: ($stack $symbol pushvar)| |
| 170 | :: get $symbol as string :: z-encode string :: push to arguments |
| 171 | :: get $stack as string :: push to arguments |
| 172 | :: compile pushvar operation |
| 173 | :: compile bytecode for current rule :compiled rules: (pushvar $symbol $stack) |
| 174 | |
| 175 | |:: compile bytecode for current rule :rule: done| |
| 176 | :: compile done operation |
| 177 | |
| 178 | |:: compile footer for current rule| |
| 179 | :: print (formatted) |
| 180 | :message: "end\n" |
| 181 | |
| 182 | |:: compile empty stack| |
| 183 | :: print (formatted) :message: "nova_core.stacks["{}"] = { n = 0 ; }\n" |
| 184 | |
| 185 | |
| 186 | |:: compile match operation| |
| 187 | :: print (formatted) |
| 188 | :message: "\tif not match(self.stacks["{}"], {%d}, "{}") then return false end\n" |
| 189 | |
| 190 | |:: compile bind operation| |
| 191 | :: print (formatted) |
| 192 | :message: "\tlocal {} = peek(self.stacks["{}"], {%d})\n\tif not {} then return false end\n" |
| 193 | |
| 194 | |:: compile pop operation| |
| 195 | :: print (formatted) |
| 196 | :message: "\tpop(self.stacks["{}"])\n" |
| 197 | |
| 198 | |:: compile pushsym operation| |
| 199 | :: print (formatted) |
| 200 | :message: "\tpush(self.stacks["{}"], "{}")\n" |
| 201 | |
| 202 | |:: compile pushvar operation| |
| 203 | :: print (formatted) |
| 204 | :message: "\tpush(self.stacks["{}"], {})\n" |
| 205 | |
| 206 | |:: compile done operation| |
| 207 | :: print (formatted) |
| 208 | :message: "\treturn true\n" |
| 209 | |
| 210 | |:: compile run header| |
| 211 | :: print (formatted) :message: " |
| 212 | function nova_core\:run() |
| 213 | \tlocal run_rules = true |
| 214 | \tself\:rule_0() |
| 215 | \twhile run_rules do |
| 216 | \t\trun_rules = false |
| 217 | " |
| 218 | |
| 219 | |:: compile rule tree :rule index: 0 :rule id: 0?| |
| 220 | |:: compile rule tree :rule index: $index :rule id: $index?| |
| 221 | :: end rule tree |
| 222 | |:: compile rule tree :rule index: $index?| |
| 223 | :: compile rule $index |
| 224 | :: next rule index |
| 225 | :: compile rule tree |
| 226 | |
| 227 | |:: compile rule 1| |
| 228 | :: print (formatted) :message: "\t\tif self\:rule_1() then\n\t\t\trun_rules = true\n" |
| 229 | |:: compile rule $n| |
| 230 | :: print (formatted) :message: "\t\telseif self\:rule_{%d}() then\n\t\t\trun_rules = true\n" |
| 231 | :arguments: $n :arguments: |
| 232 | |
| 233 | |:: next rule index? :rule index: $index| |
| 234 | :@math: add $index 1 |
| 235 | |:: next rule index :@math: $z| |
| 236 | :rule index: $z |
| 237 | |
| 238 | |:: end rule tree| |
| 239 | :: print (formatted) :message: "\t\tend\n" |
| 240 | |
| 241 | |:: compile run footer| |
| 242 | :: print (formatted) :message: "\tend\nend\nnova_core\:run()\n" |
| 243 | |
| 244 | |
| 245 | |:: z-encode string? :@symbol as string: "!" | :reversed string: "nz" |
| 246 | |:: z-encode string? :@symbol as string: """ | :reversed string: "Qz" |
| 247 | |:: z-encode string? :@symbol as string: "#" | :reversed string: "hz" |
| 248 | |:: z-encode string? :@symbol as string: "$" | :reversed string: "dz" |
| 249 | |:: z-encode string? :@symbol as string: "%" | :reversed string: "vz" |
| 250 | |:: z-encode string? :@symbol as string: "&" | :reversed string: "az" |
| 251 | |:: z-encode string? :@symbol as string: """ | :reversed string: "qz" |
| 252 | |:: z-encode string? :@symbol as string: "(" | :reversed string: "LZ" |
| 253 | |:: z-encode string? :@symbol as string: ")" | :reversed string: "RZ" |
| 254 | |:: z-encode string? :@symbol as string: "*" | :reversed string: "tz" |
| 255 | |:: z-encode string? :@symbol as string: "+" | :reversed string: "pz" |
| 256 | |:: z-encode string? :@symbol as string: "," | :reversed string: "Cz" |
| 257 | |:: z-encode string? :@symbol as string: "-" | :reversed string: "mz" |
| 258 | |:: z-encode string? :@symbol as string: "." | :reversed string: "iz" |
| 259 | |:: z-encode string? :@symbol as string: "/" | :reversed string: "sz" |
| 260 | |:: z-encode string? :@symbol as string: "\:"| :reversed string: "CZ" |
| 261 | |:: z-encode string? :@symbol as string: ";" | :reversed string: "SZ" |
| 262 | |:: z-encode string? :@symbol as string: ">" | :reversed string: "gz" |
| 263 | |:: z-encode string? :@symbol as string: "=" | :reversed string: "ez" |
| 264 | |:: z-encode string? :@symbol as string: "<" | :reversed string: "lz" |
| 265 | |:: z-encode string? :@symbol as string: "?" | :reversed string: "Iz" |
| 266 | |:: z-encode string? :@symbol as string: "@" | :reversed string: "Az" |
| 267 | |:: z-encode string? :@symbol as string: "Z" | :reversed string: "ZZ" |
| 268 | |:: z-encode string? :@symbol as string: "[" | :reversed string: "MZ" |
| 269 | |:: z-encode string? :@symbol as string: "\" | :reversed string: "rz" |
| 270 | |:: z-encode string? :@symbol as string: "]" | :reversed string: "NZ" |
| 271 | |:: z-encode string? :@symbol as string: "^" | :reversed string: "cz" |
| 272 | |:: z-encode string? :@symbol as string: "_" | :reversed string: "uz" |
| 273 | |:: z-encode string? :@symbol as string: "`" | :reversed string: "Bz" |
| 274 | |:: z-encode string? :@symbol as string: "z" | :reversed string: "zz" |
| 275 | |:: z-encode string? :@symbol as string: "{" | :reversed string: "OZ" |
| 276 | |:: z-encode string? :@symbol as string: "\|"| :reversed string: "bz" |
| 277 | |:: z-encode string? :@symbol as string: "}" | :reversed string: "PZ" |
| 278 | |:: z-encode string? :@symbol as string: "~" | :reversed string: "Tz" |
| 279 | |:: z-encode string? :@symbol as string: $ch | :reversed string: $ch |
| 280 | |:: z-encode string| |
| 281 | |
| 282 | |:: compile module header| |
| 283 | :: print (formatted) :message: " |
| 284 | local nova_core = { } |
| 285 | nova_core.stacks = { } |
| 286 | local function push(stack, value) |
| 287 | table.insert(stack, value) |
| 288 | stack.n = stack.n + 1 |
| 289 | end |
| 290 | |
| 291 | local function match(stack, depth, value) |
| 292 | local index = stack.n - depth |
| 293 | if index <= 0 then return false end |
| 294 | local tuple = stack[index] |
| 295 | if not tuple then return false end |
| 296 | return tuple == value |
| 297 | end |
| 298 | |
| 299 | local function peek(stack, depth) |
| 300 | local index = stack.n - depth |
| 301 | if index <= 0 then return nil end |
| 302 | local tuple = stack[index] |
| 303 | if not tuple then return nil end |
| 304 | return tuple |
| 305 | end |
| 306 | |
| 307 | local function pop(stack) |
| 308 | stack.n = stack.n - 1 |
| 309 | table.remove(stack) |
| 310 | end |
| 311 | |
| 312 | function nova_core\:fact(stack, ...) |
| 313 | local tuple, arity, arity_label, symbol_label_template = {...}, tostring(select("#", ...)), stack .. ".arity", stack .. ".%d" |
| 314 | push(self.stacks[arity_label], arity) |
| 315 | for i, symbol in ipairs(tuple) do |
| 316 | push(self.stacks[symbol_label_template\:format(i)], symbol) |
| 317 | end |
| 318 | end |
| 319 | |
| 320 | function nova_core\:take(stack) |
| 321 | local tuple = { } |
| 322 | local arity_label, symbol_label_template = stack .. ".arity", stack .. ".%d" |
| 323 | local arity_stack = self.stacks[arity_label] |
| 324 | |
| 325 | if arity_stack.n == 0 then return nil end |
| 326 | |
| 327 | for arity = 1, tonumber(peek(arity_stack, 0)) do |
| 328 | local stack = self.stacks[symbol_label_template\:format(arity)] |
| 329 | table.insert(tuple, peek(stack, 0)) |
| 330 | pop(stack) |
| 331 | end |
| 332 | pop(self.stacks[arity_label]) |
| 333 | return tuple |
| 334 | end |
| 335 | |
| 336 | function nova_core\:take_string(stack) |
| 337 | local str = { } |
| 338 | local fact = self\:take(stack) |
| 339 | while fact do |
| 340 | table.insert(str, string.char(tonumber(fact[1]))) |
| 341 | fact = self\:take(stack) |
| 342 | end |
| 343 | return table.concat(str) |
| 344 | end |
| 345 | |
| 346 | function nova_core\:push_string(stack, string) |
| 347 | for i = #string, 1, -1 do |
| 348 | self\:fact(stack, tostring(string.byte(string\:sub(i, i)))) |
| 349 | end |
| 350 | end |
| 351 | |
| 352 | function nova_core\:ensure_stack(stack) |
| 353 | if not self.stacks[stack] then |
| 354 | self.stacks[stack] = { n = 0 } |
| 355 | end |
| 356 | end |
| 357 | |
| 358 | function nova_core\:print_stacks() |
| 359 | local stack_names = {} |
| 360 | local longest_name = -math.huge |
| 361 | for key, _ in pairs(self.stacks) do |
| 362 | table.insert(stack_names, key) |
| 363 | longest_name = math.max(#key, longest_name) |
| 364 | end |
| 365 | table.sort(stack_names) |
| 366 | for _, stack_name in ipairs(stack_names) do |
| 367 | local tuples = { |
| 368 | string.rep(" ", longest_name - #stack_name) .. stack_name .. "\:" |
| 369 | } |
| 370 | local stack = self.stacks[stack_name] |
| 371 | for i = stack.n, 1, -1 do |
| 372 | table.insert(tuples, "(" .. stack[i] .. ")") |
| 373 | end |
| 374 | io.stderr\:write(table.concat(tuples, " ")) |
| 375 | io.stderr\:write("%\n") |
| 376 | end |
| 377 | end |
| 378 | " |