Dernière activité 1738214147

luneur.lua Brut Playground
1local net, live = {}, {}
2
3local 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]
14end
15
16local 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
34end
35
36local 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
47end
48
49local 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
83end
84
85local 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
124end
125
126parse(tokenize [[
127init*; init*: signal*.
128
129The signal* will fire once:
130 and activate the cat* program.
131
132cat* tiggers a: read* from standard io.
133
134no-input* prevents another;
135 no-input* means the program is:
136 done*.
137
138if there character-read*;
139 consume the character-read* event:
140 then write* to standard io.
141
142if there was a write*: then read*.
143
144init* my program.
145]])
146
147
148local char = nil
149net["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
156end
157
158net["write"].hook = function(live)
159 io.write(char)
160end
161
162local count = 0
163while step(count) and count < 0x30 do count = count + 1 end