lib/js2lua.lua

changeset 0
b2e55f320d48
equal deleted inserted replaced
-1:000000000000 0:b2e55f320d48
1 local t = { op = {}, keyword = {}, name = {}, eos = {}, string = {}, regex = {} };
2
3 local debug = function (...) io.stderr:write(table.concat({...}, "\t")); io.stderr:write"\n";end;
4 local debug = function () end
5
6 local function read_balanced(tokens, start, left, right)
7 local c = 0;
8 for i=start,#tokens do
9 if tokens[i].type == "op" then
10 local token = tokens[i].value;
11 if token == left then
12 c = c + 1;
13 elseif token == right then
14 c = c - 1;
15 end
16 end
17 if c == 0 then return i; end
18 end
19 return start;
20 end
21
22 local pair_op = { ["("] = ")", ["{"] = "}", ["["] = "]" };
23 local function read_balanced_to(tokens, start, to)
24 local c = 0;
25 local i = start;
26 while i <= #tokens do
27 if tokens[i].type == "op" or tokens[i].type == "eos" then
28 local token = tokens[i].value;
29 if token == to then return i; end
30
31 if pair_op[token] then
32 i = read_balanced(tokens, i, token, pair_op[token]);
33 end
34 end
35 i = i + 1;
36 end
37 return nil;
38 end
39
40 function js2lua(tokens, write)
41
42 -- Scan
43 local i = 1;
44 while i <= #tokens do
45 local token = tokens[i];
46 debug(token.type, token.value);
47 if token.type == "keyword" and token.value == "function" then
48 local j = read_balanced_to(tokens, i+3, ")"); -- Find matching )
49 j = j + 1; -- j now points to {
50 local k = read_balanced_to(tokens, j+1, "}");
51 table.remove(tokens, j); -- Remove {
52 tokens[k-1].type, tokens[k-1].value = "keyword", "end";
53 elseif token.type == "keyword" and token.value == "if" then
54 table.remove(tokens, i+1); -- Remove (
55 local j = read_balanced_to(tokens, i, ")");
56 tokens[j].type, tokens[j].value = "keyword", "then";
57
58 -- Make sure to end a single-statement block
59 if tokens[j+1].type ~= "op" or tokens[j+1].value ~= "{" then
60 local eos = read_balanced_to(tokens, j+1, ";");
61 if tokens[eos+1].type ~= "keyword" or tokens[eos+1].value ~= "else" then
62 table.insert(tokens, eos+1, { type = "keyword", value = "end" });
63 end
64 end
65 elseif token.type == "keyword" and token.value == "else" then
66 if tokens[i+1].type == "keyword" and tokens[i+1].value == "if" then
67 token.value = "elseif";
68 table.remove(tokens, i+1);
69
70 table.remove(tokens, i+1); -- Remove (
71 local j = read_balanced_to(tokens, i, ")");
72 tokens[j].type, tokens[j].value = "keyword", "then";
73 end
74
75 -- Make sure to end a single-statement block
76 if tokens[i+1].type ~= "op" or tokens[i+1].value ~= "{" then
77 local eos = read_balanced_to(tokens, i+1, ";");
78 if tokens[eos+1].type ~= "keyword" or tokens[eos+1].value ~= "else" then
79 table.insert(tokens, eos+1, { type = "keyword", value = "end" });
80 end
81 end
82 elseif token.type == "op" and token.value == "+" and tokens[i-1].type == "string" then
83 token.value = "..";
84 elseif token.type == "op" and token.value == "{" then
85 elseif token.type == "keyword" and token.value == "var" then
86 token.value = "local";
87 end
88 i = i + 1;
89 end
90
91 -- Serialize
92 local last_token_type;
93 for _, token in ipairs(tokens) do
94 if token.type == "string" then
95 write("\"");
96 elseif token.type == "name" then
97 if last_token_type == "keyword" or last_token_type == "name" or last_token_type == "number" then
98 write(" ");
99 end
100 elseif token.type == "keyword" then
101 if last_token_type == "keyword" or last_token_type == "name" or last_token_type == "number" then
102 write(" ");
103 end
104 end
105 write(token.value);
106 if token.type == "string" then
107 write("\"");
108 end
109 last_token_type = token.type;
110 end
111 end
112
113 return js2lua;

mercurial