– This file contains a set of compile actions needed for bootstrapping {:match, :sub, :gsub, :format, :byte, :find} = string {:LuaCode, :Source} = require “codeobj” SyntaxTree = require “syntaxtree” Files = require “files”
{:failat} = require(‘nomsucompiler’)
MAXLINE = 80 – For beautification purposes, try not to make lines much longer than this value compileactions = { [““]: (t, fn, …)=> lua = LuaCode! fnlua = @compile(fn) lua\add fnlua unless fnlua\text!\match(“^%(.%)$”) or fn_lua\text!\match(“^[a-zA-Z][a-zA-Z0-9.]$”) lua\parenthesize! lua\add “(“ for i=1,select(‘#’,…) lua\add(“, “) if i > 1 lua\add @compile((select(i, …))) lua\add “)” return lua
["Lua"]: (_t, code)=>
if not code
return LuaCode("LuaCode()")
if code.type != "Text"
return LuaCode("LuaCode:from(", tostring(code.source)\as_lua!, ", ", @compile(code), ")")
operate_on_text = (text)->
lua = LuaCode\from(text.source, "LuaCode:from(", tostring(text.source)\as_lua!)
for bit in *text
local bit_lua
if type(bit) == "string"
bit_lua = bit\as_lua!
elseif bit.type == "Text"
bit_lua = operate_on_text(bit)
elseif bit.type == "Block"
bit_lua = LuaCode\from bit.source, "(function()",
"\n local _lua = LuaCode:from(", tostring(bit.source)\as_lua!, ")",
"\n local function add(...) _lua:add(...) end",
"\n local function join_with(glue)",
"\n local old_bits = _lua.bits",
"\n _lua = LuaCode:from(_lua.source)",
"\n _lua:concat_add(old_bits, glue)",
"\n end",
"\n ", @compile(bit),
"\n return _lua",
"\nend)()"
else
bit_lua = @compile(bit)
bit_leading_len = #(bit_lua\match("^[^\n]*"))
lua\add(lua\trailing_line_len! + bit_leading_len > MAX_LINE and ",\n " or ", ")
lua\add(bit_lua)
lua\add ")"
return lua
return operate_on_text code
["lua >"]: (_t, code)=>
if code.type != "Text"
return code
operate_on_text = (text)->
lua = LuaCode\from(text.source)
for bit in *text
if type(bit) == "string"
lua\add bit
elseif bit.type == "Text"
lua\add(operate_on_text(bit))
else
lua\add @compile(bit)
return lua
return operate_on_text code
["= lua"]: (_t, code)=>
@compile(SyntaxTree{type:"Action", "lua", ">", code})
["1 as lua"]: (_t, code)=>
LuaCode("_ENV:compile(", @compile(code), ")")
["use"]: (_t, path)=>
LuaCode("_ENV:use(#{@compile(path)})")
["export"]: (_t, path)=>
LuaCode("_ENV:export(#{@compile(path)})")
["run"]: (_t, path)=>
LuaCode("_ENV:run(#{@compile(path)})")
["test"]: (_t, body)=>
unless body.type == 'Block'
fail_at(body, "Compile error: This should be a Block")
test_nomsu = body\get_source_code!\match(":[ ]*(.*)")
if indent = test_nomsu\match("\n([ ]*)")
test_nomsu = test_nomsu\gsub("\n"..indent, "\n")
test_text = @compile(SyntaxTree{type:"Text", source:body.source, test_nomsu})
return LuaCode "TESTS[#{tostring(body.source)\as_lua!}] = ", test_text
["is jit"]: (_t, code)=> LuaCode("jit")
["nomsu environment"]: (_t)=> LuaCode("_ENV")
["nomsu environment name"]: (_t)=> LuaCode('"_ENV"')
["Lua version"]: (_t)=> LuaCode("LUA_API")
["this file was run directly"]: (_t)=> LuaCode('WAS_RUN_DIRECTLY')
["the command line arguments"]: (_t)=> LuaCode('COMMAND_LINE_ARGS')
}
return compile_actions
