Tangent 3 years ago
commit
796953ab80
8 changed files with 1002 additions and 0 deletions
  1. 103
    0
      fargor.lua
  2. 34
    0
      notes centrifuge.txt
  3. 171
    0
      parser.lua
  4. 317
    0
      recipes.lua
  5. 148
    0
      relgan.lua
  6. 64
    0
      split.lua
  7. 95
    0
      testfn.lua
  8. 70
    0
      tokenize.lua

+ 103
- 0
fargor.lua View File

@@ -0,0 +1,103 @@
1
+local ptable
2
+ptable = function(t,d)
3
+  local str = ""
4
+  d = d or 0
5
+  for k,v in pairs(t) do
6
+    str = str .. string.rep(" ", d) .. tostring(k) .. " = " .. tostring(v) .. "\n"
7
+    if type(v) == "table" then str = str .. ptable(v, d+1) end
8
+  end
9
+  return str
10
+end
11
+
12
+local split
13
+split = function(str)
14
+  --print("split<"..tostring(str)..">")
15
+  local ast = {}
16
+  local prev = 0
17
+  local cur = str:find(" ", 0, true)
18
+  local ret
19
+  while cur do
20
+    ret = str:sub(prev + 1, cur - 1)
21
+    if ret and #ret > 0 then
22
+      table.insert(ast, ret)
23
+    end
24
+    prev = cur
25
+    cur = str:find(" ", prev + 1, true)
26
+  end
27
+  ret = str:sub(prev + 1)
28
+  if ret and #ret > 0 then
29
+    table.insert(ast, ret)
30
+  end
31
+  --print("split's result:")
32
+  --print(ptable(ast))
33
+  if #ast == 1 then
34
+    --print("split '" .. str .. "' returns '" .. ast[1] .. "'")
35
+    return ast[1]
36
+  elseif #ast > 1 then
37
+    --print("split '" .. str .. "' returns '" .. table.concat(ast, ",") .. "'")
38
+    return ast
39
+  end
40
+end
41
+
42
+local brace
43
+brace = function(str)
44
+  --print("brace<"..tostring(str)..">")
45
+  local ast = {}
46
+  local open, close = str:find("(", 0, true), str:find(")", 0, true)
47
+  local ret
48
+  while open and close and open < close do
49
+    -- we want what came before the next level starts
50
+    ret = split(str:sub(1, open - 1))
51
+    if ret then
52
+      table.insert(ast, ret)
53
+    end
54
+    -- we want the object formed from the next level
55
+    ret, str = brace(str:sub(open + 1))
56
+    if ret then
57
+      table.insert(ast, ret)
58
+    end
59
+    -- and now we need to find what is next
60
+    open, close = str:find("(", 0, true), str:find(")", 0, true)
61
+  end
62
+  if close then
63
+    -- we want what came before our close
64
+    ret = split(str:sub(1, close - 1))
65
+    if ret then
66
+      table.insert(ast, ret)
67
+    end
68
+    --print("CLOSING \""..str:sub(close + 1).."\"")
69
+    -- return our result + what is still unparsed
70
+    return ast, str:sub(close + 1)
71
+  end
72
+  -- if there is anything left, add it (we should be on the top level only here)
73
+  ret = split(str)
74
+  --print("STR->RET", str, ret)
75
+  if ret then
76
+    table.insert(ast, ret)
77
+  end
78
+  --print("brace's result:")
79
+  --print(ptable(ast))
80
+  if #ast == 1 then
81
+    return ast[1]
82
+  elseif #ast > 1 then
83
+    return ast
84
+  end
85
+end
86
+
87
+local a = "(echo (: 'value' ($ name)))"
88
+ast = brace(a)
89
+print(ptable(ast))
90
+print(ast[2][1][1])
91
+--print(ast)
92
+
93
+--(
94
+-- 1echo
95
+-- 2(
96
+--   1:
97
+--   2'value'
98
+--   3(
99
+--     1$
100
+--     2name
101
+--    )
102
+--  )
103
+--)

+ 34
- 0
notes centrifuge.txt View File

