generated.hailstone.nv.lua
· 6.1 KiB · Lua
原始檔案
Playground
local min, max, huge = math.min, math.max, math.huge
local machine = {}
machine.counters = {
["x:3"] = 0,
["x:27"] = 1,
["1"] = 0,
["2"] = 0,
["copy x to @number"] = 0,
["print number"] = 0,
["x -> @number:9007199254740991"] = 0,
["move"] = 0,
["temporary x"] = 0,
["@print number"] = 0,
["hailstone"] = 1,
["x"] = 0,
["odd"] = 0,
["x:6"] = 0,
["@number"] = 0,
["x -> @number"] = 0,
["eval"] = 0,
["show x"] = 0,
}
function machine.on_print_number(counters, number)
end
function match(self, counters)
if counters["@print number"] > 0 then
self.on_print_number(counters, counters["@number"])
counters["@print number"] = 0
counters["@number"] = 0
return true
end
if counters["x:27"] > 0 then
acc = counters["x:27"]
counters["x:27"] = max(counters["x:27"] - acc, 0)
counters["x"] = counters["x"] + acc * 27
return true
end
if counters["x:6"] > 0 then
acc = counters["x:6"]
counters["x:6"] = max(counters["x:6"] - acc, 0)
counters["x"] = counters["x"] + acc * 6
return true
end
if counters["x -> @number:9007199254740991"] > 0 then
acc = counters["x -> @number:9007199254740991"]
counters["x -> @number:9007199254740991"] = max(counters["x -> @number:9007199254740991"] - acc, 0)
counters["x -> @number"] = counters["x -> @number"] + acc * 9007199254740991
return true
end
if counters["x:3"] > 0 then
acc = counters["x:3"]
counters["x:3"] = max(counters["x:3"] - acc, 0)
counters["x"] = counters["x"] + acc * 3
return true
end
if counters["show x"] > 0 then
acc = counters["show x"]
counters["show x"] = max(counters["show x"] - acc, 0)
counters["print number"] = counters["print number"] + acc * 1
counters["copy x to @number"] = counters["copy x to @number"] + acc * 1
return true
end
if counters["copy x to @number"] > 0 then
acc = counters["copy x to @number"]
counters["copy x to @number"] = max(counters["copy x to @number"] - acc, 0)
counters["x -> @number:9007199254740991"] = counters["x -> @number:9007199254740991"] + acc * 1
return true
end
if counters["x -> @number"] > 0 and counters["x"] > 0 then
local acc = huge
acc = min(acc, counters["x -> @number"])
acc = min(acc, counters["x"])
counters["x -> @number"] = max(counters["x -> @number"] - acc, 0)
counters["x"] = max(counters["x"] - acc, 0)
counters["@number"] = counters["@number"] + acc * 1
counters["temporary x"] = counters["temporary x"] + acc * 1
return true
end
if counters["x -> @number"] > 0 then
acc = counters["x -> @number"]
counters["x -> @number"] = max(counters["x -> @number"] - acc, 0)
return true
end
if counters["temporary x"] > 0 then
acc = counters["temporary x"]
counters["temporary x"] = max(counters["temporary x"] - acc, 0)
counters["x"] = counters["x"] + acc * 1
return true
end
if counters["print number"] > 0 then
acc = counters["print number"]
counters["print number"] = max(counters["print number"] - acc, 0)
counters["@print number"] = counters["@print number"] + acc * 1
return true
end
if counters["move"] > 0 and counters["2"] > 0 then
local acc = huge
acc = min(acc, counters["move"])
acc = min(acc, counters["2"])
counters["move"] = max(counters["move"] - acc, 0)
counters["2"] = max(counters["2"] - acc, 0)
counters["move"] = counters["move"] + acc * 1
counters["x"] = counters["x"] + acc * 1
return true
end
if counters["move"] > 0 and counters["1"] > 0 then
local acc = huge
acc = min(acc, counters["move"])
acc = min(acc, counters["1"])
counters["move"] = max(counters["move"] - acc, 0)
counters["1"] = max(counters["1"] - acc, 0)
counters["x"] = counters["x"] + acc * 1
return true
end
if counters["move"] > 0 then
acc = counters["move"]
counters["move"] = max(counters["move"] - acc, 0)
counters["hailstone"] = counters["hailstone"] + acc * 1
return true
end
if counters["odd"] > 0 and counters["2"] > 0 then
local acc = huge
acc = min(acc, counters["2"])
acc = min(acc, counters["odd"])
counters["odd"] = max(counters["odd"] - acc, 0)
counters["2"] = max(counters["2"] - acc, 0)
counters["x:6"] = counters["x:6"] + acc * 1
counters["odd"] = counters["odd"] + acc * 1
return true
end
if counters["odd"] > 0 then
acc = counters["odd"]
counters["odd"] = max(counters["odd"] - acc, 0)
counters["x"] = counters["x"] + acc * 1
counters["hailstone"] = counters["hailstone"] + acc * 1
return true
end
if counters["eval"] > 0 and counters["x"] > 0 and counters["1"] > 0 then
local acc = huge
acc = min(acc, counters["1"])
acc = min(acc, counters["eval"])
acc = min(acc, counters["x"])
counters["eval"] = max(counters["eval"] - acc, 0)
counters["x"] = max(counters["x"] - acc, 0)
counters["1"] = max(counters["1"] - acc, 0)
counters["eval"] = counters["eval"] + acc * 1
counters["2"] = counters["2"] + acc * 1
return true
end
if counters["eval"] > 0 and counters["x"] > 0 then
local acc = huge
acc = min(acc, counters["eval"])
acc = min(acc, counters["x"])
counters["eval"] = max(counters["eval"] - acc, 0)
counters["x"] = max(counters["x"] - acc, 0)
counters["eval"] = counters["eval"] + acc * 1
counters["1"] = counters["1"] + acc * 1
return true
end
if counters["eval"] > 0 and counters["2"] > 0 and counters["1"] > 0 then
local acc = huge
acc = min(acc, counters["1"])
acc = min(acc, counters["eval"])
acc = min(acc, counters["2"])
counters["eval"] = max(counters["eval"] - acc, 0)
counters["2"] = max(counters["2"] - acc, 0)
counters["1"] = max(counters["1"] - acc, 0)
counters["x:3"] = counters["x:3"] + acc * 1
counters["2"] = counters["2"] + acc * 1
counters["odd"] = counters["odd"] + acc * 1
return true
end
if counters["eval"] > 0 then
acc = counters["eval"]
counters["eval"] = max(counters["eval"] - acc, 0)
counters["move"] = counters["move"] + acc * 1
return true
end
if counters["hailstone"] > 0 then
acc = counters["hailstone"]
counters["hailstone"] = max(counters["hailstone"] - acc, 0)
counters["show x"] = counters["show x"] + acc * 1
counters["eval"] = counters["eval"] + acc * 1
return true
end
return false
end
function machine:run()
local counters = self.counters
while match(self, counters) do end
end
return machine
| 1 | local min, max, huge = math.min, math.max, math.huge |
| 2 | local machine = {} |
| 3 | |
| 4 | machine.counters = { |
| 5 | ["x:3"] = 0, |
| 6 | ["x:27"] = 1, |
| 7 | ["1"] = 0, |
| 8 | ["2"] = 0, |
| 9 | ["copy x to @number"] = 0, |
| 10 | ["print number"] = 0, |
| 11 | ["x -> @number:9007199254740991"] = 0, |
| 12 | ["move"] = 0, |
| 13 | ["temporary x"] = 0, |
| 14 | ["@print number"] = 0, |
| 15 | ["hailstone"] = 1, |
| 16 | ["x"] = 0, |
| 17 | ["odd"] = 0, |
| 18 | ["x:6"] = 0, |
| 19 | ["@number"] = 0, |
| 20 | ["x -> @number"] = 0, |
| 21 | ["eval"] = 0, |
| 22 | ["show x"] = 0, |
| 23 | } |
| 24 | |
| 25 | function machine.on_print_number(counters, number) |
| 26 | end |
| 27 | |
| 28 | function match(self, counters) |
| 29 | if counters["@print number"] > 0 then |
| 30 | self.on_print_number(counters, counters["@number"]) |
| 31 | counters["@print number"] = 0 |
| 32 | counters["@number"] = 0 |
| 33 | return true |
| 34 | end |
| 35 | if counters["x:27"] > 0 then |
| 36 | acc = counters["x:27"] |
| 37 | counters["x:27"] = max(counters["x:27"] - acc, 0) |
| 38 | counters["x"] = counters["x"] + acc * 27 |
| 39 | return true |
| 40 | end |
| 41 | if counters["x:6"] > 0 then |
| 42 | acc = counters["x:6"] |
| 43 | counters["x:6"] = max(counters["x:6"] - acc, 0) |
| 44 | counters["x"] = counters["x"] + acc * 6 |
| 45 | return true |
| 46 | end |
| 47 | if counters["x -> @number:9007199254740991"] > 0 then |
| 48 | acc = counters["x -> @number:9007199254740991"] |
| 49 | counters["x -> @number:9007199254740991"] = max(counters["x -> @number:9007199254740991"] - acc, 0) |
| 50 | counters["x -> @number"] = counters["x -> @number"] + acc * 9007199254740991 |
| 51 | return true |
| 52 | end |
| 53 | if counters["x:3"] > 0 then |
| 54 | acc = counters["x:3"] |
| 55 | counters["x:3"] = max(counters["x:3"] - acc, 0) |
| 56 | counters["x"] = counters["x"] + acc * 3 |
| 57 | return true |
| 58 | end |
| 59 | if counters["show x"] > 0 then |
| 60 | acc = counters["show x"] |
| 61 | counters["show x"] = max(counters["show x"] - acc, 0) |
| 62 | counters["print number"] = counters["print number"] + acc * 1 |
| 63 | counters["copy x to @number"] = counters["copy x to @number"] + acc * 1 |
| 64 | return true |
| 65 | end |
| 66 | if counters["copy x to @number"] > 0 then |
| 67 | acc = counters["copy x to @number"] |
| 68 | counters["copy x to @number"] = max(counters["copy x to @number"] - acc, 0) |
| 69 | counters["x -> @number:9007199254740991"] = counters["x -> @number:9007199254740991"] + acc * 1 |
| 70 | return true |
| 71 | end |
| 72 | if counters["x -> @number"] > 0 and counters["x"] > 0 then |
| 73 | local acc = huge |
| 74 | acc = min(acc, counters["x -> @number"]) |
| 75 | acc = min(acc, counters["x"]) |
| 76 | counters["x -> @number"] = max(counters["x -> @number"] - acc, 0) |
| 77 | counters["x"] = max(counters["x"] - acc, 0) |
| 78 | counters["@number"] = counters["@number"] + acc * 1 |
| 79 | counters["temporary x"] = counters["temporary x"] + acc * 1 |
| 80 | return true |
| 81 | end |
| 82 | if counters["x -> @number"] > 0 then |
| 83 | acc = counters["x -> @number"] |
| 84 | counters["x -> @number"] = max(counters["x -> @number"] - acc, 0) |
| 85 | return true |
| 86 | end |
| 87 | if counters["temporary x"] > 0 then |
| 88 | acc = counters["temporary x"] |
| 89 | counters["temporary x"] = max(counters["temporary x"] - acc, 0) |
| 90 | counters["x"] = counters["x"] + acc * 1 |
| 91 | return true |
| 92 | end |
| 93 | if counters["print number"] > 0 then |
| 94 | acc = counters["print number"] |
| 95 | counters["print number"] = max(counters["print number"] - acc, 0) |
| 96 | counters["@print number"] = counters["@print number"] + acc * 1 |
| 97 | return true |
| 98 | end |
| 99 | if counters["move"] > 0 and counters["2"] > 0 then |
| 100 | local acc = huge |
| 101 | acc = min(acc, counters["move"]) |
| 102 | acc = min(acc, counters["2"]) |
| 103 | counters["move"] = max(counters["move"] - acc, 0) |
| 104 | counters["2"] = max(counters["2"] - acc, 0) |
| 105 | counters["move"] = counters["move"] + acc * 1 |
| 106 | counters["x"] = counters["x"] + acc * 1 |
| 107 | return true |
| 108 | end |
| 109 | if counters["move"] > 0 and counters["1"] > 0 then |
| 110 | local acc = huge |
| 111 | acc = min(acc, counters["move"]) |
| 112 | acc = min(acc, counters["1"]) |
| 113 | counters["move"] = max(counters["move"] - acc, 0) |
| 114 | counters["1"] = max(counters["1"] - acc, 0) |
| 115 | counters["x"] = counters["x"] + acc * 1 |
| 116 | return true |
| 117 | end |
| 118 | if counters["move"] > 0 then |
| 119 | acc = counters["move"] |
| 120 | counters["move"] = max(counters["move"] - acc, 0) |
| 121 | counters["hailstone"] = counters["hailstone"] + acc * 1 |
| 122 | return true |
| 123 | end |
| 124 | if counters["odd"] > 0 and counters["2"] > 0 then |
| 125 | local acc = huge |
| 126 | acc = min(acc, counters["2"]) |
| 127 | acc = min(acc, counters["odd"]) |
| 128 | counters["odd"] = max(counters["odd"] - acc, 0) |
| 129 | counters["2"] = max(counters["2"] - acc, 0) |
| 130 | counters["x:6"] = counters["x:6"] + acc * 1 |
| 131 | counters["odd"] = counters["odd"] + acc * 1 |
| 132 | return true |
| 133 | end |
| 134 | if counters["odd"] > 0 then |
| 135 | acc = counters["odd"] |
| 136 | counters["odd"] = max(counters["odd"] - acc, 0) |
| 137 | counters["x"] = counters["x"] + acc * 1 |
| 138 | counters["hailstone"] = counters["hailstone"] + acc * 1 |
| 139 | return true |
| 140 | end |
| 141 | if counters["eval"] > 0 and counters["x"] > 0 and counters["1"] > 0 then |
| 142 | local acc = huge |
| 143 | acc = min(acc, counters["1"]) |
| 144 | acc = min(acc, counters["eval"]) |
| 145 | acc = min(acc, counters["x"]) |
| 146 | counters["eval"] = max(counters["eval"] - acc, 0) |
| 147 | counters["x"] = max(counters["x"] - acc, 0) |
| 148 | counters["1"] = max(counters["1"] - acc, 0) |
| 149 | counters["eval"] = counters["eval"] + acc * 1 |
| 150 | counters["2"] = counters["2"] + acc * 1 |
| 151 | return true |
| 152 | end |
| 153 | if counters["eval"] > 0 and counters["x"] > 0 then |
| 154 | local acc = huge |
| 155 | acc = min(acc, counters["eval"]) |
| 156 | acc = min(acc, counters["x"]) |
| 157 | counters["eval"] = max(counters["eval"] - acc, 0) |
| 158 | counters["x"] = max(counters["x"] - acc, 0) |
| 159 | counters["eval"] = counters["eval"] + acc * 1 |
| 160 | counters["1"] = counters["1"] + acc * 1 |
| 161 | return true |
| 162 | end |
| 163 | if counters["eval"] > 0 and counters["2"] > 0 and counters["1"] > 0 then |
| 164 | local acc = huge |
| 165 | acc = min(acc, counters["1"]) |
| 166 | acc = min(acc, counters["eval"]) |
| 167 | acc = min(acc, counters["2"]) |
| 168 | counters["eval"] = max(counters["eval"] - acc, 0) |
| 169 | counters["2"] = max(counters["2"] - acc, 0) |
| 170 | counters["1"] = max(counters["1"] - acc, 0) |
| 171 | counters["x:3"] = counters["x:3"] + acc * 1 |
| 172 | counters["2"] = counters["2"] + acc * 1 |
| 173 | counters["odd"] = counters["odd"] + acc * 1 |
| 174 | return true |
| 175 | end |
| 176 | if counters["eval"] > 0 then |
| 177 | acc = counters["eval"] |
| 178 | counters["eval"] = max(counters["eval"] - acc, 0) |
| 179 | counters["move"] = counters["move"] + acc * 1 |
| 180 | return true |
| 181 | end |
| 182 | if counters["hailstone"] > 0 then |
| 183 | acc = counters["hailstone"] |
| 184 | counters["hailstone"] = max(counters["hailstone"] - acc, 0) |
| 185 | counters["show x"] = counters["show x"] + acc * 1 |
| 186 | counters["eval"] = counters["eval"] + acc * 1 |
| 187 | return true |
| 188 | end |
| 189 | return false |
| 190 | end |
| 191 | |
| 192 | function machine:run() |
| 193 | local counters = self.counters |
| 194 | while match(self, counters) do end |
| 195 | end |
| 196 | |
| 197 | return machine |
hailstone.nv
· 703 B · Text
原始檔案
Playground
|_| Convert our parity encoding back into unary,
looping as needed.
|show x|
, copy x to @number
, print number
|copy x to @number|
x -> @number:9007199254740991
|x -> @number, x| @number, temporary x
|x -> @number|
|temporary x| x
|print number| @print number
|move, 2| move, x
|move, 1| x
|move | hailstone
|_| Compute 3x + 1
|odd, 2| odd, x:6
|odd | hailstone, x
|_| compute the parity of x
|eval, x, 1| eval, 2
|eval, x | eval, 1
|_| resolve our base cases 3x + 1 and x / 2
|eval, 2, 1| odd, 2, x:3
|eval | move
|hailstone| show x, eval
|#port, on print number
, needs, @print number, clears, @print number
, takes, @number|
|| hailstone
|| x:27
| 1 | |_| Convert our parity encoding back into unary, |
| 2 | looping as needed. |
| 3 | |
| 4 | |show x| |
| 5 | , copy x to @number |
| 6 | , print number |
| 7 | |
| 8 | |copy x to @number| |
| 9 | x -> @number:9007199254740991 |
| 10 | |
| 11 | |x -> @number, x| @number, temporary x |
| 12 | |x -> @number| |
| 13 | |temporary x| x |
| 14 | |
| 15 | |print number| @print number |
| 16 | |
| 17 | |move, 2| move, x |
| 18 | |move, 1| x |
| 19 | |move | hailstone |
| 20 | |
| 21 | |_| Compute 3x + 1 |
| 22 | |odd, 2| odd, x:6 |
| 23 | |odd | hailstone, x |
| 24 | |
| 25 | |_| compute the parity of x |
| 26 | |eval, x, 1| eval, 2 |
| 27 | |eval, x | eval, 1 |
| 28 | |
| 29 | |_| resolve our base cases 3x + 1 and x / 2 |
| 30 | |eval, 2, 1| odd, 2, x:3 |
| 31 | |eval | move |
| 32 | |
| 33 | |hailstone| show x, eval |
| 34 | |
| 35 | |#port, on print number |
| 36 | , needs, @print number, clears, @print number |
| 37 | , takes, @number| |
| 38 | |
| 39 | || hailstone |
| 40 | || x:27 |
main.lua
· 591 B · Lua
原始檔案
Playground
package.path = package.path .. ";./src/?.lua"
local Lvera = require "lvera"
local lua_generator = require "generators.lua"
local lvera = Lvera.new()
lvera:load("samples/hailstone.nv")
lvera:add_pass(require "passes.ports" (lua_generator.ports))
lvera:add_pass(require "passes.constants")
lvera:add_pass(require "passes.eliminate-dead-code")
local compiled_lua = lvera:compile(lua_generator)
local out_file = io.open("generated.lua", "w+")
out_file:write(compiled_lua)
local machine = load(compiled_lua)()
function machine.on_print_number(_, number)
print(number)
end
machine:run()
| 1 | package.path = package.path .. ";./src/?.lua" |
| 2 | local Lvera = require "lvera" |
| 3 | local lua_generator = require "generators.lua" |
| 4 | |
| 5 | local lvera = Lvera.new() |
| 6 | |
| 7 | lvera:load("samples/hailstone.nv") |
| 8 | |
| 9 | lvera:add_pass(require "passes.ports" (lua_generator.ports)) |
| 10 | lvera:add_pass(require "passes.constants") |
| 11 | lvera:add_pass(require "passes.eliminate-dead-code") |
| 12 | |
| 13 | local compiled_lua = lvera:compile(lua_generator) |
| 14 | |
| 15 | local out_file = io.open("generated.lua", "w+") |
| 16 | out_file:write(compiled_lua) |
| 17 | |
| 18 | local machine = load(compiled_lua)() |
| 19 | function machine.on_print_number(_, number) |
| 20 | print(number) |
| 21 | end |
| 22 | |
| 23 | machine:run() |