]> dreyeck.freedombox.rocks Git - idiomatic.git/blob - visitor.js
better scopes
[idiomatic.git] / visitor.js
1 let stack=[]
2 let log = false ? console.log : () => null
3 let doit = () => null
4
5 const rules = {
6 Program({body}) {body.map(step)},
7 VariableDeclaration({kind,declarations}) {declarations.map(step)},
8 VariableDeclarator({id,init}) {step(id);if(init)step(init)},
9 Identifier({start,name}) {doit(name); log(start,name)},
10 CallExpression({callee}) {step(callee); arguments[0]['arguments'].map(step)},
11 NewExpression({callee}) {step(callee); arguments[0]['arguments'].map(step)},
12 FunctionExpression({params,body}) {params.map(step); step(body)},
13 MemberExpression({object,property}) {step(object); step(property)},
14 ObjectPattern({properties}) {properties.map(step)},
15 ExpressionStatement({expression}) {step(expression)},
16 IfStatement({test,consequent}) {step(test); step(consequent)},
17 BlockStatement({body}) {body.map(step)},
18 ReturnStatement({argument}) {if(argument)step(argument)},
19
20 Literal({start,value,raw}) {log(start,raw)},
21 AssignmentExpression({operator,left,right}) {log(operator);step(left);step(right)},
22 LogicalExpression({operator,left,right}) {log(operator);step(left);step(right)},
23 BinaryExpression({operator,left,right}) {log(operator);step(left);step(right)},
24 UnaryExpression({operator,prefix,argument}) {log(prefix?'prefix':'suffix',operator); step(argument)},
25 UpdateExpression({operator,prefix,argument}) {log(prefix?'prefix':'suffix',operator); step(argument)},
26 ObjectExpression({properties}) {properties.map(step)},
27 Property({key,value}) {step(key);step(value)},
28 ArrayExpression({elements}) {elements.map(step)},
29 ArrayPattern({elements}) {elements.map(step)},
30 ArrowFunctionExpression({params,body}) {params.map(step);step(body)},
31 TemplateLiteral({expressions,quasis}) {quasis.map(step);expressions.map(step)},
32 TemplateElement({start,end}) {log(end-start,'bytes')},
33
34 ForStatement({init,test,update,body}) {step(init);step(test);step(update);step(body)},
35 ForInStatement({left,right,body}) {step(left); step(right); step(body)},
36 ForOfStatement({left,right,body}) {step(left); step(right); step(body)},
37 ChainExpression({expression}) {step(expression)},
38 ConditionalExpression({test,consequent,alternative}) {step(test);step(consequent);step(alternative)},
39 ContinueStatement(){},
40 BreakStatement(){},
41
42 AssignmentPattern({left,right}) {step(left);step(right)},
43 WhileStatement({test,body}) {step(test);step(body)},
44 TryStatement({block,handler,finalizer}) {step(block);step(handler);step(finalizer)},
45 CatchClause({param,body}) {step(param);step(body)},
46
47 EmptyStatement() {},
48 AwaitExpression({argument}) {step(argument)},
49 ThrowStatement({argument}) {step(argument)},
50 SwitchStatement({discriminant,cases}) {step(discriminant); cases.map(step)},
51 SwitchCase({test,consequent}) {step(test); consequent.map(step)},
52 RestElement({argument}) {step(argument)},
53 ImportExpression({source}) {step(source)},
54 FunctionDeclaration({id,params,body}) {step(id),params.map(step),step(body)},
55
56 ThisExpression({context}) {step(context)},
57
58 DoWhileStatement({test,body}) {step(test);step(body)},
59 SequenceExpression({expressions}) {expressions.map(step)},
60
61 SpreadElement({argument}) {step(argument)},
62 }
63
64 let each = (branch,stack) => {}
65 function walk(mods,doit) {
66 each = doit
67 for (const mod of mods) {
68 stack = [mod.file]
69 step(mod.tree)
70 }
71 each = (branch,stack) => {}
72 }
73 function step(branch) {
74 if(branch) {
75 const type = branch?.type;
76 stack.unshift(branch);
77 log('PARSING',type);
78 each(branch,stack);
79 (rules[type]||fail)(branch);
80 stack.shift()
81 }
82 }
83 function fail(branch) {
84 console.log('FAIL',branch)
85 }
86
87 module.exports = {walk}