importGlobal(""); function main() { var code = File.readMapFile("PROMPT_MAP").CODE; evalFile("d:/rub/esprima.min.js"); var ast = esprima.parse(code); // println(Str.formatJson(ast)); // return; var scopes = { a : function(){ return "AAAA"; }, b : function(){ return "bbbb"; } } var evalAST = new EvalEsprimaAST(ast, scopes); evalAST.execute({}); } function EvalEsprimaAST(astRoot, globalVarbs) { function ASTStackItem() { this._mapId2Varb = {}; } //////////////////////////////////////////////////////////////////////// function ASTValueItem(value) { this._value = value; this.getValue = function() { return this._value; } } //////////////////////////////////////////////////////////////////////// function ASTVarbItem(refObj, refKey) { this._refObj = refObj; this._refKey = refKey; this.getValue = function() { return this._refObj[this._refKey]; } this.setValue = function(value) { this._refObj[this._refKey] = value; } } //////////////////////////////////////////////////////////////////////// // 初始化函数 this._astRoot = astRoot; this._mapId2Global = {}; for(var globalName in globalVarbs) { this._mapId2Global[globalName] = globalVarbs[globalName]; } // 执行根函数 this.execute = function(args) { var stack = new ASTStackItem(); if(this._astRoot.type != "Program") throw new Exception("first node must be Program"); var stack = new ASTStackItem(); if(this._astRoot.body[0].type != "FunctionDeclaration") throw new Exception("second node must be FunctionDeclaration"); this._execASTNode(this._astRoot.body[0].body, stack); var r = stack._mapId2Varb["c"]; println(r); } this._isStringType = function(value) { if(typeof value === "string") return true; return false; } this._isNumberType = function(value) { if(typeof value === "number") return true; return false; } this._getAstVarbValue = function(varbName, stack) { // 如果在局部变量里能找到,则将其返回 var varbItem = stack._mapId2Varb[varbName]; if(varbItem !== undefined) return new ASTVarbItem(stack._mapId2Varb, varbName); // 如果在全局变量里能找到,则返回 var varbItem = this._mapId2Global[varbName]; if(varbItem !== undefined) return new ASTVarbItem(this._mapId2Global, varbName); throw "can't find variable : " + varbName; } this._getAstVarbNode = function(astNode, stack) { if(astNode.type == "Identifier") { var varbName = astNode.name; return this._getAstVarbValue(varbName, stack); } else { throw "unsupport ast variable type : " + astNode.type; } } // 执行ast节点 this._execASTNode = function(astNode, stack) { var execNodeFunc = this["_execASTNode_" + astNode.type]; if(!execNodeFunc) throw "unsupport ast node : " + astNode.type; return execNodeFunc.call(this, astNode, stack); } // 执行ast节点: Identifier this._execASTNode_Identifier = function(astNode, stack) { return this._getAstVarbValue(astNode.name, stack); } // 执行ast节点: BlockStatement this._execASTNode_BlockStatement = function(astNode, stack) { for(var bodyIdx in astNode.body) { this._execASTNode(astNode.body[bodyIdx], stack); } } // 执行ast节点: ExpressionStatement this._execASTNode_ExpressionStatement = function(astNode, stack) { return this._execASTNode(astNode.expression, stack); } // 执行ast节点: AssignmentExpression this._execASTNode_AssignmentExpression = function(astNode, stack) { // 获取右值 var rightValue = this._execASTNode(astNode.right, stack).getValue(); // 获取左值引用 var leftVarb = this._getAstVarbNode(astNode.left, stack); // 将右值内容赋值到左值变量 leftVarb.setValue(rightValue); } // 执行ast节点: CallExpression this._execASTNode_CallExpression = function(astNode, stack) { // 获取所有参数 var args = []; for(var argIdx in astNode.arguments) { var argValue = this._execASTNode(astNode.arguments[argIdx], stack).getValue(); args.push(argValue); } var varbFunc = this._getAstVarbNode(astNode.callee, stack); var ret = new ASTValueItem(varbFunc.getValue().apply(varbFunc._varb, args)); return ret; } // 执行ast节点: VariableDeclaration this._execASTNode_VariableDeclaration = function(astNode, stack) { for(var astDeclIdx in astNode.declarations) { var astDeclNode = astNode.declarations[astDeclIdx]; var varbName = astDeclNode.id.name; // 创建变量 var varbItem; if(astNode.kind == "var") { varbItem = stack._mapId2Varb[varbName]; if(varbItem === undefined) { stack._mapId2Varb[varbName] = null; varbItem = new ASTVarbItem(stack._mapId2Varb, varbName); } } else if(astNode.kind == "let") { varbItem = this._mapId2Global[varbName]; if(!varbItem === undefined) { this._mapId2Global[varbName] = null; varbItem = new ASTVarbItem(this._mapId2Global, varbName); } } else { throw "unsupport variable define type : " + astNode.kind; } // 初始化变量 if(astDeclNode.init) { var value = this._execASTNode(astDeclNode.init, stack).getValue(); varbItem.setValue(value); } } } // 执行ast节点: Literal this._execASTNode_Literal = function(astNode, stack) { return new ASTValueItem(astNode.value); } // 执行ast节点: ObjectExpression this._execASTNode_ObjectExpression = function(astNode, stack) { var jsonValue = {}; for(var propIdx in astNode.properties) { var propItem = astNode.properties[propIdx]; // 获取属性key var propKey; if(propItem.key.type == "Identifier") propKey = propItem.key.name; else if(propItem.key.type == "Literal") propKey = propItem.key.value; else throw "unsupport property type : " + propItem.key.type; // 获取属性值 var propValue = this._execASTNode(propItem.value, stack).getValue(); // 设置jsons属性 jsonValue[propKey] = propValue; } return new ASTValueItem(jsonValue); } // 执行ast节点: MemberExpression this._execASTNode_MemberExpression = function(astNode, stack) { // 获取主变量 var varbItem = this._getAstVarbNode(astNode.object, stack); // 获取属性key var propKey; if(astNode.property.type == "Identifier") { if(!astNode.computed) propKey = astNode.property.name; else propKey = this._getAstVarbValue(astNode.property.name, stack).getValue(); } else propKey = this._execASTNode(astNode.property, stack).getValue(); return new ASTVarbItem(varbItem.getValue(), propKey); } // 执行ast节点: ArrayExpression this._execASTNode_ArrayExpression = function(astNode, stack) { var jsonValue = []; for(var index in astNode.elements) { var value = this._execASTNode(astNode.elements[index], stack).getValue(); jsonValue.push(value); } return new ASTValueItem(jsonValue); } // 执行ast节点: BinaryExpression this._execASTNode_BinaryExpression = function(astNode, stack) { var leftValue = this._execASTNode(astNode.left, stack).getValue(); var rightValue = this._execASTNode(astNode.right, stack).getValue(); var result = null; if(astNode.operator == "+") { result = leftValue + rightValue; } else if(astNode.operator == "-") { result = leftValue - rightValue; } else if(astNode.operator == "*") { result = leftValue * rightValue; } else if(astNode.operator == "/") { result = leftValue / rightValue; } else if(astNode.operator == "%") { result = leftValue % rightValue; } else if(astNode.operator == "<") { result = leftValue < rightValue; } else if(astNode.operator == ">") { result = leftValue > rightValue; } else if(astNode.operator == "<=") { result = leftValue <= rightValue; } else if(astNode.operator == ">=") { result = leftValue >= rightValue; } else if(astNode.operator == "==") { result = leftValue == rightValue; } else if(astNode.operator == "===") { result = leftValue === rightValue; } else if(astNode.operator == "!=") { result = leftValue != rightValue; } else if(astNode.operator == "!==") { result = leftValue !== rightValue; } else { throw "unsupport BinaryExpression operate : " + astNode.operator; } return new ASTValueItem(result); } // 执行ast节点: UnaryExpression this._execASTNode_UnaryExpression = function(astNode, stack) { var value = this._execASTNode(astNode.argument, stack).getValue(); var result = null; if(astNode.operator == "!") { result = !value; } return new ASTValueItem(result); } // 执行ast节点: LogicalExpression this._execASTNode_LogicalExpression = function(astNode, stack) { var result = null; if(astNode.operator == "&&") { var leftValue = this._execASTNode(astNode.left, stack).getValue(); if(!leftValue) { result = false; } else { var rightValue = this._execASTNode(astNode.right, stack).getValue(); if(!rightValue) result = false; else result = true; } } else if(astNode.operator == "||") { var leftValue = this._execASTNode(astNode.left, stack).getValue(); if(!!leftValue) { result = true; } else { var rightValue = this._execASTNode(astNode.right, stack).getValue(); if(!!rightValue) result = true; else result = false; } } else { throw "unsupport BinaryExpression operate : " + astNode.operator; } return new ASTValueItem(result); } // 执行ast节点: IfStatement this._execASTNode_IfStatement = function(astNode, stack) { // 计算条件值 var condValue = this._execASTNode(astNode.test, stack).getValue(); // 如果条件为真,则执行以下代码 if(condValue) { this._execASTNode(astNode.consequent, stack); } else { this._execASTNode(astNode.alternate, stack); } } // 执行ast节点: ForInStatement this._execASTNode_ForInStatement = function(astNode, stack) { var itorVarbName; // 如果迭代变量是定义语句,则创建变量 if(astNode.left.type == "VariableDeclaration") { this._execASTNode(astNode.left, stack); itorVarbName = astNode.left.declarations[0].id.name; } // 如果迭代变量不是定义语句,则获取变量名 else { itorVarbName = astNode.left.name; } var itorVarbItem = this._getAstVarbValue(itorVarbName, stack); // 获取迭代对象 var aggValue = this._execASTNode(astNode.right, stack).getValue(); // 迭代操作 for(var itor in aggValue) { // 保存当前进度itor itorVarbItem.setValue(itor); // 执行后续语句 this._execASTNode(astNode.body, stack); } } // 执行ast节点: ForStatement this._execASTNode_ForStatement = function(astNode, stack) { // 执行初始化 this._execASTNode(astNode.init, stack); while(true) { // 执行判断 var condValue = this._execASTNode(astNode.test, stack).getValue(); if(!condValue) break; // 执行循环块 this._execASTNode(astNode.body, stack); // 执行步长 this._execASTNode(astNode.update, stack); } } //////////////////////////////////////////////////////////////////////////////////////////// } main(); /* * PROMPT_MAP:CODE function main() { var c = 0; for(var i = 0; i < 100; i = i + 1) { c = i; } } PROMPT_MAP$ */