Skip to content

Instantly share code, notes, and snippets.

@QuarkGluonPlasma
Created March 17, 2021 12:20
Show Gist options
  • Save QuarkGluonPlasma/7f463ebbc86160ca2142027a8d5ad414 to your computer and use it in GitHub Desktop.
Save QuarkGluonPlasma/7f463ebbc86160ca2142027a8d5ad414 to your computer and use it in GitHub Desktop.
数组ast的遍历方式
var walkers = {
"string": function(str) {
return [ "string", str ];
},
"num": function(num) {
return [ "num", num ];
},
"name": function(name) {
return [ "name", name ];
},
"toplevel": function(statements) {
return [ "toplevel", statements.map(walk) ];
},
"block": function(statements) {
var out = [ "block" ];
if (statements != null)
out.push(statements.map(walk));
return out;
},
"var": function(defs) {
return [ "var", defs.map(function(def){
var a = [ def[0] ];
if (def.length > 1)
a[1] = walk(def[1]);
return a;
})];
},
"try": function(t, c, f) {
return [
"try",
walk(t),
c != null ? [ c[0], walk(c[1]) ] : null,
f != null ? walk(f) : null
];
},
"throw": function(expr) {
return [ "throw", walk(expr) ];
},
"new": function(ctor, args) {
return [ "new", walk(ctor), args.map(walk) ];
},
"switch": function(expr, body) {
return [ "switch", walk(expr), body.map(walk) ];
},
"case": function(expr) {
return [ "case", walk(expr) ];
},
"default": function() {
return [ "default" ];
},
"break": function(label) {
return [ "break", label ];
},
"continue": function(label) {
return [ "continue", label ];
},
"conditional": function(cond, t, e) {
return [ "conditional", walk(cond), walk(t), walk(e) ];
},
"assign": function(op, lvalue, rvalue) {
return [ "assign", op, walk(lvalue), walk(rvalue) ];
},
"dot": function(expr) {
return [ "dot", walk(expr) ].concat(slice(arguments, 1));
},
"call": function(expr, args) {
return [ "call", walk(expr), args.map(walk) ];
},
"function": function(name, args, body) {
return [ "function", name, args.slice(), body.map(walk) ];
},
"defun": function(name, args, body) {
return [ "defun", name, args.slice(), body.map(walk) ];
},
"if": function(conditional, t, e) {
return [ "if", walk(conditional), walk(t), walk(e) ];
},
"for": function(init, cond, step, block) {
return [ "for", walk(init), walk(cond), walk(step), walk(block) ];
},
"for-in": function(has_var, key, hash, block) {
return [ "for-in", has_var, key, walk(hash), walk(block) ];
},
"while": function(cond, block) {
return [ "while", walk(cond), walk(block) ];
},
"do": function(cond, block) {
return [ "do", walk(cond), walk(block) ];
},
"return": function(expr) {
return [ "return", walk(expr) ];
},
"binary": function(op, left, right) {
return [ "binary", op, walk(left), walk(right) ];
},
"unary-prefix": function(op, expr) {
return [ "unary-prefix", op, walk(expr) ];
},
"unary-postfix": function(op, expr) {
return [ "unary-postfix", op, walk(expr) ];
},
"sub": function(expr, subscript) {
return [ "sub", walk(expr), walk(subscript) ];
},
"object": function(props) {
return [ "object", props.map(function(p){
return [ p[0], walk(p[1]) ];
}) ];
},
"regexp": function(rx, mods) {
return [ "regexp", rx, mods ];
},
"array": function(elements) {
return [ "array", elements.map(walk) ];
},
"stat": function(stat) {
return [ "stat", walk(stat) ];
},
"seq": function() {
return [ "seq" ].concat(slice(arguments).map(walk));
},
"label": function(name, block) {
return [ "label", name, walk(block) ];
},
"with": function(expr, block) {
return [ "with", walk(expr), walk(block) ];
},
"atom": function(name) {
return [ "atom", name ];
}
};
var user = {};
function walk(ast) {
if (ast == null)
return null;
var type = ast[0];
var gen = user[type];
if (gen) {
var ret = gen.apply(ast, ast.slice(1));
if (ret != null)
return ret;
}
gen = walkers[type];
return gen.apply(ast, ast.slice(1));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment