aboutsummaryrefslogtreecommitdiff

– 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