RunEnvironment.java 4.5 KB
Newer Older
T
update  
tianqiao 已提交
1 2 3
package com.ql.util.express;


4
import com.ql.util.express.exception.QLException;
T
update  
tianqiao 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

public final class RunEnvironment {
		private static int INIT_DATA_LENTH = 15;
	    private boolean isTrace = false;	
		private int point = -1;
	    protected int programPoint = 0;
		private OperateData[] dataContainer;
		private ArraySwap arraySwap = new ArraySwap();
		
		private boolean isExit = false;
		private Object returnValue = null; 
		
		private InstructionSet instructionSet;
		private InstructionSetContext context;
		
		
		public RunEnvironment(InstructionSet aInstructionSet,InstructionSetContext  aContext,boolean aIsTrace){
			dataContainer = new OperateData[INIT_DATA_LENTH];
			this.instructionSet = aInstructionSet;
			this.context = aContext;
			this.isTrace = aIsTrace;
		}
		
		public void initial(InstructionSet aInstructionSet,InstructionSetContext  aContext,boolean aIsTrace){
			this.instructionSet = aInstructionSet;
			this.context = aContext;
			this.isTrace = aIsTrace;
		}
		public void clear(){
		    isTrace = false;	
			point = -1;
		    programPoint = 0;
			
			isExit = false;
			returnValue = null; 
			
			instructionSet = null;
			context = null;
			
		}
		public InstructionSet getInstructionSet() {
			return instructionSet;
		}


		public InstructionSetContext getContext(){
			return this.context;
		}
		public void setContext(InstructionSetContext aContext){
			this.context = aContext;
		}

		public boolean isExit() {
			return isExit;
		}
		public Object getReturnValue() {
			return returnValue;
		}
		public void setReturnValue(Object value){
			this.returnValue = value;
		}
		public void quitExpress(Object aReturnValue){
			this.isExit = true;
			this.returnValue = aReturnValue;
		}
		public void quitExpress(){
			this.isExit = true;
			this.returnValue = null;
		}
		public boolean isTrace(){
			return this.isTrace;
		}
		public int getProgramPoint() {
			return programPoint;
		}
		public void programPointAddOne() {
			programPoint ++ ;
		}
		public void gotoLastWhenReturn(){
			programPoint = this.instructionSet.getInstructionLength();
		}
	    public int getDataStackSize(){
	    	return this.point + 1;
	    }
		public void push(OperateData data){
			this.point++;
			if(this.point >= this.dataContainer.length){
			   ensureCapacity(this.point + 1);
			}
			this.dataContainer[point] = data;
		}
		public OperateData peek(){
			if(point <0){
				throw new RuntimeException("系统异常,堆栈指针错误");
			}
			return this.dataContainer[point];		
		}
		public OperateData pop(){
			if(point <0)
				throw new RuntimeException("系统异常,堆栈指针错误");
			OperateData result = this.dataContainer[point];
			this.point--;
			return result;
		}
		public void clearDataStack(){
			this.point = -1;
		}
		public void gotoWithOffset(int aOffset ){
			this.programPoint = this.programPoint + aOffset;
		}
	/**
	 * 此方法是调用最频繁的,因此尽量精简代码,提高效率 
	 * @param context
	 * @param len
	 * @return
	 * @throws Exception
	 */
		public ArraySwap popArray(InstructionSetContext context,int len) throws Exception {
			int start = point - len + 1;
			this.arraySwap.swap(this.dataContainer,start,len);
			point = point - len;
			return this.arraySwap;
		}
		
		public OperateData[] popArrayOld(InstructionSetContext context,int len) throws Exception {
			int start = point - len + 1;
			OperateData[] result = new OperateData[len];
			System.arraycopy(this.dataContainer,start, result,0, len);
			point = point - len;
			return result;
		}
		
		public OperateData[] popArrayBackUp(InstructionSetContext context,int len) throws Exception {
			int start = point - len + 1;
			if(start <0){
140
				throw new QLException("堆栈溢出,请检查表达式是否错误");
T
update  
tianqiao 已提交
141 142 143 144 145
			}
			OperateData[] result = new OperateData[len];
			for (int i = 0 ; i < len; i++) {
				result[i] = this.dataContainer[start + i];
				if(void.class.equals(result[i].getType(context))){
146
					throw new QLException("void 不能参与任何操作运算,请检查使用在表达式中使用了没有返回值的函数,或者分支不完整的if语句");
T
update  
tianqiao 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
				}
			}
			point = point - len;
			return result;
		}

		public void ensureCapacity(int minCapacity) {
			int oldCapacity = this.dataContainer.length;
			if (minCapacity > oldCapacity) {
				int newCapacity = (oldCapacity * 3) / 2 + 1;
				if (newCapacity < minCapacity){
					newCapacity = minCapacity;
				}
				OperateData[] tempList = new OperateData[newCapacity];
				System.arraycopy(this.dataContainer,0,tempList,0,oldCapacity);
				this.dataContainer = tempList;
			}
		}
	}