aboutsummaryrefslogtreecommitdiff
path: root/nomsu.lua
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-01-08 18:53:57 -0800
committerBruce Hill <bitbucket@bruce-hill.com>2018-01-08 18:53:57 -0800
commitf97ab858edae5495f8ebfef46656e86150665888 (patch)
treeed47620eba2365192ba54950647d6307223cac29 /nomsu.lua
parent568a44ef191e1f4072d379700e3b6f599150a92b (diff)
Modernized the codebase a bit to include "immediately:" for immediately
running code before further parsing takes place. That means that in the default case, whole files can be run at once, which makes all but the weirdest edge cases make a lot more sense and operate smoothly.
Diffstat (limited to 'nomsu.lua')
-rw-r--r--nomsu.lua371
1 files changed, 199 insertions, 172 deletions
diff --git a/nomsu.lua b/nomsu.lua
index 730ab13..39e83fc 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -194,7 +194,7 @@ do
self:write_err(...)
return self:write_err("\n")
end,
- def = function(self, signature, thunk, src, is_macro)
+ def = function(self, signature, fn, src, is_macro)
if is_macro == nil then
is_macro = false
end
@@ -205,13 +205,13 @@ do
elseif type(signature) == 'table' and type(signature[1]) == 'string' then
signature = self:get_stubs(signature)
end
- self:assert(type(thunk) == 'function', "Bad thunk: " .. tostring(repr(thunk)))
+ self:assert(type(fn) == 'function', "Bad fn: " .. tostring(repr(fn)))
local canonical_args = nil
local canonical_escaped_args = nil
local aliases = { }
self.__class.def_number = self.__class.def_number + 1
local def = {
- thunk = thunk,
+ fn = fn,
src = src,
is_macro = is_macro,
aliases = { },
@@ -256,8 +256,8 @@ do
rawset(where_defs_go, stub, stub_def)
end
end,
- defmacro = function(self, signature, thunk, src)
- return self:def(signature, thunk, src, true)
+ defmacro = function(self, signature, fn, src)
+ return self:def(signature, fn, src, true)
end,
scoped = function(self, thunk)
local old_defs = self.defs
@@ -363,8 +363,8 @@ do
if not (def.is_macro) then
self:assert_permission(stub)
end
- local thunk, arg_names
- thunk, arg_names = def.thunk, def.arg_names
+ local fn, arg_names
+ fn, arg_names = def.fn, def.arg_names
local args
do
local _tbl_0 = { }
@@ -375,12 +375,15 @@ do
end
if self.debug then
self:write(tostring(colored.bright("CALLING")) .. " " .. tostring(colored.magenta(colored.underscore(stub))) .. " ")
- self:writeln(tostring(colored.bright("WITH ARGS:")) .. " " .. tostring(colored.dim(repr(args))))
+ self:writeln(tostring(colored.bright("WITH ARGS:")))
+ for name, value in pairs(args) do
+ self:writeln(" " .. tostring(colored.bright("* " .. tostring(name))) .. " = " .. tostring(colored.dim(repr(value))))
+ end
end
local old_defs
old_defs, self.defs = self.defs, def.defs
local rets = {
- thunk(self, args)
+ fn(self, args)
}
self.defs = old_defs
remove(self.callstack)
@@ -406,9 +409,9 @@ do
self:writeln(tostring(colored.bright("WITH ARGS:")) .. " " .. tostring(colored.dim(repr(args))))
end
insert(self.callstack, "#macro")
- local expr, statement = self:call(tree.stub, tree.line_no, unpack(args))
+ local ret = self:call(tree.stub, tree.line_no, unpack(args))
remove(self.callstack)
- return expr, statement
+ return ret
end,
dedent = function(self, code)
if not (code:find("\n")) then
@@ -448,8 +451,11 @@ do
return (code:gsub("\n" .. (" "):rep(indent_spaces), "\n "))
end
end,
- indent = function(self, code)
- return (code:gsub("\n", "\n "))
+ indent = function(self, code, levels)
+ if levels == nil then
+ levels = 1
+ end
+ return code:gsub("\n", "\n" .. (" "):rep(levels))
end,
assert_permission = function(self, stub)
local fn_def = self.defs[stub]
@@ -525,72 +531,46 @@ do
debug.sethook(timeout, "", max_operations)
end
local tree = self:parse(src, filename)
- self:assert(tree, "Tree failed to compile: " .. tostring(src))
+ self:assert(tree, "Failed to parse: " .. tostring(src))
self:assert(tree.type == "File", "Attempt to run non-file: " .. tostring(tree.type))
- local buffer = { }
- local _list_0 = tree.value
- for _index_0 = 1, #_list_0 do
- local statement = _list_0[_index_0]
- if self.debug then
- self:writeln(tostring(colored.bright("RUNNING NOMSU:")) .. "\n" .. tostring(colored.bright(colored.yellow(statement.src))))
- self:writeln(colored.bright("PARSED TO TREE:"))
- self:print_tree(statement)
- end
- local ok, expr, statements = pcall(self.tree_to_lua, self, statement, filename)
- if not ok then
- self:errorln(tostring(colored.red("Error occurred in statement:")) .. "\n" .. tostring(colored.bright(colored.yellow(statement.src))))
- error(expr)
- end
- local code_for_statement = ([[return (function(nomsu, vars)
-%s
-end);]]):format(statements or ("return " .. expr .. ";"))
- if output_file then
- if statements and #statements > 0 then
- output_file:write("lua> \"..\"\n " .. tostring(self:indent(statements:gsub("\\", "\\\\"))) .. "\n")
- end
- if expr and #expr > 0 then
- output_file:write("=lua \"..\"\n " .. tostring(self:indent(expr:gsub("\\", "\\\\"))) .. "\n")
- end
- end
- if self.debug then
- self:writeln(tostring(colored.bright("RUNNING LUA:")) .. "\n" .. tostring(colored.blue(colored.bright(code_for_statement))))
- end
- local lua_thunk, err = load(code_for_statement)
- if not lua_thunk then
- local n = 1
- local fn
- fn = function()
- n = n + 1
- return ("\n%-3d|"):format(n)
- end
- local code = "1 |" .. code_for_statement:gsub("\n", fn)
- error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(colored.onblack(code)))) .. "\n\n" .. tostring(err) .. "\n\nProduced by statement:\n" .. tostring(colored.bright(colored.yellow(statement.src))))
- end
- local run_statement = lua_thunk()
- local ret
- ok, ret = pcall(run_statement, self, vars)
- if not ok then
- self:errorln(tostring(colored.red("Error occurred in statement:")) .. "\n" .. tostring(colored.yellow(statement.src)))
- self:errorln(debug.traceback())
- error(ret)
- end
- if statements then
- insert(buffer, statements)
- end
- if expr then
- insert(buffer, tostring(expr) .. ";")
- end
- end
+ local lua = self:tree_to_lua(tree)
+ local lua_code = lua.statements or (lua.expr .. ";")
+ local ret = self:run_lua(lua_code, vars)
if max_operations then
debug.sethook()
end
- local lua_code = ([[return (function(nomsu, vars)
-%s
-end);]]):format(concat(buffer, "\n"))
- return nil, lua_code, vars
+ if output_file then
+ output_file:write(lua_code)
+ end
+ return ret, lua_code, vars
+ end,
+ run_lua = function(self, lua_code, vars)
+ if vars == nil then
+ vars = { }
+ end
+ local load_lua_fn, err = load(([[return function(nomsu, vars)
+ %s
+end]]):format(lua_code))
+ if not load_lua_fn then
+ local n = 1
+ local fn
+ fn = function()
+ n = n + 1
+ return ("\n%-3d|"):format(n)
+ end
+ local code = "1 |" .. lua_code:gsub("\n", fn)
+ self:error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(colored.onblack(code)))) .. "\n\n" .. tostring(err))
+ end
+ local run_lua_fn = load_lua_fn()
+ local ok, ret = pcall(run_lua_fn, self, vars)
+ if not ok then
+ self:errorln(debug.traceback())
+ self:error(ret)
+ end
+ return ret
end,
tree_to_value = function(self, tree, vars, filename)
- local code = "return (function(nomsu, vars)\nreturn " .. tostring(self:tree_to_lua(tree, filename)) .. ";\nend);"
+ local code = "return (function(nomsu, vars)\nreturn " .. tostring(self:tree_to_lua(tree, filename).expr) .. ";\nend);"
if self.debug then
self:writeln(tostring(colored.bright("RUNNING LUA TO GET VALUE:")) .. "\n" .. tostring(colored.blue(colored.bright(code))))
end
@@ -625,9 +605,9 @@ end);]]):format(concat(buffer, "\n"))
elseif "Nomsu" == _exp_0 then
local inside, inline = self:tree_to_nomsu(tree.value, force_inline)
return "\\" .. tostring(inside), inline
- elseif "Thunk" == _exp_0 then
+ elseif "Block" == _exp_0 then
if force_inline then
- return "{" .. tostring(concat((function()
+ return "(:" .. tostring(concat((function()
local _accum_0 = { }
local _len_0 = 1
local _list_0 = tree.value
@@ -637,7 +617,7 @@ end);]]):format(concat(buffer, "\n"))
_len_0 = _len_0 + 1
end
return _accum_0
- end)(), "; ")), true
+ end)(), "; ")) .. ")", true
else
return ":" .. self:indent("\n" .. concat((function()
local _accum_0 = { }
@@ -739,7 +719,7 @@ end);]]):format(concat(buffer, "\n"))
return longbuff, false
end
elseif "Dict" == _exp_0 then
- return error("Sorry, not yet implemented.")
+ return self:error("Sorry, not yet implemented.")
elseif "Number" == _exp_0 then
return repr(tree.value), true
elseif "Var" == _exp_0 then
@@ -771,7 +751,7 @@ end);]]):format(concat(buffer, "\n"))
return _accum_0
end)(), ", ")) .. "]"
else
- return "(d{" .. tostring(concat((function()
+ return "{" .. tostring(concat((function()
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(value) do
@@ -779,7 +759,7 @@ end);]]):format(concat(buffer, "\n"))
_len_0 = _len_0 + 1
end
return _accum_0
- end)(), "; ")) .. "})"
+ end)(), ", ")) .. "}"
end
elseif "string" == _exp_0 then
if value == "\n" then
@@ -801,49 +781,59 @@ end);]]):format(concat(buffer, "\n"))
end
local _exp_0 = tree.type
if "File" == _exp_0 then
+ if #tree.value == 1 then
+ return self:tree_to_lua(tree.value[1], filename)
+ end
local lua_bits = { }
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local line = _list_0[_index_0]
- local expr, statement = self:tree_to_lua(line, filename)
- if statement then
- insert(lua_bits, statement)
+ local lua = self:tree_to_lua(line, filename)
+ if not lua then
+ self:error("No lua produced by " .. tostring(repr(line)))
+ end
+ if lua.statements then
+ insert(lua_bits, lua.statements)
end
- if expr then
- insert(lua_bits, tostring(expr) .. ";")
+ if lua.expr then
+ insert(lua_bits, tostring(lua.expr) .. ";")
end
end
- return nil, concat(lua_bits, "\n")
+ return {
+ statements = concat(lua_bits, "\n")
+ }
elseif "Nomsu" == _exp_0 then
- return "nomsu:parse(" .. tostring(repr(tree.value.src)) .. ", " .. tostring(repr(tree.line_no)) .. ").value[1]", nil
- elseif "Thunk" == _exp_0 then
+ return {
+ expr = "nomsu:parse(" .. tostring(repr(tree.value.src)) .. ", " .. tostring(repr(tree.line_no)) .. ").value[1]"
+ }
+ elseif "Block" == _exp_0 then
local lua_bits = { }
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local arg = _list_0[_index_0]
- local expr, statement = self:tree_to_lua(arg, filename)
- if #tree.value == 1 and expr and not statement then
- return ([[(function(nomsu, vars)
- return %s;
-end)]]):format(expr)
+ local lua = self:tree_to_lua(arg, filename)
+ if #tree.value == 1 and lua.expr and not lua.statements then
+ return {
+ expr = lua.expr
+ }
end
- if statement then
- insert(lua_bits, statement)
+ if lua.statements then
+ insert(lua_bits, lua.statements)
end
- if expr then
- insert(lua_bits, tostring(expr) .. ";")
+ if lua.expr then
+ insert(lua_bits, tostring(lua.expr) .. ";")
end
end
- return ([[(function(nomsu, vars)
-%s
-end)]]):format(concat(lua_bits, "\n"))
+ return {
+ statements = concat(lua_bits, "\n")
+ }
elseif "FunctionCall" == _exp_0 then
insert(self.compilestack, tree)
local def = self.defs[tree.stub]
if def and def.is_macro then
- local expr, statement = self:run_macro(tree)
+ local lua = self:run_macro(tree)
remove(self.compilestack)
- return expr, statement
+ return lua
elseif not def and self.__class.math_patt:match(tree.stub) then
local bits = { }
local _list_0 = tree.value
@@ -852,12 +842,15 @@ end)]]):format(concat(lua_bits, "\n"))
if tok.type == "Word" then
insert(bits, tok.value)
else
- local expr, statement = self:tree_to_lua(tok, filename)
- self:assert(statement == nil, "non-expression value inside math expression")
- insert(bits, expr)
+ local lua = self:tree_to_lua(tok, filename)
+ self:assert(lua.statements == nil, "non-expression value inside math expression")
+ insert(bits, lua.expr)
end
end
- return "(" .. tostring(concat(bits, " ")) .. ")"
+ remove(self.compilestack)
+ return {
+ expr = "(" .. tostring(concat(bits, " ")) .. ")"
+ }
end
local args = {
repr(tree.stub),
@@ -894,11 +887,11 @@ end)]]):format(concat(lua_bits, "\n"))
if escaped_args[arg_names[arg_num]] then
insert(args, "nomsu:parse(" .. tostring(repr(arg.src)) .. ", " .. tostring(repr(tree.line_no)) .. ").value[1]")
else
- local expr, statement = self:tree_to_lua(arg, filename)
- if statement then
+ local lua = self:tree_to_lua(arg, filename)
+ if lua.statements then
self:error("Cannot use [[" .. tostring(arg.src) .. "]] as a function argument, since it's not an expression.")
end
- insert(args, expr)
+ insert(args, lua.expr)
end
arg_num = arg_num + 1
_continue_0 = true
@@ -908,7 +901,9 @@ end)]]):format(concat(lua_bits, "\n"))
end
end
remove(self.compilestack)
- return self.__class:comma_separated_items("nomsu:call(", args, ")"), nil
+ return {
+ expr = self.__class:comma_separated_items("nomsu:call(", args, ")")
+ }
elseif "String" == _exp_0 then
local concat_parts = { }
local string_buffer = ""
@@ -926,16 +921,16 @@ end)]]):format(concat(lua_bits, "\n"))
insert(concat_parts, repr(string_buffer))
string_buffer = ""
end
- local expr, statement = self:tree_to_lua(bit, filename)
+ local lua = self:tree_to_lua(bit, filename)
if self.debug then
self:writeln((colored.bright("INTERP:")))
self:print_tree(bit)
- self:writeln(tostring(colored.bright("EXPR:")) .. " " .. tostring(expr) .. ", " .. tostring(colored.bright("STATEMENT:")) .. " " .. tostring(statement))
+ self:writeln(tostring(colored.bright("EXPR:")) .. " " .. tostring(lua.expr) .. ", " .. tostring(colored.bright("STATEMENT:")) .. " " .. tostring(lua.statements))
end
- if statement then
+ if lua.statements then
self:error("Cannot use [[" .. tostring(bit.src) .. "]] as a string interpolation value, since it's not an expression.")
end
- insert(concat_parts, "nomsu:stringify(" .. tostring(expr) .. ")")
+ insert(concat_parts, "nomsu:stringify(" .. tostring(lua.expr) .. ")")
_continue_0 = true
until true
if not _continue_0 then
@@ -946,57 +941,75 @@ end)]]):format(concat(lua_bits, "\n"))
insert(concat_parts, repr(string_buffer))
end
if #concat_parts == 0 then
- return "''", nil
+ return {
+ expr = "''"
+ }
elseif #concat_parts == 1 then
- return concat_parts[1], nil
+ return {
+ expr = concat_parts[1]
+ }
else
- return "(" .. tostring(concat(concat_parts, "..")) .. ")", nil
+ return {
+ expr = "(" .. tostring(concat(concat_parts, "..")) .. ")"
+ }
end
elseif "List" == _exp_0 then
local items = { }
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local item = _list_0[_index_0]
- local expr, statement = self:tree_to_lua(item, filename)
- if statement then
+ local lua = self:tree_to_lua(item, filename)
+ if lua.statements then
self:error("Cannot use [[" .. tostring(item.src) .. "]] as a list item, since it's not an expression.")
end
- insert(items, expr)
+ insert(items, lua.expr)
end
- return self.__class:comma_separated_items("{", items, "}"), nil
+ return {
+ expr = self.__class:comma_separated_items("{", items, "}")
+ }
elseif "Dict" == _exp_0 then
local items = { }
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local entry = _list_0[_index_0]
- local key_expr, key_statement
+ local key_lua
if entry.dict_key.type == "Word" then
- key_expr, key_statement = repr(entry.dict_key.value), nil
+ key_lua = {
+ expr = repr(entry.dict_key.value)
+ }
else
- key_expr, key_statement = self:tree_to_lua(entry.dict_key, filename)
+ key_lua = self:tree_to_lua(entry.dict_key, filename)
end
- if key_statement then
+ if key_lua.statements then
self:error("Cannot use [[" .. tostring(entry.dict_key.src) .. "]] as a dict key, since it's not an expression.")
end
- local value_expr, value_statement = self:tree_to_lua(entry.dict_value, filename)
- if value_statement then
+ local value_lua = self:tree_to_lua(entry.dict_value, filename)
+ if value_lua.statements then
self:error("Cannot use [[" .. tostring(entry.dict_value.src) .. "]] as a dict value, since it's not an expression.")
end
- local key_str = key_expr:match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
+ local key_str = key_lua.expr:match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
if key_str then
- insert(items, tostring(key_str) .. "=" .. tostring(value_expr))
+ insert(items, tostring(key_str) .. "=" .. tostring(value_lua.expr))
else
- insert(items, "[" .. tostring(key_expr) .. "]=" .. tostring(value_expr))
+ insert(items, "[" .. tostring(key_lua.expr) .. "]=" .. tostring(value_lua.expr))
end
end
- return self.__class:comma_separated_items("{", items, "}"), nil
+ return {
+ expr = self.__class:comma_separated_items("{", items, "}")
+ }
elseif "Number" == _exp_0 then
- return repr(tree.value), nil
+ return {
+ expr = repr(tree.value)
+ }
elseif "Var" == _exp_0 then
if tree.value:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
- return "vars." .. tostring(tree.value), nil
+ return {
+ expr = "vars." .. tostring(tree.value)
+ }
else
- return "vars[" .. tostring(repr(tree.value)) .. "]", nil
+ return {
+ expr = "vars[" .. tostring(repr(tree.value)) .. "]"
+ }
end
else
return self:error("Unknown/unimplemented thingy: " .. tostring(tree.type))
@@ -1011,7 +1024,7 @@ end)]]):format(concat(lua_bits, "\n"))
return
end
local _exp_0 = tree.type
- if "List" == _exp_0 or "File" == _exp_0 or "Thunk" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
+ if "List" == _exp_0 or "File" == _exp_0 or "Block" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
@@ -1064,7 +1077,7 @@ end)]]):format(concat(lua_bits, "\n"))
if vars[tree.value] ~= nil then
tree = vars[tree.value]
end
- elseif "File" == _exp_0 or "Nomsu" == _exp_0 or "Thunk" == _exp_0 or "List" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
+ elseif "File" == _exp_0 or "Nomsu" == _exp_0 or "Block" == _exp_0 or "List" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
local new_value = self:replaced_vars(tree.value, vars)
if new_value ~= tree.value then
do
@@ -1281,43 +1294,52 @@ end)]]):format(concat(lua_bits, "\n"))
if type(bit) == "string" then
insert(concat_parts, bit)
else
- local expr, statement = self:tree_to_lua(bit, filename)
- if statement then
+ local lua = self:tree_to_lua(bit, filename)
+ if lua.statements then
self:error("Cannot use [[" .. tostring(bit.src) .. "]] as a string interpolation value, since it's not an expression.")
end
- insert(concat_parts, expr)
+ insert(concat_parts, lua.expr)
end
end
return concat(concat_parts)
end
- local lua_code
- lua_code = function(self, vars)
+ self:defmacro("do %block", function(self, vars)
+ local make_line
+ make_line = function(lua)
+ return lua.expr and (lua.expr .. ";") or lua.statements
+ end
+ if vars.block.type == "Block" then
+ return self:tree_to_lua(vars.block)
+ else
+ return {
+ expr = tostring(self:tree_to_lua(vars.block)) .. "(nomsu, vars)"
+ }
+ end
+ end)
+ self:defmacro("immediately %block", function(self, vars)
+ local lua = self:tree_to_lua(vars.block)
+ local lua_code = lua.statements or (lua.expr .. ";")
+ self:run_lua(lua_code, vars)
+ return {
+ statements = lua_code
+ }
+ end)
+ self:defmacro("lua> %code", function(self, vars)
local lua = nomsu_string_as_lua(self, vars.code)
- return nil, lua
- end
- self:defmacro("lua> %code", lua_code)
- local lua_value
- lua_value = function(self, vars)
+ return {
+ statements = lua
+ }
+ end)
+ self:defmacro("=lua %code", function(self, vars)
local lua = nomsu_string_as_lua(self, vars.code)
- return lua, nil
- end
- self:defmacro("=lua %code", lua_value)
- self:defmacro("__src__ %level", function(self, vars)
- return self:repr(self:source_code(self:tree_to_value(vars.level)))
+ return {
+ expr = lua
+ }
end)
- self:def("derp \\%foo derp \\%bar", function(self, vars)
- local lua = "local x = " .. repr((function()
- local _accum_0 = { }
- local _len_0 = 1
- local _list_0 = vars.foo.value
- for _index_0 = 1, #_list_0 do
- local t = _list_0[_index_0]
- _accum_0[_len_0] = t.stub
- _len_0 = _len_0 + 1
- end
- return _accum_0
- end)()) .. ";\nlocal y = " .. self:tree_to_lua(vars.bar)
- return print(colored.green(lua))
+ self:defmacro("__src__ %level", function(self, vars)
+ return {
+ expr = repr(self:source_code(self:tree_to_value(vars.level)))
+ }
end)
local run_file
run_file = function(self, vars)
@@ -1340,17 +1362,19 @@ end)]]):format(concat(lua_bits, "\n"))
end
end
self:def("run file %filename", run_file)
- local _require
- _require = function(self, vars)
+ return self:defmacro("require %filename", function(self, vars)
+ local filename = self:tree_to_value(vars.filename)
local loaded = self.defs["#loaded_files"]
- if not loaded[vars.filename] then
- loaded[vars.filename] = run_file(self, {
- filename = vars.filename
+ if not loaded[filename] then
+ loaded[filename] = run_file(self, {
+ filename = filename
}) or true
end
- return loaded[vars.filename]
- end
- return self:def("require %filename", _require)
+ local _ = loaded[filename]
+ return {
+ statements = ""
+ }
+ end)
end
}
_base_0.__index = _base_0
@@ -1476,7 +1500,10 @@ if arg then
input = io.open(args.input):read("*a")
end
local vars = { }
- local retval, code = c:run(input, args.input, vars, nil, compiled_output)
+ local retval, code = c:run(input, args.input, vars)
+ if args.output then
+ compiled_output:write("lua> \"..\"\n " .. c:indent(code:gsub("\\", "\\\\"), 1))
+ end
end
if args.flags["-p"] then
c.write = _write