|
@@ -1,7 +1,6 @@
|
|
|
import { Store } from './store/store';
|
|
|
import { StoreObject } from './store/storeObject';
|
|
|
import { StoreObjectArray } from './store/storeObjectArray';
|
|
|
-import { StoreObjectRef } from './store/storeObjectRef';
|
|
|
import { Modes } from './modes';
|
|
|
import { Context } from './context';
|
|
|
import { Types } from './../typeSystem/types';
|
|
@@ -18,6 +17,8 @@ import { Config } from '../util/config';
|
|
|
import { ProcessorErrorFactory } from './error/processorErrorFactory';
|
|
|
import { RuntimeError } from './error/runtimeError';
|
|
|
import { Location } from '../memory/location';
|
|
|
+import { StoreValue } from './store/store_value';
|
|
|
+import { StoreValueRef } from './store/store_value_ref';
|
|
|
|
|
|
export class IVProgProcessor {
|
|
|
|
|
@@ -135,7 +136,7 @@ export class IVProgProcessor {
|
|
|
returnStoreObject = new StoreObjectArray(func.returnType,-1,null,[]);
|
|
|
}
|
|
|
} else {
|
|
|
- returnStoreObject = new StoreObject(func.returnType, Location.allocate(null));
|
|
|
+ returnStoreObject = new StoreValue(func.returnType, null, null);//new StoreObject(func.returnType, Location.allocate(null));
|
|
|
}
|
|
|
funcStore.insertStore('$', returnStoreObject);
|
|
|
const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
|
|
@@ -177,24 +178,25 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(formalParameter.byRef && !stoObj.inStore) {
|
|
|
+ if(formalParameter.byRef && !stoObj.inStore()) {
|
|
|
throw ProcessorErrorFactory.invalid_ref(funcName, exp.toString());
|
|
|
}
|
|
|
|
|
|
if(formalParameter.byRef) {
|
|
|
let ref = null;
|
|
|
if (stoObj instanceof StoreObjectArrayAddress) {
|
|
|
- ref = new StoreObjectArrayAddressRef(stoObj);
|
|
|
+ ref = new StoreObjectArrayAddressRef(callerStore.getStoreObject(stoObj.id));
|
|
|
} else {
|
|
|
- ref = new StoreObjectRef(stoObj);
|
|
|
+ const realObj = callerStore.getStoreObject(stoObj.id);
|
|
|
+ ref = new StoreValueRef(realObj.type, realObj.value, realObj.locAddress, realObj.id);
|
|
|
}
|
|
|
calleeStore.insertStore(formalParameter.id, ref);
|
|
|
} else {
|
|
|
- let realValue = this.parseStoreObjectValue(stoObj);
|
|
|
+ let realValue = stoObj;
|
|
|
if (shouldTypeCast) {
|
|
|
realValue = Store.doImplicitCasting(formalParameter.type, realValue);
|
|
|
}
|
|
|
- calleeStore.insertStore(formalParameter.id, realValue.copy());
|
|
|
+ calleeStore.insertStore(formalParameter.id, realValue);
|
|
|
}
|
|
|
}
|
|
|
return calleeStore;
|
|
@@ -221,9 +223,6 @@ export class IVProgProcessor {
|
|
|
} else if(this.checkContext(Context.BREAKABLE) && store.mode === Modes.BREAK) {
|
|
|
return Promise.resolve(store);
|
|
|
}
|
|
|
- if (Location.size() % 100 == 0) {
|
|
|
- Location.gc();
|
|
|
- }
|
|
|
if (cmd instanceof Commands.Declaration) {
|
|
|
return this.executeDeclaration(store, cmd);
|
|
|
} else if (cmd instanceof Commands.ArrayIndexAssign) {
|
|
@@ -267,11 +266,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
return this.runFunction(func, cmd.actualParameters, store)
|
|
|
.then(sto => {
|
|
|
- for(let id in sto.store) {
|
|
|
- if (Object.prototype.hasOwnProperty.call(sto.store, id)) {
|
|
|
- sto.store[id].destroy();
|
|
|
- }
|
|
|
- }
|
|
|
+ sto.destroy();
|
|
|
if(!Types.VOID.isCompatible(func.returnType) && sto.mode !== Modes.RETURN) {
|
|
|
const funcName = func.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
LanguageDefinedFunction.getMainFunctionName() : func.name;
|
|
@@ -279,7 +274,7 @@ export class IVProgProcessor {
|
|
|
} else {
|
|
|
return store;
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
executeSwitch (store, cmd) {
|
|
@@ -295,7 +290,7 @@ export class IVProgProcessor {
|
|
|
} else {
|
|
|
const equalityInfixApp = new Expressions.InfixApp(Operators.EQ, cmd.expression, next.expression);
|
|
|
equalityInfixApp.sourceInfo = next.sourceInfo;
|
|
|
- return outerRef.evaluateExpression(tuple[1],equalityInfixApp).then(stoObj => stoObj.value)
|
|
|
+ return outerRef.evaluateExpression(tuple[1],equalityInfixApp).then(stoObj => stoObj.get())
|
|
|
.then(isEqual => {
|
|
|
if (isEqual) {
|
|
|
return this.executeCommands(tuple[1], next.commands)
|
|
@@ -353,10 +348,10 @@ export class IVProgProcessor {
|
|
|
if (!vl.type.isCompatible(Types.BOOLEAN)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
|
|
|
}
|
|
|
- if (vl.value) {
|
|
|
+ if (vl.get()) {
|
|
|
outerRef.context.pop();
|
|
|
- for (let i = 0; i < outerRef.loopTimers.length; i++) {
|
|
|
- const time = outerRef.loopTimers[i];
|
|
|
+ if(outerRef.loopTimers.length > 0) {
|
|
|
+ const time = outerRef.loopTimers[0];
|
|
|
if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
|
|
|
outerRef.forceKill = true;
|
|
|
return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
|
|
@@ -383,7 +378,7 @@ export class IVProgProcessor {
|
|
|
const $value = outerRef.evaluateExpression(store, cmd.expression);
|
|
|
return $value.then(vl => {
|
|
|
if(vl.type.isCompatible(Types.BOOLEAN)) {
|
|
|
- if(vl.value) {
|
|
|
+ if(vl.get()) {
|
|
|
const $newStore = outerRef.executeCommands(store, cmd.commands);
|
|
|
return $newStore.then(sto => {
|
|
|
outerRef.context.pop();
|
|
@@ -392,8 +387,8 @@ export class IVProgProcessor {
|
|
|
sto.mode = Modes.RUN;
|
|
|
return sto;
|
|
|
}
|
|
|
- for (let i = 0; i < outerRef.loopTimers.length; i++) {
|
|
|
- const time = outerRef.loopTimers[i];
|
|
|
+ if (outerRef.loopTimers.length > 0) {
|
|
|
+ const time = outerRef.loopTimers[0];
|
|
|
if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
|
|
|
outerRef.forceKill = true;
|
|
|
return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
|
|
@@ -421,7 +416,7 @@ export class IVProgProcessor {
|
|
|
const $value = this.evaluateExpression(store, cmd.condition);
|
|
|
return $value.then(vl => {
|
|
|
if(vl.type.isCompatible(Types.BOOLEAN)) {
|
|
|
- if(vl.value) {
|
|
|
+ if(vl.get()) {
|
|
|
return this.executeCommands(store, cmd.ifTrue.commands);
|
|
|
} else if( cmd.ifFalse !== null){
|
|
|
if(cmd.ifFalse instanceof Commands.IfThenElse) {
|
|
@@ -516,14 +511,14 @@ export class IVProgProcessor {
|
|
|
if(!Types.INTEGER.isCompatible(lineSO.type)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
}
|
|
|
- const line = lineSO.number;
|
|
|
+ const line = lineSO.get();
|
|
|
const columnSO = results[1];
|
|
|
let column = null
|
|
|
if (columnSO !== null) {
|
|
|
if(!Types.INTEGER.isCompatible(columnSO.type)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
}
|
|
|
- column = columnSO.number;
|
|
|
+ column = columnSO.get();
|
|
|
}
|
|
|
const value = this.parseStoreObjectValue(results[2]);
|
|
|
let actualValue = value;
|
|
@@ -599,7 +594,7 @@ export class IVProgProcessor {
|
|
|
if(!Types.INTEGER.isCompatible(lineSO.type)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
}
|
|
|
- const line = lineSO.number;
|
|
|
+ const line = lineSO.get();
|
|
|
if(line < 0) {
|
|
|
throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
|
|
|
}
|
|
@@ -609,7 +604,7 @@ export class IVProgProcessor {
|
|
|
if(!Types.INTEGER.isCompatible(columnSO.type)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
}
|
|
|
- column = columnSO.number;
|
|
|
+ column = columnSO.get();
|
|
|
if(column < 0) {
|
|
|
throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
|
|
|
}
|
|
@@ -644,7 +639,7 @@ export class IVProgProcessor {
|
|
|
if(cmd.initial !== null) {
|
|
|
$value = this.evaluateExpression(store, cmd.initial);
|
|
|
}
|
|
|
- const temp = new StoreObject(cmd.type, Location.allocate(null));
|
|
|
+ const temp = new StoreValue(cmd.type, null);
|
|
|
store.insertStore(cmd.id, temp);
|
|
|
return $value.then(vl => {
|
|
|
let realValue = vl;
|
|
@@ -667,9 +662,9 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- realValue = new StoreObject(cmd.type, Location.allocate(0));
|
|
|
+ realValue = new StoreValue(cmd.type, 0);
|
|
|
}
|
|
|
- realValue.readOnly = cmd.isConst;
|
|
|
+ realValue.isConst = cmd.isConst;
|
|
|
store.updateStore(cmd.id, realValue);
|
|
|
return store;
|
|
|
});
|
|
@@ -715,14 +710,10 @@ export class IVProgProcessor {
|
|
|
const $newStore = this.runFunction(func, exp.actualParameters, store);
|
|
|
return $newStore.then( sto => {
|
|
|
if(sto.mode !== Modes.RETURN) {
|
|
|
- return Promise.reject(new Error("The function that was called did not had a return command: "+exp.id));
|
|
|
+ return Promise.reject(new Error("The function that was called did not have a return command: "+exp.id));
|
|
|
}
|
|
|
const val = sto.applyStore('$');
|
|
|
- for(let id in sto.store) {
|
|
|
- if (Object.prototype.hasOwnProperty.call(sto.store, id)) {
|
|
|
- sto.store[id].destroy();
|
|
|
- }
|
|
|
- }
|
|
|
+ sto.destroy();
|
|
|
if (val instanceof StoreObjectArray) {
|
|
|
return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null,null), val));
|
|
|
} else {
|
|
@@ -836,7 +827,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
|
|
|
evaluateLiteral (_, exp) {
|
|
|
- return Promise.resolve(new StoreObject(exp.type, Location.allocate(exp.value)));
|
|
|
+ return Promise.resolve(new StoreValue(exp.type, exp.value));
|
|
|
}
|
|
|
|
|
|
evaluateVariableLiteral (store, exp) {
|
|
@@ -865,13 +856,13 @@ export class IVProgProcessor {
|
|
|
if(!Types.INTEGER.isCompatible(lineSO.type)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
|
}
|
|
|
- const line = lineSO.number;
|
|
|
+ const line = lineSO.get();
|
|
|
let column = null;
|
|
|
if(columnSO !== null) {
|
|
|
if(!Types.INTEGER.isCompatible(columnSO.type)) {
|
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
|
}
|
|
|
- column = columnSO.number;
|
|
|
+ column = columnSO.get();
|
|
|
}
|
|
|
|
|
|
if (line >= mustBeArray.lines) {
|
|
@@ -909,11 +900,11 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
switch (unaryApp.op.ord) {
|
|
|
case Operators.ADD.ord:
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value));
|
|
|
+ return new StoreValue(resultType, left.get());
|
|
|
case Operators.SUB.ord:
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value.negated()));
|
|
|
+ return new StoreValue(resultType, left.get().negated());
|
|
|
case Operators.NOT.ord:
|
|
|
- return new StoreObject(resultType, Location.allocate(!left.value));
|
|
|
+ return new StoreValue(resultType, !left.get());
|
|
|
default:
|
|
|
return Promise.reject(new RuntimeError('!!!Critical Invalid UnaryApp '+ unaryApp.op));
|
|
|
}
|
|
@@ -944,37 +935,37 @@ export class IVProgProcessor {
|
|
|
switch (infixApp.op.ord) {
|
|
|
case Operators.ADD.ord: {
|
|
|
if(Types.STRING.isCompatible(left.type)) {
|
|
|
- const rightStr = convertToString(right.value, right.type);
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value + rightStr));
|
|
|
+ const rightStr = convertToString(right.get(), right.type);
|
|
|
+ return new StoreValue(resultType, (left.get() + rightStr));
|
|
|
} else if (Types.STRING.isCompatible(right.type)) {
|
|
|
- const leftStr = convertToString(left.value, left.type);
|
|
|
- return new StoreObject(resultType, Location.allocate(leftStr + right.value));
|
|
|
+ const leftStr = convertToString(left.get(), left.type);
|
|
|
+ return new StoreValue(resultType, (leftStr + right.get()));
|
|
|
} else {
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value.plus(right.value)));
|
|
|
+ return new StoreValue(resultType, (left.get().plus(right.get())));
|
|
|
}
|
|
|
}
|
|
|
case Operators.SUB.ord:
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value.minus(right.value)));
|
|
|
+ return new StoreValue(resultType, (left.get().minus(right.get())));
|
|
|
case Operators.MULT.ord: {
|
|
|
- result = left.value.times(right.value);
|
|
|
+ result = left.get().times(right.get());
|
|
|
// if(result.dp() > Config.decimalPlaces) {
|
|
|
// result = new Decimal(result.toFixed(Config.decimalPlaces));
|
|
|
// }
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
case Operators.DIV.ord: {
|
|
|
if (Types.INTEGER.isCompatible(resultType))
|
|
|
- result = left.value.divToInt(right.value);
|
|
|
+ result = left.get().divToInt(right.get());
|
|
|
else
|
|
|
- result = left.value.div(right.value);
|
|
|
+ result = left.get().div(right.get());
|
|
|
// if(result.dp() > Config.decimalPlaces) {
|
|
|
// result = new Decimal(result.toFixed(Config.decimalPlaces));
|
|
|
// }
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, (result));
|
|
|
}
|
|
|
case Operators.MOD.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if(shouldImplicitCast) {
|
|
|
resultType = Types.INTEGER;
|
|
|
leftValue = leftValue.trunc();
|
|
@@ -984,13 +975,13 @@ export class IVProgProcessor {
|
|
|
// if(result.dp() > Config.decimalPlaces) {
|
|
|
// result = new Decimal(result.toFixed(Config.decimalPlaces));
|
|
|
// }
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, (result));
|
|
|
}
|
|
|
case Operators.GT.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = left.value.length > right.value.length;
|
|
|
+ result = leftValue.length > rightValue.length;
|
|
|
} else {
|
|
|
if (shouldImplicitCast) {
|
|
|
resultType = Types.BOOLEAN;
|
|
@@ -999,13 +990,13 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.gt(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
case Operators.GE.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = left.value.length >= right.value.length;
|
|
|
+ result = leftValue.length >= rightValue.length;
|
|
|
} else {
|
|
|
if (shouldImplicitCast) {
|
|
|
resultType = Types.BOOLEAN;
|
|
@@ -1014,13 +1005,13 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.gte(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
case Operators.LT.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = left.value.length < right.value.length;
|
|
|
+ result = leftValue.length < rightValue.length;
|
|
|
} else {
|
|
|
if (shouldImplicitCast) {
|
|
|
resultType = Types.BOOLEAN;
|
|
@@ -1029,13 +1020,13 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.lt(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, (result));
|
|
|
}
|
|
|
case Operators.LE.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = left.value.length <= right.value.length;
|
|
|
+ result = leftValue.length <= rightValue.length;
|
|
|
} else {
|
|
|
if (shouldImplicitCast) {
|
|
|
resultType = Types.BOOLEAN;
|
|
@@ -1044,11 +1035,11 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.lte(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
case Operators.EQ.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
|
|
|
if (shouldImplicitCast) {
|
|
|
resultType = Types.BOOLEAN;
|
|
@@ -1057,13 +1048,13 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.eq(rightValue);
|
|
|
} else {
|
|
|
- result = left.value === right.value;
|
|
|
+ result = leftValue === rightValue;
|
|
|
}
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
case Operators.NEQ.ord: {
|
|
|
- let leftValue = left.value;
|
|
|
- let rightValue = right.value;
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
|
|
|
if (shouldImplicitCast) {
|
|
|
resultType = Types.BOOLEAN;
|
|
@@ -1072,14 +1063,14 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = !leftValue.eq(rightValue);
|
|
|
} else {
|
|
|
- result = left.value !== right.value;
|
|
|
+ result = leftValue !== rightValue;
|
|
|
}
|
|
|
- return new StoreObject(resultType, Location.allocate(result));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
case Operators.AND.ord:
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value && right.value));
|
|
|
+ return new StoreValue(resultType, (left.get() && right.get()));
|
|
|
case Operators.OR.ord:
|
|
|
- return new StoreObject(resultType, Location.allocate(left.value || right.value));
|
|
|
+ return new StoreValue(resultType, (left.get() || right.get()));
|
|
|
default:
|
|
|
return Promise.reject(new RuntimeError('!!!Critical Invalid InfixApp '+ infixApp.op));
|
|
|
}
|
|
@@ -1092,7 +1083,7 @@ export class IVProgProcessor {
|
|
|
if(vl.type instanceof ArrayType) {
|
|
|
switch(vl.type.dimensions) {
|
|
|
case 1: {
|
|
|
- realValue = new StoreObjectArray(vl.type, vl.value.length, null, vl.value);
|
|
|
+ realValue = new StoreObjectArray(vl.type, vl.get().length, null, vl.get());
|
|
|
break;
|
|
|
}
|
|
|
default: {
|
|
@@ -1100,7 +1091,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- realValue = new StoreObject(vl.type, vl.value);
|
|
|
+ realValue = new StoreValue(vl.type, vl.get());
|
|
|
}
|
|
|
}
|
|
|
return realValue;
|