diff -r 000000000000 -r b2e55f320d48 lib/js2lua.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/js2lua.lua Fri Oct 15 15:17:17 2010 +0100 @@ -0,0 +1,113 @@ +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;