Last active 1755999453

Revision 35667fc05e11dc0e4186bd648f5cacc9dedb5099

february.lua Raw Playground
1local program = [[
2 = [What is] February =
3 [February is] a syntax front end for nova , designed around streaming tokens .
4 = = =
5
6 ~ [Many Rules] Many Delimiter ~
7 [February can] let you switch between them on the fly .
8 ~ ~ ~
9
10 *** [A note] ***
11 SAYS you don't need those [backets] .
12 BUT they might help with clarity
13
14 *** *** [What is] February
15 *** *** ***
16]]
17local stream = program:gmatch(".")
18local char, rule, rule_symbol, label_symbol, depth, symbol, side
19local tuple, rules, LEFT, RIGHT = {}, {}, 1, 2
20repeat
21 rule_symbol, char = "", stream()
22 side, rule = LEFT, {{}, {}}
23 while char and char:match("[%s%.,]") do
24 char = stream()
25 end
26 if char == nil then
27 break
28 elseif char == "[" then
29 depth, char = 1, stream()
30 while char do
31 if char == "[" then depth = depth + 1 end
32 if char == "]" then depth = depth - 1 end
33 if depth == 0 then break end
34 rule_symbol, char = rule_symbol .. char, stream()
35 end
36 else
37 rule_symbol = "" while char and not char:match("%s") do
38 rule_symbol, char = rule_symbol .. char, stream() if char == "[" then
39 io.stderr:write "Warning: symbol contains `[`. A space may be missing?"
40 end
41 end
42 end
43 repeat
44 char = stream()
45 while char and (char:match("[%s]") or not label_symbol and char:match("[%.,]")) do
46 char = stream()
47 end
48 if not char then
49 if label_symbol then
50 table.insert(rule[side], {label_symbol, tuple})
51 end
52 break
53 end
54 if char:match("[%.,]") then
55 symbol = char
56 elseif char == "[" then
57 symbol, depth, char = "", 1, stream() while char do
58 if char == "[" then depth = depth + 1 end
59 if char == "]" then depth = depth - 1 end
60 if depth == 0 then break end
61 symbol, char = symbol .. char, stream()
62 end
63 else
64 symbol = "" while char and not char:match("%s") do
65 symbol, char = symbol .. char, stream() if char == "[" then
66 io.stderr:write "Warning: symbol contains `[`. A space may be missing?"
67 end
68 end
69 end
70 if symbol == "," then
71 table.insert(rule[side], {label_symbol, tuple})
72 tuple = {}
73 elseif symbol == "." then
74 table.insert(rule[side], {label_symbol, tuple})
75 tuple, label_symbol = {}, nil
76 elseif symbol == rule_symbol and side == RIGHT then
77 if label_symbol then
78 table.insert(rule[side], {label_symbol, tuple})
79 tuple = {}
80 end
81 if #rule[LEFT] == 0 and #rule[RIGHT] == 0 then
82 break
83 else
84 table.insert(rules, rule)
85 side, rule, label_symbol = LEFT, {{}, {}}, nil
86 end
87 elseif symbol == rule_symbol and side == LEFT then
88 if label_symbol then
89 table.insert(rule[side], {label_symbol, tuple})
90 end
91 tuple, side, label_symbol = {}, RIGHT, nil
92 elseif not label_symbol then
93 label_symbol = symbol
94 else
95 table.insert(tuple, symbol)
96 end
97 until not char
98 if #rule[LEFT] ~= 0 or #rule[RIGHT] ~= 0 then
99 table.insert(rules, rule)
100 end
101until not char