Ultima attività 1738819593

Revisione 60e438df780d71580fdd10290ead84ab7d3253b2

moonlets.lua Raw Playground
1-- slow, inefficient, and partial implemention of a fraglets
2-- interpreter. Basically enough to run a factorial program
3-- Also, I changed the syntax.
4local fraglets = {}
5local function print_pool()
6 print("--- fraglets ---")
7 for i, fraglet in ipairs(fraglets) do
8 print(table.concat(fraglet, " "))
9 end
10 print()
11end
12
13local program = [[
14nul factorial(n): [in $n] --> [out $n!].
15
16res 1.
17matchp in split t1 2 * match t1 lt f1 c1.
18matchp f1 split finish * nul.
19matchp c1 exch c2 nul.
20matchp c2 exch c3 *.
21matchp c3 split continue.
22
23matchp finish match res out.
24matchp continue split match t2 match res mult res * split match t2 sum in -1 * copy t2.
25
26nul test.
27in 5.
28]]
29
30local fraglet, symbol = {}, {}
31
32local function push_symbol()
33 if #symbol ~= 0 then
34 table.insert(fraglet, table.concat(symbol))
35 symbol = {}
36 end
37end
38
39local function push_fraglet()
40 push_symbol()
41 if #fraglet ~= 0 then
42 table.insert(fraglets, fraglet)
43 fraglet = {}
44 end
45end
46
47for 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
52end
53push_fraglet()
54
55local ops = {}
56
57local function merge(t1, t2, start)
58 for i = start, #t2 do
59 table.insert(t1, t2[i])
60 end
61 return t1
62end
63
64local function swap_and_delete(index, pool)
65 pool[index] = pool[#pool]
66 pool[#pool] = nil
67end
68
69function ops.nul(fraglet, index, pool)
70 swap_and_delete(index, pool)
71 return true
72end
73
74function 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
82end
83
84function 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
109end
110
111function 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
117end
118
119function 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
126end
127
128function 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
132end
133
134function 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
142end
143
144function 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
151end
152
153function 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
160end
161
162local i, reaction = 1, true
163print("=== initial ===")
164print_pool()
165while 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
177end
178print("=== final ===")
179print_pool()