OLD | NEW |
1 /** | 1 /** |
2 * A brief description of some nodes. | 2 * A brief description of some nodes. |
3 * | 3 * |
4 * Scope block information: | 4 * Scope block information: |
5 * variables (Variable[]): a list of variables declared in the block | 5 * variables (Variable[]): a list of variables declared in the block |
6 * functions (Function[]): a list of functions declared in the block | 6 * functions (Function[]): a list of functions declared in the block |
7 * constants (Variable[]): a list of constants declared in the block | 7 * constants (Variable[]): a list of constants declared in the block |
8 * classes (Class[]): a list of classes declared in the block | 8 * classes (Class[]): a list of classes declared in the block |
9 * objects (Class[]): a list of objects declared in the block | 9 * objects (Class[]): a list of objects declared in the block |
10 * code (Statement[]): a list of statements in the block | 10 * code (Statement[]): a list of statements in the block |
11 */ | 11 */ |
12 | 12 |
13 /** | 13 /** |
14 * Takes the node rooted at the AST and decomposes it into readable sections. | 14 * Takes the node rooted at the AST and decomposes it into readable sections. |
15 */ | 15 */ |
16 function clean_ast(ast) { | 16 function clean_ast(ast) { |
17 assert(ast.type == TOK_LC); | 17 assert(ast.type == TOK_LC); |
18 let info = { | 18 let info = { |
19 variables: [], | 19 variables: [], |
20 constants: [], | 20 constants: [], |
21 objects: [], | 21 objects: [], |
22 classes: [], | 22 classes: [], |
23 functions: [], | 23 functions: [], |
24 code: [] | 24 code: [] |
25 }; | 25 }; |
26 | 26 |
27 for each (let statement in ast.kids) { | 27 for (let statement of ast.kids) { |
28 if (statement.op == JSOP_DEFVAR) { | 28 if (statement.op == JSOP_DEFVAR) { |
29 let ret = make_variables(statement); | 29 let ret = make_variables(statement); |
30 info.variables = info.variables.concat(ret.vars); | 30 info.variables = info.variables.concat(ret.vars); |
31 info.objects = info.objects.concat(ret.objs); | 31 info.objects = info.objects.concat(ret.objs); |
32 } else if (statement.op == JSOP_DEFCONST) { | 32 } else if (statement.op == JSOP_DEFCONST) { |
33 let ret = make_variables(statement); | 33 let ret = make_variables(statement); |
34 info.constants = info.constants.concat(ret.vars); | 34 info.constants = info.constants.concat(ret.vars); |
35 info.objects = info.objects.concat(ret.objs); | 35 info.objects = info.objects.concat(ret.objs); |
36 } else if (statement.type == TOK_FUNCTION) { | 36 } else if (statement.type == TOK_FUNCTION) { |
37 info.functions.push(make_function(statement)); | 37 info.functions.push(make_function(statement)); |
38 } else if (prototype_assign(statement)) { | 38 } else if (prototype_assign(statement)) { |
39 let obj = make_class(statement); | 39 let obj = make_class(statement); |
40 merge_class(info, obj); | 40 merge_class(info, obj); |
41 } else { | 41 } else { |
42 info.code.push(statement); | 42 info.code.push(statement); |
43 } | 43 } |
44 } | 44 } |
45 return info; | 45 return info; |
46 } | 46 } |
47 | 47 |
48 /** | 48 /** |
49 * Visits the AST using the given function as a parameter. | 49 * Visits the AST using the given function as a parameter. |
50 * The parameter will take in a single argument, the AST node. | 50 * The parameter will take in a single argument, the AST node. |
51 */ | 51 */ |
52 function visit(root_ast, func, to_expand) { | 52 function visit(root_ast, func, to_expand) { |
53 function v_r(ast, func) { | 53 function v_r(ast, func) { |
54 if (ast == null) | 54 if (ast == null) |
55 return; | 55 return; |
56 if (func(ast)) return; | 56 if (func(ast)) return; |
57 for each (let child in ast.kids) | 57 for (let child of ast.kids) |
58 v_r(child, func); | 58 v_r(child, func); |
59 } | 59 } |
60 | 60 |
61 function sanitize(ast) { | 61 function sanitize(ast) { |
62 if (ast == null) | 62 if (ast == null) |
63 return null; | 63 return null; |
64 if (ast.op == JSOP_NAME && ast.atom in to_expand) { | 64 if (ast.op == JSOP_NAME && ast.atom in to_expand) { |
65 ast = sanitize(to_expand[ast.atom]); | 65 ast = sanitize(to_expand[ast.atom]); |
66 ast.expanded = true; | 66 ast.expanded = true; |
67 } | 67 } |
68 let sanitized_ast = { kids: [] }; | 68 let sanitized_ast = { kids: [] }; |
69 for (let key in ast) { | 69 for (let key of ast) { |
70 if (key == 'kids') { | 70 if (key == 'kids') { |
71 for each (let kid in ast.kids) { | 71 for (let kid of ast.kids) { |
72 sanitized_ast.kids.push(sanitize(kid)); | 72 sanitized_ast.kids.push(sanitize(kid)); |
73 } | 73 } |
74 } else { | 74 } else { |
75 sanitized_ast[key] = ast[key]; | 75 sanitized_ast[key] = ast[key]; |
76 } | 76 } |
77 } | 77 } |
78 return sanitized_ast; | 78 return sanitized_ast; |
79 } | 79 } |
80 | 80 |
81 if (to_expand) | 81 if (to_expand) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 } | 150 } |
151 } | 151 } |
152 } else { | 152 } else { |
153 info_list.classes = info_list.classes.concat(obj); | 153 info_list.classes = info_list.classes.concat(obj); |
154 } | 154 } |
155 } | 155 } |
156 function make_variables(var_root) { | 156 function make_variables(var_root) { |
157 assert(var_root.op == JSOP_DEFVAR || var_root.op == JSOP_DEFCONST); | 157 assert(var_root.op == JSOP_DEFVAR || var_root.op == JSOP_DEFCONST); |
158 let variables = []; | 158 let variables = []; |
159 let objects = []; | 159 let objects = []; |
160 for each (let name in var_root.kids) { | 160 for (let name of var_root.kids) { |
161 let v = { name: name.atom }; | 161 let v = { name: name.atom }; |
162 v.init = (name.kids.length > 0 ? name.kids[0] : null); | 162 v.init = (name.kids.length > 0 ? name.kids[0] : null); |
163 v.loc = get_location(var_root); | 163 v.loc = get_location(var_root); |
164 if (v.init && v.init.op == JSOP_NEWINIT && v.init.kids[0] && | 164 if (v.init && v.init.op == JSOP_NEWINIT && v.init.kids[0] && |
165 v.init.kids[0].type == TOK_COLON) | 165 v.init.kids[0].type == TOK_COLON) |
166 objects.push(make_object(v)); | 166 objects.push(make_object(v)); |
167 else | 167 else |
168 variables.push(v); | 168 variables.push(v); |
169 } | 169 } |
170 return { vars: variables, objs: objects }; | 170 return { vars: variables, objs: objects }; |
171 } | 171 } |
172 | 172 |
173 function make_object(stub) { | 173 function make_object(stub) { |
174 stub.variables = {}; | 174 stub.variables = {}; |
175 stub.functions = {}; | 175 stub.functions = {}; |
176 stub.getters = {}; | 176 stub.getters = {}; |
177 stub.setters = {}; | 177 stub.setters = {}; |
178 let ast = stub.init; | 178 let ast = stub.init; |
179 let proto = stub.init.op == JSOP_GETPROP && stub.init.atom == 'prototype'; | 179 let proto = stub.init.op == JSOP_GETPROP && stub.init.atom == 'prototype'; |
180 delete stub['init']; | 180 delete stub['init']; |
181 if (proto) { | 181 if (proto) { |
182 » stub.inherits = [ast.kids[0].atom]; | 182 stub.inherits = [ast.kids[0].atom]; |
183 » return stub; | 183 return stub; |
184 } | 184 } |
185 for each (let init in ast.kids) { | 185 for (let init of ast.kids) { |
186 if (init.type != TOK_COLON) { | 186 if (init.type != TOK_COLON) { |
187 dump_ast(init); | 187 dump_ast(init); |
188 } | 188 } |
189 assert(init.type == TOK_COLON); | 189 assert(init.type == TOK_COLON); |
190 if (init.kids[0].type == TOK_NAME) { | 190 if (init.kids[0].type == TOK_NAME) { |
191 let name = init.kids[0].atom; | 191 let name = init.kids[0].atom; |
192 let value = init.kids[1]; | 192 let value = init.kids[1]; |
193 if (init.op == JSOP_GETTER) | 193 if (init.op == JSOP_GETTER) |
194 stub.getters[name] = make_function(value); | 194 stub.getters[name] = make_function(value); |
195 else if (init.op == JSOP_SETTER) | 195 else if (init.op == JSOP_SETTER) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 239 |
240 function assert(cmd) { | 240 function assert(cmd) { |
241 if (!cmd) { | 241 if (!cmd) { |
242 throw new Error("Assertion failed"); | 242 throw new Error("Assertion failed"); |
243 } | 243 } |
244 } | 244 } |
245 | 245 |
246 function get_location(ast_node) { | 246 function get_location(ast_node) { |
247 return { line: ast_node.line, column: ast_node.column }; | 247 return { line: ast_node.line, column: ast_node.column }; |
248 } | 248 } |
OLD | NEW |