-- This file contains a set of compile actions needed for bootstrapping {:match, :sub, :gsub, :format, :byte, :find} = string {:LuaCode, :Source} = require "code_obj" SyntaxTree = require "syntax_tree" Files = require "files" {:fail_at} = require('nomsu_compiler') MAX_LINE = 80 -- For beautification purposes, try not to make lines much longer than this value compile_actions = { [""]: (_t, fn, ...)=> lua = LuaCode! fn_lua = @compile(fn) lua\add fn_lua unless fn_lua\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