Fri, 15 Oct 2010 15:17:17 +0100
Initial commit
local t = { op = {}, keyword = {}, name = {}, eos = {}, string = {}, regex = {} }; local debug = function (...) io.stderr:write(table.concat({...}, "\t")); io.stderr:write"\n";end; local debug = function () end local function read_balanced(tokens, start, left, right) local c = 0; for i=start,#tokens do if tokens[i].type == "op" then local token = tokens[i].value; if token == left then c = c + 1; elseif token == right then c = c - 1; end end if c == 0 then return i; end end return start; end local pair_op = { ["("] = ")", ["{"] = "}", ["["] = "]" }; local function read_balanced_to(tokens, start, to) local c = 0; local i = start; while i <= #tokens do if tokens[i].type == "op" or tokens[i].type == "eos" then local token = tokens[i].value; if token == to then return i; end if pair_op[token] then i = read_balanced(tokens, i, token, pair_op[token]); end end i = i + 1; end return nil; end function js2lua(tokens, write) -- Scan local i = 1; while i <= #tokens do local token = tokens[i]; debug(token.type, token.value); if token.type == "keyword" and token.value == "function" then local j = read_balanced_to(tokens, i+3, ")"); -- Find matching ) j = j + 1; -- j now points to { local k = read_balanced_to(tokens, j+1, "}"); table.remove(tokens, j); -- Remove { tokens[k-1].type, tokens[k-1].value = "keyword", "end"; elseif token.type == "keyword" and token.value == "if" then table.remove(tokens, i+1); -- Remove ( local j = read_balanced_to(tokens, i, ")"); tokens[j].type, tokens[j].value = "keyword", "then"; -- Make sure to end a single-statement block if tokens[j+1].type ~= "op" or tokens[j+1].value ~= "{" then local eos = read_balanced_to(tokens, j+1, ";"); if tokens[eos+1].type ~= "keyword" or tokens[eos+1].value ~= "else" then table.insert(tokens, eos+1, { type = "keyword", value = "end" }); end end elseif token.type == "keyword" and token.value == "else" then if tokens[i+1].type == "keyword" and tokens[i+1].value == "if" then token.value = "elseif"; table.remove(tokens, i+1); table.remove(tokens, i+1); -- Remove ( local j = read_balanced_to(tokens, i, ")"); tokens[j].type, tokens[j].value = "keyword", "then"; end -- Make sure to end a single-statement block if tokens[i+1].type ~= "op" or tokens[i+1].value ~= "{" then local eos = read_balanced_to(tokens, i+1, ";"); if tokens[eos+1].type ~= "keyword" or tokens[eos+1].value ~= "else" then table.insert(tokens, eos+1, { type = "keyword", value = "end" }); end end elseif token.type == "op" and token.value == "+" and tokens[i-1].type == "string" then token.value = ".."; elseif token.type == "op" and token.value == "{" then elseif token.type == "keyword" and token.value == "var" then token.value = "local"; end i = i + 1; end -- Serialize local last_token_type; for _, token in ipairs(tokens) do if token.type == "string" then write("\""); elseif token.type == "name" then if last_token_type == "keyword" or last_token_type == "name" or last_token_type == "number" then write(" "); end elseif token.type == "keyword" then if last_token_type == "keyword" or last_token_type == "name" or last_token_type == "number" then write(" "); end end write(token.value); if token.type == "string" then write("\""); end last_token_type = token.type; end end return js2lua;