@@ -0,0 +1,34 @@
1
+4,16,3,6,3,11,5,14,5,10,5,7,4,3,5,5,2,1,5,12,5,9
2
+
3
+0.0 - 3.5
4
+0.1 - 3.4 needed (34)
5
+
6
+366m long, 49m wide "Neo-Panamacs" 57m tall
7
+
8
+2,12,2,17,6,6,4,8,6,11,3,10,3,7,7,13,4,2,4,15,5,9,7,4
9
+7,12,3,6,5,8,3,1,2,11,7,10,3,16,4,7,6,14,6,5,2,9,6,3
10
+3,12,
11
+4,6,
12
+2,8,
13
+6,11,
14
+3,10,
15
+5,7,
16
+6,13,
17
+3,5,
18
+4,2,
19
+4,15,
20
+6,9,
21
+6,4
22
+count, value
23
+count / 2, value -1 & value +2
24
+500.61 -> 501.82
25
+
26
+ADHD problems with executive functions
27
+ (goal directed problem-solving, all of these are hindered by ADHD)
28
+inhibiting behavior to focus
29
+visually imagery as related to executive function:
30
+- aiming for goals and knowing the steps to get there
31
+- hindsight/foresight/perception of time
32
+talking to yourself to guide yourself
33
+controlling emotions to focus on the long term
34
+planning and problem solving (mental play)

+ 171
- 0
parser.lua View File

@@ -0,0 +1,171 @@
1
+if not event then
2
+  -- compat running outside of minetest
3
+  digiline_send = function(c, ...) print(...) end
4
+  event = { type = "program" }
5
+else
6
+  -- compat running inside minetest
7
+  string.rep = function(str, c)
8
+    local out = ""
9
+    while c > 0 do
10
+      out = out .. str
11
+      c = c - 1
12
+    end
13
+    return out
14
+  end
15
+end
16
+
17
+local print_table -- basic debug output / pretty print for objects
18
+print_table = function(t,d)
19
+  local str = ""
20
+  d = d or 0
21
+  for k,v in pairs(t) do
22
+    str = str .. string.rep(" ", d) .. tostring(k) .. " = " .. tostring(v) .. "\n"
23
+    if type(v) == "table" then str = str .. print_table(v,d+1) end
24
+  end
25
+  return str
26
+end
27
+
28
+local tokenize -- translate string into tokens of parenthesis & sequences of non-space characters
29
+tokenize = function(str)
30
+  local tokens = {}
31
+  local currentToken = ""
32
+  while #str > 0 do
33
+    local t = str:sub(1, 1)
34
+    if t == " " then
35
+      if #currentToken > 0 then
36
+        table.insert(tokens, currentToken)
37
+        currentToken = ""
38
+      end
39
+    elseif t == "(" then
40
+      if #currentToken > 0 then
41
+        table.insert(tokens, currentToken)
42
+        currentToken = ""
43
+      end
44
+      table.insert(tokens, "(")
45
+    elseif t == ")" then
46
+      if #currentToken > 0 then
47
+        table.insert(tokens, currentToken)
48
+        currentToken = ""
49
+      end
50
+      table.insert(tokens, ")")
51
+    else
52
+      currentToken = currentToken .. t
53
+    end
54
+    str = str:sub(2)
55
+  end
56
+  if #currentToken > 0 then
57
+    table.insert(tokens, currentToken)
58
+  end
59
+  return tokens
60
+end
61
+
62
+local store -- store tokens into an abstract syntax tree
63
+store = function(tokens)
64
+  local ast = {}
65
+  local ret
66
+  while #tokens > 0 do
67
+    if tokens[1] == "(" then
68
+      table.remove(tokens, 1)
69
+      ret, tokens = store(tokens)
70
+      table.insert(ast, ret)
71
+    elseif tokens[1] == ")" then
72
+      table.remove(tokens, 1)
73
+      return ast, tokens
74
+    else
75
+      table.insert(ast, table.remove(tokens, 1))
76
+    end
77
+  end
78
+  if #ast == 1 then
79
+    return ast[1]
80
+  else
81
+    return ast
82
+  end
83
+end
84
+
85
+local run, fns, print
86
+run = function(str_or_ast, args)
87
+  local program, fn
88
+  if "string" == type(str_or_ast) then
89
+    program = store(tokenize(str_or_ast))
90
+  else
91
+    program = str_or_ast
92
+  end
93
+  if "string" == type(program) then
94
+    fn = program
95
+    program = {}
96
+  else
97
+    fn = table.remove(program, 1)
98
+  end
99
+  if "string" == type(fn) then
100
+    if fns[fn] then
101
+      if args then
102
+        return fns[fn](args, unpack(program))
103
+      else
104
+        return fns[fn](unpack(program))
105
+      end
106
+    elseif _G[fn] then
107
+      if args then
108
+        return _G[fn](args, unpack(program))
109
+      else
110
+        return _G[fn](unpack(program))
111
+      end
112
+    else
113
+      print("error! function '"..tostring(fn).."' doesn't exist")
114
+    end
115
+  else
116
+    return run(fn, args)
117
+  end
118
+end
119
+
120
+print = function(...) -- slightly modified version of print, and also goes to our display instead of the server console
121
+  local args = {...}
122
+  if #args > 1 then
123
+    digiline_send("display", table.concat(args, "\t"))
124
+  elseif #args == 1 then
125
+    if "table" == type(args[1]) then
126
+      digiline_send("display", print_table(args[1]))
127
+    else
128
+      digiline_send("display", tostring(args[1]))
129
+    end
130
+  end
131
+end
132
+
133
+local function _if(condition, codeT, codeF)
134
+  if run(condition) then
135
+    return run(codeT)
136
+  elseif codeF then
137
+    return run(codeF)
138
+  end
139
+end
140
+
141
+local function _while(condition, loop)
142
+  while run(condition) do
143
+    run(loop)
144
+  end
145
+end
146
+
147
+local function _for(iterate, code)
148
+  local res = run(iterate)
149
+  while res do
150
+    run(code, res)
151
+  end
152
+end
153
+
154
+fns = { -- available to custom code
155
+  print = print,
156
+  ["$"] = run,
157
+  ["if"] = _if,
158
+  ["while"] = _while,
159
+  ["for"] = _for,
160
+  ["true"] = function() return true end,
161
+  ["false"] = function() return false end,
162
+}
163
+
164
+-- local example_code = "digiline_send display Hello!"
165
+-- local example_code = "print Hello world!"
166
+-- local example_code = "$(print hi there)"
167
+local example_code = "if false (print This is true.) (print This is false.)"
168
+
169
+if event.type == "program" then
170
+  run(example_code)
171
+end

