code / nomsu

Lines6.6K Lua5.1K PEG1.3K make117
2 others 83
Markdown60 Bourne Again Shell23
(293 lines)
1 local List, Dict
2 do
3 local _obj_0 = require("containers")
4 List, Dict = _obj_0.List, _obj_0.Dict
5 end
6 local reverse, upper, lower, find, byte, match, gmatch, gsub, sub, format, rep, char
7 do
8 local _obj_0 = string
9 reverse, upper, lower, find, byte, match, gmatch, gsub, sub, format, rep, char = _obj_0.reverse, _obj_0.upper, _obj_0.lower, _obj_0.find, _obj_0.byte, _obj_0.match, _obj_0.gmatch, _obj_0.gsub, _obj_0.sub, _obj_0.format, _obj_0.rep, _obj_0.char
10 end
11 local isplit
12 isplit = function(self, sep)
13 if sep == nil then
14 sep = '%s+'
15 end
16 local step
17 step = function(self, i)
18 local start = self.pos
19 if not (start) then
20 return
21 end
22 i = i + 1
23 local nl = find(self.str, self.sep, start)
24 self.pos = nl and (nl + 1) or nil
25 local line = sub(self.str, start, nl and (nl - 1) or #self.str)
26 return i, line, start, (nl and (nl - 1) or #self.str)
27 end
28 return step, {
29 str = self,
30 pos = 1,
31 sep = sep
32 }, 0
33 end
34 local lua_keywords = {
35 ["and"] = true,
36 ["break"] = true,
37 ["do"] = true,
38 ["else"] = true,
39 ["elseif"] = true,
40 ["end"] = true,
41 ["false"] = true,
42 ["for"] = true,
43 ["function"] = true,
44 ["goto"] = true,
45 ["if"] = true,
46 ["in"] = true,
47 ["local"] = true,
48 ["nil"] = true,
49 ["not"] = true,
50 ["or"] = true,
51 ["repeat"] = true,
52 ["return"] = true,
53 ["then"] = true,
54 ["true"] = true,
55 ["until"] = true,
56 ["while"] = true
58 local is_lua_id
59 is_lua_id = function(str)
60 return match(str, "^[_a-zA-Z][_a-zA-Z0-9]*$") and not lua_keywords[str]
61 end
62 local as_lua_id
63 as_lua_id = function(str)
64 str = gsub(str, "x([0-9A-F][0-9A-F])", "x78%1")
65 str = gsub(str, "%W", function(c)
66 if c == ' ' then
67 return '_'
68 else
69 return format("x%02X", byte(c))
70 end
71 end)
72 if not (is_lua_id(match(str, "^_*(.*)$"))) then
73 str = "_" .. str
74 end
75 return str
76 end
77 local from_lua_id
78 from_lua_id = function(str)
79 if not (is_lua_id(match(str, "^_*(.*)$"))) then
80 str = sub(str, 2, -1)
81 end
82 str = gsub(str, "_", " ")
83 str = gsub(str, "x([0-9A-F][0-9A-F])", function(hex)
84 return char(tonumber(hex, 16))
85 end)
86 return str
87 end
88 local Text = {
89 isplit = isplit,
90 uppercase = upper,
91 lowercase = lower,
92 reversed = reverse,
93 is_lua_id = is_lua_id,
94 capitalized = function(self)
95 return (gsub(self, '%l', upper, 1))
96 end,
97 byte = byte,
98 as_a_number = tonumber,
99 as_a_base_1_number = tonumber,
100 bytes = function(self, i, j)
101 return List({
102 byte(self, i or 1, j or -1)
104 end,
105 split = function(self, sep)
106 return List((function()
107 local _accum_0 = { }
108 local _len_0 = 1
109 for i, chunk in isplit(self, sep) do
110 _accum_0[_len_0] = chunk
111 _len_0 = _len_0 + 1
112 end
113 return _accum_0
114 end)())
115 end,
116 starts_with = function(self, s)
117 return sub(self, 1, #s) == s
118 end,
119 ends_with = function(self, s)
120 return #self >= #s and sub(self, #self - #s, -1) == s
121 end,
122 lines = function(self)
123 return List((function()
124 local _accum_0 = { }
125 local _len_0 = 1
126 for i, line in isplit(self, '\n') do
127 _accum_0[_len_0] = line
128 _len_0 = _len_0 + 1
129 end
130 return _accum_0
131 end)())
132 end,
133 line = function(self, line_num)
134 for i, line, start in isplit(self, '\n') do
135 if i == line_num then
136 return line
137 end
138 end
139 end,
140 line_info_at = function(self, pos)
141 assert(type(pos) == 'number', "Invalid string position")
142 for i, line, start, stop in isplit(self, '\n') do
143 if stop + 1 >= pos then
144 return line, i, (pos - start + 1)
145 end
146 end
147 end,
148 indented = function(self, indent)
149 if indent == nil then
150 indent = " "
151 end
152 return indent .. (gsub(self, "\n", "\n" .. indent))
153 end,
154 as_lua = function(self)
155 local escaped = gsub(self, "\\", "\\\\")
156 escaped = gsub(escaped, "\n", "\\n")
157 escaped = gsub(escaped, '"', '\\"')
158 escaped = gsub(escaped, "[^ %g]", function(c)
159 return format("\\%03d", byte(c, 1))
160 end)
161 return '"' .. escaped .. '"'
162 end,
163 as_nomsu = function(self)
164 return self:as_lua()
165 end,
166 formatted_with = format,
167 byte = byte,
168 position_of = (function(...)
169 return (find(...))
170 end),
171 position_of_1_after = (function(...)
172 return (find(...))
173 end),
174 as_a_lua_identifier = as_lua_id,
175 is_a_lua_identifier = is_lua_id,
176 as_lua_id = as_lua_id,
177 as_a_lua_id = as_lua_id,
178 is_a_lua_id = is_lua_id,
179 is_lua_id = is_lua_id,
180 from_lua_id = from_lua_id,
181 bytes_1_to = function(self, start, stop)
182 return List({
183 byte(self, start, stop)
185 end,
186 [as_lua_id("with 1 ->")] = function(...)
187 return (gsub(...))
188 end,
189 bytes = function(self)
190 return List({
191 byte(self, 1, -1)
193 end,
194 wrapped_to = function(self, maxlen, margin)
195 if maxlen == nil then
196 maxlen = 80
197 end
198 if margin == nil then
199 margin = 8
200 end
201 local lines = { }
202 local _list_0 = self:lines()
203 for _index_0 = 1, #_list_0 do
204 local line = _list_0[_index_0]
205 while #line > maxlen do
206 local chunk = sub(line, 1, maxlen)
207 local split = find(chunk, ' ', maxlen - margin, true) or maxlen
208 chunk = sub(line, 1, split)
209 line = sub(line, split + 1, -1)
210 lines[#lines + 1] = chunk
211 end
212 lines[#lines + 1] = line
213 end
214 return table.concat(lines, "\n")
215 end,
216 line_at = function(self, i)
217 return (self:line_info_at(i))
218 end,
219 line_number_at = function(self, i)
220 return select(2, self:line_info_at(i))
221 end,
222 line_position_at = function(self, i)
223 return select(3, self:line_info_at(i))
224 end,
225 matches = function(self, patt)
226 return match(self, patt) and true or false
227 end,
228 matching = function(self, patt)
229 return (match(self, patt))
230 end,
231 matching_groups = function(self, patt)
232 return List({
233 match(self, patt)
235 end,
236 [as_lua_id("* 1")] = function(self, n)
237 return rep(self, n)
238 end,
239 all_matches_of = function(self, patt)
240 local result = { }
241 local stepper, x, i = gmatch(self, patt)
242 while true do
243 local tmp = List({
244 stepper(x, i)
246 if #tmp == 0 then
247 break
248 end
249 i = tmp[1]
250 result[#result + 1] = (#tmp == 1) and tmp[1] or tmp
251 end
252 return List(result)
253 end,
254 from_1_to = sub,
255 from = sub,
256 character = function(self, i)
257 return sub(self, i, i)
258 end
260 for k, v in pairs(string) do
261 Text[k] = Text[k] or v
262 end
263 local _1_as_text
264 _1_as_text = function(x)
265 if x == true then
266 return "yes"
267 end
268 if x == false then
269 return "no"
270 end
271 return tostring(x)
272 end
273 setmetatable(Text, {
274 __call = function(self, ...)
275 local ret = {
276 ...
278 for i = 1, select("#", ...) do
279 ret[i] = _1_as_text(ret[i])
280 end
281 return table.concat(ret)
282 end
284 debug.setmetatable("", {
285 __type = "Text",
286 __index = function(self, k)
287 return Text[k] or (type(k) == 'number' and sub(self, k, k) or nil)
288 end,
289 __add = function(self, x)
290 return _1_as_text(self) .. _1_as_text(x)
291 end
293 return Text