Son aktivite 1 month ago

tree.lua Ham Playground
1local function table_stream(t)
2 return coroutine.wrap(function()
3 for _, v in ipairs(t) do
4 coroutine.yield(v)
5 end
6 end)
7end
8
9local function push(t, v)
10 table.insert(t, v)
11end
12
13local function show_tree(tree)
14 local buffer = {}
15 for node in table_stream(tree) do
16 if type(node) == "table" then
17 local subtree = ("(%s)"):format(show_tree(node))
18 push(buffer, subtree)
19 else
20 push(buffer, tostring(node))
21 end
22 end
23 return table.concat(buffer, " ")
24end
25
26
27local function build_symbol(bits)
28 local symbol = table.concat(bits)
29 if tonumber(symbol) then return tonumber(symbol)
30 elseif symbol == "true" then return true
31 elseif symbol == "false" then return false
32 else return symbol
33 end
34end
35
36local function build_tree(stream)
37 local tree = {}
38 local symbol = {}
39 for char in stream do
40 if char == "(" then
41 push(tree, build_tree(stream))
42 elseif char == ")" then
43 break
44 elseif char == " " and #symbol ~= 0 then
45 push(tree, build_symbol(symbol))
46 symbol = {}
47 elseif char:match("%s") then
48 -- no op
49 else
50 push(symbol, char)
51 end
52 end
53
54 if #symbol ~= 0 then
55 push(tree, build_symbol(symbol))
56 end
57
58 return tree
59end
60
61local function parse(string)
62 return build_tree(string:gmatch("."))
63end
64
65local objects = {}
66objects.Nowhere = {
67 objects = {},
68 create = function(self, stream)
69 local name = table.concat(stream(), " ")
70 self.objects[name] = {
71 lookAt = function(self, stream)
72 print("You see " .. name)
73 return self
74 end
75 }
76 return self.objects[name]
77 end
78}
79
80local function reduce(tree)
81 if type(tree) ~= "table" then
82 return tree
83 end
84
85 local index = 1
86 local target = nil
87 local node_stream = coroutine.wrap(function()
88 for _, node in ipairs(tree) do
89 coroutine.yield(node)
90 end
91 end)
92
93 for node in node_stream do
94 if not target then
95 target = reduce(node)
96 if objects[target] then
97 target = objects[target]
98 end
99 elseif type(target) == "table" then
100 if target[node] then
101 target = target[node](target, node_stream)
102 else
103 error("Object does not respond to " .. node)
104 end
105 elseif type(target) == "number" then
106 local next = reduce(node_stream())
107 if node == "+" then
108 target = target + next
109 elseif node == "-" then
110 target = target - next
111 elseif node == "*" then
112 target = target * next
113 elseif node == "/" then
114 target = target / next
115 else
116 error("Object does not respond to " .. node)
117 end
118 end
119 end
120 return target
121end
122
123print(show_tree(parse(arg[1])))
124print(reduce(parse(arg[1])))
125