PageSourceSearch

https://erde-lang.github.io/erde-preload.lua

js erde-lang.github.io collected 2026-10-03 09:09:56 UTC 78,453 bytes, 2,912 lines download raw bytes

1do
2local _ENV = _ENV
3package.preload[ "erde" ] = function( ... ) local arg = _G.arg;
4local lib = require("erde.lib")
5local VERSION
6do
7	local __ERDE_TMP_4__
8	__ERDE_TMP_4__ = require("erde.constants")
9	VERSION = __ERDE_TMP_4__["VERSION"]
10end
11return {
12	version = VERSION,
13	compile = require("erde.compile"),
14	rewrite = lib.rewrite,
15	traceback = lib.traceback,
16	run = lib.run,
17	load = lib.load,
18	unload = lib.unload,
19}
20-- Compiled with Erde 0.6.0-1
21-- __ERDE_COMPILED__
22end
23end
24
25do
26local _ENV = _ENV
27package.preload[ "erde.compile" ] = function( ... ) local arg = _G.arg;
28local config = require("erde.config")
29local BINOP_ASSIGNMENT_TOKENS, BINOPS, BITOPS, BITLIB_METHODS, COMPILED_FOOTER_COMMENT, DIGIT, KEYWORDS, LEFT_ASSOCIATIVE, LUA_KEYWORDS, SURROUND_ENDS, TERMINALS, TOKEN_TYPES, UNOPS, VERSION
30do
31	local __ERDE_TMP_4__
32	__ERDE_TMP_4__ = require("erde.constants")
33	BINOP_ASSIGNMENT_TOKENS = __ERDE_TMP_4__["BINOP_ASSIGNMENT_TOKENS"]
34	BINOPS = __ERDE_TMP_4__["BINOPS"]
35	BITOPS = __ERDE_TMP_4__["BITOPS"]
36	BITLIB_METHODS = __ERDE_TMP_4__["BITLIB_METHODS"]
37	COMPILED_FOOTER_COMMENT = __ERDE_TMP_4__["COMPILED_FOOTER_COMMENT"]
38	DIGIT = __ERDE_TMP_4__["DIGIT"]
39	KEYWORDS = __ERDE_TMP_4__["KEYWORDS"]
40	LEFT_ASSOCIATIVE = __ERDE_TMP_4__["LEFT_ASSOCIATIVE"]
41	LUA_KEYWORDS = __ERDE_TMP_4__["LUA_KEYWORDS"]
42	SURROUND_ENDS = __ERDE_TMP_4__["SURROUND_ENDS"]
43	TERMINALS = __ERDE_TMP_4__["TERMINALS"]
44	TOKEN_TYPES = __ERDE_TMP_4__["TOKEN_TYPES"]
45	UNOPS = __ERDE_TMP_4__["UNOPS"]
46	VERSION = __ERDE_TMP_4__["VERSION"]
47end
48local table
49do
50	local __ERDE_TMP_7__
51	__ERDE_TMP_7__ = require("erde.stdlib")
52	table = __ERDE_TMP_7__["table"]
53end
54local tokenize = require("erde.tokenize")
55local get_source_alias
56do
57	local __ERDE_TMP_12__
58	__ERDE_TMP_12__ = require("erde.utils")
59	get_source_alias = __ERDE_TMP_12__["get_source_alias"]
60end
61local unpack = table.unpack or unpack
62local arrow_function, block, expression, statement
63local tokens
64local current_token_index
65local current_token
66local block_depth
67local tmp_name_counter
68local break_name
69local has_continue
70local has_module_declarations
71local is_module_return_block, module_return_line
72local is_varargs_block
73local block_declarations, block_declaration_stack
74local goto_jumps, goto_labels
75local alias
76local lua_target
77local bitlib
78local function throw(message, line)
79	if line == nil then
80		line = current_token.line
81	end
82	error((tostring(alias) .. ":" .. tostring(line) .. ": " .. tostring(message)), 0)
83end
84local function add_block_declaration(var, scope, stack_depth)
85	if stack_depth == nil then
86		stack_depth = block_depth
87	end
88	if block_declaration_stack[stack_depth] == nil then
89		for i = stack_depth - 1, 1, -1 do
90			local parent_block_declarations = block_declaration_stack[i]
91			if parent_block_declarations ~= nil then
92				block_declaration_stack[stack_depth] = table.shallowcopy(parent_block_declarations)
93				break
94			end
95		end
96	end
97	local target_block_declarations = block_declaration_stack[stack_depth]
98	if type(var) == "string" then
99		target_block_declarations[var] = scope
100	else
101		for _, declaration_name in ipairs(var.declaration_names) do
102			target_block_declarations[declaration_name] = scope
103		end
104	end
105end
106local function consume()
107	local consumed_token_value = current_token.value
108	current_token_index = current_token_index + 1
109	current_token = tokens[current_token_index]
110	return consumed_token_value
111end
112local function branch(token)
113	if token == current_token.value then
114		consume()
115		return true
116	end
117end
118local function expect(token, should_consume)
119	if current_token.type == TOKEN_TYPES.EOF then
120		throw(("unexpected eof (expected " .. tostring(token) .. ")"))
121	end
122	if token ~= current_token.value then
123		throw(("expected '" .. tostring(token) .. "' got '" .. tostring(current_token.value) .. "'"))
124	end
125	if should_consume then
126		return consume()
127	end
128end
129local function look_past_surround(token_start_index)
130	if token_start_index == nil then
131		token_start_index = current_token_index
132	end
133	local surround_start_token = tokens[token_start_index]
134	local surround_end = SURROUND_ENDS[surround_start_token.value]
135	local surround_depth = 1
136	local look_ahead_token_index = token_start_index + 1
137	local look_ahead_token = tokens[look_ahead_token_index]
138	repeat
139		if look_ahead_token.type == TOKEN_TYPES.EOF then
140			throw(("unexpected eof, missing '" .. tostring(surround_end) .. "'"), surround_start_token.line)
141		end
142		if look_ahead_token.value == surround_start_token.value then
143			surround_depth = surround_depth + 1
144		elseif look_ahead_token.value == surround_end then
145			surround_depth = surround_depth - 1
146		end
147		look_ahead_token_index = look_ahead_token_index + 1
148		look_ahead_token = tokens[look_ahead_token_index]
149	until surround_depth == 0
150	return look_ahead_token, look_ahead_token_index
151end
152local function new_tmp_name()
153	tmp_name_counter = tmp_name_counter + 1
154	return ("__ERDE_TMP_" .. tostring(tmp_name_counter) .. "__")
155end
156local function get_compile_name(name, scope)
157	if scope == "module" then
158		if LUA_KEYWORDS[name] then
159			return ("_MODULE['" .. tostring(name) .. "']")
160		else
161			return "_MODULE." .. name
162		end
163	elseif scope == "global" then
164		if LUA_KEYWORDS[name] then
165			return ("_G['" .. tostring(name) .. "']")
166		else
167			return "_G." .. name
168		end
169	end
170	if LUA_KEYWORDS[name] then
171		return (tostring(name) .. "_")
172	else
173		return name
174	end
175end
176local function weave(t, separator)
177	if separator == nil then
178		separator = ","
179	end
180	local woven = {}
181	local len = #t
182	for i = 1, len - 1 do
183		table.insert(woven, t[i])
184		if type(t[i]) ~= "number" then
185			table.insert(woven, separator)
186		end
187	end
188	table.insert(woven, t[len])
189	return woven
190end
191local function compile_binop(op_token, op_line, lhs, rhs)
192	local needs_floor_division_polyfill = (
193		op_token == "//"
194		and lua_target ~= "5.3"
195		and lua_target ~= "5.4"
196		and lua_target ~= "5.3+"
197		and lua_target ~= "5.4+"
198	)
199	if needs_floor_division_polyfill then
200		return {
201			op_line,
202			"math.floor(",
203			lhs,
204			op_line,
205			"/",
206			rhs,
207			")",
208		}
209	elseif bitlib and BITOPS[op_token] then
210		return {
211			op_line,
212			("(require('" .. tostring(bitlib) .. "')." .. tostring(BITLIB_METHODS[op_token]) .. "("),
213			lhs,
214			",",
215			rhs,
216			"))",
217		}
218	elseif op_token == "!=" then
219		return {
220			lhs,
221			"~=",
222			rhs,
223		}
224	elseif op_token == "==" then
225		return {
226			lhs,
227			op_token,
228			rhs,
229		}
230	elseif op_token == "||" then
231		return {
232			lhs,
233			"or",
234			rhs,
235		}
236	elseif op_token == "&&" then
237		return {
238			lhs,
239			"and",
240			rhs,
241		}
242	else
243		return {
244			lhs,
245			op_line,
246			op_token,
247			rhs,
248		}
249	end
250end
251local function list(callback, break_token)
252	local list = {}
253	repeat
254		table.insert(list, callback() or nil)
255	until not branch(",") or (break_token and current_token.value == break_token)
256	return list
257end
258local function surround(open_char, close_char, callback)
259	expect(open_char, true)
260	local result = callback()
261	expect(close_char, true)
262	return result
263end
264local function surround_list(open_char, close_char, allow_empty, callback)
265	return surround(open_char, close_char, function()
266		if current_token.value ~= close_char or not allow_empty then
267			return list(callback, close_char)
268		else
269			return {}
270		end
271	end)
272end
273local function name()
274	if current_token.type == TOKEN_TYPES.EOF then
275		throw("unexpected eof")
276	end
277	if current_token.type ~= TOKEN_TYPES.WORD then
278		throw(("unexpected token '" .. tostring(current_token.value) .. "'"))
279	end
280	if KEYWORDS[current_token.value] ~= nil then
281		throw(("unexpected keyword '" .. tostring(current_token.value) .. "'"))
282	end
283	if TERMINALS[current_token.value] ~= nil then
284		throw(("unexpected builtin '" .. tostring(current_token.value) .. "'"))
285	end
286	return consume()
287end
288local function array_destructure(scope)
289	local compile_lines = {}
290	local compile_name = new_tmp_name()
291	local declaration_names = {}
292	local array_index = 0
293	table.insert(compile_lines, current_token.line)
294	surround_list("[", "]", false, function()
295		array_index = array_index + 1
296		local declaration_name = name()
297		table.insert(declaration_names, declaration_name)
298		local assignment_name = get_compile_name(declaration_name, scope)
299		table.insert(
300			compile_lines,
301			(tostring(assignment_name) .. " = " .. tostring(compile_name) .. "[" .. tostring(array_index) .. "]")
302		)
303		if branch("=") then
304			table.insert(
305				compile_lines,
306				("if " .. tostring(assignment_name) .. " == nil then " .. tostring(assignment_name) .. " = ")
307			)
308			table.insert(compile_lines, expression())
309			table.insert(compile_lines, "end")
310		end
311	end)
312	return {
313		compile_lines = compile_lines,
314		compile_name = compile_name,
315		declaration_names = declaration_names,
316	}
317end
318local function map_destructure(scope)
319	local compile_lines = {}
320	local compile_name = new_tmp_name()
321	local declaration_names = {}
322	table.insert(compile_lines, current_token.line)
323	surround_list("{", "}", false, function()
324		local key = name()
325		local declaration_name = branch(":") and name() or key
326		table.insert(declaration_names, declaration_name)
327		local assignment_name = get_compile_name(declaration_name, scope)
328		if LUA_KEYWORDS[declaration_name] then
329			table.insert(
330				compile_lines,
331				(tostring(assignment_name) .. " = " .. tostring(compile_name) .. "['" .. tostring(key) .. "']")
332			)
333		else
334			table.insert(
335				compile_lines,
336				(tostring(assignment_name) .. " = " .. tostring(compile_name) .. "." .. tostring(key))
337			)
338		end
339		if branch("=") then
340			table.insert(
341				compile_lines,
342				("if " .. tostring(assignment_name) .. " == nil then " .. tostring(assignment_name) .. " = ")
343			)
344			table.insert(compile_lines, expression())
345			table.insert(compile_lines, "end")
346		end
347	end)
348	return {
349		compile_lines = compile_lines,
350		compile_name = compile_name,
351		declaration_names = declaration_names,
352	}
353end
354local function variable(scope)
355	if scope == nil then
356		scope = "local"
357	end
358	if current_token.value == "[" then
359		return array_destructure(scope)
360	elseif current_token.value == "{" then
361		return map_destructure(scope)
362	else
363		return name()
364	end
365end
366local function bracket_index(index_chain_state)
367	local compile_lines = {
368		current_token.line,
369		"[",
370		surround("[", "]", expression),
371		"]",
372	}
373	index_chain_state.final_base_compile_lines = table.shallowcopy(index_chain_state.compile_lines)
374	index_chain_state.final_index_compile_lines = compile_lines
375	table.insert(index_chain_state.compile_lines, compile_lines)
376end
377local function dot_index(index_chain_state)
378	local compile_lines = {
379		current_token.line,
380	}
381	consume()
382	local key = name()
383	if LUA_KEYWORDS[key] then
384		table.insert(compile_lines, ("['" .. tostring(key) .. "']"))
385	else
386		table.insert(compile_lines, "." .. key)
387	end
388	index_chain_state.final_base_compile_lines = table.shallowcopy(index_chain_state.compile_lines)
389	index_chain_state.final_index_compile_lines = compile_lines
390	table.insert(index_chain_state.compile_lines, compile_lines)
391end
392local function method_index(index_chain_state)
393	table.insert(index_chain_state.compile_lines, current_token.line)
394	consume()
395	local method_name = name()
396	local method_parameters = surround_list("(", ")", true, expression)
397	if not LUA_KEYWORDS[method_name] then
398		table.insert(index_chain_state.compile_lines, (":" .. tostring(method_name) .. "("))
399		table.insert(index_chain_state.compile_lines, weave(method_parameters))
400		table.insert(index_chain_state.compile_lines, ")")
401	elseif index_chain_state.has_trivial_base and index_chain_state.chain_len == 0 then
402		table.insert(index_chain_state.compile_lines, ("['" .. tostring(method_name) .. "']("))
403		table.insert(method_parameters, 1, index_chain_state.base_compile_lines)
404		table.insert(index_chain_state.compile_lines, weave(method_parameters))
405		table.insert(index_chain_state.compile_lines, ")")
406	else
407		index_chain_state.needs_block_compile = true
408		table.insert(index_chain_state.block_compile_lines, index_chain_state.block_compile_name .. "=")
409		table.insert(index_chain_state.block_compile_lines, index_chain_state.compile_lines)
410		table.insert(method_parameters, 1, index_chain_state.block_compile_name)
411		index_chain_state.compile_lines = {
412			(tostring(index_chain_state.block_compile_name) .. "['" .. tostring(method_name) .. "']("),
413			weave(method_parameters),
414			")",
415		}
416	end
417end
418local function function_call_index(index_chain_state)
419	local preceding_compile_lines = index_chain_state.compile_lines
420	local preceding_compile_lines_len = #preceding_compile_lines
421	while type(preceding_compile_lines[preceding_compile_lines_len]) == "table" do
422		preceding_compile_lines = preceding_compile_lines[preceding_compile_lines_len]
423		preceding_compile_lines_len = #preceding_compile_lines
424	end
425	preceding_compile_lines[preceding_compile_lines_len] = preceding_compile_lines[preceding_compile_lines_len] .. "("
426	table.insert(index_chain_state.compile_lines, weave(surround_list("(", ")", true, expression)))
427	table.insert(index_chain_state.compile_lines, ")")
428end
429local function index_chain(options)
430	local block_compile_name = new_tmp_name()
431	local index_chain_state = {
432		base_compile_lines = options.base_compile_lines,
433		compile_lines = {
434			options.base_compile_lines,
435		},
436		has_trivial_base = options.has_trivial_base,
437		chain_len = 0,
438		is_function_call = false,
439		needs_block_compile = false,
440		block_compile_name = block_compile_name,
441		block_compile_lines = {
442			"local " .. block_compile_name,
443		},
444		final_base_compile_lines = options.base_compile_lines,
445		final_index_compile_lines = {},
446	}
447	if options.wrap_base_compile_lines then
448		table.insert(index_chain_state.compile_lines, 1, "(")
449		table.insert(index_chain_state.compile_lines, ")")
450	end
451	while true do
452		if current_token.value == "(" and current_token.line == tokens[current_token_index - 1].line then
453			index_chain_state.is_function_call = true
454			function_call_index(index_chain_state)
455		elseif current_token.value == "[" then
456			index_chain_state.is_function_call = false
457			bracket_index(index_chain_state)
458		elseif current_token.value == "." then
459			index_chain_state.is_function_call = false
460			dot_index(index_chain_state)
461		elseif current_token.value == ":" then
462			index_chain_state.is_function_call = true
463			method_index(index_chain_state)
464		else
465			break
466		end
467		index_chain_state.chain_len = index_chain_state.chain_len + 1
468	end
469	if options.require_chain and index_chain_state.chain_len == 0 then
470		if current_token.type == TOKEN_TYPES.EOF then
471			throw("unexpected eof")
472		else
473			throw(("unexpected token '" .. tostring(current_token.value) .. "'"))
474		end
475	end
476	if index_chain_state.chain_len == 0 then
477		index_chain_state.compile_lines = options.base_compile_lines
478	end
479	return index_chain_state
480end
481local function single_quote_string()
482	consume()
483	if current_token.type == TOKEN_TYPES.SINGLE_QUOTE_STRING then
484		return {
485			current_token.line,
486			"'" .. consume(),
487		}
488	else
489		return {
490			current_token.line,
491			"'" .. consume() .. consume(),
492		}
493	end
494end
495local function double_quote_string()
496	local double_quote_string_line = current_token.line
497	local has_interpolation = false
498	consume()
499	if current_token.type == TOKEN_TYPES.DOUBLE_QUOTE_STRING then
500		return {
501			double_quote_string_line,
502			'"' .. consume(),
503		}, has_interpolation
504	end
505	local compile_lines = {}
506	local content = ""
507	repeat
508		if current_token.type == TOKEN_TYPES.INTERPOLATION then
509			has_interpolation = true
510			if content ~= "" then
511				table.insert(compile_lines, '"' .. content .. '"')
512			end
513			table.insert(compile_lines, {
514				"tostring(",
515				surround("{", "}", expression),
516				")",
517			})
518			content = ""
519		else
520			content = content .. consume()
521		end
522	until current_token.type == TOKEN_TYPES.DOUBLE_QUOTE_STRING
523	if content ~= "" then
524		table.insert(compile_lines, '"' .. content .. '"')
525	end
526	consume()
527	return {
528		double_quote_string_line,
529		weave(compile_lines, ".."),
530	}, has_interpolation
531end
532local function block_string()
533	local block_string_line = current_token.line
534	local has_interpolation = false
535	local start_quote = "[" .. current_token.equals .. "["
536	local end_quote = "]" .. current_token.equals .. "]"
537	consume()
538	if current_token.type == TOKEN_TYPES.BLOCK_STRING then
539		consume()
540		return {
541			block_string_line,
542			start_quote .. end_quote,
543		}, has_interpolation
544	end
545	local compile_lines = {}
546	local content = ""
547	repeat
548		if current_token.type == TOKEN_TYPES.INTERPOLATION then
549			has_interpolation = true
550			if content ~= "" then
551				table.insert(compile_lines, start_quote .. content .. end_quote)
552			end
553			table.insert(compile_lines, {
554				"tostring(",
555				surround("{", "}", expression),
556				")",
557			})
558			content = ""
559			if current_token.value:sub(1, 1) == "\n" then
560				content = content .. "\n" .. consume()
561			end
562		else
563			content = content .. consume()
564		end
565	until current_token.type == TOKEN_TYPES.BLOCK_STRING
566	if content ~= "" then
567		table.insert(compile_lines, start_quote .. content .. end_quote)
568	end
569	consume()
570	return {
571		block_string_line,
572		weave(compile_lines, ".."),
573	}, has_interpolation
574end
575local function table_constructor()
576	local table_constructor_line = current_token.line
577	local compile_lines = {}
578	surround_list("{", "}", true, function()
579		local next_token = tokens[current_token_index + 1]
580		if current_token.value == "[" then
581			table.insert(compile_lines, "[")
582			table.insert(compile_lines, surround("[", "]", expression))
583			table.insert(compile_lines, "]")
584			table.insert(compile_lines, expect("=", true))
585		elseif next_token.type == TOKEN_TYPES.SYMBOL and next_token.value == "=" then
586			local key = name()
587			if LUA_KEYWORDS[key] then
588				table.insert(compile_lines, ("['" .. tostring(key) .. "']") .. consume())
589			else
590				table.insert(compile_lines, key .. consume())
591			end
592		end
593		table.insert(compile_lines, expression())
594		table.insert(compile_lines, ",")
595	end)
596	return {
597		table_constructor_line,
598		"{",
599		compile_lines,
600		"}",
601	}
602end
603local function return_list()
604	local look_ahead_limit_token, look_ahead_limit_token_index = look_past_surround()
605	if look_ahead_limit_token.value == "->" or look_ahead_limit_token.value == "=>" then
606		return arrow_function()
607	end
608	local look_ahead_token_index = current_token_index + 1
609	local look_ahead_token = tokens[look_ahead_token_index]
610	while look_ahead_token_index < look_ahead_limit_token_index do
611		if look_ahead_token.type == TOKEN_TYPES.SYMBOL and SURROUND_ENDS[look_ahead_token.value] then
612			look_ahead_token, look_ahead_token_index = look_past_surround(look_ahead_token_index)
613		elseif look_ahead_token.type == TOKEN_TYPES.SYMBOL and look_ahead_token.value == "," then
614			return weave(surround_list("(", ")", false, expression))
615		else
616			look_ahead_token_index = look_ahead_token_index + 1
617			look_ahead_token = tokens[look_ahead_token_index]
618		end
619	end
620	return expression()
621end
622local function block_return()
623	if is_module_return_block then
624		module_return_line = current_token.line
625	end
626	local compile_lines = {
627		consume(),
628	}
629	if block_depth == 1 then
630		if current_token.type ~= TOKEN_TYPES.EOF then
631			if current_token.value == "(" then
632				table.insert(compile_lines, return_list())
633			else
634				table.insert(compile_lines, weave(list(expression)))
635			end
636		end
637		if current_token.type ~= TOKEN_TYPES.EOF then
638			throw(("expected '<eof>', got '" .. tostring(current_token.value) .. "'"))
639		end
640	else
641		if current_token.value ~= "}" then
642			if current_token.value == "(" then
643				table.insert(compile_lines, return_list())
644			else
645				table.insert(compile_lines, weave(list(expression)))
646			end
647		end
648		if current_token.value ~= "}" then
649			throw(("expected '}', got '" .. tostring(current_token.value) .. "'"))
650		end
651	end
652	return compile_lines
653end
654local function parameters()
655	local compile_lines = {}
656	local compile_names = {}
657	local has_varargs = false
658	surround_list("(", ")", true, function()
659		if branch("...") then
660			has_varargs = true
661			table.insert(compile_names, "...")
662			if current_token.type == TOKEN_TYPES.WORD then
663				local varargs_name = name()
664				table.insert(compile_lines, ("local " .. tostring(get_compile_name(varargs_name)) .. " = { ... }"))
665				add_block_declaration(varargs_name, "local", block_depth + 1)
666			end
667			branch(",")
668			expect(")")
669		else
670			local var = variable()
671			add_block_declaration(var, "local", block_depth + 1)
672			local compile_name = type(var) == "string" and get_compile_name(var) or var.compile_name
673			table.insert(compile_names, compile_name)
674			if branch("=") then
675				table.insert(
676					compile_lines,
677					("if " .. tostring(compile_name) .. " == nil then " .. tostring(compile_name) .. " = ")
678				)
679				table.insert(compile_lines, expression())
680				table.insert(compile_lines, "end")
681			end
682			if type(var) == "table" then
683				table.insert(
684					compile_lines,
685					"local " .. table.concat(table.map(var.declaration_names, get_compile_name), ",")
686				)
687				table.insert(compile_lines, var.compile_lines)
688			end
689		end
690	end)
691	return {
692		compile_lines = compile_lines,
693		compile_names = compile_names,
694		has_varargs = has_varargs,
695	}
696end
697local function function_block()
698	local old_is_module_return_block = is_module_return_block
699	local old_break_name = break_name
700	is_module_return_block = false
701	break_name = nil
702	local compile_lines = block()
703	is_module_return_block = old_is_module_return_block
704	break_name = old_break_name
705	return compile_lines
706end
707function arrow_function()
708	local old_is_varargs_block = is_varargs_block
709	local arrow_function_line = current_token.line
710	local param_compile_lines = {}
711	local param_compile_names = {}
712	if current_token.value == "(" then
713		local params = parameters()
714		table.insert(param_compile_lines, params.compile_lines)
715		is_varargs_block = params.has_varargs
716		param_compile_names = params.compile_names
717	else
718		is_varargs_block = false
719		local var = variable()
720		add_block_declaration(var, "local", block_depth + 1)
721		if type(var) == "string" then
722			table.insert(param_compile_names, get_compile_name(var))
723		else
724			table.insert(param_compile_names, var.compile_name)
725			table.insert(
726				param_compile_lines,
727				"local " .. table.concat(table.map(var.declaration_names, get_compile_name), ",")
728			)
729			table.insert(param_compile_lines, var.compile_lines)
730		end
731	end
732	if current_token.value == "->" then
733		consume()
734	elseif current_token.value == "=>" then
735		table.insert(param_compile_names, 1, "self")
736		consume()
737	elseif current_token.type == TOKEN_TYPES.EOF then
738		throw("unexpected eof (expected '->' or '=>')")
739	else
740		throw(("unexpected token '" .. tostring(current_token.value) .. "' (expected '->' or '=>')"))
741	end
742	local compile_lines = {
743		arrow_function_line,
744		("function(" .. tostring(table.concat(param_compile_names, ",")) .. ")"),
745		param_compile_lines,
746	}
747	if current_token.value == "{" then
748		table.insert(compile_lines, surround("{", "}", function_block))
749	else
750		table.insert(compile_lines, "return")
751		local old_block_declarations = block_declarations
752		block_depth = block_depth + 1
753		block_declaration_stack[block_depth] = block_declaration_stack[block_depth] or {}
754		block_declarations = block_declaration_stack[block_depth]
755		if current_token.value == "(" then
756			table.insert(compile_lines, return_list())
757		else
758			table.insert(compile_lines, expression())
759		end
760		block_declarations = old_block_declarations
761		block_declaration_stack[block_depth] = nil
762		block_depth = block_depth - 1
763	end
764	table.insert(compile_lines, "end")
765	is_varargs_block = old_is_varargs_block
766	return compile_lines
767end
768local function function_signature(scope)
769	local base_name = name()
770	if (current_token.value == "." or current_token.value == ":") and scope ~= nil then
771		throw("cannot use scopes for table values", current_token.line)
772	end
773	if scope == "module" or scope == "global" then
774		block_declarations[base_name] = scope
775	end
776	local signature = get_compile_name(base_name, scope or block_declarations[base_name])
777	local needs_label_assignment = false
778	local needs_self_injection = false
779	while branch(".") do
780		local key = name()
781		if LUA_KEYWORDS[key] then
782			needs_label_assignment = true
783			signature = signature .. ("['" .. tostring(key) .. "']")
784		else
785			signature = signature .. "." .. key
786		end
787	end
788	if branch(":") then
789		local key = name()
790		if LUA_KEYWORDS[key] then
791			needs_label_assignment = true
792			needs_self_injection = true
793			signature = signature .. ("['" .. tostring(key) .. "']")
794		else
795			signature = signature .. ":" .. key
796		end
797	end
798	return {
799		signature = signature,
800		needs_label_assignment = needs_label_assignment,
801		needs_self_injection = needs_self_injection,
802	}
803end
804local function function_declaration(scope)
805	local compile_lines = {
806		current_token.line,
807	}
808	consume()
809	local signature, needs_label_assignment, needs_self_injection
810	do
811		local __ERDE_TMP_979__
812		__ERDE_TMP_979__ = function_signature(scope)
813		signature = __ERDE_TMP_979__["signature"]
814		needs_label_assignment = __ERDE_TMP_979__["needs_label_assignment"]
815		needs_self_injection = __ERDE_TMP_979__["needs_self_injection"]
816	end
817	if scope == "local" then
818		table.insert(compile_lines, "local")
819	end
820	if needs_label_assignment then
821		table.insert(compile_lines, signature)
822		table.insert(compile_lines, "=")
823		table.insert(compile_lines, "function")
824	else
825		table.insert(compile_lines, "function")
826		table.insert(compile_lines, signature)
827	end
828	local params = parameters()
829	if needs_self_injection then
830		table.insert(params.compile_names, "self")
831	end
832	table.insert(compile_lines, "(" .. table.concat(params.compile_names, ",") .. ")")
833	table.insert(compile_lines, params.compile_lines)
834	local old_is_varargs_block = is_varargs_block
835	is_varargs_block = params.has_varargs
836	table.insert(compile_lines, surround("{", "}", function_block))
837	is_varargs_block = old_is_varargs_block
838	table.insert(compile_lines, "end")
839	return compile_lines
840end
841local function index_chain_expression(options)
842	local index_chain = index_chain(options)
843	if index_chain.needs_block_compile then
844		return {
845			"(function()",
846			index_chain.block_compile_lines,
847			"return",
848			index_chain.compile_lines,
849			"end)()",
850		}
851	else
852		return index_chain.compile_lines
853	end
854end
855local function terminal_expression()
856	if current_token.type == TOKEN_TYPES.NUMBER then
857		return {
858			current_token.line,
859			consume(),
860		}
861	elseif current_token.type == TOKEN_TYPES.SINGLE_QUOTE_STRING then
862		return index_chain_expression({
863			base_compile_lines = single_quote_string(),
864			has_trivial_base = true,
865			wrap_base_compile_lines = true,
866		})
867	elseif current_token.type == TOKEN_TYPES.DOUBLE_QUOTE_STRING then
868		local compile_lines, has_interpolation = double_quote_string()
869		return index_chain_expression({
870			base_compile_lines = compile_lines,
871			has_trivial_base = not has_interpolation,
872			wrap_base_compile_lines = true,
873		})
874	elseif current_token.type == TOKEN_TYPES.BLOCK_STRING then
875		local compile_lines, has_interpolation = block_string()
876		return index_chain_expression({
877			base_compile_lines = compile_lines,
878			has_trivial_base = not has_interpolation,
879			wrap_base_compile_lines = true,
880		})
881	end
882	if TERMINALS[current_token.value] then
883		if current_token.value == "..." and not is_varargs_block then
884			throw("cannot use '...' outside a vararg function")
885		end
886		return {
887			current_token.line,
888			consume(),
889		}
890	end
891	local next_token = tokens[current_token_index + 1]
892	local is_arrow_function = (
893		next_token.type == TOKEN_TYPES.SYMBOL and (next_token.value == "->" or next_token.value == "=>")
894	)
895	if not is_arrow_function and SURROUND_ENDS[current_token.value] then
896		local past_surround_token = look_past_surround()
897		is_arrow_function = (
898			past_surround_token.type == TOKEN_TYPES.SYMBOL
899			and (past_surround_token.value == "->" or past_surround_token.value == "=>")
900		)
901	end
902	if is_arrow_function then
903		return arrow_function()
904	elseif current_token.value == "{" then
905		return table_constructor()
906	elseif current_token.value == "(" then
907		return index_chain_expression({
908			base_compile_lines = {
909				current_token.line,
910				"(",
911				surround("(", ")", expression),
912				")",
913			},
914		})
915	else
916		local base_name_line, base_name = current_token.line, name()
917		return index_chain_expression({
918			base_compile_lines = {
919				base_name_line,
920				get_compile_name(base_name, block_declarations[base_name]),
921			},
922			has_trivial_base = true,
923		})
924	end
925end
926local function unop_expression()
927	local unop_line, unop = current_token.line, UNOPS[consume()]
928	local operand = expression(unop.prec + 1)
929	if unop.token == "!" then
930		return {
931			"not",
932			operand,
933		}
934	elseif unop.token ~= "~" then
935		return {
936			unop_line,
937			unop.token,
938			operand,
939		}
940	elseif bitlib then
941		return {
942			unop_line,
943			("(require('" .. tostring(bitlib) .. "').bnot("),
944			operand,
945			"))",
946		}
947	elseif lua_target == "5.1+" or lua_target == "5.2+" then
948		throw("must specify bitlib for compiling bit operations when targeting 5.1+ or 5.2+", unop_line)
949	else
950		return {
951			unop_line,
952			unop.token,
953			operand,
954		}
955	end
956end
957function expression(min_prec)
958	if min_prec == nil then
959		min_prec = 1
960	end
961	if current_token.type == TOKEN_TYPES.EOF then
962		throw("unexpected eof (expected expression)")
963	end
964	local compile_lines = UNOPS[current_token.value] and unop_expression() or terminal_expression()
965	local binop_line, binop = current_token.line, BINOPS[current_token.value]
966	while binop and binop.prec >= min_prec do
967		if BITOPS[binop.token] and (lua_target == "5.1+" or lua_target == "5.2+") and not bitlib then
968			throw("must specify bitlib for compiling bit operations when targeting 5.1+ or 5.2+", binop_line)
969		end
970		consume()
971		if binop.token == "~" and current_token.value == "=" then
972			throw("unexpected token '~=', did you mean '!='?")
973		end
974		local operand = binop.assoc == LEFT_ASSOCIATIVE and expression(binop.prec + 1) or expression(binop.prec)
975		compile_lines = compile_binop(binop.token, binop_line, compile_lines, operand)
976		binop_line, binop = current_token.line, BINOPS[current_token.value]
977	end
978	return compile_lines
979end
980function block()
981	local old_block_declarations = block_declarations
982	block_depth = block_depth + 1
983	block_declaration_stack[block_depth] = block_declaration_stack[block_depth]
984		or table.shallowcopy(block_declaration_stack[block_depth - 1])
985	block_declarations = block_declaration_stack[block_depth]
986	local compile_lines = {}
987	while current_token.value ~= "}" do
988		table.insert(compile_lines, statement())
989	end
990	block_declarations = old_block_declarations
991	block_declaration_stack[block_depth] = nil
992	block_depth = block_depth - 1
993	return compile_lines
994end
995local function do_block()
996	return {
997		consume(),
998		surround("{", "}", block),
999		"end",
1000	}
1001end
1002local function loop_block()
1003	local old_break_name = break_name
1004	local old_has_continue = has_continue
1005	break_name = new_tmp_name()
1006	has_continue = false
1007	local compile_lines = block()
1008	if has_continue then
1009		if lua_target == "5.1" or lua_target == "5.1+" then
1010			table.insert(compile_lines, 1, ("local " .. tostring(break_name) .. " = true repeat"))
1011			table.insert(
1012				compile_lines,
1013				(tostring(break_name) .. " = false until true if " .. tostring(break_name) .. " then break end")
1014			)
1015		else
1016			table.insert(compile_lines, ("::" .. tostring(break_name) .. "::"))
1017		end
1018	end
1019	break_name = old_break_name
1020	has_continue = old_has_continue
1021	return compile_lines
1022end
1023local function loop_break()
1024	consume()
1025	if break_name == nil then
1026		throw("cannot use 'break' outside of loop")
1027	end
1028	if lua_target == "5.1" or lua_target == "5.1+" or lua_target == "jit" then
1029		if current_token.value ~= "}" then
1030			throw(("expected '}', got '" .. tostring(current_token.value) .. "'"))
1031		end
1032	end
1033	return "break"
1034end
1035local function loop_continue()
1036	if break_name == nil then
1037		throw("cannot use 'continue' outside of loop")
1038	end
1039	has_continue = true
1040	consume()
1041	if lua_target == "5.1" or lua_target == "5.1+" then
1042		return (tostring(break_name) .. " = false do break end")
1043	else
1044		return ("goto " .. tostring(break_name))
1045	end
1046end
1047local function for_loop()
1048	local compile_lines = {}
1049	local pre_body_compile_lines = {}
1050	table.insert(compile_lines, consume())
1051	local next_token = tokens[current_token_index + 1]
1052	if next_token.type == TOKEN_TYPES.SYMBOL and next_token.value == "=" then
1053		local loop_name = name()
1054		add_block_declaration(loop_name, "local", block_depth + 1)
1055		table.insert(compile_lines, get_compile_name(loop_name) .. consume())
1056		local expressions_line = current_token.line
1057		local expressions = list(expression)
1058		local num_expressions = #expressions
1059		if num_expressions ~= 2 and num_expressions ~= 3 then
1060			throw(
1061				("invalid numeric for, expected 2-3 expressions, got " .. tostring(num_expressions)),
1062				expressions_line
1063			)
1064		end
1065		table.insert(compile_lines, weave(expressions))
1066	else
1067		local names = {}
1068		for _, var in ipairs(list(variable)) do
1069			add_block_declaration(var, "local", block_depth + 1)
1070			if type(var) == "string" then
1071				table.insert(names, get_compile_name(var))
1072			else
1073				table.insert(names, var.compile_name)
1074				table.insert(
1075					pre_body_compile_lines,
1076					"local " .. table.concat(table.map(var.declaration_names, get_compile_name), ",")
1077				)
1078				table.insert(pre_body_compile_lines, var.compile_lines)
1079			end
1080		end
1081		table.insert(compile_lines, weave(names))
1082		table.insert(compile_lines, expect("in", true))
1083		table.insert(compile_lines, weave(list(expression)))
1084	end
1085	table.insert(compile_lines, "do")
1086	table.insert(compile_lines, pre_body_compile_lines)
1087	table.insert(compile_lines, surround("{", "}", loop_block))
1088	table.insert(compile_lines, "end")
1089	return compile_lines
1090end
1091local function repeat_until()
1092	return {
1093		consume(),
1094		surround("{", "}", loop_block),
1095		expect("until", true),
1096		expression(),
1097	}
1098end
1099local function while_loop()
1100	return {
1101		consume(),
1102		expression(),
1103		"do",
1104		surround("{", "}", loop_block),
1105		"end",
1106	}
1107end
1108local function goto_jump()
1109	if lua_target == "5.1" or lua_target == "5.1+" then
1110		throw("'goto' statements only compatibly with lua targets 5.2+, jit")
1111	end
1112	consume()
1113	local label_line, label = current_token.line, name()
1114	table.insert(goto_jumps, {
1115		label = label,
1116		line = label_line,
1117	})
1118	return "goto " .. get_compile_name(label)
1119end
1120local function goto_label()
1121	if lua_target == "5.1" or lua_target == "5.1+" then
1122		throw("'goto' statements only compatibly with lua targets 5.2+, jit")
1123	end
1124	consume()
1125	local label = name()
1126	goto_labels[label] = true
1127	return "::" .. get_compile_name(label) .. expect("::", true)
1128end
1129local function if_else()
1130	local compile_lines = {}
1131	table.insert(compile_lines, consume())
1132	table.insert(compile_lines, expression())
1133	table.insert(compile_lines, "then")
1134	table.insert(compile_lines, surround("{", "}", block))
1135	while current_token.value == "elseif" do
1136		table.insert(compile_lines, consume())
1137		table.insert(compile_lines, expression())
1138		table.insert(compile_lines, "then")
1139		table.insert(compile_lines, surround("{", "}", block))
1140	end
1141	if current_token.value == "else" then
1142		table.insert(compile_lines, consume())
1143		if current_token.value == "if" then
1144			throw("unexpected tokens 'else if', did you mean 'elseif'?")
1145		end
1146		table.insert(compile_lines, surround("{", "}", block))
1147	end
1148	table.insert(compile_lines, "end")
1149	return compile_lines
1150end
1151local function assignment_index_chain()
1152	if current_token.value == "(" then
1153		return index_chain({
1154			base_compile_lines = {
1155				current_token.line,
1156				"(",
1157				surround("(", ")", expression),
1158				")",
1159			},
1160			require_chain = true,
1161		})
1162	else
1163		local base_name_line, base_name = current_token.line, name()
1164		return index_chain({
1165			base_compile_lines = {
1166				base_name_line,
1167				get_compile_name(base_name, block_declarations[base_name]),
1168			},
1169			has_trivial_base = true,
1170		})
1171	end
1172end
1173local function non_operator_assignment(ids, expressions)
1174	local assignment_ids = {}
1175	local assignment_block_compile_names = {}
1176	local assignment_block_compile_lines = {}
1177	for _, id in ipairs(ids) do
1178		if not id.needs_block_compile then
1179			table.insert(assignment_ids, id.compile_lines)
1180		else
1181			local assignment_name = new_tmp_name()
1182			table.insert(assignment_ids, assignment_name)
1183			table.insert(assignment_block_compile_names, assignment_name)
1184			table.insert(assignment_block_compile_lines, id.block_compile_lines)
1185			table.insert(assignment_block_compile_lines, id.compile_lines)
1186			table.insert(assignment_block_compile_lines, "=" .. assignment_name)
1187		end
1188	end
1189	local compile_lines = {}
1190	if #assignment_block_compile_names > 0 then
1191		table.insert(compile_lines, "local")
1192		table.insert(compile_lines, weave(assignment_block_compile_names))
1193	end
1194	table.insert(compile_lines, weave(assignment_ids))
1195	table.insert(compile_lines, "=")
1196	table.insert(compile_lines, weave(expressions))
1197	table.insert(compile_lines, assignment_block_compile_lines)
1198	return compile_lines
1199end
1200local function single_operator_assignment(id, expr, op_token, op_line)
1201	local compile_lines = {}
1202	local id_compile_lines = id.compile_lines
1203	if id.needs_block_compile then
1204		table.insert(compile_lines, id.block_compile_lines)
1205	end
1206	if not id.has_trivial_base or id.chain_len > 1 then
1207		local final_base_name = new_tmp_name()
1208		table.insert(compile_lines, ("local " .. tostring(final_base_name) .. " ="))
1209		table.insert(compile_lines, id.final_base_compile_lines)
1210		id_compile_lines = {
1211			final_base_name,
1212			id.final_index_compile_lines,
1213		}
1214	end
1215	table.insert(compile_lines, id_compile_lines)
1216	table.insert(compile_lines, "=")
1217	if type(expr) == "table" then
1218		expr = {
1219			"(",
1220			expr,
1221			")",
1222		}
1223	end
1224	table.insert(compile_lines, compile_binop(op_token, op_line, id_compile_lines, expr))
1225	return compile_lines
1226end
1227local function operator_assignment(ids, expressions, op_token, op_line)
1228	if #ids == 1 then
1229		return single_operator_assignment(ids[1], expressions[1], op_token, op_line)
1230	end
1231	local assignment_names = {}
1232	local assignment_compile_lines = {}
1233	for _, id in ipairs(ids) do
1234		local assignment_name = new_tmp_name()
1235		table.insert(assignment_names, assignment_name)
1236		table.insert(assignment_compile_lines, single_operator_assignment(id, assignment_name, op_token, op_line))
1237	end
1238	return {
1239		("local " .. tostring(table.concat(assignment_names, ",")) .. " ="),
1240		weave(expressions),
1241		assignment_compile_lines,
1242	}
1243end
1244local function variable_assignment(first_id)
1245	local ids = {
1246		first_id,
1247	}
1248	while branch(",") do
1249		local id_line, id = current_token.line, assignment_index_chain()
1250		if id.is_function_call then
1251			throw("cannot assign value to function call", id_line)
1252		end
1253		table.insert(ids, id)
1254	end
1255	local op_line, op_token = current_token.line, BINOP_ASSIGNMENT_TOKENS[current_token.value] and consume()
1256	if BITOPS[op_token] and (lua_target == "5.1+" or lua_target == "5.2+") and not bitlib then
1257		throw("must specify bitlib for compiling bit operations when targeting 5.1+ or 5.2+", op_line)
1258	end
1259	expect("=", true)
1260	local expressions = list(expression)
1261	if op_token then
1262		return operator_assignment(ids, expressions, op_token, op_line)
1263	else
1264		return non_operator_assignment(ids, expressions)
1265	end
1266end
1267local function variable_declaration(scope)
1268	local assignment_names = {}
1269	local has_destructure = false
1270	local destructure_declaration_names = {}
1271	local destructure_compile_lines = {}
1272	for _, var in
1273		ipairs(list(function()
1274			return variable(scope)
1275		end))
1276	do
1277		add_block_declaration(var, scope)
1278		if type(var) == "string" then
1279			table.insert(assignment_names, get_compile_name(var, scope))
1280		else
1281			has_destructure = true
1282			table.insert(assignment_names, var.compile_name)
1283			table.insert(destructure_compile_lines, var.compile_lines)
1284			if scope == "local" then
1285				table.merge(destructure_declaration_names, table.map(var.declaration_names, get_compile_name))
1286			else
1287				table.insert(destructure_declaration_names, var.compile_name)
1288			end
1289		end
1290	end
1291	if has_destructure then
1292		expect("=", true)
1293	elseif scope == "local" and current_token.value ~= "=" then
1294		return "local " .. table.concat(assignment_names, ",")
1295	elseif not branch("=") then
1296		return ""
1297	end
1298	local compile_lines = {}
1299	if has_destructure then
1300		table.insert(compile_lines, "local " .. table.concat(destructure_declaration_names, ","))
1301	end
1302	if scope == "local" then
1303		table.insert(compile_lines, "local")
1304	end
1305	table.insert(compile_lines, table.concat(assignment_names, ",") .. "=")
1306	table.insert(compile_lines, weave(list(expression)))
1307	table.insert(compile_lines, destructure_compile_lines)
1308	return compile_lines
1309end
1310function statement()
1311	local compile_lines = {}
1312	if current_token.value == "break" then
1313		table.insert(compile_lines, loop_break())
1314	elseif current_token.value == "continue" then
1315		table.insert(compile_lines, loop_continue())
1316	elseif current_token.value == "goto" then
1317		table.insert(compile_lines, goto_jump())
1318	elseif current_token.value == "::" then
1319		table.insert(compile_lines, goto_label())
1320	elseif current_token.value == "do" then
1321		table.insert(compile_lines, do_block())
1322	elseif current_token.value == "if" then
1323		table.insert(compile_lines, if_else())
1324	elseif current_token.value == "for" then
1325		table.insert(compile_lines, for_loop())
1326	elseif current_token.value == "while" then
1327		table.insert(compile_lines, while_loop())
1328	elseif current_token.value == "repeat" then
1329		table.insert(compile_lines, repeat_until())
1330	elseif current_token.value == "return" then
1331		table.insert(compile_lines, block_return())
1332	elseif current_token.value == "function" then
1333		table.insert(compile_lines, function_declaration())
1334	elseif current_token.value == "local" or current_token.value == "global" or current_token.value == "module" then
1335		local scope_line, scope = current_token.line, consume()
1336		if scope == "module" then
1337			if block_depth > 1 then
1338				throw("module declarations must appear at the top level", scope_line)
1339			end
1340			has_module_declarations = true
1341		end
1342		if current_token.value == "function" then
1343			table.insert(compile_lines, function_declaration(scope))
1344		else
1345			table.insert(compile_lines, variable_declaration(scope))
1346		end
1347	else
1348		local chain = assignment_index_chain()
1349		if not chain.is_function_call then
1350			table.insert(compile_lines, variable_assignment(chain))
1351		elseif chain.needs_block_compile then
1352			table.insert(compile_lines, "do")
1353			table.insert(compile_lines, chain.block_compile_lines)
1354			table.insert(compile_lines, chain.compile_lines)
1355			table.insert(compile_lines, "end")
1356		else
1357			table.insert(compile_lines, chain.compile_lines)
1358		end
1359	end
1360	if current_token.value == ";" then
1361		table.insert(compile_lines, consume())
1362	elseif current_token.value == "(" then
1363		table.insert(compile_lines, ";")
1364	end
1365	return compile_lines
1366end
1367local function module_block()
1368	local compile_lines = {}
1369	block_declarations = {}
1370	block_declaration_stack[block_depth] = block_declarations
1371	if current_token.type == TOKEN_TYPES.SHEBANG then
1372		table.insert(compile_lines, consume())
1373	end
1374	while current_token.type ~= TOKEN_TYPES.EOF do
1375		table.insert(compile_lines, statement())
1376	end
1377	if has_module_declarations then
1378		if module_return_line ~= nil then
1379			throw("cannot use 'return' w/ 'module' declarations", module_return_line)
1380		end
1381		table.insert(compile_lines, 1, "local _MODULE = {}")
1382		table.insert(compile_lines, "return _MODULE")
1383	end
1384	return compile_lines
1385end
1386local function collect_compile_lines(lines, state)
1387	for _, line in ipairs(lines) do
1388		if type(line) == "number" then
1389			state.source_line = line
1390		elseif type(line) == "string" then
1391			table.insert(state.compile_lines, line)
1392			table.insert(state.source_map, state.source_line)
1393		else
1394			collect_compile_lines(line, state)
1395		end
1396	end
1397end
1398return function(source, options)
1399	if options == nil then
1400		options = {}
1401	end
1402	tokens = tokenize(source, options.alias)
1403	current_token_index = 1
1404	current_token = tokens[current_token_index]
1405	block_depth = 1
1406	tmp_name_counter = 1
1407	break_name = nil
1408	has_continue = false
1409	has_module_declarations = false
1410	is_module_return_block = true
1411	module_return_line = nil
1412	is_varargs_block = true
1413	block_declarations = {}
1414	block_declaration_stack = {}
1415	goto_jumps = {}
1416	goto_labels = {}
1417	alias = options.alias or get_source_alias(source)
1418	lua_target = options.lua_target or config.lua_target
1419	bitlib = options.bitlib
1420		or config.bitlib
1421		or (lua_target == "5.1" and "bit")
1422		or (lua_target == "jit" and "bit")
1423		or (lua_target == "5.2" and "bit32")
1424	local source_map = {}
1425	local compile_lines = {}
1426	collect_compile_lines(module_block(), {
1427		compile_lines = compile_lines,
1428		source_map = source_map,
1429		source_line = current_token.line,
1430	})
1431	for _, __ERDE_TMP_1927__ in ipairs(goto_jumps) do
1432		local label, line
1433		label = __ERDE_TMP_1927__["label"]
1434		line = __ERDE_TMP_1927__["line"]
1435		if goto_labels[label] == nil then
1436			throw(("failed to find goto label '" .. tostring(label) .. "'"), line)
1437		end
1438	end
1439	table.insert(
1440		compile_lines,
1441		("-- Compiled with Erde " .. tostring(VERSION) .. " w/ Lua target " .. tostring(lua_target))
1442	)
1443	table.insert(compile_lines, COMPILED_FOOTER_COMMENT)
1444	return table.concat(compile_lines, "\n"), source_map
1445end
1446-- Compiled with Erde 0.6.0-1
1447-- __ERDE_COMPILED__
1448end
1449end
1450
1451do
1452local _ENV = _ENV
1453package.preload[ "erde.config" ] = function( ... ) local arg = _G.arg;
1454local _MODULE = {}
1455local lua_target = "5.1+"
1456_MODULE.lua_target = lua_target
1457local is_cli_runtime = false
1458_MODULE.is_cli_runtime = is_cli_runtime
1459local bitlib = nil
1460_MODULE.bitlib = bitlib
1461local disable_source_maps = false
1462_MODULE.disable_source_maps = disable_source_maps
1463return _MODULE
1464-- Compiled with Erde 0.6.0-1
1465-- __ERDE_COMPILED__
1466end
1467end
1468
1469do
1470local _ENV = _ENV
1471package.preload[ "erde.constants" ] = function( ... ) local arg = _G.arg;
1472local _MODULE = {}
1473local VERSION = "1.0.0-1"
1474_MODULE.VERSION = VERSION
1475local PATH_SEPARATOR = package.config:sub(1, 1)
1476_MODULE.PATH_SEPARATOR = PATH_SEPARATOR
1477local COMPILED_FOOTER_COMMENT = "-- __ERDE_COMPILED__"
1478_MODULE.COMPILED_FOOTER_COMMENT = COMPILED_FOOTER_COMMENT
1479local TOKEN_TYPES = {
1480	EOF = 0,
1481	SHEBANG = 1,
1482	SYMBOL = 2,
1483	WORD = 3,
1484	NUMBER = 4,
1485	SINGLE_QUOTE_STRING = 5,
1486	DOUBLE_QUOTE_STRING = 6,
1487	STRING_CONTENT = 7,
1488	INTERPOLATION = 8,
1489}
1490_MODULE.TOKEN_TYPES = TOKEN_TYPES
1491local VALID_LUA_TARGETS = {
1492	"jit",
1493	"5.1",
1494	"5.1+",
1495	"5.2",
1496	"5.2+",
1497	"5.3",
1498	"5.3+",
1499	"5.4",
1500	"5.4+",
1501}
1502_MODULE.VALID_LUA_TARGETS = VALID_LUA_TARGETS
1503for i, target in ipairs(VALID_LUA_TARGETS) do
1504	VALID_LUA_TARGETS[target] = true
1505end
1506local KEYWORDS = {
1507	["break"] = true,
1508	["continue"] = true,
1509	["do"] = true,
1510	["else"] = true,
1511	["elseif"] = true,
1512	["for"] = true,
1513	["function"] = true,
1514	["global"] = true,
1515	["if"] = true,
1516	["in"] = true,
1517	["local"] = true,
1518	["module"] = true,
1519	["repeat"] = true,
1520	["return"] = true,
1521	["until"] = true,
1522	["while"] = true,
1523}
1524_MODULE.KEYWORDS = KEYWORDS
1525local LUA_KEYWORDS = {
1526	["not"] = true,
1527	["and"] = true,
1528	["or"] = true,
1529	["end"] = true,
1530	["then"] = true,
1531}
1532_MODULE.LUA_KEYWORDS = LUA_KEYWORDS
1533local TERMINALS = {
1534	["true"] = true,
1535	["false"] = true,
1536	["nil"] = true,
1537	["..."] = true,
1538}
1539_MODULE.TERMINALS = TERMINALS
1540local LEFT_ASSOCIATIVE = -1
1541_MODULE.LEFT_ASSOCIATIVE = LEFT_ASSOCIATIVE
1542local RIGHT_ASSOCIATIVE = 1
1543_MODULE.RIGHT_ASSOCIATIVE = RIGHT_ASSOCIATIVE
1544local UNOPS = {
1545	["-"] = {
1546		prec = 13,
1547	},
1548	["#"] = {
1549		prec = 13,
1550	},
1551	["!"] = {
1552		prec = 13,
1553	},
1554	["~"] = {
1555		prec = 13,
1556	},
1557}
1558_MODULE.UNOPS = UNOPS
1559for token, op in pairs(UNOPS) do
1560	op.token = token
1561end
1562local BITOPS = {
1563	["|"] = {
1564		prec = 6,
1565		assoc = LEFT_ASSOCIATIVE,
1566	},
1567	["~"] = {
1568		prec = 7,
1569		assoc = LEFT_ASSOCIATIVE,
1570	},
1571	["&"] = {
1572		prec = 8,
1573		assoc = LEFT_ASSOCIATIVE,
1574	},
1575	["<<"] = {
1576		prec = 9,
1577		assoc = LEFT_ASSOCIATIVE,
1578	},
1579	[">>"] = {
1580		prec = 9,
1581		assoc = LEFT_ASSOCIATIVE,
1582	},
1583}
1584_MODULE.BITOPS = BITOPS
1585local BITLIB_METHODS = {
1586	["|"] = "bor",
1587	["~"] = "bxor",
1588	["&"] = "band",
1589	["<<"] = "lshift",
1590	[">>"] = "rshift",
1591}
1592_MODULE.BITLIB_METHODS = BITLIB_METHODS
1593local BINOPS = {
1594	["||"] = {
1595		prec = 3,
1596		assoc = LEFT_ASSOCIATIVE,
1597	},
1598	["&&"] = {
1599		prec = 4,
1600		assoc = LEFT_ASSOCIATIVE,
1601	},
1602	["=="] = {
1603		prec = 5,
1604		assoc = LEFT_ASSOCIATIVE,
1605	},
1606	["!="] = {
1607		prec = 5,
1608		assoc = LEFT_ASSOCIATIVE,
1609	},
1610	["<="] = {
1611		prec = 5,
1612		assoc = LEFT_ASSOCIATIVE,
1613	},
1614	[">="] = {
1615		prec = 5,
1616		assoc = LEFT_ASSOCIATIVE,
1617	},
1618	["<"] = {
1619		prec = 5,
1620		assoc = LEFT_ASSOCIATIVE,
1621	},
1622	[">"] = {
1623		prec = 5,
1624		assoc = LEFT_ASSOCIATIVE,
1625	},
1626	[".."] = {
1627		prec = 10,
1628		assoc = LEFT_ASSOCIATIVE,
1629	},
1630	["+"] = {
1631		prec = 11,
1632		assoc = LEFT_ASSOCIATIVE,
1633	},
1634	["-"] = {
1635		prec = 11,
1636		assoc = LEFT_ASSOCIATIVE,
1637	},
1638	["*"] = {
1639		prec = 12,
1640		assoc = LEFT_ASSOCIATIVE,
1641	},
1642	["/"] = {
1643		prec = 12,
1644		assoc = LEFT_ASSOCIATIVE,
1645	},
1646	["//"] = {
1647		prec = 12,
1648		assoc = LEFT_ASSOCIATIVE,
1649	},
1650	["%"] = {
1651		prec = 12,
1652		assoc = LEFT_ASSOCIATIVE,
1653	},
1654	["^"] = {
1655		prec = 14,
1656		assoc = RIGHT_ASSOCIATIVE,
1657	},
1658}
1659_MODULE.BINOPS = BINOPS
1660for token, op in pairs(BITOPS) do
1661	BINOPS[token] = op
1662end
1663for token, op in pairs(BINOPS) do
1664	op.token = token
1665end
1666local BINOP_ASSIGNMENT_TOKENS = {
1667	["||"] = true,
1668	["&&"] = true,
1669	[".."] = true,
1670	["+"] = true,
1671	["-"] = true,
1672	["*"] = true,
1673	["/"] = true,
1674	["//"] = true,
1675	["%"] = true,
1676	["^"] = true,
1677	["|"] = true,
1678	["~"] = true,
1679	["&"] = true,
1680	["<<"] = true,
1681	[">>"] = true,
1682}
1683_MODULE.BINOP_ASSIGNMENT_TOKENS = BINOP_ASSIGNMENT_TOKENS
1684local SURROUND_ENDS = {
1685	["("] = ")",
1686	["["] = "]",
1687	["{"] = "}",
1688}
1689_MODULE.SURROUND_ENDS = SURROUND_ENDS
1690local SYMBOLS = {
1691	["->"] = true,
1692	["=>"] = true,
1693	["..."] = true,
1694	["::"] = true,
1695}
1696_MODULE.SYMBOLS = SYMBOLS
1697for token, op in pairs(BINOPS) do
1698	if #token > 1 then
1699		SYMBOLS[token] = true
1700	end
1701end
1702local STANDARD_ESCAPE_CHARS = {
1703	a = true,
1704	b = true,
1705	f = true,
1706	n = true,
1707	r = true,
1708	t = true,
1709	v = true,
1710	["\\"] = true,
1711	['"'] = true,
1712	["'"] = true,
1713	["\n"] = true,
1714}
1715_MODULE.STANDARD_ESCAPE_CHARS = STANDARD_ESCAPE_CHARS
1716local DIGIT = {}
1717_MODULE.DIGIT = DIGIT
1718local HEX = {}
1719_MODULE.HEX = HEX
1720local WORD_HEAD = {
1721	["_"] = true,
1722}
1723_MODULE.WORD_HEAD = WORD_HEAD
1724local WORD_BODY = {
1725	["_"] = true,
1726}
1727_MODULE.WORD_BODY = WORD_BODY
1728for byte = string.byte("0"), string.byte("9") do
1729	local char = string.char(byte)
1730	DIGIT[char] = true
1731	HEX[char] = true
1732	WORD_BODY[char] = true
1733end
1734for byte = string.byte("A"), string.byte("F") do
1735	local char = string.char(byte)
1736	HEX[char] = true
1737	WORD_HEAD[char] = true
1738	WORD_BODY[char] = true
1739end
1740for byte = string.byte("G"), string.byte("Z") do
1741	local char = string.char(byte)
1742	WORD_HEAD[char] = true
1743	WORD_BODY[char] = true
1744end
1745for byte = string.byte("a"), string.byte("f") do
1746	local char = string.char(byte)
1747	HEX[char] = true
1748	WORD_HEAD[char] = true
1749	WORD_BODY[char] = true
1750end
1751for byte = string.byte("g"), string.byte("z") do
1752	local char = string.char(byte)
1753	WORD_HEAD[char] = true
1754	WORD_BODY[char] = true
1755end
1756return _MODULE
1757-- Compiled with Erde 0.6.0-1
1758-- __ERDE_COMPILED__
1759end
1760end
1761
1762do
1763local _ENV = _ENV
1764package.preload[ "erde.lib" ] = function( ... ) local arg = _G.arg;
1765local _MODULE = {}
1766local compile = require("erde.compile")
1767local config = require("erde.config")
1768local PATH_SEPARATOR, VALID_LUA_TARGETS
1769do
1770	local __ERDE_TMP_6__
1771	__ERDE_TMP_6__ = require("erde.constants")
1772	PATH_SEPARATOR = __ERDE_TMP_6__["PATH_SEPARATOR"]
1773	VALID_LUA_TARGETS = __ERDE_TMP_6__["VALID_LUA_TARGETS"]
1774end
1775local io, string
1776do
1777	local __ERDE_TMP_9__
1778	__ERDE_TMP_9__ = require("erde.stdlib")
1779	io = __ERDE_TMP_9__["io"]
1780	string = __ERDE_TMP_9__["string"]
1781end
1782local echo, get_source_summary
1783do
1784	local __ERDE_TMP_12__
1785	__ERDE_TMP_12__ = require("erde.utils")
1786	echo = __ERDE_TMP_12__["echo"]
1787	get_source_summary = __ERDE_TMP_12__["get_source_summary"]
1788end
1789local loadlua = loadstring or load
1790local unpack = table.unpack or unpack
1791local native_traceback = debug.traceback
1792local searchers = package.loaders or package.searchers
1793local erde_source_cache = {}
1794local erde_source_id_counter = 1
1795local function rewrite(message)
1796	if type(message) ~= "string" then
1797		return message
1798	end
1799	for erde_source_id, chunkname, compiled_line in message:gmatch('%[string "erde::(%d+)::([^\n]+)"]:(%d+)') do
1800		local cache = erde_source_cache[tonumber(erde_source_id)] or {}
1801		local source_map = cache.source_map or {}
1802		local source_line = source_map[tonumber(compiled_line)] or ("(compiled:" .. tostring(compiled_line) .. ")")
1803		local match = string.escape(
1804			(
1805					'[string "erde::'
1806					.. tostring(erde_source_id)
1807					.. "::"
1808					.. tostring(chunkname)
1809					.. '"]:'
1810					.. tostring(compiled_line)
1811				)
1812		)
1813		message = cache.has_alias and message:gsub(match, chunkname .. ":" .. source_line)
1814			or message:gsub(match, ('[string "' .. tostring(chunkname) .. '"]:' .. tostring(source_line)))
1815	end
1816	message = message:gsub("__ERDE_SUBSTITUTE_([a-zA-Z]+)__", "%1")
1817	return message
1818end
1819_MODULE.rewrite = rewrite
1820local function traceback(arg1, arg2, arg3)
1821	local stacktrace, level
1822	if type(arg1) == "thread" then
1823		level = arg3 or 1
1824		stacktrace = native_traceback(arg1, arg2, level + 1)
1825	else
1826		level = arg2 or 1
1827		stacktrace = native_traceback(arg1, level + 1)
1828	end
1829	if type(stacktrace) ~= "string" then
1830		return stacktrace
1831	end
1832	if level > -1 and config.is_cli_runtime then
1833		local stack = string.split(stacktrace, "\n")
1834		local stacklen = #stack
1835		for i = 1, 4 do
1836			table.remove(stack, stacklen - i)
1837		end
1838		stacktrace = table.concat(stack, "\n")
1839	end
1840	stacktrace = stacktrace:gsub(
1841		table.concat({
1842			"[^\n]*\n",
1843			"[^\n]*__erde_internal_load_source__[^\n]*\n",
1844			"[^\n]*\n",
1845		}),
1846		""
1847	)
1848	return rewrite(stacktrace)
1849end
1850_MODULE.traceback = traceback
1851local function __erde_internal_load_source__(source, options)
1852	if options == nil then
1853		options = {}
1854	end
1855	local chunkname = table.concat({
1856		"erde",
1857		erde_source_id_counter,
1858		options.alias or get_source_summary(source),
1859	}, "::")
1860	local compiled, source_map = compile(source, {
1861		alias = options.alias,
1862		lua_target = options.lua_target,
1863		bitlib = options.bitlib,
1864	})
1865	compiled = compiled:gsub("^#![^\n]+", "")
1866	local loader, load_error = loadlua(compiled, chunkname)
1867	if load_error ~= nil then
1868		error(table.concat({
1869			"Failed to load compiled code:",
1870			tostring(load_error),
1871			"",
1872			"This is an internal error that should never happen.",
1873			"Please report this at: https://github.com/erde-lang/erde/issues",
1874			"",
1875			"erde",
1876			"----",
1877			source,
1878			"",
1879			"lua",
1880			"---",
1881			compiled,
1882		}, "\n"))
1883	end
1884	erde_source_cache[erde_source_id_counter] = {
1885		has_alias = options.alias ~= nil,
1886	}
1887	if not config.disable_source_maps and not options.disable_source_maps then
1888		erde_source_cache[erde_source_id_counter].source_map = source_map
1889	end
1890	erde_source_id_counter = erde_source_id_counter + 1
1891	return loader()
1892end
1893_MODULE.__erde_internal_load_source__ = __erde_internal_load_source__
1894local function run(source, options)
1895	return echo(__erde_internal_load_source__(source, options))
1896end
1897_MODULE.run = run
1898local function erde_searcher(module_name)
1899	local module_path = module_name:gsub("%.", PATH_SEPARATOR)
1900	for path in package.path:gmatch("[^;]+") do
1901		local fullpath = path:gsub("%.lua$", ".erde"):gsub("?", module_path)
1902		if io.exists(fullpath) then
1903			return function()
1904				local source = io.readfile(fullpath)
1905				local result = {
1906					__erde_internal_load_source__(source, {
1907						alias = fullpath,
1908					}),
1909				}
1910				return unpack(result)
1911			end
1912		end
1913	end
1914end
1915local function load(arg1, arg2)
1916	local new_lua_target, options = nil, {}
1917	if type(arg1) == "string" then
1918		new_lua_target = arg1
1919	end
1920	if type(arg1) == "table" then
1921		options = arg1
1922	elseif type(arg2) == "table" then
1923		options = arg2
1924	end
1925	config.bitlib = options.bitlib
1926	config.disable_source_maps = options.disable_source_maps
1927	debug.traceback = options.keep_traceback == true and native_traceback or traceback
1928	if new_lua_target ~= nil then
1929		if VALID_LUA_TARGETS[new_lua_target] then
1930			config.lua_target = new_lua_target
1931		else
1932			error(table.concat({
1933				("Invalid Lua target: " .. tostring(new_lua_target)),
1934				("Must be one of: " .. tostring(table.concat(VALID_LUA_TARGETS, ", "))),
1935			}, "\n"))
1936		end
1937	elseif jit ~= nil then
1938		config.lua_target = "jit"
1939	else
1940		new_lua_target = _VERSION:match("Lua (%d%.%d)")
1941		if VALID_LUA_TARGETS[new_lua_target] then
1942			config.lua_target = new_lua_target
1943		else
1944			error(("Unsupported Lua version: " .. tostring(_VERSION)))
1945		end
1946	end
1947	for _, searcher in ipairs(searchers) do
1948		if searcher == erde_searcher then
1949			return
1950		end
1951	end
1952	table.insert(searchers, 2, erde_searcher)
1953end
1954_MODULE.load = load
1955local function unload()
1956	debug.traceback = native_traceback
1957	for i, searcher in ipairs(searchers) do
1958		if searcher == erde_searcher then
1959			table.remove(searchers, i)
1960			return
1961		end
1962	end
1963end
1964_MODULE.unload = unload
1965return _MODULE
1966-- Compiled with Erde 0.6.0-1
1967-- __ERDE_COMPILED__
1968end
1969end
1970
1971do
1972local _ENV = _ENV
1973package.preload[ "erde.stdlib" ] = function( ... ) local arg = _G.arg;
1974local _MODULE = {}
1975local _native_coroutine = coroutine
1976local coroutine = {}
1977_MODULE.coroutine = coroutine
1978local _native_debug = debug
1979local debug = {}
1980_MODULE.debug = debug
1981local _native_io = io
1982local io = {}
1983_MODULE.io = io
1984local _native_math = math
1985local math = {}
1986_MODULE.math = math
1987local _native_os = os
1988local os = {}
1989_MODULE.os = os
1990local _native_package = package
1991local package = {}
1992_MODULE.package = package
1993local _native_string = string
1994local string = {}
1995_MODULE.string = string
1996local _native_table = table
1997local table = {}
1998_MODULE.table = table
1999local function load()
2000	for key, value in pairs(_MODULE) do
2001		local value_type = type(value)
2002		if value_type == "function" then
2003			if key ~= "load" and key ~= "unload" then
2004				_G[key] = value
2005			end
2006		elseif value_type == "table" then
2007			local library = _G[key]
2008			if type(library) == "table" then
2009				for subkey, subvalue in pairs(value) do
2010					library[subkey] = subvalue
2011				end
2012			end
2013		end
2014	end
2015end
2016_MODULE.load = load
2017local function unload()
2018	for key, value in pairs(_MODULE) do
2019		local value_type = type(value)
2020		if value_type == "function" then
2021			if _G[key] == value then
2022				_G[key] = nil
2023			end
2024		elseif value_type == "table" then
2025			local library = _G[key]
2026			if type(library) == "table" then
2027				for subkey, subvalue in pairs(value) do
2028					if library[subkey] == subvalue then
2029						library[subkey] = nil
2030					end
2031				end
2032			end
2033		end
2034	end
2035end
2036_MODULE.unload = unload
2037local function _kpairs_iter(a, i)
2038	local key, value = i, nil
2039	repeat
2040		key, value = next(a, key)
2041	until type(key) ~= "number"
2042	return key, value
2043end
2044local function kpairs(t)
2045	return _kpairs_iter, t, nil
2046end
2047_MODULE.kpairs = kpairs
2048function io.exists(path)
2049	local file = io.open(path, "r")
2050	if file == nil then
2051		return false
2052	end
2053	file:close()
2054	return true
2055end
2056function io.readfile(path)
2057	local file = assert(io.open(path, "r"))
2058	local content = assert(file:read("*a"))
2059	file:close()
2060	return content
2061end
2062function io.writefile(path, content)
2063	local file = assert(io.open(path, "w"))
2064	assert(file:write(content))
2065	file:close()
2066end
2067function math.clamp(x, min, max)
2068	return math.min(math.max(x, min), max)
2069end
2070function math.round(x)
2071	if x < 0 then
2072		return math.ceil(x - 0.5)
2073	else
2074		return math.floor(x + 0.5)
2075	end
2076end
2077function math.sign(x)
2078	if x < 0 then
2079		return -1
2080	elseif x > 0 then
2081		return 1
2082	else
2083		return 0
2084	end
2085end
2086function os.capture(cmd)
2087	local file = assert(io.popen(cmd, "r"))
2088	local stdout = assert(file:read("*a"))
2089	file:close()
2090	return stdout
2091end
2092function package.cinsert(...)
2093	local templates = package.split(package.cpath)
2094	table.insert(templates, ...)
2095	package.cpath = package.concat(templates)
2096end
2097function package.concat(templates, i, j)
2098	local template_separator = string.split(package.config, "\n")[2]
2099	return table.concat(templates, template_separator, i, j)
2100end
2101function package.cremove(position)
2102	local templates = package.split(package.cpath)
2103	local removed = table.remove(templates, position)
2104	package.cpath = package.concat(templates)
2105	return removed
2106end
2107function package.insert(...)
2108	local templates = package.split(package.path)
2109	table.insert(templates, ...)
2110	package.path = package.concat(templates)
2111end
2112function package.remove(position)
2113	local templates = package.split(package.path)
2114	local removed = table.remove(templates, position)
2115	package.path = package.concat(templates)
2116	return removed
2117end
2118function package.split(path)
2119	local template_separator = string.split(package.config, "\n")[2]
2120	return string.split(path, template_separator)
2121end
2122local function _string_chars_iter(a, i)
2123	i = i + 1
2124	local char = a:sub(i, i)
2125	if char ~= "" then
2126		return i, char
2127	end
2128end
2129function string.chars(s)
2130	return _string_chars_iter, s, 0
2131end
2132function string.escape(s)
2133	local escaped = s:gsub("[().%%+%-*?[^$]", "%%%1")
2134	return escaped
2135end
2136function string.lpad(s, length, padding)
2137	if padding == nil then
2138		padding = " "
2139	end
2140	return padding:rep(math.ceil((length - #s) / #padding)) .. s
2141end
2142function string.ltrim(s, pattern)
2143	if pattern == nil then
2144		pattern = "%s+"
2145	end
2146	local trimmed = s:gsub(("^" .. tostring(pattern)), "")
2147	return trimmed
2148end
2149function string.pad(s, length, padding)
2150	if padding == nil then
2151		padding = " "
2152	end
2153	local num_pads = math.ceil(((length - #s) / #padding) / 2)
2154	return padding:rep(num_pads) .. s .. padding:rep(num_pads)
2155end
2156function string.rpad(s, length, padding)
2157	if padding == nil then
2158		padding = " "
2159	end
2160	return s .. padding:rep(math.ceil((length - #s) / #padding))
2161end
2162function string.rtrim(s, pattern)
2163	if pattern == nil then
2164		pattern = "%s+"
2165	end
2166	local trimmed = s:gsub((tostring(pattern) .. "$"), "")
2167	return trimmed
2168end
2169function string.split(s, separator)
2170	if separator == nil then
2171		separator = "%s+"
2172	end
2173	local result = {}
2174	local i, j = s:find(separator)
2175	while i ~= nil do
2176		table.insert(result, s:sub(1, i - 1))
2177		s = s:sub(j + 1) or ""
2178		i, j = s:find(separator)
2179	end
2180	table.insert(result, s)
2181	return result
2182end
2183function string.trim(s, pattern)
2184	if pattern == nil then
2185		pattern = "%s+"
2186	end
2187	return string.ltrim(string.rtrim(s, pattern), pattern)
2188end
2189if _VERSION == "Lua 5.1" then
2190	table.pack = function(...)
2191		return {
2192			n = select("#", ...),
2193			...,
2194		}
2195	end
2196	table.unpack = unpack
2197end
2198function table.clear(t, callback)
2199	if type(callback) == "function" then
2200		for key, value in kpairs(t) do
2201			if callback(value, key) then
2202				t[key] = nil
2203			end
2204		end
2205		for i = #t, 1, -1 do
2206			if callback(t[i], i) then
2207				table.remove(t, i)
2208			end
2209		end
2210	else
2211		for key, value in kpairs(t) do
2212			if value == callback then
2213				t[key] = nil
2214			end
2215		end
2216		for i = #t, 1, -1 do
2217			if t[i] == callback then
2218				table.remove(t, i)
2219			end
2220		end
2221	end
2222end
2223function table.collect(...)
2224	local result = {}
2225	for key, value in ... do
2226		if value == nil then
2227			table.insert(result, key)
2228		else
2229			result[key] = value
2230		end
2231	end
2232	return result
2233end
2234function table.deepcopy(t)
2235	local result = {}
2236	for key, value in pairs(t) do
2237		if type(value) == "table" then
2238			result[key] = table.deepcopy(value)
2239		else
2240			result[key] = value
2241		end
2242	end
2243	return result
2244end
2245function table.empty(t)
2246	return next(t) == nil
2247end
2248function table.filter(t, callback)
2249	local result = {}
2250	for key, value in pairs(t) do
2251		if callback(value, key) then
2252			if type(key) == "number" then
2253				table.insert(result, value)
2254			else
2255				result[key] = value
2256			end
2257		end
2258	end
2259	return result
2260end
2261function table.find(t, callback)
2262	if type(callback) == "function" then
2263		for key, value in pairs(t) do
2264			if callback(value, key) then
2265				return value, key
2266			end
2267		end
2268	else
2269		for key, value in pairs(t) do
2270			if value == callback then
2271				return value, key
2272			end
2273		end
2274	end
2275end
2276function table.has(t, callback)
2277	local _, key = table.find(t, callback)
2278	return key ~= nil
2279end
2280function table.keys(t)
2281	local result = {}
2282	for key, value in pairs(t) do
2283		table.insert(result, key)
2284	end
2285	return result
2286end
2287function table.map(t, callback)
2288	local result = {}
2289	for key, value in pairs(t) do
2290		local newValue, newKey = callback(value, key)
2291		if newKey ~= nil then
2292			result[newKey] = newValue
2293		elseif type(key) == "number" then
2294			table.insert(result, newValue)
2295		else
2296			result[key] = newValue
2297		end
2298	end
2299	return result
2300end
2301function table.merge(t, ...)
2302	for _, _t in pairs({
2303		...,
2304	}) do
2305		for key, value in pairs(_t) do
2306			if type(key) == "number" then
2307				table.insert(t, value)
2308			else
2309				t[key] = value
2310			end
2311		end
2312	end
2313end
2314function table.reduce(t, initial, callback)
2315	local result = initial
2316	for key, value in pairs(t) do
2317		result = callback(result, value, key)
2318	end
2319	return result
2320end
2321function table.reverse(t)
2322	local len = #t
2323	for i = 1, math.floor(len / 2) do
2324		t[i], t[len - i + 1] = t[len - i + 1], t[i]
2325	end
2326end
2327function table.shallowcopy(t)
2328	local result = {}
2329	for key, value in pairs(t) do
2330		result[key] = value
2331	end
2332	return result
2333end
2334function table.slice(t, i, j)
2335	if i == nil then
2336		i = 1
2337	end
2338	if j == nil then
2339		j = #t
2340	end
2341	local result, len = {}, #t
2342	if i < 0 then
2343		i = i + len + 1
2344	end
2345	if j < 0 then
2346		j = j + len + 1
2347	end
2348	for i = math.max(i, 0), math.min(j, len) do
2349		table.insert(result, t[i])
2350	end
2351	return result
2352end
2353function table.values(t)
2354	local result = {}
2355	for key, value in pairs(t) do
2356		table.insert(result, value)
2357	end
2358	return result
2359end
2360setmetatable(coroutine, {
2361	__index = _native_coroutine,
2362	__newindex = _native_coroutine,
2363})
2364setmetatable(debug, {
2365	__index = _native_debug,
2366	__newindex = _native_debug,
2367})
2368setmetatable(io, {
2369	__index = _native_io,
2370	__newindex = _native_io,
2371})
2372setmetatable(math, {
2373	__index = _native_math,
2374	__newindex = _native_math,
2375})
2376setmetatable(os, {
2377	__index = _native_os,
2378	__newindex = _native_os,
2379})
2380setmetatable(package, {
2381	__index = _native_package,
2382	__newindex = _native_package,
2383})
2384setmetatable(string, {
2385	__index = _native_string,
2386	__newindex = _native_string,
2387})
2388setmetatable(table, {
2389	__index = _native_table,
2390	__newindex = _native_table,
2391})
2392return _MODULE
2393-- Compiled with Erde 0.6.0-1
2394-- __ERDE_COMPILED__
2395end
2396end
2397
2398do
2399local _ENV = _ENV
2400package.preload[ "erde.tokenize" ] = function( ... ) local arg = _G.arg;
2401local config = require("erde.config")
2402local DIGIT, HEX, STANDARD_ESCAPE_CHARS, SYMBOLS, TOKEN_TYPES, WORD_BODY, WORD_HEAD
2403do
2404	local __ERDE_TMP_4__
2405	__ERDE_TMP_4__ = require("erde.constants")
2406	DIGIT = __ERDE_TMP_4__["DIGIT"]
2407	HEX = __ERDE_TMP_4__["HEX"]
2408	STANDARD_ESCAPE_CHARS = __ERDE_TMP_4__["STANDARD_ESCAPE_CHARS"]
2409	SYMBOLS = __ERDE_TMP_4__["SYMBOLS"]
2410	TOKEN_TYPES = __ERDE_TMP_4__["TOKEN_TYPES"]
2411	WORD_BODY = __ERDE_TMP_4__["WORD_BODY"]
2412	WORD_HEAD = __ERDE_TMP_4__["WORD_HEAD"]
2413end
2414local get_source_alias
2415do
2416	local __ERDE_TMP_7__
2417	__ERDE_TMP_7__ = require("erde.utils")
2418	get_source_alias = __ERDE_TMP_7__["get_source_alias"]
2419end
2420local tokenize_token
2421local tokens = {}
2422local text = ""
2423local current_char = ""
2424local current_char_index = 1
2425local current_line = 1
2426local source_name = ""
2427local function peek(n)
2428	return text:sub(current_char_index, current_char_index + n - 1)
2429end
2430local function look_ahead(n)
2431	return text:sub(current_char_index + n, current_char_index + n)
2432end
2433local function throw(message, line)
2434	if line == nil then
2435		line = current_line
2436	end
2437	error((tostring(source_name) .. ":" .. tostring(line) .. ": " .. tostring(message)), 0)
2438end
2439local function consume(n)
2440	if n == nil then
2441		n = 1
2442	end
2443	local consumed = n == 1 and current_char or peek(n)
2444	current_char_index = current_char_index + n
2445	current_char = text:sub(current_char_index, current_char_index)
2446	return consumed
2447end
2448local function newline()
2449	current_line = current_line + 1
2450	return consume()
2451end
2452local function tokenize_binary()
2453	consume(2)
2454	if current_char ~= "0" and current_char ~= "1" then
2455		throw("malformed binary")
2456	end
2457	local value = 0
2458	repeat
2459		value = 2 * value + tonumber(consume())
2460	until current_char ~= "0" and current_char ~= "1"
2461	table.insert(tokens, {
2462		type = TOKEN_TYPES.NUMBER,
2463		line = current_line,
2464		value = tostring(value),
2465	})
2466end
2467local function tokenize_decimal()
2468	local value = ""
2469	while DIGIT[current_char] do
2470		value = value .. consume()
2471	end
2472	if current_char == "." and DIGIT[look_ahead(1)] then
2473		value = value .. consume(2)
2474		while DIGIT[current_char] do
2475			value = value .. consume()
2476		end
2477	end
2478	if current_char == "e" or current_char == "E" then
2479		value = value .. consume()
2480		if current_char == "+" or current_char == "-" then
2481			value = value .. consume()
2482		end
2483		if not DIGIT[current_char] then
2484			throw("missing exponent value")
2485		end
2486		while DIGIT[current_char] do
2487			value = value .. consume()
2488		end
2489	end
2490	table.insert(tokens, {
2491		type = TOKEN_TYPES.NUMBER,
2492		line = current_line,
2493		value = value,
2494	})
2495end
2496local function tokenize_hex()
2497	consume(2)
2498	if not HEX[current_char] and not (current_char == "." and HEX[look_ahead(1)]) then
2499		throw("malformed hex")
2500	end
2501	local value = 0
2502	while HEX[current_char] do
2503		value = 16 * value + tonumber(consume(), 16)
2504	end
2505	if current_char == "." and HEX[look_ahead(1)] then
2506		consume()
2507		local counter = 1
2508		repeat
2509			value = value + tonumber(consume(), 16) / (16 ^ counter)
2510			counter = counter + 1
2511		until not HEX[current_char]
2512	end
2513	if current_char == "p" or current_char == "P" then
2514		consume()
2515		local exponent, sign = 0, 1
2516		if current_char == "+" or current_char == "-" then
2517			sign = sign * tonumber(consume() .. "1")
2518		end
2519		if not DIGIT[current_char] then
2520			throw("missing exponent value")
2521		end
2522		repeat
2523			exponent = 10 * exponent + tonumber(consume())
2524		until not DIGIT[current_char]
2525		value = value * 2 ^ (sign * exponent)
2526	end
2527	table.insert(tokens, {
2528		type = TOKEN_TYPES.NUMBER,
2529		line = current_line,
2530		value = tostring(value),
2531	})
2532end
2533local function escape_sequence()
2534	if STANDARD_ESCAPE_CHARS[current_char] then
2535		return consume()
2536	elseif DIGIT[current_char] then
2537		return consume()
2538	elseif current_char == "z" then
2539		if config.lua_target == "5.1" or config.lua_target == "5.1+" then
2540			throw("escape sequence \\z not compatible w/ lua targets 5.1, 5.1+")
2541		end
2542		return consume()
2543	elseif current_char == "x" then
2544		if config.lua_target == "5.1" or config.lua_target == "5.1+" then
2545			throw("escape sequence \\xXX not compatible w/ lua targets 5.1, 5.1+")
2546		end
2547		if not HEX[look_ahead(1)] or not HEX[look_ahead(2)] then
2548			throw("escape sequence \\xXX must use exactly 2 hex characters")
2549		end
2550		return consume(3)
2551	elseif current_char == "u" then
2552		if
2553			config.lua_target == "5.1"
2554			or config.lua_target == "5.1+"
2555			or config.lua_target == "5.2"
2556			or config.lua_target == "5.2+"
2557		then
2558			throw("escape sequence \\u{XXX} not compatible w/ lua targets 5.1, 5.1+, 5.2, 5.2+")
2559		end
2560		local sequence = consume()
2561		if current_char ~= "{" then
2562			throw("missing { in escape sequence \\u{XXX}")
2563		end
2564		sequence = sequence .. consume()
2565		if not HEX[current_char] then
2566			throw("missing hex in escape sequence \\u{XXX}")
2567		end
2568		while HEX[current_char] do
2569			sequence = sequence .. consume()
2570		end
2571		if current_char ~= "}" then
2572			throw("missing } in escape sequence \\u{XXX}")
2573		end
2574		return sequence .. consume()
2575	else
2576		throw(("invalid escape sequence \\" .. tostring(current_char)))
2577	end
2578end
2579local function tokenize_interpolation()
2580	table.insert(tokens, {
2581		type = TOKEN_TYPES.INTERPOLATION,
2582		line = current_line,
2583		value = consume(),
2584	})
2585	local interpolation_line = current_line
2586	local brace_depth = 0
2587	while current_char ~= "}" or brace_depth > 0 do
2588		if current_char == "{" then
2589			brace_depth = brace_depth + 1
2590			table.insert(tokens, {
2591				type = TOKEN_TYPES.SYMBOL,
2592				line = current_line,
2593				value = consume(),
2594			})
2595		elseif current_char == "}" then
2596			brace_depth = brace_depth - 1
2597			table.insert(tokens, {
2598				type = TOKEN_TYPES.SYMBOL,
2599				line = current_line,
2600				value = consume(),
2601			})
2602		elseif current_char == "" then
2603			throw("unterminated interpolation", interpolation_line)
2604		else
2605			tokenize_token()
2606		end
2607	end
2608	table.insert(tokens, {
2609		type = TOKEN_TYPES.INTERPOLATION,
2610		line = current_line,
2611		value = consume(),
2612	})
2613end
2614local function tokenize_single_quote_string()
2615	table.insert(tokens, {
2616		type = TOKEN_TYPES.SINGLE_QUOTE_STRING,
2617		line = current_line,
2618		value = consume(),
2619	})
2620	local content = ""
2621	while current_char ~= "'" do
2622		if current_char == "" or current_char == "\n" then
2623			throw("unterminated string")
2624		elseif current_char == "\\" then
2625			content = content .. consume() .. escape_sequence()
2626		else
2627			content = content .. consume()
2628		end
2629	end
2630	if content ~= "" then
2631		table.insert(tokens, {
2632			type = TOKEN_TYPES.STRING_CONTENT,
2633			line = current_line,
2634			value = content,
2635		})
2636	end
2637	table.insert(tokens, {
2638		type = TOKEN_TYPES.SINGLE_QUOTE_STRING,
2639		line = current_line,
2640		value = consume(),
2641	})
2642end
2643local function tokenize_double_quote_string()
2644	table.insert(tokens, {
2645		type = TOKEN_TYPES.DOUBLE_QUOTE_STRING,
2646		line = current_line,
2647		value = consume(),
2648	})
2649	local content, content_line = "", current_line
2650	while current_char ~= '"' do
2651		if current_char == "" or current_char == "\n" then
2652			throw("unterminated string")
2653		elseif current_char == "\\" then
2654			consume()
2655			if current_char == "{" or current_char == "}" then
2656				content = content .. consume()
2657			else
2658				content = content .. "\\" .. escape_sequence()
2659			end
2660		elseif current_char == "{" then
2661			if content ~= "" then
2662				table.insert(tokens, {
2663					type = TOKEN_TYPES.STRING_CONTENT,
2664					line = content_line,
2665					value = content,
2666				})
2667				content, content_line = "", current_line
2668			end
2669			tokenize_interpolation()
2670		else
2671			content = content .. consume()
2672		end
2673	end
2674	if content ~= "" then
2675		table.insert(tokens, {
2676			type = TOKEN_TYPES.STRING_CONTENT,
2677			line = content_line,
2678			value = content,
2679		})
2680	end
2681	table.insert(tokens, {
2682		type = TOKEN_TYPES.DOUBLE_QUOTE_STRING,
2683		line = current_line,
2684		value = consume(),
2685	})
2686end
2687local function tokenize_block_string()
2688	consume()
2689	local equals = ""
2690	while current_char == "=" do
2691		equals = equals .. consume()
2692	end
2693	if current_char ~= "[" then
2694		throw("unterminated block string opening", current_line)
2695	end
2696	consume()
2697	table.insert(tokens, {
2698		type = TOKEN_TYPES.BLOCK_STRING,
2699		line = current_line,
2700		value = "[" .. equals .. "[",
2701		equals = equals,
2702	})
2703	local close_quote = "]" .. equals .. "]"
2704	local close_quote_len = #close_quote
2705	local block_string_line = current_line
2706	local content, content_line = "", current_line
2707	while current_char ~= "]" or peek(close_quote_len) ~= close_quote do
2708		if current_char == "" then
2709			throw("unterminated block string", block_string_line)
2710		elseif current_char == "\n" then
2711			content = content .. newline()
2712		elseif current_char == "\\" then
2713			consume()
2714			if current_char == "{" or current_char == "}" then
2715				content = content .. consume()
2716			else
2717				content = content .. "\\"
2718			end
2719		elseif current_char == "{" then
2720			if content ~= "" then
2721				table.insert(tokens, {
2722					type = TOKEN_TYPES.STRING_CONTENT,
2723					line = content_line,
2724					value = content,
2725				})
2726				content, content_line = "", current_line
2727			end
2728			tokenize_interpolation()
2729		else
2730			content = content .. consume()
2731		end
2732	end
2733	if content ~= "" then
2734		table.insert(tokens, {
2735			type = TOKEN_TYPES.STRING_CONTENT,
2736			line = content_line,
2737			value = content,
2738		})
2739	end
2740	table.insert(tokens, {
2741		type = TOKEN_TYPES.BLOCK_STRING,
2742		line = current_line,
2743		value = consume(close_quote_len),
2744	})
2745end
2746local function tokenize_word()
2747	local word = consume()
2748	while WORD_BODY[current_char] do
2749		word = word .. consume()
2750	end
2751	table.insert(tokens, {
2752		type = TOKEN_TYPES.WORD,
2753		line = current_line,
2754		value = word,
2755	})
2756end
2757local function tokenize_comment()
2758	consume(2)
2759	local is_block_comment, equals = false, ""
2760	if current_char == "[" then
2761		consume()
2762		while current_char == "=" do
2763			equals = equals .. consume()
2764		end
2765		if current_char == "[" then
2766			consume()
2767			is_block_comment = true
2768		end
2769	end
2770	if not is_block_comment then
2771		while current_char ~= "" and current_char ~= "\n" do
2772			consume()
2773		end
2774	else
2775		local close_quote = "]" .. equals .. "]"
2776		local close_quote_len = #close_quote
2777		local comment_line = current_line
2778		while current_char ~= "]" or peek(close_quote_len) ~= close_quote do
2779			if current_char == "" then
2780				throw("unterminated comment", comment_line)
2781			elseif current_char == "\n" then
2782				newline()
2783			else
2784				consume()
2785			end
2786		end
2787		consume(close_quote_len)
2788	end
2789end
2790function tokenize_token()
2791	if current_char == "\n" then
2792		newline()
2793	elseif current_char == " " or current_char == "\t" then
2794		consume()
2795	elseif WORD_HEAD[current_char] then
2796		tokenize_word()
2797	elseif current_char == "'" then
2798		tokenize_single_quote_string()
2799	elseif current_char == '"' then
2800		tokenize_double_quote_string()
2801	else
2802		local peek_two = peek(2)
2803		if peek_two == "--" then
2804			tokenize_comment()
2805		elseif peek_two == "0x" or peek_two == "0X" then
2806			tokenize_hex()
2807		elseif peek_two == "0b" or peek_two == "0B" then
2808			tokenize_binary()
2809		elseif DIGIT[current_char] or (current_char == "." and DIGIT[look_ahead(1)]) then
2810			tokenize_decimal()
2811		elseif peek_two == "[[" or peek_two == "[=" then
2812			tokenize_block_string()
2813		elseif SYMBOLS[peek(3)] then
2814			table.insert(tokens, {
2815				type = TOKEN_TYPES.SYMBOL,
2816				line = current_line,
2817				value = consume(3),
2818			})
2819		elseif SYMBOLS[peek_two] then
2820			table.insert(tokens, {
2821				type = TOKEN_TYPES.SYMBOL,
2822				line = current_line,
2823				value = consume(2),
2824			})
2825		else
2826			table.insert(tokens, {
2827				type = TOKEN_TYPES.SYMBOL,
2828				line = current_line,
2829				value = consume(1),
2830			})
2831		end
2832	end
2833end
2834return function(new_text, new_source_name)
2835	tokens = {}
2836	text = new_text
2837	current_char = text:sub(1, 1)
2838	current_char_index = 1
2839	current_line = 1
2840	source_name = new_source_name or get_source_alias(text)
2841	if peek(2) == "#!" then
2842		local shebang = consume(2)
2843		while current_char ~= "" and current_char ~= "\n" do
2844			shebang = shebang .. consume()
2845		end
2846		table.insert(tokens, {
2847			type = TOKEN_TYPES.SHEBANG,
2848			line = current_line,
2849			value = shebang,
2850		})
2851	end
2852	while current_char ~= "" do
2853		tokenize_token()
2854	end
2855	table.insert(tokens, {
2856		type = TOKEN_TYPES.EOF,
2857		line = current_line,
2858		value = nil,
2859	})
2860	return tokens
2861end
2862-- Compiled with Erde 0.6.0-1
2863-- __ERDE_COMPILED__
2864end
2865end
2866
2867do
2868local _ENV = _ENV
2869package.preload[ "erde.utils" ] = function( ... ) local arg = _G.arg;
2870local _MODULE = {}
2871local PATH_SEPARATOR
2872do
2873	local __ERDE_TMP_2__
2874	__ERDE_TMP_2__ = require("erde.constants")
2875	PATH_SEPARATOR = __ERDE_TMP_2__["PATH_SEPARATOR"]
2876end
2877local io, string
2878do
2879	local __ERDE_TMP_5__
2880	__ERDE_TMP_5__ = require("erde.stdlib")
2881	io = __ERDE_TMP_5__["io"]
2882	string = __ERDE_TMP_5__["string"]
2883end
2884local function echo(...)
2885	return ...
2886end
2887_MODULE.echo = echo
2888local function join_paths(...)
2889	local joined = table.concat({
2890		...,
2891	}, PATH_SEPARATOR):gsub(PATH_SEPARATOR .. "+", PATH_SEPARATOR)
2892	return joined
2893end
2894_MODULE.join_paths = join_paths
2895local function get_source_summary(source)
2896	local summary = string.trim(source):sub(1, 5)
2897	if #source > 5 then
2898		summary = summary .. "..."
2899	end
2900	return summary
2901end
2902_MODULE.get_source_summary = get_source_summary
2903local function get_source_alias(source)
2904	return ('[string "' .. tostring(get_source_summary(source)) .. '"]')
2905end
2906_MODULE.get_source_alias = get_source_alias
2907return _MODULE
2908-- Compiled with Erde 0.6.0-1
2909-- __ERDE_COMPILED__
2910end
2911end
2912

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.