moonlets.lua
· 3.9 KiB · Lua
原始文件
Playground
-- slow, inefficient, and partial implemention of a fraglets
-- interpreter. Basically enough to run a factorial program
-- Also, I changed the syntax.
local fraglets = {}
local function print_pool()
print("--- fraglets ---")
for i, fraglet in ipairs(fraglets) do
print(table.concat(fraglet, " "))
end
print()
end
local program = [[
nul factorial(n): [in $n] --> [out $n!].
res 1.
matchp in split t1 2 * match t1 lt f1 c1.
matchp f1 split finish * nul.
matchp c1 exch c2 nul.
matchp c2 exch c3 *.
matchp c3 split continue.
matchp finish match res out.
matchp continue split match t2 match res mult res * split match t2 sum in -1 * copy t2.
nul test.
in 5.
]]
local fraglet, symbol = {}, {}
local function push_symbol()
if #symbol ~= 0 then
table.insert(fraglet, table.concat(symbol))
symbol = {}
end
end
local function push_fraglet()
push_symbol()
if #fraglet ~= 0 then
table.insert(fraglets, fraglet)
fraglet = {}
end
end
for char in program:gmatch(".") do
if char:find("%s") then push_symbol()
elseif char == "." then push_fraglet()
else table.insert(symbol, char)
end
end
push_fraglet()
local ops = {}
local function merge(t1, t2, start)
for i = start, #t2 do
table.insert(t1, t2[i])
end
return t1
end
local function swap_and_delete(index, pool)
pool[index] = pool[#pool]
pool[#pool] = nil
end
function ops.nul(fraglet, index, pool)
swap_and_delete(index, pool)
return true
end
function ops.matchp(fraglet, index, pool)
for i, other_fraglet in ipairs(pool) do
if i ~= index and fraglet[2] == other_fraglet[1] then
pool[i] = merge(merge({}, fraglet, 3), other_fraglet, 2)
return true, index + 1
end
end
return false, index
end
function ops.split(fraglet, index, pool)
local left, right = {}, {}
local split = 0
for i, v in ipairs(fraglet) do
split = i
if v == "*" then break end
if i ~= 1 then
table.insert(left, v)
end
end
if #left == 0 then return false end
for i = split + 1, #fraglet do
table.insert(right, fraglet[i])
end
pool[index] = left
if #right > 0 then
table.insert(pool, right)
end
return true
end
function ops.match(fraglet, index, pool)
if ops.matchp(fraglet, index, pool) then
swap_and_delete(index, pool)
return true
end
return false
end
function ops.lt(fraglet, index, pool)
if tonumber(fraglet[4]) < tonumber(fraglet[5]) then
pool[index] = merge({fraglet[2]}, fraglet, 4)
else
pool[index] = merge({fraglet[3]}, fraglet, 4)
end
return true
end
function ops.exch(fraglet, index, pool)
pool[index][3], pool[index][4] = pool[index][4], pool[index][3]
table.remove(pool[index], 1)
return true
end
function ops.copy(fraglet, index, pool)
table.remove(fraglet, 1)
local copy = {}
for _, v in ipairs(fraglet) do
table.insert(copy, v)
end
table.insert(pool, copy)
return true
end
function ops.mult(fraglet, index, pool)
local tag, x, y = fraglet[2], tonumber(fraglet[3]), tonumber(fraglet[4])
if x and y then
pool[index] = {tag, tostring(x * y)}
return true
end
return false
end
function ops.sum(fraglet, index, pool)
local tag, x, y = fraglet[2], tonumber(fraglet[3]), tonumber(fraglet[4])
if x and y then
pool[index] = {tag, tostring(x + y)}
return true
end
return false
end
local i, reaction = 1, true
print("=== initial ===")
print_pool()
while reaction do
i, reaction = 1, false
while i <= #fraglets do
local op = fraglets[i][1]
if ops[op] then
if ops[op](fraglets[i], i, fraglets) then
print_pool()
reaction = true
end
end
i = i + 1
end
end
print("=== final ===")
print_pool()
| 1 | -- slow, inefficient, and partial implemention of a fraglets |
| 2 | -- interpreter. Basically enough to run a factorial program |
| 3 | -- Also, I changed the syntax. |
| 4 | local fraglets = {} |
| 5 | local function print_pool() |
| 6 | print("--- fraglets ---") |
| 7 | for i, fraglet in ipairs(fraglets) do |
| 8 | print(table.concat(fraglet, " ")) |
| 9 | end |
| 10 | print() |
| 11 | end |
| 12 | |
| 13 | local program = [[ |
| 14 | nul factorial(n): [in $n] --> [out $n!]. |
| 15 | |
| 16 | res 1. |
| 17 | matchp in split t1 2 * match t1 lt f1 c1. |
| 18 | matchp f1 split finish * nul. |
| 19 | matchp c1 exch c2 nul. |
| 20 | matchp c2 exch c3 *. |
| 21 | matchp c3 split continue. |
| 22 | |
| 23 | matchp finish match res out. |
| 24 | matchp continue split match t2 match res mult res * split match t2 sum in -1 * copy t2. |
| 25 | |
| 26 | nul test. |
| 27 | in 5. |
| 28 | ]] |
| 29 | |
| 30 | local fraglet, symbol = {}, {} |
| 31 | |
| 32 | local function push_symbol() |
| 33 | if #symbol ~= 0 then |
| 34 | table.insert(fraglet, table.concat(symbol)) |
| 35 | symbol = {} |
| 36 | end |
| 37 | end |
| 38 | |
| 39 | local function push_fraglet() |
| 40 | push_symbol() |
| 41 | if #fraglet ~= 0 then |
| 42 | table.insert(fraglets, fraglet) |
| 43 | fraglet = {} |
| 44 | end |
| 45 | end |
| 46 | |
| 47 | for char in program:gmatch(".") do |
| 48 | if char:find("%s") then push_symbol() |
| 49 | elseif char == "." then push_fraglet() |
| 50 | else table.insert(symbol, char) |
| 51 | end |
| 52 | end |
| 53 | push_fraglet() |
| 54 | |
| 55 | local ops = {} |
| 56 | |
| 57 | local function merge(t1, t2, start) |
| 58 | for i = start, #t2 do |
| 59 | table.insert(t1, t2[i]) |
| 60 | end |
| 61 | return t1 |
| 62 | end |
| 63 | |
| 64 | local function swap_and_delete(index, pool) |
| 65 | pool[index] = pool[#pool] |
| 66 | pool[#pool] = nil |
| 67 | end |
| 68 | |
| 69 | function ops.nul(fraglet, index, pool) |
| 70 | swap_and_delete(index, pool) |
| 71 | return true |
| 72 | end |
| 73 | |
| 74 | function ops.matchp(fraglet, index, pool) |
| 75 | for i, other_fraglet in ipairs(pool) do |
| 76 | if i ~= index and fraglet[2] == other_fraglet[1] then |
| 77 | pool[i] = merge(merge({}, fraglet, 3), other_fraglet, 2) |
| 78 | return true, index + 1 |
| 79 | end |
| 80 | end |
| 81 | return false, index |
| 82 | end |
| 83 | |
| 84 | function ops.split(fraglet, index, pool) |
| 85 | local left, right = {}, {} |
| 86 | local split = 0 |
| 87 | |
| 88 | for i, v in ipairs(fraglet) do |
| 89 | split = i |
| 90 | |
| 91 | if v == "*" then break end |
| 92 | if i ~= 1 then |
| 93 | table.insert(left, v) |
| 94 | end |
| 95 | end |
| 96 | |
| 97 | if #left == 0 then return false end |
| 98 | |
| 99 | for i = split + 1, #fraglet do |
| 100 | table.insert(right, fraglet[i]) |
| 101 | end |
| 102 | |
| 103 | pool[index] = left |
| 104 | if #right > 0 then |
| 105 | table.insert(pool, right) |
| 106 | end |
| 107 | |
| 108 | return true |
| 109 | end |
| 110 | |
| 111 | function ops.match(fraglet, index, pool) |
| 112 | if ops.matchp(fraglet, index, pool) then |
| 113 | swap_and_delete(index, pool) |
| 114 | return true |
| 115 | end |
| 116 | return false |
| 117 | end |
| 118 | |
| 119 | function ops.lt(fraglet, index, pool) |
| 120 | if tonumber(fraglet[4]) < tonumber(fraglet[5]) then |
| 121 | pool[index] = merge({fraglet[2]}, fraglet, 4) |
| 122 | else |
| 123 | pool[index] = merge({fraglet[3]}, fraglet, 4) |
| 124 | end |
| 125 | return true |
| 126 | end |
| 127 | |
| 128 | function ops.exch(fraglet, index, pool) |
| 129 | pool[index][3], pool[index][4] = pool[index][4], pool[index][3] |
| 130 | table.remove(pool[index], 1) |
| 131 | return true |
| 132 | end |
| 133 | |
| 134 | function ops.copy(fraglet, index, pool) |
| 135 | table.remove(fraglet, 1) |
| 136 | local copy = {} |
| 137 | for _, v in ipairs(fraglet) do |
| 138 | table.insert(copy, v) |
| 139 | end |
| 140 | table.insert(pool, copy) |
| 141 | return true |
| 142 | end |
| 143 | |
| 144 | function ops.mult(fraglet, index, pool) |
| 145 | local tag, x, y = fraglet[2], tonumber(fraglet[3]), tonumber(fraglet[4]) |
| 146 | if x and y then |
| 147 | pool[index] = {tag, tostring(x * y)} |
| 148 | return true |
| 149 | end |
| 150 | return false |
| 151 | end |
| 152 | |
| 153 | function ops.sum(fraglet, index, pool) |
| 154 | local tag, x, y = fraglet[2], tonumber(fraglet[3]), tonumber(fraglet[4]) |
| 155 | if x and y then |
| 156 | pool[index] = {tag, tostring(x + y)} |
| 157 | return true |
| 158 | end |
| 159 | return false |
| 160 | end |
| 161 | |
| 162 | local i, reaction = 1, true |
| 163 | print("=== initial ===") |
| 164 | print_pool() |
| 165 | while reaction do |
| 166 | i, reaction = 1, false |
| 167 | while i <= #fraglets do |
| 168 | local op = fraglets[i][1] |
| 169 | if ops[op] then |
| 170 | if ops[op](fraglets[i], i, fraglets) then |
| 171 | print_pool() |
| 172 | reaction = true |
| 173 | end |
| 174 | end |
| 175 | i = i + 1 |
| 176 | end |
| 177 | end |
| 178 | print("=== final ===") |
| 179 | print_pool() |