+ 317
- 0
recipes.lua View File

@@ -0,0 +1,317 @@
1
+local recipes = {
2
+  ["technic:mv_centrifuge"] = {
3
+    craft = {
4
+      {"basic_materials:motor", "technic:copper_plate", "technic:diamond_drill_head"},
5
+      {"technic:copper_plate", "technic:machine_casing", "technic:copper_plate"},
6
+      {"pipeworks:one_way_tube", "technic:mv_cable", "pipeworks:mese_filter"}
7
+    }
8
+  },
9
+  ["basic_materials:motor"] = {
10
+    craft = {
11
+      {"default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet"},
12
+      {"default:copper_ingot", "default:steel_ingot", "default:steel_ingot"},
13
+      {"default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet"}
14
+    },
15
+    produces = 2
16
+  },
17
+  ["technic:copper_plate"] = {
18
+    compress = {
19
+      item = "technic:copper_ingot",
20
+      amount = 5
21
+    }
22
+  },
23
+  ["technic:diamond_drill_head"] = {
24
+    craft = {
25
+      {"technic:stainless_steel_ingot", "default:diamond", "technic:stainless_steel_ingot"},
26
+      {"default:diamond", "", "default:diamond"},
27
+      {"technic:stainless_steel_ingot", "default:diamond", "technic:stainless_steel_ingot"}
28
+    }
29
+  },
30
+  ["technic:stainless_steel_ingot"] = {
31
+    alloy = {
32
+      ["technic:carbon_steel_ingot"] = 3,
33
+      ["technic:chromium_ingot"] = 1
34
+    },
35
+    produces = 4
36
+  },
37
+  ["technic:carbon_steel_ingot"] = {
38
+    alloy = {
39
+      ["default:steel_ingot"] = 1,
40
+      ["technic:coal_dust"] = 1
41
+    }
42
+  },
43
+  ["technic:machine_casing"] = {
44
+    craft = {
45
+      {"technic:cast_iron_ingot", "technic:cast_iron_ingot", "technic:cast_iron_ingot"},
46
+      {"technic:cast_iron_ingot", "basic_materials:brass_ingot", "technic:cast_iron_ingot"},
47
+      {"technic:cast_iron_ingot", "technic:cast_iron_ingot", "technic:cast_iron_ingot"}
48
+    }
49
+  },
50
+  ["basic_materials:brass_ingot"] = {
51
+    alloy = {
52
+      ["default:copper_ingot"] = 2,
53
+      ["technic:zinc_ingot"] = 1
54
+    },
55
+    produces = 3
56
+  },
57
+  ["technic:cast_iron_ingot"] = {
58
+    smelt = "default:steel_ingot"
59
+  },
60
+  ["pipeworks:one_way_tube"] = {
61
+    craft = {
62
+      {"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"},
63
+      {"default:stick", "default:mese_crystal", "basic_materials:plastic_sheet"},
64
+      {"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"}
65
+    },
66
+    produces = 2
67
+  },
68
+  ["technic:mv_cable"] = {
69
+    craft = {
70
+      {"technic:rubber", "technic:rubber", "technic:rubber"},
71
+      {"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"},
72
+      {"technic:rubber", "technic:rubber", "technic:rubber"}
73
+    },
74
+    produces = 3
75
+  },
76
+  ["technic:rubber"] = {
77
+    alloy = {
78
+      ["technic:raw_latex"] = 4,
79
+      ["technic:coal_dust"] = 2
80
+    },
81
+    produces = 6
82
+  },
83
+  ["technic:raw_latex"] = {
84
+    extract = {
85
+      item = "technic:rubber_tree_grindings",
86
+      amount = 4
87
+    }
88
+  },
89
+  ["technic:lv_cable"] = {
90
+    craft = {
91
+      {"default:paper", "default:paper", "default:paper"},
92
+      {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"},
93
+      {"default:paper", "default:paper", "default:paper"}
94
+    },
95
+    produces = 6
96
+  },
97
+  ["default:paper"] = {
98
+    craft = {
99
+      {"", "", ""},
100
+      {"default:papyrus", "default:papyrus", "default:papyrus"},
101
+      {"", "", ""}
102
+    },
103
+    produces = 4
104
+  },
105
+  ["pipeworks:mese_filter"] = {
106
+    craft = {
107
+      {"default:steel_ingot", "default:steel_ingot", "basic_materials:plastic_sheet"},
108
+      {"default:stick", "default:mese", "basic_materials:plastic_sheet"},
109
+      {"default:steel_ingot", "default:steel_ingot", "basic_materials:plastic_sheet"}
110
+    },
111
+    produces = 2
112
+  },
113
+  ["default:mese"] = {
114
+    craft = {
115
+      {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"},
116
+      {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"},
117
+      {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}
118
+    }
119
+  },
120
+  ["default:mese_crystal_fragment"] = {
121
+    craft = {
122
+      {"", "", ""},
123
+      {"", "default:mese_crystal", ""},
124
+      {"", "", ""}
125
+    },
126
+    produces = 9
127
+  },
128
+  ["basic_materials:copper_wire"] = {
129
+    craft = {
130
+      {"default:copper_ingot", "basic_materials:empty_spool", ""},
131
+      {"basic_materials:empty_spool", "", ""},
132
+      {"", "", ""}
133
+    },
134
+    produces = 2
135
+  },
136
+  ["basic_materials:empty_spool"] = {
137
+    craft = {
138
+      {"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"},
139
+      {"", "basic_materials:plastic_sheet", ""},
140
+      {"basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet"}
141
+    },
142
+    produces = 3
143
+  },
144
+  ["basic_materials:plastic_sheet"] = {
145
+    smelt = "basic_materials:paraffin"
146
+  },
147
+  ["basic_materials:paraffin"] = {
148
+    smelt = "basic_materials:oil_extract"
149
+  },
150
+  ["technic:solar_panel"] = {
151
+    craft = {
152
+      {"technic:doped_silicon_wafer", "technic:doped_silicon_wafer", "technic:doped_silicon_wafer"},
153
+      {"basic_materials:silver_wire", "technic:lv_cable", "mesecons_materials:glue"},
154
+      {"", "", ""}
155
+    }
156
+  },
157
+  ["technic:doped_silicon_wafer"] = {
158
+    alloy = {
159
+      ["technic:silicon_wafer"] = 1,
160
+      ["technic:gold_dust"] = 1
161
+    }
162
+  },
163
+  ["technic:silicon_wafer"] = {
164
+    alloy = {
165
+      ["default:sand"] = 2,
166
+      ["technic:coal_dust"] = 2
167
+    }
168
+  },
169
+  ["basic_materials:silver_wire"] = {
170
+    craft = {
171
+      {"moreores:silver_ingot", "basic_materials:empty_spool", ""},
172
+      {"basic_materials:empty_spool", "", ""},
173
+      {"", "", ""}
174
+    },
175
+    produces = 2
176
+  },
177
+  ["mesecons_materials:glue"] = {
178
+    smelt = "technic:raw_latex"
179
+  },
180
+  ["technic:solar_array_lv"] = {
181
+    craft = {
182
+      {"technic:solar_panel", "technic:solar_panel", "technic:solar_panel"},
183
+      {"technic:carbon_steel_ingot", "technic:lv_transformer", "technic:carbon_steel_ingot"},
184
+      {"", "technic:lv_cable", ""}
185
+    }
186
+  },
187
+  ["technic:lv_transformer"] = {
188
+    craft = {
189
+      {"mesecons_materials:fiber", "default:steel_ingot", "mesecons_materials:fiber"},
190
+      {"technic:copper_coil", "default:steel_ingot", "technic:copper_coil"},
191
+      {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
192
+    }
193
+  },
194
+  ["mesecons_materials:fiber"] = {
195
+    smelt = "mesecons_materials:glue",
196
+    produces = 6
197
+  },
198
+  ["technic:copper_coil"] = {
199
+    craft = {
200
+      {"basic_materials:copper_wire", "default:steel_ingot", "basic_materials:copper_wire"},
201
+      {"default:steel_ingot", "", "default:steel_ingot"},
202
+      {"basic_materials:copper_wire", "default:steel_ingot", "basic_materials:copper_wire"}
203
+    }
204
+  },
205
+  ["technic:solar_array_mv"] = {
206
+    craft = {
207
+      {"technic:solar_array_lv", "technic:solar_array_lv", "technic:solar_array_lv"},
208
+      {"technic:carbon_steel_ingot", "technic:mv_transformer", "technic:carbon_steel_ingot"},
209
+      {"", "technic:mv_cable", ""}
210
+    }
211
+  },
212
+  ["technic:mv_transformer"] = {
213
+    craft = {
214
+      {"mesecons_materials:fiber", "technic:carbon_steel_ingot", "mesecons_materials:fiber"},
215
+      {"technic:copper_coil", "technic:carbon_steel_ingot", "technic:copper_coil"},
216
+      {"technic:carbon_steel_ingot", "technic:carbon_steel_ingot", "technic:carbon_steel_ingot"}
217
+    }
218
+  },
219
+}
220
+
221
+local items = {
222
+  -- ["technic:mv_centrifuge"] = 31 -- 34 minus 3 I already have
223
+  ["technic:mv_transformer"] = 1
224
+}
225
+
226
+local function get_count(goal, recipe)
227
+  local count = goal / (recipe.produces or 1)
228
+  if count ~= math.floor(count) then
229
+    count = math.floor(count) + 1
230
+  end
231
+  return count
232
+end
233
+
234
+local steps = {}
235
+
236
+local active = true
237
+while active do
238
+  active = false
239
+  for item, count in pairs(items) do
240
+    if recipes[item] then
241
+      active = item
242
+      local current = recipes[item]
243
+      local _count = get_count(count, current)
244
+      if current.craft then
245
+        table.insert(steps, "craft "..item.." "..tostring(_count).." times")
246
+        local new = {}
247
+        for y=1,3 do
248
+          for x=1,3 do
249
+            if current.craft[y][x] ~= "" then
250
+              item = current.craft[y][x]
251
+              if new[item] then
252
+                new[item] = new[item] + _count
253
+              else
254
+                new[item] = _count
255
+              end
256
+            end
257
+          end
258
+        end
259
+        for item, count in pairs(new) do
260
+          if items[item] then
261
+            items[item] = items[item] + count
262
+          else
263
+            items[item] = count
264
+          end
265
+        end
266
+      elseif current.compress then
267
+        table.insert(steps, "compress "..item.." "..tostring(_count).." times")
268
+        if current.compress.amount then
269
+          _count = _count * current.compress.amount
270
+        end
271
+        if items[current.compress.item] then
272
+          items[current.compress.item] = items[current.compress.item] + _count
273
+        else
274
+          items[current.compress.item] = _count
275
+        end
276
+      elseif current.alloy then
277
+        table.insert(steps, "alloy "..item.." "..tostring(_count).." times")
278
+        for item, amount in pairs(current.alloy) do
279
+          if items[item] then
280
+            items[item] = items[item] + _count * amount
281
+          else
282
+            items[item] = _count * amount
283
+          end
284
+        end
285
+      elseif current.smelt then
286
+        table.insert(steps, "smelt "..item.." "..tostring(_count).." times")
287
+        if items[current.smelt] then
288
+          items[current.smelt] = items[current.smelt] + _count
289
+        else
290
+          items[current.smelt] = _count
291
+        end
292
+      elseif current.extract then
293
+        table.insert(steps, "extract "..item.." "..tostring(_count).." times")
294
+        if current.extract.amount then
295
+          _count = _count * current.extract.amount
296
+        end
297
+        if items[current.extract.item] then
298
+          items[current.extract.item] = items[current.extract.item] + _count
299
+        else
300
+          items[current.extract.item] = _count
301
+        end
302
+      end
303
+      break
304
+    end
305
+  end
306
+  if active then
307
+    items[active] = nil
308
+  end
309
+end
310
+
311
+for k,v in pairs(items) do
312
+  print(k,v)
313
+end
314
+
315
+for i=#steps,1,-1 do
316
+  print(steps[i])
317
+end

+ 148
- 0
relgan.lua View File

@@ -0,0 +1,148 @@
1
+if not event then
2
+  -- compat running outside of minetest
3
+  digiline_send = function(c, ...) print(...) end
4
+  event = { type = "program" }
5
+else
6
+  -- compat running inside minetest
7
+  string.rep = function(str, c)
8
+    local out = ""
9
+    while c > 0 do
10
+      out = out .. str
11
+      c = c - 1
12
+    end
13
+    return out
14
+  end
15
+end
16
+
17
+local print_table -- basic debug output / pretty print for objects
18
+print_table = function(t,d)
19
+  local str = ""
20
+  d = d or 0
21
+  for k,v in pairs(t) do
22
+    str = str .. string.rep(" ", d) .. tostring(k) .. " = " .. tostring(v) .. "\n"
23
+    if type(v) == "table" then str = str .. print_table(v,d+1) end
24
+  end
25
+  return str
26
+end
27
+
28
+local tokenize -- translate string into tokens of parenthesis & sequences of non-space characters
29
+tokenize = function(str)
30
+  local tokens = {}
31
+  local currentToken = ""
32
+  while #str > 0 do
33
+    local t = str:sub(1, 1)
34
+    if t == " " then
35
+      if #currentToken > 0 then
36
+        table.insert(tokens, currentToken)
37
+        currentToken = ""
38
+      end
39
+    elseif t == "(" then
40
+      if #currentToken > 0 then
41
+        table.insert(tokens, currentToken)
42
+        currentToken = ""
43
+      end
44
+      table.insert(tokens, "(")
45
+    elseif t == ")" then
46
+      if #currentToken > 0 then
47
+        table.insert(tokens, currentToken)
48
+        currentToken = ""
49
+      end
50
+      table.insert(tokens, ")")
51
+    else
52
+      currentToken = currentToken .. t
53
+    end
54
+    str = str:sub(2)
55
+  end
56
+  if #currentToken > 0 then
57
+    table.insert(tokens, currentToken)
58
+  end
59
+  return tokens
60
+end
61
+
62
+local store -- store tokens into an abstract syntax tree
63
+store = function(tokens)
64
+  local ast = {}
65
+  local ret
66
+  while #tokens > 0 do
67
+    if tokens[1] == "(" then
68
+      table.remove(tokens, 1)
69
+      ret, tokens = store(tokens)
70
+      table.insert(ast, ret)
71
+    elseif tokens[1] == ")" then
72
+      table.remove(tokens, 1)
73
+      return ast, tokens
74
+    else
75
+      table.insert(ast, table.remove(tokens, 1))
76
+    end
77
+  end
78
+  if #ast == 1 then
79
+    return ast[1]
80
+  else
81
+    return ast
82
+  end
83
+end
84
+
85
+local run, fns, print
86
+run = function(str_or_ast)
87
+  local program, fn
88
+  if "string" == type(str_or_ast) then
89
+    program = store(tokenize(str_or_ast))
90
+  else
91
+    program = str_or_ast
92
+  end
93
+  if "string" == type(program) then
94
+    fn = program
95
+    program = {}
96
+  else
97
+    fn = table.remove(program, 1)
98
+  end
99
+  if "string" == type(fn) then
100
+    if fns[fn] then
101
+      return fns[fn](unpack(program))
102
+    elseif _G[fn] then
103
+      return _G[fn](unpack(program))
104
+    else
105
+      print("error! function '"..tostring(fn).."' doesn't exist")
106
+    end
107
+  else
108
+    return run(fn)
109
+  end
110
+end
111
+
112
+print = function(...) -- slightly modified version of print, and also goes to our display instead of the server console
113
+  local args = {...}
114
+  if #args > 1 then
115
+    digiline_send("display", table.concat(args, "\t"))
116
+  elseif #args == 1 then
117
+    if "table" == type(args[1]) then
118
+      digiline_send("display", print_table(args[1]))
119
+    else
120
+      digiline_send("display", tostring(args[1]))
121
+    end
122
+  end
123
+end
124
+
125
+local function _if(condition, codeT, codeF)
126
+  if run(condition) then
127
+    return run(codeT)
128
+  else
129
+    return run(codeF)
130
+  end
131
+end
132
+
133
+fns = { -- available to custom code
134
+  print = print,
135
+  ["$"] = run,
136
+  ["if"] = _if,
137
+  ["true"] = function() return true end,
138
+  ["false"] = function() return false end,
139
+}
140
+
141
+-- local example_code = "digiline_send display Hello!"
142
+-- local example_code = "print Hello world!"
143
+-- local example_code = "$(print hi there)"
144
+local example_code = "if true (print This is true.) (print This is false.)"
145
+
146
+if event.type == "program" then
147
+  run(example_code)
148
+end

+ 64
- 0
split.lua View File

@@ -0,0 +1,64 @@
1
+-- {5, 7} count, value
2
+local items = {
3
+  {50, 7},
4
+  {60, 3},
5
+  {90, 10},
6
+  {100, 20},
7
+}
8
+
9
+function centrifuge(what)
10
+  local v = what
11
+  if what[1] % 2 ~= 0 then print(v[1], v[2]) error('uneven') end
12
+  local value = what[2]
13
+  if value < 1 or value > 34 then print(v[1], v[2]) error('invalid') end
14
+
15
+  local count = what[1] / 2
16
+  local value1 = what[2] - 1
17
+  local value2 = what[2] + 1
18
+  return {count, value1}, {count, value2}
19
+end
20
+
21
+function sort(A, B)
22
+  if A[1] == 35 then return false end
23
+  --if A[1] == B[1] then
24
+  --  return A[2] > B[2]
25
+  --end
26
+  return A[1] > B[1]
27
+end
28
+
29
+table.sort(items, sort)
30
+for k,v in ipairs(items) do print(v[1], v[2]) end
31
+--if true then return end
32
+
33
+function grabeven(what)
34
+  if what[1] % 2 == 0 then
35
+    return what, nil
36
+  else
37
+    return {what[1]-1, what[2]}, {1, what[1]}
38
+  end
39
+end
40
+
41
+function give(what)
42
+  for k,v in ipairs(items) do
43
+    if v[2] == what[2] then
44
+      v[2] = v[2] + what[2]
45
+      return
46
+    end
47
+  end
48
+  table.insert(items, what)
49
+end
50
+
51
+table.sort(items, sort)
52
+while items[1][1] > 1 and items[1][2] ~= 0 do
53
+  local take, left = grabeven(table.remove(items, 1))
54
+  local result1, result2 = centrifuge(take)
55
+  give(result1)
56
+  give(result2)
57
+  if left then give(left) end
58
+
59
+  table.sort(items, sort)
60
+  --print("-")
61
+  --for k,v in ipairs(items) do print(v[1], v[2]) end
62
+end
63
+
64
+for k,v in ipairs(items) do print(v[1], v[2]) end

+ 95
- 0
testfn.lua View File

@@ -0,0 +1,95 @@
1
+local function split(str)
2
+  -- should return single string, flat table of strings, or nil
3
+  local ast = {}
4
+  local prev, space = 0, str:find(" ", 0, true)
5
+  local ret
6
+  while space do
7
+    ret = str:sub(prev + 1, space - 1)
8
+    if #ret > 0 then
9
+      table.insert(ast, ret)
10
+    end
11
+    prev = space
12
+    space = str:find(" ", prev + 1, true)
13
+  end
14
+  ret = str:sub(prev + 1)
15
+  if #ret > 0 then
16
+    table.insert(ast, ret)
17
+  end
18
+  if #ast < 1 then
19
+    return nil
20
+  elseif #ast == 1 then
21
+    return ast[1]
22
+  else
23
+    return ast
24
+  end
25
+end
26
+
27
+local table_tostring
28
+local function parse(str)
29
+  -- should return table with strings and tables, etc, or nil
30
+  local ast = {}
31
+  local open, close = str:find("(", 0, true), str:find(")", 0, true)
32
+  local ret
33
+  while open and close and open < close do
34
+    --print("---" .. str:sub(1, open - 1))
35
+    table.insert(ast, split(str:sub(1, open - 1)))
36
+    --print(str:sub(open + 1))
37
+    ret, str = parse(str:sub(open + 1))
38
+    --print("RET", ret, ret[1], ret[2])
39
+    --print(table_tostring(ast))
40
+    --print(ret, "'"..str.."'", #ret, ret[1], ret[2])
41
+    table.insert(ast, ret)
42
+    --print(table_tostring(ast))
43
+    --print("--------------")
44
+    open, close = str:find("(", 0, true), str:find(")", 0, true)
45
+  end
46
+  --print(";;"..str)
47
+  if close then
48
+    --print(str:sub(1, close - 1))
49
+    table.insert(ast, split(str:sub(1, close - 1)))
50
+    ret = str:sub(close + 1)
51
+    if #ast < 1 then
52
+      return nil, ret
53
+    elseif #ast == 1 then
54
+      return ast[1], ret
55
+    else
56
+      return ast, ret
57
+    end
58
+  end
59
+  if #ast < 1 then
60
+    return nil
61
+  elseif #ast == 1 then
62
+    return ast[1]
63
+  else
64
+    return ast
65
+  end
66
+end
67
+
68
+-- (echo (: "value" ($ name))) -- true/false depending on $name == "value"
69
+-- (while ($ name) (run command)) -- while $name run(command)
70
+
71
+-- fns = {
72
+--   print, =, if, for, while
73
+-- }
74
+
75
+--local table_tostring
76
+table_tostring = function(tab, depth)
77
+  local str = ""
78
+  depth = depth or 0
79
+  if "table" == type(tab) then
80
+    for k,v in pairs(tab) do
81
+      str = str .. table_tostring(k, depth) .. " =\n"
82
+      str = str .. table_tostring(v, depth + 1) .. "\n"
83
+    end
84
+    return str
85
+  else
86
+    return string.rep(" ", depth) .. tostring(tab) .. " (" .. type(tab):sub(1, 1) .. ")"
87
+  end
88
+end
89
+
90
+local ast, extra = parse("(echo (: \"value\" ($ name)))")
91
+--local ast, extra = parse("(while ($ name) (run command))")
92
+--local ast, extra = parse("b b (c c)")
93
+
94
+print(table_tostring(ast))
95
+print(extra)

+ 70
- 0
tokenize.lua View File

@@ -0,0 +1,70 @@
1
+-- things between spaces, () separate depths
2
+local tokenize
3
+tokenize = function(str)
4
+  if not str then return nil end
5
+  local ast = {}
6
+  local open = str:find("(", 0, true) or math.huge
7
+  local close = str:find(")", 0, true) or math.huge
8
+  local space = str:find(" ", 0, true) or math.huge
9
+  local ret
10
+  if open < close and open < space then
11
+    -- tokenize what came before (call on substring, unpack here), call tokenize on what comes after
12
+    ret = tokenize(str:sub(1, open - 1))
13
+    if ret then
14
+      while #ret > 0 do
15
+        table.insert(ast, table.remove(ret, 1))
16
+      end
17
+    end
18
+    ret, str = tokenize(str:sub(open + 1))
19
+    if ret and #ret > 0 then
20
+      table.insert(ast, ret)
21
+    end
22
+    ret = tokenize(str)
23
+    if ret then
24
+      while #ret > 0 do
25
+        table.insert(ast, table.remove(ret, 1))
26
+      end
27
+    end
28
+    return ast
29
+  elseif close < open and close < space then
30
+    return ast, str:sub(close + 1)
31
+  elseif space < open and space < close then
32
+    ret = str:sub(1, space - 1)
33
+    if ret and #ret > 0 then
34
+      table.insert(ast, ret)
35
+    end
36
+    ret, str = tokenize(str:sub(space + 1))
37
+    if ret and #ret > 0 then
38
+      table.insert(ast, ret)
39
+    end
40
+    ret = tokenize(str)
41
+    if ret then
42
+      while #ret > 0 do
43
+        table.insert(ast, table.remove(ret, 1))
44
+      end
45
+    end
46
+    return ast
47
+  else
48
+    table.insert(ast, str:sub(1, space - 1))
49
+    return ast
50
+  end
51
+end
52
+
53
+local ptable
54
+ptable = function(tab, depth)
55
+  local str = ""
56
+  depth = depth or 0
57
+  if "table" == type(tab) then
58
+    for k,v in pairs(tab) do
59
+      str = str .. string.rep(" ", depth) .. ptable(k, depth) .. "\n"
60
+      str = str .. string.rep(" ", depth) .. ptable(v, depth + 1) .. "\n"
61
+    end
62
+  else
63
+    return tostring(tab)
64
+  end
65
+  return str
66
+end
67
+
68
+local a = "(echo (: 'value' ($ name)))"
69
+ast = tokenize(a)
70
+print(ptable(ast))