lib/js2lua.lua

Fri, 15 Oct 2010 15:17:17 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Fri, 15 Oct 2010 15:17:17 +0100
changeset 0
b2e55f320d48
permissions
-rw-r--r--

Initial commit

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

mercurial