|
@@ -15,11 +15,9 @@ import { StoreObjectArrayAddressRef } from './store/storeObjectArrayAddressRef';
|
|
|
import { ArrayType } from './../typeSystem/array_type';
|
|
|
import { convertToString } from '../typeSystem/parsers';
|
|
|
import { Config } from '../util/config';
|
|
|
-import Decimal from 'decimal.js';
|
|
|
import { ProcessorErrorFactory } from './error/processorErrorFactory';
|
|
|
import { RuntimeError } from './error/runtimeError';
|
|
|
-import { Type } from '../typeSystem/type';
|
|
|
-import { Literal } from '../ast/expressions/literal';
|
|
|
+import { Location } from '../memory/location';
|
|
|
|
|
|
export class IVProgProcessor {
|
|
|
|
|
@@ -88,6 +86,7 @@ export class IVProgProcessor {
|
|
|
|
|
|
interpretAST () {
|
|
|
this.prepareState();
|
|
|
+ Location.clear();
|
|
|
return this.initGlobal().then( _ => {
|
|
|
const mainFunc = this.findMainFunction();
|
|
|
if(mainFunc === null) {
|
|
@@ -111,13 +110,13 @@ export class IVProgProcessor {
|
|
|
findFunction (name) {
|
|
|
if(name.match(/^\$.+$/)) {
|
|
|
const fun = LanguageDefinedFunction.getFunction(name);
|
|
|
- if(!!!fun) {
|
|
|
+ if(!fun) {
|
|
|
throw ProcessorErrorFactory.not_implemented(name);
|
|
|
}
|
|
|
return fun;
|
|
|
} else {
|
|
|
const val = this.ast.functions.find( v => v.name === name);
|
|
|
- if (!!!val) {
|
|
|
+ if (!val) {
|
|
|
throw ProcessorErrorFactory.function_missing(name);
|
|
|
}
|
|
|
return val;
|
|
@@ -136,7 +135,7 @@ export class IVProgProcessor {
|
|
|
returnStoreObject = new StoreObjectArray(func.returnType,-1,null,[]);
|
|
|
}
|
|
|
} else {
|
|
|
- returnStoreObject = new StoreObject(func.returnType, null);
|
|
|
+ returnStoreObject = new StoreObject(func.returnType, Location.allocate(null));
|
|
|
}
|
|
|
funcStore.insertStore('$', returnStoreObject);
|
|
|
const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
|
|
@@ -187,7 +186,7 @@ export class IVProgProcessor {
|
|
|
if (stoObj instanceof StoreObjectArrayAddress) {
|
|
|
ref = new StoreObjectArrayAddressRef(stoObj);
|
|
|
} else {
|
|
|
- ref = new StoreObjectRef(stoObj.id, callerStore);
|
|
|
+ ref = new StoreObjectRef(stoObj);
|
|
|
}
|
|
|
calleeStore.insertStore(formalParameter.id, ref);
|
|
|
} else {
|
|
@@ -195,7 +194,7 @@ export class IVProgProcessor {
|
|
|
if (shouldTypeCast) {
|
|
|
realValue = Store.doImplicitCasting(formalParameter.type, realValue);
|
|
|
}
|
|
|
- calleeStore.insertStore(formalParameter.id, realValue);
|
|
|
+ calleeStore.insertStore(formalParameter.id, realValue.copy());
|
|
|
}
|
|
|
}
|
|
|
return calleeStore;
|
|
@@ -222,7 +221,9 @@ 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) {
|
|
@@ -244,8 +245,7 @@ export class IVProgProcessor {
|
|
|
} else if (cmd instanceof Commands.Switch) {
|
|
|
return this.executeSwitch(store, cmd);
|
|
|
} else if (cmd instanceof Expressions.FunctionCall) {
|
|
|
-
|
|
|
- return this.executeFunctionCall(store, cmd);
|
|
|
+ return this.executeFunctionCall(store, cmd);
|
|
|
} else if (cmd instanceof Commands.SysCall) {
|
|
|
return this.executeSysCall(store, cmd);
|
|
|
} else {
|
|
@@ -267,6 +267,11 @@ 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
if(!Types.VOID.isCompatible(func.returnType) && sto.mode !== Modes.RETURN) {
|
|
|
const funcName = func.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
LanguageDefinedFunction.getMainFunctionName() : func.name;
|
|
@@ -618,6 +623,7 @@ export class IVProgProcessor {
|
|
|
if(value.type instanceof ArrayType) {
|
|
|
realValue = Object.assign(new StoreObjectArray(null,null,null), value.refValue);
|
|
|
} else {
|
|
|
+ // TODO - update StoObj
|
|
|
realValue = Object.assign(new StoreObject(null,null), value.refValue);
|
|
|
}
|
|
|
}
|
|
@@ -638,7 +644,7 @@ export class IVProgProcessor {
|
|
|
if(cmd.initial !== null) {
|
|
|
$value = this.evaluateExpression(store, cmd.initial);
|
|
|
}
|
|
|
- const temp = new StoreObject(cmd.type, null);
|
|
|
+ const temp = new StoreObject(cmd.type, Location.allocate(null));
|
|
|
store.insertStore(cmd.id, temp);
|
|
|
return $value.then(vl => {
|
|
|
let realValue = vl;
|
|
@@ -647,7 +653,7 @@ export class IVProgProcessor {
|
|
|
if(Config.enable_type_casting && Store.canImplicitTypeCast(cmd.type, vl.type)) {
|
|
|
realValue = Store.doImplicitCasting(cmd.type, realValue);
|
|
|
} else {
|
|
|
- const stringInfo = typeInfo.type.stringInfo();
|
|
|
+ const stringInfo = vl.type.stringInfo();
|
|
|
const info = stringInfo[0];
|
|
|
return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
|
|
|
}
|
|
@@ -656,11 +662,12 @@ export class IVProgProcessor {
|
|
|
if(vl.type instanceof ArrayType) {
|
|
|
return Promise.reject(new Error("!!!Critical Error: Compatibility check failed, a Type accepts a ArrayType"))
|
|
|
} else {
|
|
|
+ // TODO - update StoObj
|
|
|
realValue = Object.assign(new StoreObject(null,null), vl.refValue);
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- realValue = new StoreObject(cmd.type, 0);
|
|
|
+ realValue = new StoreObject(cmd.type, Location.allocate(0));
|
|
|
}
|
|
|
realValue.readOnly = cmd.isConst;
|
|
|
store.updateStore(cmd.id, realValue);
|
|
@@ -672,8 +679,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- evaluateExpression (store, exp) {
|
|
|
-
|
|
|
+ evaluateExpression (store, exp) {
|
|
|
if (exp instanceof Expressions.UnaryApp) {
|
|
|
return this.evaluateUnaryApp(store, exp);
|
|
|
} else if (exp instanceof Expressions.InfixApp) {
|
|
@@ -712,10 +718,15 @@ export class IVProgProcessor {
|
|
|
return Promise.reject(new Error("The function that was called did not had 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
if (val instanceof StoreObjectArray) {
|
|
|
return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null,null), val));
|
|
|
} else {
|
|
|
- return Promise.resolve(Object.assign(new StoreObject(null,null), val));
|
|
|
+ return val;
|
|
|
}
|
|
|
});
|
|
|
}
|
|
@@ -825,7 +836,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
|
|
|
evaluateLiteral (_, exp) {
|
|
|
- return Promise.resolve(new StoreObject(exp.type, exp.value));
|
|
|
+ return Promise.resolve(new StoreObject(exp.type, Location.allocate(exp.value)));
|
|
|
}
|
|
|
|
|
|
evaluateVariableLiteral (store, exp) {
|
|
@@ -834,7 +845,7 @@ export class IVProgProcessor {
|
|
|
if (val instanceof StoreObjectArray) {
|
|
|
return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
|
|
|
} else {
|
|
|
- return Promise.resolve(Object.assign(new StoreObject(null,null), val));
|
|
|
+ return Promise.resolve(val);
|
|
|
}
|
|
|
} catch (error) {
|
|
|
return Promise.reject(error);
|
|
@@ -898,11 +909,11 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
switch (unaryApp.op.ord) {
|
|
|
case Operators.ADD.ord:
|
|
|
- return new StoreObject(resultType, left.value);
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value));
|
|
|
case Operators.SUB.ord:
|
|
|
- return new StoreObject(resultType, left.value.negated());
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value.negated()));
|
|
|
case Operators.NOT.ord:
|
|
|
- return new StoreObject(resultType, !left.value);
|
|
|
+ return new StoreObject(resultType, Location.allocate(!left.value));
|
|
|
default:
|
|
|
return Promise.reject(new RuntimeError('!!!Critical Invalid UnaryApp '+ unaryApp.op));
|
|
|
}
|
|
@@ -934,22 +945,22 @@ export class IVProgProcessor {
|
|
|
case Operators.ADD.ord: {
|
|
|
if(Types.STRING.isCompatible(left.type)) {
|
|
|
const rightStr = convertToString(right.value, right.type);
|
|
|
- return new StoreObject(resultType, left.value + rightStr);
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value + rightStr));
|
|
|
} else if (Types.STRING.isCompatible(right.type)) {
|
|
|
const leftStr = convertToString(left.value, left.type);
|
|
|
- return new StoreObject(resultType, leftStr + right.value);
|
|
|
+ return new StoreObject(resultType, Location.allocate(leftStr + right.value));
|
|
|
} else {
|
|
|
- return new StoreObject(resultType, left.value.plus(right.value));
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value.plus(right.value)));
|
|
|
}
|
|
|
}
|
|
|
case Operators.SUB.ord:
|
|
|
- return new StoreObject(resultType, left.value.minus(right.value));
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value.minus(right.value)));
|
|
|
case Operators.MULT.ord: {
|
|
|
result = left.value.times(right.value);
|
|
|
// if(result.dp() > Config.decimalPlaces) {
|
|
|
// result = new Decimal(result.toFixed(Config.decimalPlaces));
|
|
|
// }
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.DIV.ord: {
|
|
|
if (Types.INTEGER.isCompatible(resultType))
|
|
@@ -959,7 +970,7 @@ export class IVProgProcessor {
|
|
|
// if(result.dp() > Config.decimalPlaces) {
|
|
|
// result = new Decimal(result.toFixed(Config.decimalPlaces));
|
|
|
// }
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.MOD.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -973,7 +984,7 @@ export class IVProgProcessor {
|
|
|
// if(result.dp() > Config.decimalPlaces) {
|
|
|
// result = new Decimal(result.toFixed(Config.decimalPlaces));
|
|
|
// }
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.GT.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -988,7 +999,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.gt(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.GE.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -1003,7 +1014,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.gte(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.LT.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -1018,7 +1029,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.lt(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.LE.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -1033,7 +1044,7 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
result = leftValue.lte(rightValue);
|
|
|
}
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.EQ.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -1048,7 +1059,7 @@ export class IVProgProcessor {
|
|
|
} else {
|
|
|
result = left.value === right.value;
|
|
|
}
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.NEQ.ord: {
|
|
|
let leftValue = left.value;
|
|
@@ -1063,12 +1074,12 @@ export class IVProgProcessor {
|
|
|
} else {
|
|
|
result = left.value !== right.value;
|
|
|
}
|
|
|
- return new StoreObject(resultType, result);
|
|
|
+ return new StoreObject(resultType, Location.allocate(result));
|
|
|
}
|
|
|
case Operators.AND.ord:
|
|
|
- return new StoreObject(resultType, left.value && right.value);
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value && right.value));
|
|
|
case Operators.OR.ord:
|
|
|
- return new StoreObject(resultType, left.value || right.value);
|
|
|
+ return new StoreObject(resultType, Location.allocate(left.value || right.value));
|
|
|
default:
|
|
|
return Promise.reject(new RuntimeError('!!!Critical Invalid InfixApp '+ infixApp.op));
|
|
|
}
|
|
@@ -1077,7 +1088,7 @@ export class IVProgProcessor {
|
|
|
|
|
|
parseStoreObjectValue (vl) {
|
|
|
let realValue = vl;
|
|
|
- if(vl instanceof StoreObjectArrayAddress) {
|
|
|
+ if(vl instanceof StoreObjectArrayAddress) {
|
|
|
if(vl.type instanceof ArrayType) {
|
|
|
switch(vl.type.dimensions) {
|
|
|
case 1: {
|