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$
|
|
*/
|