最終更新 1738214147

capitalex's Avatar capitalex revised this gist 1738214147. Go to revision

1 file changed, 163 insertions

luneur.lua(file created)

@@ -0,0 +1,163 @@
1 + local net, live = {}, {}
2 +
3 + local function neuron(name)
4 + if not net[name] then
5 + net[name] = {
6 + name = name,
7 + alive = false, sleep = false,
8 + arity = 0, saturation = 0,
9 + excite = {},
10 + inhibit = {},
11 + }
12 + end
13 + return net[name]
14 + end
15 +
16 + local function tokenize(program)
17 + local tokens, current_token = {}, {}
18 + for char in program:gmatch(".") do
19 + if char:match "%s" then
20 + current_token = {}
21 + elseif char:match "[:;.]" then
22 + current_token = {}
23 + table.insert(tokens, char)
24 + elseif char == "*" then
25 + if #current_token ~= 0 then
26 + table.insert(tokens, table.concat(current_token))
27 + current_token = {}
28 + end
29 + else
30 + table.insert(current_token, char)
31 + end
32 + end
33 + return tokens
34 + end
35 +
36 + local function connect_neurons(lhs, rhs, inhibit)
37 + for _, left in ipairs(lhs) do
38 + for _, right in ipairs(rhs) do
39 + if inhibit then table.insert(left.inhibit, right)
40 + else table.insert(left.excite, right)
41 + end
42 + if not right.alive then
43 + right.arity, right.alive = #lhs, true
44 + end
45 + end
46 + end
47 + end
48 +
49 + local function parse(tokens)
50 + local is_right, inhibit, chaining = false, false, false
51 + local lhs, rhs = {}, {}
52 + for _, token in ipairs(tokens) do
53 + if token == ":" or token == ";" then
54 + is_right = not is_right
55 + if chaining then
56 + if is_right then
57 + connect_neurons(rhs, lhs, inhibit) ; rhs = {}
58 + else
59 + connect_neurons(lhs, rhs, inhibit) ; lhs = {}
60 + end
61 + end
62 + chaining = true
63 + inhibit = token == ";"
64 + elseif token == "." then
65 + if not chaining then
66 + for _, left in ipairs(lhs) do
67 + left.alive = true
68 + table.insert(live, left)
69 + end
70 + elseif is_right then
71 + connect_neurons(lhs, rhs, inhibit)
72 + else
73 + connect_neurons(rhs, lhs, inhibit)
74 + end
75 + lhs, rhs, is_right, inhibit, chaining = {}, {}, false, false, false
76 + elseif is_right then
77 + table.insert(rhs, neuron(token))
78 + else
79 + table.insert(lhs, neuron(token))
80 + end
81 + end
82 + return net
83 + end
84 +
85 + local function step(count)
86 + local excited, dirty = {}, {}
87 + -- io.write(("%02d "):format(count))
88 + for _, neuron in ipairs(live) do
89 + -- io.write(("%s/%d "):format(neuron.name, neuron.arity))
90 + if neuron.arity == 0 then
91 + table.insert(excited, neuron)
92 + end
93 +
94 + for _, inhibit_neuron in ipairs(neuron.inhibit) do
95 + inhibit_neuron.sleep = true
96 + table.insert(dirty, inhibit_neuron)
97 + end
98 +
99 + for _, excited_neuron in ipairs(neuron.excite) do
100 + excited_neuron.saturation = excited_neuron.saturation + 1
101 + table.insert(dirty, excited_neuron)
102 + if excited_neuron.saturation == excited_neuron.arity then
103 + table.insert(excited, excited_neuron)
104 + end
105 + end
106 + end
107 + -- io.write("\n")
108 + live = {}
109 + for _, excited_neuron in ipairs(excited) do
110 + if not excited_neuron.sleep then
111 + table.insert(live, excited_neuron)
112 + if excited_neuron.hook then
113 + excited_neuron.hook(live)
114 + end
115 + end
116 + end
117 +
118 + for _, dirty_neuron in ipairs(dirty) do
119 + dirty_neuron.saturation = 0
120 + dirty_neuron.sleep = false
121 + end
122 +
123 + return #live ~= 0
124 + end
125 +
126 + parse(tokenize [[
127 + init*; init*: signal*.
128 +
129 + The signal* will fire once:
130 + and activate the cat* program.
131 +
132 + cat* tiggers a: read* from standard io.
133 +
134 + no-input* prevents another;
135 + no-input* means the program is:
136 + done*.
137 +
138 + if there character-read*;
139 + consume the character-read* event:
140 + then write* to standard io.
141 +
142 + if there was a write*: then read*.
143 +
144 + init* my program.
145 + ]])
146 +
147 +
148 + local char = nil
149 + net["read"].hook = function(live)
150 + char = io.read(1)
151 + if not char then
152 + table.insert(live, net["no-input"])
153 + else
154 + table.insert(live, net["character-read"])
155 + end
156 + end
157 +
158 + net["write"].hook = function(live)
159 + io.write(char)
160 + end
161 +
162 + local count = 0
163 + while step(count) and count < 0x30 do count = count + 1 end
Newer Older