案例研究之聊聊 QLExpress 源码 (八 -2)
发布于: 2021 年 01 月 17 日
承接上一篇,关于指令模块的第二部分,在源码中么有明细区分,但是实际上是将杂七杂八的指令和操作函数等放到了这里
8.4、other
8.4.1、BlockInstructionFactory 代码块指令工厂
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionClearDataStack;
import com.ql.util.express.instruction.detail.InstructionCloseNewArea;
import com.ql.util.express.instruction.detail.InstructionOpenNewArea;
import com.ql.util.express.parse.ExpressNode;
/**
* 代码块指令工厂
* @author xiaochengxinyizhan
*/
public class BlockInstructionFactory extends InstructionFactory {
/**
* 创建指令
* @param aCompile
* @param result
* @param forStack
* @param node
* @param isRoot
* @return
* @throws Exception
*/
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
//检测是否分号
if (node.isTypeEqualsOrChild("STAT_SEMICOLON")
&&result.getCurrentPoint() >=0 && result.getInstruction(result.getCurrentPoint()) instanceof InstructionClearDataStack == false) {
result.addInstruction(new InstructionClearDataStack().setLine(node.getLine()));
}
int tmpPoint = result.getCurrentPoint()+1;
boolean returnVal = false;
boolean hasDef = false;
for(ExpressNode tmpNode : node.getChildren()){
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
hasDef = hasDef || tmpHas;
}
//检测是否代码块
if (hasDef == true&& isRoot == false
&& node.getTreeType().isEqualsOrChild("STAT_BLOCK")){
result.insertInstruction(tmpPoint,new InstructionOpenNewArea().setLine(node.getLine()));
result.insertInstruction(result.getCurrentPoint() + 1,new InstructionCloseNewArea().setLine(node.getLine()));
returnVal = false;
}else{
returnVal = hasDef;
}
return returnVal;
}
}
复制代码
8.4.2、BreakInstructionFactory(break 指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.parse.ExpressNode;
/**
* break指令工厂
* @author xiaochengxinyizhan
*/
public class BreakInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
InstructionGoTo breakInstruction = new InstructionGoTo(result.getCurrentPoint()+1);
breakInstruction.name = "break";
forStack.peek().breakList.add(breakInstruction);
result.addInstruction(breakInstruction.setLine(node.getLine()));
return false;
}
}
复制代码
8.4.3、CallFunctionInstructionFactory 调用函数指令工厂
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionCallSelfDefineFunction;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* 调用函数指令工厂
* @author xiaochengxinyizhan
*/
public class CallFunctionInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
ExpressNode[] children = node.getChildren();
String functionName = children[0].getValue();
boolean returnVal = false;
children = node.getChildren();
for (int i = 1; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,
forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().getOperator(
functionName);
int opNum = children.length -1;
if (op != null) {
result.addInstruction(new InstructionOperator(op,opNum ).setLine(node.getLine()));
} else {
result.addInstruction(new InstructionCallSelfDefineFunction(
functionName,opNum).setLine(children[0].getLine()));
}
return returnVal;
}
}
复制代码
8.4.4、CastInstructionFactory(扩展类指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* 扩展类指令工厂
*
* @author xiaochengxinyizhan
*/
public class CastInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result, Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
boolean returnVal = false;
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
ExpressNode[] children = node.getChildren();
if(children.length ==0){
throw new QLException("扩展类型不存在");
}else if(children.length > 2) {
throw new QLException("扩展操作只能有一个类型为Class的操作数");
}else if(children[0].getNodeType().isEqualsOrChild("CONST_CLASS") == false){
throw new QLException("扩展操作只能有一个类型为Class的操作数,当前的数据类型是:" + children[0].getNodeType().getName());
}
for(int i =0;i < children.length;i++){
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,children[i],false);
returnVal = returnVal || tmpHas;
}
result.addInstruction(new InstructionOperator(op,children.length).setLine(node.getLine()));
return returnVal;
}
}
复制代码
8.4.5、ConstDataInstructionFactory(常量数据指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.OperateData;
import com.ql.util.express.instruction.detail.InstructionConstData;
import com.ql.util.express.instruction.opdata.OperateClass;
import com.ql.util.express.parse.ExpressNode;
/**
* 常量数据指令工厂
* @author didi
*/
public class ConstDataInstructionFactory extends InstructionFactory {
public OperateData genOperateData(ExpressNode node) {
if (node.isTypeEqualsOrChild("CONST_CLASS")) {
return new OperateClass(node.getValue(), (Class<?>) node.getObjectValue());
} else {
return new OperateData(node.getObjectValue(), node.getObjectValue().getClass());
}
}
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
result.addInstruction(new InstructionConstData(genOperateData(node)).setLine(node.getLine()));
return false;
}
}
复制代码
8.4.6、ContinueInstructionFactory(continue 关键字指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.parse.ExpressNode;
/**
* continue关键字指令工厂
* @author xiaochengxinyizhan
*/
public class ContinueInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
InstructionGoTo continueInstruction = new InstructionGoTo(result.getCurrentPoint()+1);
continueInstruction.name = "continue";
forStack.peek().continueList.add(continueInstruction);
result.addInstruction(continueInstruction.setLine(node.getLine()));
return false;
}
}
复制代码
8.4.7、DefineInstructionFactory(定义指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.ExpressUtil;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLCompileException;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* 定义指令工厂
* @author xiaochengxinyizhan
*/
class DefineInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result, Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
int [] finishPoint = new int[children.length];
int arrayDimeCount =0;
String tempStr="";
for(int i = children.length - 2;i>0;i--){
ExpressNode tmpNode = children[i];
if(tmpNode.isTypeEqualsOrChild("[]")){
arrayDimeCount = arrayDimeCount +1;
node.getLeftChildren().remove(i);
tempStr = tempStr +"[]";
}else{
throw new QLCompileException("不正确的类型定义");
}
}
if(arrayDimeCount > 0){
node.getLeftChildren().get(0).setValue(node.getLeftChildren().get(0).getValue() + tempStr);
node.getLeftChildren().get(0).setOrgiValue(node.getLeftChildren().get(0).getOrgiValue() + tempStr);
Object objValue = node.getLeftChildren().get(0).getObjectValue();
if(objValue instanceof Class){
Class<?> tmpClass = ExpressUtil.getJavaClass(ExpressUtil.getClassName((Class<?>)objValue) + tempStr);
node.getLeftChildren().get(0).setObjectValue(tmpClass);
}else{
node.getLeftChildren().get(0).setObjectValue(node.getLeftChildren().get(0).getObjectValue()+ tempStr);
}
}
children = node.getChildren();
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
finishPoint[i] = result.getCurrentPoint();
}
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op, children.length).setLine(node.getLine()));
returnVal = true;
return returnVal;
}
}
复制代码
8.4.8、FieldCallInstructionFactory(属性调用指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLCompileException;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.instruction.op.OperatorField;
import com.ql.util.express.parse.ExpressNode;
/**
* 属性调用指令工厂
* @author xiaochengxinyizhan
*/
public class FieldCallInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
//处理对象
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[0], false);
returnVal = returnVal || tmpHas;
//处理属性名称
if(children[1].getNodeType().getName().equalsIgnoreCase("CONST_STRING") == false){
throw new QLCompileException("对象属性名称不是字符串常量:" + children[1] );
}
String fieldName = (String)children[1].getObjectValue();
OperatorBase op = new OperatorField(fieldName);
result.addInstruction(new InstructionOperator(op,1).setLine(node.getLine()));
return returnVal;
}
}
复制代码
8.4.9、ForInstructionFactory(for 指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLCompileException;
import com.ql.util.express.instruction.detail.InstructionCloseNewArea;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
import com.ql.util.express.instruction.detail.InstructionOpenNewArea;
import com.ql.util.express.parse.ExpressNode;
/**
* for指令工厂
* @author xiaochengxinyizhan
*/
public class ForInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
if(node.getChildren().length < 2){
throw new QLCompileException("for 操作符至少需要2个操作数 " );
}else if(node.getChildren().length > 2){
throw new QLCompileException("for 操作符最多只有2个操作数 " );
}
if(node.getChildren()[0].getChildren()!= null && node.getChildren()[0].getChildren().length > 3){
throw new QLCompileException("循环语句的设置不合适:" + node.getChildren()[0]);
}
//生成作用域开始指令
result.addInstruction(new InstructionOpenNewArea().setLine(node.getLine()));
forStack.push(new ForRelBreakContinue());
//生成条件语句部分指令
ExpressNode conditionNode = node.getChildren()[0];
int nodePoint = 0;
if (conditionNode.getChildren() != null && conditionNode.getChildren().length == 3){//变量定义,判断,自增都存在
int tempPoint = result.getCurrentPoint();
aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[0],false);
if(result.getCurrentPoint() > tempPoint){
nodePoint = nodePoint + 1;
}
}
//循环的开始的位置
int loopStartPoint = result.getCurrentPoint()+ 1;
//有条件语句
InstructionGoToWithCondition conditionInstruction=null;
if(conditionNode.getChildren() != null
&& (conditionNode.getChildren().length == 1
|| conditionNode.getChildren().length == 2
|| conditionNode.getChildren().length == 3)
) {
aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false);
//跳转的位置需要根据后续的指令情况决定
conditionInstruction = new InstructionGoToWithCondition(false,-1,true);
result.insertInstruction(result.getCurrentPoint()+1,conditionInstruction.setLine(node.getLine()));
nodePoint = nodePoint+ 1;
}
int conditionPoint = result.getCurrentPoint();
//生成循环体的代码
aCompile.createInstructionSetPrivate(result,forStack,node.getChildren()[1],false);
int selfAddPoint = result.getCurrentPoint()+1;
//生成自增代码指令
if(conditionNode.getChildren()!= null &&(
conditionNode.getChildren().length == 2 || conditionNode.getChildren().length == 3
)){
aCompile.createInstructionSetPrivate(result,forStack,conditionNode.getChildren()[nodePoint],false);
}
//增加一个无条件跳转
InstructionGoTo reStartGoto = new InstructionGoTo(loopStartPoint - (result.getCurrentPoint() + 1));
result.addInstruction(reStartGoto.setLine(node.getLine()));
//修改条件判断的跳转位置
if(conditionInstruction != null){
conditionInstruction.setOffset( result.getCurrentPoint() - conditionPoint + 1);
}
//修改Break和Continue指令的跳转位置,循环出堆
ForRelBreakContinue rel = forStack.pop();
for(InstructionGoTo item:rel.breakList){
item.setOffset(result.getCurrentPoint() - item.getOffset()) ;
}
for(InstructionGoTo item:rel.continueList){
item.setOffset(selfAddPoint - item.getOffset() - 1);
}
//生成作用域结束指令
result.addInstruction(new InstructionCloseNewArea().setLine(node.getLine()));
return false;
}
}
复制代码
8.4.10、ForRelBreakContinue(for 循环中 break 和 continue 指令)
package com.ql.util.express.instruction;
import java.util.ArrayList;
import java.util.List;
import com.ql.util.express.instruction.detail.InstructionGoTo;
/**
* for循环中break和continue指令
* @author xiaochengxinyizhan
*/
public class ForRelBreakContinue{
List<InstructionGoTo> breakList = new ArrayList<InstructionGoTo>();
List<InstructionGoTo> continueList = new ArrayList<InstructionGoTo>();
}
复制代码
8.4.11、FunctionInstructionFactory(函数指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
import com.ql.util.express.parse.ExpressNode;
/**
* 函数指令工厂
*/
public class FunctionInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
ExpressNode[] children = node.getChildren();
if(children.length != 3){
throw new QLException("funciton 操作符需要3个操作数 " );
}
String functionName =children[0].getValue();
ExpressNode[] varDefines = children[1].getChildren();
int point =0;
String instructionSetType ="";
if (node.isTypeEqualsOrChild("class")) {
instructionSetType = InstructionSet.TYPE_CLASS;
} else {
instructionSetType = InstructionSet.TYPE_FUNCTION;
}
InstructionSet functionSet = new InstructionSet(instructionSetType);
while(point<varDefines.length){
if(varDefines[point].isTypeEqualsOrChild("def") == false){
throw new QLException("function的参数定义错误," + varDefines[point] + "不是一个Class");
}
Class<?> varClass = (Class<?>)varDefines[point].getChildren()[0].getObjectValue();
String varName = varDefines[point].getChildren()[1].getValue();
OperateDataLocalVar tmpVar = new OperateDataLocalVar(varName,varClass);
functionSet.addParameter(tmpVar);
point = point + 1;
}
ExpressNode functionRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"function-" + functionName);
for(ExpressNode tempNode : children[2].getChildren()){
functionRoot.addLeftChild(tempNode);
}
aCompile.createInstructionSet(functionRoot,functionSet);
result.addMacroDefine(functionName, new FunctionInstructionSet(functionName,instructionSetType,functionSet));
return false;
}
}
复制代码
8.4.12、FunctionInstructionSet(函数指令集合)
package com.ql.util.express.instruction;
import java.io.Serializable;
import com.ql.util.express.InstructionSet;
/**
* 函数指令集合
* @author xiaochengxinyizhan
*/
public class FunctionInstructionSet implements Serializable{
private static final long serialVersionUID = 8735208809492617401L;
public String name;
public String type;
public InstructionSet instructionSet;
public FunctionInstructionSet(String aName,String aType,InstructionSet aInstructionSet){
this.name = aName;
this.type = aType;
this.instructionSet = aInstructionSet;
}
}
复制代码
8.4.13、IfInstructionFactory(if 指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLCompileException;
import com.ql.util.express.instruction.detail.InstructionGoTo;
import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
import com.ql.util.express.parse.ExpressNode;
/**
* if指令工厂
* @author xiaochengxinyizhan
*/
public class IfInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
ExpressNode[] oldChildren = node.getChildren();
if(oldChildren.length < 2){
throw new QLCompileException("if 操作符至少需要2个操作数 " );
}else if(oldChildren.length > 5){
throw new QLCompileException("if 操作符最多只有5个操作数 " );
}
ExpressNode[] children = new ExpressNode[3];
int point = 0;
for(int i=0;i<oldChildren.length;i++){
if(oldChildren[i].isTypeEqualsOrChild("then")
||oldChildren[i].isTypeEqualsOrChild("else")
||oldChildren[i].isTypeEqualsOrChild("?")
||oldChildren[i].isTypeEqualsOrChild(":")){
continue;
}
children[point] = oldChildren[i];
point = point + 1;
}
if(point == 2){
children[2] = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("STAT_BLOCK"),null);
}
int [] finishPoint = new int[children.length];
boolean r1 = aCompile.createInstructionSetPrivate(result,forStack,children[0],false);//condition
finishPoint[0] = result.getCurrentPoint();
boolean r2 = aCompile.createInstructionSetPrivate(result,forStack,children[1],false);//true
result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(false,result.getCurrentPoint() - finishPoint[0] + 2,true).setLine(node.getLine()));
finishPoint[1] = result.getCurrentPoint();
boolean r3 = aCompile.createInstructionSetPrivate(result,forStack,children[2],false);//false
result.insertInstruction(finishPoint[1]+1,new InstructionGoTo(result.getCurrentPoint() - finishPoint[1] + 1).setLine(node.getLine()));
return r1 || r2 || r3;
}
}
复制代码
8.4.14、InInstructionFactory(in 指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* in指令工厂
* @author xiaochengxinyizhan
*/
public class InInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
ExpressNode[] children = node.getChildren();
if (children[1].isTypeEqualsOrChild("CHILD_EXPRESS")) {
node.getLeftChildren().remove(1);
ExpressNode[] parameterList = children[1].getChildren();
for (int i = 0; i < parameterList.length; i++) {
node.getLeftChildren().add(parameterList[i]);
}
}
boolean returnVal = false;
children = node.getChildren();
for (int i = 0; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op, children.length).setLine(node.getLine()));
return returnVal;
}
}
复制代码
8.4.15、InstructionFactory 指令工厂
package com.ql.util.express.instruction;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.parse.ExpressNode;
/**
* 指令工厂
* @author xiaochengxinyizhan
*/
public abstract class InstructionFactory {
private static Map<String,InstructionFactory> instructionFactory = new HashMap<String,InstructionFactory>();
public static InstructionFactory getInstructionFactory(String factory) {
try {
InstructionFactory result = instructionFactory.get(factory);
if (result == null) {
result = (InstructionFactory) Class.forName(factory)
.newInstance();
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public abstract boolean createInstruction(ExpressRunner aCompile,InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node,boolean isRoot)
throws Exception;
}
复制代码
8.4.16、IOperateDataCache(操作数据缓存)
package com.ql.util.express.instruction;
import com.ql.util.express.CallResult;
import com.ql.util.express.ExpressLoader;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.RunEnvironment;
import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
import com.ql.util.express.instruction.opdata.OperateDataAttr;
import com.ql.util.express.instruction.opdata.OperateDataField;
import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
/**
* 操作数据缓存
*
* @author xiaochengxinyizhan
*/
public interface IOperateDataCache {
/**
* 获取操作数据
* @param obj
* @param aType
* @return
*/
OperateData fetchOperateData(Object obj, Class<?> aType);
/**
* 获取操作数据属性
* @param name
* @param aType
* @return
*/
OperateDataAttr fetchOperateDataAttr(String name, Class<?> aType);
/**
* 获取操作数据本地变量
* @param name
* @param aType
* @return
*/
OperateDataLocalVar fetchOperateDataLocalVar(String name, Class<?> aType);
/**
* 获取操作数据属性
* @param aFieldObject
* @param aFieldName
* @return
*/
OperateDataField fetchOperateDataField(Object aFieldObject, String aFieldName);
/**
* 获取操作数据数组项
* @param aArrayObject
* @param aIndex
* @return
*/
OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject, int aIndex);
/**
* 获取操作数据键-值
* @param aKey
* @param aValue
* @return
*/
OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue);
/**
* 获取运行环境
* @param aInstructionSet
* @param aContext
* @param aIsTrace
* @return
*/
RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet, InstructionSetContext aContext, boolean aIsTrace);
/**
* 获取调用结果
* @param aReturnValue
* @param aIsExit
* @return
*/
CallResult fetchCallResult(Object aReturnValue, boolean aIsExit);
/**
* 获取指令集上下文
* @param aIsExpandToParent
* @param aRunner
* @param aParent
* @param aExpressLoader
* @param aIsSupportDynamicFieldName
* @return
*/
InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent, ExpressRunner aRunner, IExpressContext<String, Object> aParent, ExpressLoader aExpressLoader, boolean aIsSupportDynamicFieldName);
/**
* 重置缓存
*/
void resetCache();
/**
* 获取数量
* @return
*/
long getFetchCount();
}
复制代码
8.4.17、KeyValueInstructionFactory(键值指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* 键值指令工厂
* @author xiaochengxinyizhan
*/
class KeyValueInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result, Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT")){
children[0].setNodeType(aCompile.getNodeTypeManager().findNodeType("CONST_STRING"));
children[0].setTreeType(aCompile.getNodeTypeManager().findNodeType("CONST"));
children[0].setObjectValue(children[0].getValue());
}
if( node.getParent() != null && node.getParent().isTypeEqualsOrChild("STATEMENT") && children[1].isTypeEqualsOrChild("STAT_BLOCK")){
returnVal = new MacroInstructionFactory().createInstruction(aCompile, result, forStack, node, isRoot);
} else if (node.getParent() != null&& node.getParent().isTypeEqualsOrChild("STATEMENT")) {
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().newInstance("alias");
result.addInstruction(new InstructionOperator(op, children.length).setLine(node.getLine()));
returnVal = true;
}else{
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op,children.length).setLine(node.getLine()));
}
return returnVal;
}
}
复制代码
8.4.18、LoadAttrInstructionFactory(加载属性指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.detail.InstructionCallMacro;
import com.ql.util.express.instruction.detail.InstructionLoadAttr;
import com.ql.util.express.parse.ExpressNode;
/**
* 加载属性指令工厂
* @author xiaochengxinyizhan
*/
public class LoadAttrInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception{
FunctionInstructionSet functionSet = result.getMacroDefine(node.getValue());
if(functionSet != null){//是宏定义
result.insertInstruction(result.getCurrentPoint()+1, new InstructionCallMacro(node.getValue()).setLine(node.getLine()).setLine(node.getLine()));
}else{
result.addInstruction(new InstructionLoadAttr(node.getValue()).setLine(node.getLine()));
if(node.getChildren().length >0){
throw new QLException("表达式设置错误");
}
}
return false;
}
}
复制代码
8.4.19、MacroInstructionFactory(宏指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.parse.ExpressNode;
/**
* 宏指令工厂
* @author xiaochengxinyizhan
*/
public class MacroInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
ExpressNode[] children = node.getChildren();
String macroName =children[0].getValue();
ExpressNode macroRoot = new ExpressNode(aCompile.getNodeTypeManager().findNodeType("FUNCTION_DEFINE"),"macro-" + macroName);
for(ExpressNode tempNode : children[1].getChildren()){
macroRoot.addLeftChild(tempNode);
}
InstructionSet macroInstructionSet = aCompile.createInstructionSet(macroRoot,InstructionSet.TYPE_MARCO);
result.addMacroDefine(macroName, new FunctionInstructionSet(macroName,"macro",macroInstructionSet));
return false;
}
}
复制代码
8.4.20、MethodCallInstructionFactory(方法调用指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLException;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.instruction.op.OperatorMethod;
import com.ql.util.express.parse.ExpressNode;
/**
* 方法调用指令工厂
* @author xiaochengxinyizhan
*/
public class MethodCallInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
//处理对象
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[0], false);
returnVal = returnVal || tmpHas;
//处理方法名称
if(children[1].getNodeType().getName().equalsIgnoreCase("CONST_STRING") == false){
throw new QLException("对象方法名称不是字符串常量:" + children[1] );
}
String methodName = (String)children[1].getObjectValue();
//处理方法参数
for (int i = 2; i < children.length; i++) {
tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
OperatorBase op = new OperatorMethod(methodName);
result.addInstruction(new InstructionOperator(op, children.length - 1).setLine(node.getLine()));
return returnVal;
}
}
复制代码
8.4.21、NewInstructionFactory(new 指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.ExpressUtil;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* new指令工厂
* @author xiaochengxinyizhan
*/
public class NewInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
OperatorBase op = aCompile.getOperatorFactory().newInstance("new");
ExpressNode[] children = node.getChildren();
if (node.isTypeEqualsOrChild("NEW_ARRAY")) {
String tempStr = children[0].getValue();
for (int i = 0; i < children.length - 1; i++) {
tempStr = tempStr + "[]";
}
children[0].setValue(tempStr);
children[0].setOrgiValue(tempStr);
children[0].setObjectValue(ExpressUtil.getJavaClass(tempStr));
}else if (node.isTypeEqualsOrChild("anonymousNewArray")) {
op = aCompile.getOperatorFactory().newInstance("anonymousNewArray");
}
boolean returnVal = false;
children = node.getChildren();// 需要重新获取数据
for (int i = 0; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
result.addInstruction(new InstructionOperator(op, children.length).setLine(node.getLine()));
return returnVal;
}
}
复制代码
8.4.22、NewVClassInstructionFactory(new 虚拟机类指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionNewVirClass;
import com.ql.util.express.parse.ExpressNode;
/**
* new虚拟机类指令工厂
* @author xiaochengxinyizhan
*/
public class NewVClassInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile,
InstructionSet result, Stack<ForRelBreakContinue> forStack,
ExpressNode node, boolean isRoot) throws Exception {
ExpressNode[] children = node.getChildren();
boolean returnVal = false;
String virClassName = children[0].getValue();
for (int i = 1; i < children.length; i++) {
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack, children[i], false);
returnVal = returnVal || tmpHas;
}
result.addInstruction(new InstructionNewVirClass(virClassName, children.length -1).setLine(node.getLine()));
return returnVal;
}
}
复制代码
8.4.23、NullInstructionFactory(空指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.parse.ExpressNode;
/**
* 空指令工厂
* @author xiaochengxinyizhan
*/
public class NullInstructionFactory extends InstructionFactory {
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result,
Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
return false;
}
}
复制代码
8.4.24、OperateDataCacheImpl(操作数缓存实现类)
package com.ql.util.express.instruction;
import com.ql.util.express.CallResult;
import com.ql.util.express.ExpressLoader;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.RunEnvironment;
import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
import com.ql.util.express.instruction.opdata.OperateDataAttr;
import com.ql.util.express.instruction.opdata.OperateDataField;
import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
/**
* 操作数缓存实现类
* @author xiaochengxinyizhan
*/
public class OperateDataCacheImpl implements IOperateDataCache{
OperateData[] dataList;
OperateDataAttr[] attrList;
OperateDataLocalVar[] localVarList;
OperateDataField[] fieldList;
OperateDataArrayItem[] arrayList;
OperateDataKeyValue[] keyValueList;
RunEnvironment[] environmentList;
CallResult[] callResultList;
InstructionSetContext[] contextList;
int dataPoint = 0;
int attrPoint = 0;
int localVarPoint =0;
int fieldPoint =0;
int arrayPoint =0;
int keyValuePoint=0;
int environmentPoint =0;
int callResultPoint = 0;
int contextPoint =0;
int length;
public OperateDataCacheImpl(int len){
length = len;
dataList = new OperateData[len];
attrList = new OperateDataAttr[len];
localVarList = new OperateDataLocalVar[len];
fieldList = new OperateDataField[len];
arrayList = new OperateDataArrayItem[len];
keyValueList = new OperateDataKeyValue[len];
callResultList = new CallResult[len];
environmentList = new RunEnvironment[len];
contextList = new InstructionSetContext[len];
for(int i=0;i<len;i++){
dataList[i] = new OperateData(null,null);
attrList[i] = new OperateDataAttr(null,null);
localVarList[i] = new OperateDataLocalVar(null,null);
fieldList[i] = new OperateDataField(null,null);
arrayList[i] = new OperateDataArrayItem(null,-1);
keyValueList[i] = new OperateDataKeyValue(null,null);
callResultList[i] = new CallResult(null,false);
environmentList[i] = new RunEnvironment(null,null,false);
contextList[i] = new InstructionSetContext(false,null,null,null,false);
}
}
@Override
public void resetCache(){
for(int i=0;i<=dataPoint&&i<length;i++){
dataList[i].clear();
}
for(int i=0;i<=attrPoint&&i<length;i++){
attrList[i].clearDataAttr();
}
for(int i=0;i<=localVarPoint&&i<length;i++){
localVarList[i].clearDataLocalVar();
}
for(int i=0;i<=fieldPoint&&i<length;i++){
fieldList[i].clearDataField();
}
for(int i=0;i<=arrayPoint&&i<length;i++){
arrayList[i].clearDataArrayItem();
}
for(int i=0;i<=keyValuePoint&&i<length;i++){
keyValueList[i].clearDataKeyValue();
}
for(int i=0;i<=callResultPoint&&i<length;i++){
callResultList[i].clear();
}
for(int i=0;i<=environmentPoint&&i<length;i++){
environmentList[i].clear();
}
for(int i=0;i<=contextPoint&&i<length;i++){
contextList[i].clear();
}
dataPoint =0 ;
attrPoint =0 ;
localVarPoint =0;
fieldPoint =0;
arrayPoint =0;
keyValuePoint=0;
callResultPoint = 0;
environmentPoint = 0;
contextPoint = 0;
}
@Override
public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent, ExpressRunner aRunner, IExpressContext<String,Object> aParent, ExpressLoader aExpressLoader, boolean aIsSupportDynamicFieldName){
InstructionSetContext result = null;
if(contextPoint < length){
result = contextList[contextPoint];
result.initial(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
contextPoint = contextPoint + 1;
}else{
result = new InstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
}
return result;
}
@Override
public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet, InstructionSetContext aContext, boolean aIsTrace){
RunEnvironment result = null;
if(environmentPoint < length){
result = environmentList[environmentPoint];
result.initial(aInstructionSet, aContext, aIsTrace);
environmentPoint = environmentPoint + 1;
}else{
result = new RunEnvironment(aInstructionSet, aContext, aIsTrace);
}
return result;
}
@Override
public CallResult fetchCallResult(Object aReturnValue, boolean aIsExit){
CallResult result = null;
if(callResultPoint < length){
result = callResultList[callResultPoint];
result.initial(aReturnValue,aIsExit);
callResultPoint = callResultPoint + 1;
}else{
result = new CallResult(aReturnValue,aIsExit);
}
return result;
}
@Override
public OperateData fetchOperateData(Object obj, Class<?> aType){
OperateData result = null;
if(dataPoint < length){
result = dataList[dataPoint];
result.initial(obj, aType);
dataPoint = dataPoint + 1;
}else{
result = new OperateData(obj,aType);
}
return result;
}
@Override
public OperateDataAttr fetchOperateDataAttr(String name, Class<?> aType){
OperateDataAttr result = null;
if(attrPoint < length){
result = attrList[attrPoint];
result.initialDataAttr(name, aType);
attrPoint = attrPoint + 1;
}else{
result = new OperateDataAttr(name,aType);
}
return result;
}
@Override
public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class<?> aType){
OperateDataLocalVar result = null;
if(localVarPoint < length){
result = localVarList[localVarPoint];
result.initialDataLocalVar(name, aType);
localVarPoint = localVarPoint + 1;
}else{
result = new OperateDataLocalVar(name,aType);
}
return result;
}
@Override
public OperateDataField fetchOperateDataField(Object aFieldObject, String aFieldName){
OperateDataField result = null;
if(fieldPoint < length){
result = fieldList[fieldPoint];
result.initialDataField(aFieldObject,aFieldName);
fieldPoint = fieldPoint + 1;
}else{
result = new OperateDataField(aFieldObject,aFieldName);
}
return result;
}
@Override
public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject, int aIndex){
OperateDataArrayItem result = null;
if(arrayPoint < length){
result = arrayList[arrayPoint];
result.initialDataArrayItem(aArrayObject,aIndex);
arrayPoint = arrayPoint + 1;
}else{
result = new OperateDataArrayItem(aArrayObject,aIndex);
}
return result;
}
@Override
public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){
OperateDataKeyValue result = null;
if(this.keyValuePoint < length){
result = this.keyValueList[keyValuePoint];
result.initialDataKeyValue(aKey,aValue);
keyValuePoint = keyValuePoint + 1;
}else{
result = new OperateDataKeyValue(aKey,aValue);
}
return result;
}
@Override
public long getFetchCount() {
return 0;
}
}
复制代码
8.4.25、OperateDataCacheImpl4Orig(操作数据缓存实现类支持原生的)
package com.ql.util.express.instruction;
import com.ql.util.express.CallResult;
import com.ql.util.express.ExpressLoader;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.RunEnvironment;
import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
import com.ql.util.express.instruction.opdata.OperateDataAttr;
import com.ql.util.express.instruction.opdata.OperateDataField;
import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
/**
* 操作数据缓存实现类支持原生的
* @author xiaochengxinyiizhan
*/
class OperateDataCacheImpl4Orig implements IOperateDataCache {
@Override
public OperateData fetchOperateData(Object obj, Class<?> aType) {
return new OperateData(obj,aType);
}
@Override
public OperateDataAttr fetchOperateDataAttr(String name, Class<?> aType) {
return new OperateDataAttr(name, aType);
}
@Override
public OperateDataLocalVar fetchOperateDataLocalVar(String name, Class<?> aType) {
return new OperateDataLocalVar(name, aType);
}
@Override
public OperateDataField fetchOperateDataField(Object aFieldObject, String aFieldName){
return new OperateDataField(aFieldObject, aFieldName);
}
@Override
public OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject, int aIndex){
return new OperateDataArrayItem(aArrayObject, aIndex);
}
@Override
public OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){
return new OperateDataKeyValue(aKey, aValue);
}
@Override
public RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet, InstructionSetContext aContext, boolean aIsTrace){
return new RunEnvironment(aInstructionSet, aContext, aIsTrace);
}
@Override
public CallResult fetchCallResult(Object aReturnValue, boolean aIsExit){
return new CallResult(aReturnValue, aIsExit);
}
@Override
public InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent, ExpressRunner aRunner, IExpressContext<String,Object> aParent, ExpressLoader aExpressLoader, boolean aIsSupportDynamicFieldName){
return new InstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
}
@Override
public void resetCache(){
}
@Override
public long getFetchCount(){
return 0;
}
}
复制代码
8.4.26、OperateDataCacheManager(操作数据缓存管理器)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.CallResult;
import com.ql.util.express.ExpressLoader;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.RunEnvironment;
import com.ql.util.express.instruction.opdata.OperateDataArrayItem;
import com.ql.util.express.instruction.opdata.OperateDataAttr;
import com.ql.util.express.instruction.opdata.OperateDataField;
import com.ql.util.express.instruction.opdata.OperateDataKeyValue;
import com.ql.util.express.instruction.opdata.OperateDataLocalVar;
/**
* 操作数据缓存管理器
* @author xiaochengxinyizhan
*/
public class OperateDataCacheManager {
private static ThreadLocal<RunnerDataCache> m_OperateDataObjectCache = new ThreadLocal<RunnerDataCache>(){
protected RunnerDataCache initialValue() {
return new RunnerDataCache();
}
};
public static void push(ExpressRunner aRunner){
m_OperateDataObjectCache.get().push(aRunner);
}
public static IOperateDataCache getOperateDataCache(){
return m_OperateDataObjectCache.get().cache;
}
public static OperateData fetchOperateData(Object obj, Class<?> aType) {
return getOperateDataCache().fetchOperateData(obj, aType);
}
public static OperateDataAttr fetchOperateDataAttr(String name, Class<?> aType) {
return getOperateDataCache().fetchOperateDataAttr(name, aType);
}
public static OperateDataLocalVar fetchOperateDataLocalVar(String name, Class<?> aType) {
return getOperateDataCache().fetchOperateDataLocalVar(name, aType);
}
public static OperateDataField fetchOperateDataField(Object aFieldObject,String aFieldName){
return getOperateDataCache().fetchOperateDataField(aFieldObject, aFieldName);
}
public static OperateDataArrayItem fetchOperateDataArrayItem(OperateData aArrayObject,int aIndex){
return getOperateDataCache().fetchOperateDataArrayItem(aArrayObject, aIndex);
}
public static OperateDataKeyValue fetchOperateDataKeyValue(OperateData aKey, OperateData aValue){
return getOperateDataCache().fetchOperateDataKeyValue(aKey, aValue);
}
public static RunEnvironment fetRunEnvironment(InstructionSet aInstructionSet,InstructionSetContext aContext,boolean aIsTrace){
return getOperateDataCache().fetRunEnvironment(aInstructionSet, aContext, aIsTrace);
}
public static CallResult fetchCallResult(Object aReturnValue,boolean aIsExit){
return getOperateDataCache().fetchCallResult(aReturnValue, aIsExit);
}
public static InstructionSetContext fetchInstructionSetContext(boolean aIsExpandToParent,ExpressRunner aRunner,IExpressContext<String,Object> aParent,ExpressLoader aExpressLoader,boolean aIsSupportDynamicFieldName){
return getOperateDataCache().fetchInstructionSetContext(aIsExpandToParent, aRunner, aParent, aExpressLoader, aIsSupportDynamicFieldName);
}
public static long getFetchCount(){
return getOperateDataCache().getFetchCount();
}
public static void resetCache(ExpressRunner aRunner){
getOperateDataCache().resetCache();
m_OperateDataObjectCache.get().pop(aRunner);
}
}
class RunnerDataCache{
IOperateDataCache cache;
Stack<ExpressRunner> stack = new Stack<ExpressRunner>();
public void push(ExpressRunner aRunner){
this.cache = aRunner.getOperateDataCache();
this.stack.push(aRunner);
}
public IOperateDataCache getOperateDataCache(){
return this.cache;
}
public void pop(ExpressRunner aRunner){
// 原有的逻辑
// this.cache = this.stack.pop().getOperateDataCache();
//bugfix处理ExpressRunner嵌套情况下,cache还原的问题
this.stack.pop();
if(!this.stack.isEmpty()){
this.cache = this.stack.peek().getOperateDataCache();
}else{
this.cache = null;
}
}
}
复制代码
8.4.27、OperatorInstructionFactory(操作指令工厂)
package com.ql.util.express.instruction;
import java.util.Stack;
import com.ql.util.express.ExportItem;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.instruction.detail.InstructionGoToWithCondition;
import com.ql.util.express.instruction.detail.InstructionGoToWithNotNull;
import com.ql.util.express.instruction.detail.InstructionOperator;
import com.ql.util.express.instruction.detail.InstructionReturn;
import com.ql.util.express.instruction.op.OperatorBase;
import com.ql.util.express.parse.ExpressNode;
/**
* 操作指令工厂
* @author xiaochengxinyizhan
*/
class OperatorInstructionFactory extends InstructionFactory{
@Override
public boolean createInstruction(ExpressRunner aCompile, InstructionSet result, Stack<ForRelBreakContinue> forStack, ExpressNode node, boolean isRoot)
throws Exception {
boolean returnVal = false;
ExpressNode[] children = node.getChildren();
int [] finishPoint = new int[children.length];
for(int i =0;i < children.length;i++){
ExpressNode tmpNode = children[i];
boolean tmpHas = aCompile.createInstructionSetPrivate(result,forStack,tmpNode,false);
returnVal = returnVal || tmpHas;
finishPoint[i] = result.getCurrentPoint();
}
if(node.isTypeEqualsOrChild("return")){
result.addInstruction(new InstructionReturn(children.length > 0).setLine(node.getLine()));
}else{
OperatorBase op = aCompile.getOperatorFactory().newInstance(node);
result.addInstruction(new InstructionOperator(op,children.length).setLine(node.getLine()).setLine(node.getLine()));
if(node.isTypeEqualsOrChild("&&") && aCompile.isShortCircuit()){
result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(false,result.getCurrentPoint() - finishPoint[0] + 1,false).setLine(node.getLine()));
}else if(node.isTypeEqualsOrChild("||") && aCompile.isShortCircuit()){
result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithCondition(true,result.getCurrentPoint() - finishPoint[0] + 1,false).setLine(node.getLine()));
}else if(node.isTypeEqualsOrChild("nor") ){
result.insertInstruction(finishPoint[0]+1,new InstructionGoToWithNotNull(result.getCurrentPoint() - finishPoint[0] + 1,false).setLine(node.getLine()));
}else if(node.isTypeEqualsOrChild("def") || node.isTypeEqualsOrChild("alias")){
returnVal = true;
}else if(node.isTypeEqualsOrChild("exportDef")){
//添加对外的变量声明
result.addExportDef(new ExportItem(children[1].toString(),ExportItem.TYPE_DEF,"还没有实现"));
}else if(node.isTypeEqualsOrChild("exportAlias")){
result.addExportDef(new ExportItem(children[0].toString(),ExportItem.TYPE_ALIAS,"还没有实现"));
}
}
return returnVal;
}
}
复制代码
划线
评论
复制
发布于: 2021 年 01 月 17 日阅读数: 20
版权声明: 本文为 InfoQ 作者【小诚信驿站】的原创文章。
原文链接:【http://xie.infoq.cn/article/af6eda6216c3cc175625ebc78】。文章转载请联系作者。
小诚信驿站
关注
小胜靠智,大胜靠德 2019.06.27 加入
历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666
评论