| Index: utils/cleanast.js | 
| diff --git a/utils/cleanast.js b/utils/cleanast.js | 
| deleted file mode 100644 | 
| index 3aac61818ae171ad8cbe8b06890a183d5ce1672c..0000000000000000000000000000000000000000 | 
| --- a/utils/cleanast.js | 
| +++ /dev/null | 
| @@ -1,248 +0,0 @@ | 
| -/** | 
| - * A brief description of some nodes. | 
| - * | 
| - * Scope block information: | 
| - *  variables (Variable[]): a list of variables declared in the block | 
| - *  functions (Function[]): a list of functions declared in the block | 
| - *  constants (Variable[]): a list of constants declared in the block | 
| - *  classes (Class[]): a list of classes declared in the block | 
| - *  objects (Class[]): a list of objects declared in the block | 
| - *  code (Statement[]): a list of statements in the block | 
| - */ | 
| - | 
| -/** | 
| - * Takes the node rooted at the AST and decomposes it into readable sections. | 
| - */ | 
| -function clean_ast(ast) { | 
| -  assert(ast.type == TOK_LC); | 
| -  let info = { | 
| -    variables: [], | 
| -    constants: [], | 
| -    objects: [], | 
| -    classes: [], | 
| -    functions: [], | 
| -    code: [] | 
| -  }; | 
| - | 
| -  for each (let statement in ast.kids) { | 
| -    if (statement.op == JSOP_DEFVAR) { | 
| -      let ret = make_variables(statement); | 
| -      info.variables = info.variables.concat(ret.vars); | 
| -      info.objects = info.objects.concat(ret.objs); | 
| -    } else if (statement.op == JSOP_DEFCONST) { | 
| -      let ret = make_variables(statement); | 
| -      info.constants = info.constants.concat(ret.vars); | 
| -      info.objects = info.objects.concat(ret.objs); | 
| -    } else if (statement.type == TOK_FUNCTION) { | 
| -      info.functions.push(make_function(statement)); | 
| -    } else if (prototype_assign(statement)) { | 
| -      let obj = make_class(statement); | 
| -      merge_class(info, obj); | 
| -    } else { | 
| -      info.code.push(statement); | 
| -    } | 
| -  } | 
| -  return info; | 
| -} | 
| - | 
| -/** | 
| - * Visits the AST using the given function as a parameter. | 
| - * The parameter will take in a single argument, the AST node. | 
| - */ | 
| -function visit(root_ast, func, to_expand) { | 
| -  function v_r(ast, func) { | 
| -    if (ast == null) | 
| -      return; | 
| -    if (func(ast)) return; | 
| -    for each (let child in ast.kids) | 
| -      v_r(child, func); | 
| -  } | 
| - | 
| -  function sanitize(ast) { | 
| -    if (ast == null) | 
| -      return null; | 
| -    if (ast.op == JSOP_NAME && ast.atom in to_expand) { | 
| -      ast = sanitize(to_expand[ast.atom]); | 
| -      ast.expanded = true; | 
| -    } | 
| -    let sanitized_ast = { kids: [] }; | 
| -    for (let key in ast) { | 
| -      if (key == 'kids') { | 
| -        for each (let kid in ast.kids) { | 
| -          sanitized_ast.kids.push(sanitize(kid)); | 
| -        } | 
| -      } else { | 
| -        sanitized_ast[key] = ast[key]; | 
| -      } | 
| -    } | 
| -    return sanitized_ast; | 
| -  } | 
| - | 
| -  if (to_expand) | 
| -    v_r(sanitize(root_ast), func); | 
| -  else | 
| -    v_r(root_ast, func); | 
| -} | 
| - | 
| -function prototype_assign(statement) { | 
| -  if (statement.type != TOK_SEMI || !statement.kids[0]) | 
| -    return false; | 
| -  statement = statement.kids[0]; | 
| -  if (statement.type != TOK_ASSIGN || !statement.kids[0]) | 
| -    return false; | 
| - | 
| -  statement = statement.kids[0]; | 
| -  // Statement is either prototype or a property of prototype | 
| -  if (statement.op != JSOP_SETPROP) | 
| -    return false; | 
| -  if (statement.atom == "prototype") | 
| -    return true; | 
| -  if (statement.kids[0] && statement.kids[0] == "prototype") | 
| -    return true; | 
| - | 
| -  // Or not! | 
| -  return false; | 
| -} | 
| - | 
| -function make_class(class_root) { | 
| -  let clazz = {}; | 
| - | 
| -  class_root = class_root.kids[0]; | 
| -  let lhs = class_root.kids[0], rhs = class_root.kids[1]; | 
| -  if (lhs.atom == "prototype") { | 
| -    clazz.init = rhs; | 
| -    clazz = make_object(clazz); | 
| -  } else { | 
| -    clazz.functions = {}; | 
| -    clazz.functions[lhs.atom] = make_function(rhs); | 
| -    lhs = lhs.kids[0]; | 
| -  } | 
| -  clazz.name = lhs.kids[0].atom; | 
| -  return clazz; | 
| -} | 
| - | 
| -function merge_class(info_list, obj) { | 
| -  let name = obj.name; | 
| -  for (let i = 0; i < info_list.functions.length; i++) { | 
| -    if (info_list.functions[i].name == name) { | 
| -      obj.constructor = info_list.functions[i]; | 
| -      // remove the constructor from the list of global functions | 
| -      info_list.functions.splice(i, 1); | 
| -      break; | 
| -    } | 
| -  } | 
| -  if (obj.constructor) | 
| -    obj.loc = obj.constructor.loc; | 
| -  let oldObj = null; | 
| -  for (let i = 0; i < info_list.classes.length; i++) { | 
| -    if (info_list.classes[i].name == name) { | 
| -      oldObj = info_list.classes[i]; | 
| -      break; | 
| -    } | 
| -  } | 
| -  if (oldObj) { | 
| -    for (let prop in obj) { | 
| -      if (!(prop in oldObj)) { | 
| -        oldObj[prop] = obj[prop]; | 
| -      } else if (typeof obj[prop] == "object") { | 
| -        for (let item in obj[prop]) | 
| -          oldObj[prop][item] = obj[prop][item]; | 
| -      } | 
| -    } | 
| -  } else { | 
| -    info_list.classes = info_list.classes.concat(obj); | 
| -  } | 
| -} | 
| -function make_variables(var_root) { | 
| -  assert(var_root.op == JSOP_DEFVAR || var_root.op == JSOP_DEFCONST); | 
| -  let variables = []; | 
| -  let objects = []; | 
| -  for each (let name in var_root.kids) { | 
| -    let v = { name: name.atom }; | 
| -    v.init = (name.kids.length > 0 ? name.kids[0] : null); | 
| -    v.loc = get_location(var_root); | 
| -    if (v.init && v.init.op == JSOP_NEWINIT && v.init.kids[0] && | 
| -        v.init.kids[0].type == TOK_COLON) | 
| -      objects.push(make_object(v)); | 
| -    else | 
| -      variables.push(v); | 
| -  } | 
| -  return { vars: variables, objs: objects }; | 
| -} | 
| - | 
| -function make_object(stub) { | 
| -  stub.variables = {}; | 
| -  stub.functions = {}; | 
| -  stub.getters = {}; | 
| -  stub.setters = {}; | 
| -  let ast = stub.init; | 
| -  let proto = stub.init.op == JSOP_GETPROP && stub.init.atom == 'prototype'; | 
| -  delete stub['init']; | 
| -  if (proto) { | 
| -	  stub.inherits = [ast.kids[0].atom]; | 
| -	  return stub; | 
| -  } | 
| -  for each (let init in ast.kids) { | 
| -    if (init.type != TOK_COLON) { | 
| -      dump_ast(init); | 
| -    } | 
| -    assert(init.type == TOK_COLON); | 
| -    if (init.kids[0].type == TOK_NAME) { | 
| -      let name = init.kids[0].atom; | 
| -      let value = init.kids[1]; | 
| -      if (init.op == JSOP_GETTER) | 
| -        stub.getters[name] = make_function(value); | 
| -      else if (init.op == JSOP_SETTER) | 
| -        stub.setters[name] = make_function(value); | 
| -      else if (value.type == TOK_FUNCTION) | 
| -        stub.functions[name] = make_function(value); | 
| -      else if (name == '__proto__') { | 
| -        let supername; | 
| -        if (value.op == JSOP_NEW) | 
| -          supername = value.kids[0].atom; | 
| -        else if (value.op == JSOP_GETPROP && value.atom == 'prototype') | 
| -          supername = value.kids[0].atom; | 
| -        else | 
| -          assert(false); | 
| -        if ('inherits' in stub) | 
| -          stub.inherits.push(supoername); | 
| -        else | 
| -          stub.inherits = [supername]; | 
| -      } | 
| -      else | 
| -        stub.variables[name] = { loc: get_location(value), init: value }; | 
| -    } else { | 
| -      dump_ast(init); | 
| -    } | 
| -  } | 
| -  return stub; | 
| -} | 
| - | 
| -function make_function(func_root) { | 
| -  assert(func_root.type == TOK_FUNCTION); | 
| -  let stmts = func_root.kids[0]; | 
| -  if (stmts.type == TOK_UPVARS) | 
| -    stmts = stmts.kids[0]; | 
| -  if (stmts.type == TOK_ARGSBODY) | 
| -    stmts = stmts.kids[stmts.kids.length - 1]; | 
| -  if (stmts.type == TOK_RETURN) { | 
| -    // This is a lambda function. For simplicity's sake, I'm going to turn this | 
| -    // into a regular function by wrapping with TOK_LC (consumers of functions | 
| -    // will find this easier to use) | 
| -    let newtop = { fakeNode: true, line: stmts.line, col: stmts.col, | 
| -      type: TOK_LC, op: JSOP_NOP, kids: [stmts]}; | 
| -    stmts = newtop; | 
| -  } | 
| -  assert(stmts.type == TOK_LC); | 
| -  return { name: func_root.name, body: stmts, loc: get_location(func_root)}; | 
| -} | 
| - | 
| -function assert(cmd) { | 
| -  if (!cmd) { | 
| -    throw new Error("Assertion failed"); | 
| -  } | 
| -} | 
| - | 
| -function get_location(ast_node) { | 
| -  return { line: ast_node.line, column: ast_node.column }; | 
| -} | 
|  |