|
@@ -1,15 +1,12 @@
|
|
import { Store } from './store/store';
|
|
import { Store } from './store/store';
|
|
-import { StoreObjectArray } from './store/storeObjectArray';
|
|
|
|
import { Modes } from './modes';
|
|
import { Modes } from './modes';
|
|
import { Context } from './context';
|
|
import { Context } from './context';
|
|
-import { Types } from './../typeSystem/types';
|
|
|
|
|
|
+import { Types, fromOrdToType } from './../typeSystem/types';
|
|
import { Operators } from './../ast/operators';
|
|
import { Operators } from './../ast/operators';
|
|
import { LanguageDefinedFunction } from './definedFunctions';
|
|
import { LanguageDefinedFunction } from './definedFunctions';
|
|
import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from './compatibilityTable';
|
|
import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from './compatibilityTable';
|
|
import * as Commands from './../ast/commands/';
|
|
import * as Commands from './../ast/commands/';
|
|
import * as Expressions from './../ast/expressions/';
|
|
import * as Expressions from './../ast/expressions/';
|
|
-import { StoreObjectArrayAddress } from './store/storeObjectArrayAddress';
|
|
|
|
-import { StoreObjectArrayAddressRef } from './store/storeObjectArrayAddressRef';
|
|
|
|
import { ArrayType } from './../typeSystem/array_type';
|
|
import { ArrayType } from './../typeSystem/array_type';
|
|
import { convertToString } from '../typeSystem/parsers';
|
|
import { convertToString } from '../typeSystem/parsers';
|
|
import { Config } from '../util/config';
|
|
import { Config } from '../util/config';
|
|
@@ -130,26 +127,25 @@ export class IVProgProcessor {
|
|
const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
|
|
const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
|
|
const funcStore = new Store(funcName);
|
|
const funcStore = new Store(funcName);
|
|
funcStore.extendStore(this.globalStore);
|
|
funcStore.extendStore(this.globalStore);
|
|
- let returnStoreObject = null;
|
|
|
|
|
|
+ let dimensions = 0;
|
|
|
|
+ let type_ord = 0;
|
|
if(func.returnType instanceof ArrayType) {
|
|
if(func.returnType instanceof ArrayType) {
|
|
- if(func.returnType.dimensions > 1) {
|
|
|
|
- returnStoreObject = new StoreObjectArray(func.returnType,-1,-1,[[]]);
|
|
|
|
- } else {
|
|
|
|
- returnStoreObject = new StoreObjectArray(func.returnType,-1,null,[]);
|
|
|
|
- }
|
|
|
|
|
|
+ // multi dimensional return...
|
|
|
|
+ dimensions = func.returnType.dimensions;
|
|
|
|
+ type_ord = func.returnType.innerType.ord;
|
|
} else {
|
|
} else {
|
|
- returnStoreObject = new StoreValue(func.returnType, null, null);//new StoreObject(func.returnType, Location.allocate(null));
|
|
|
|
|
|
+ type_ord = func.returnType.ord;
|
|
}
|
|
}
|
|
- funcStore.insertStore('$', returnStoreObject);
|
|
|
|
|
|
+ funcStore.insertStore("$dim", new StoreValue(Types.INTEGER, dimensions));
|
|
|
|
+ funcStore.insertStore("$type", new StoreValue(Types.INTEGER, type_ord));
|
|
const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
|
|
const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
|
|
- const outerRef = this;
|
|
|
|
return newFuncStore$.then(sto => {
|
|
return newFuncStore$.then(sto => {
|
|
this.context.push(Context.FUNCTION);
|
|
this.context.push(Context.FUNCTION);
|
|
this.stores.push(sto);
|
|
this.stores.push(sto);
|
|
return this.executeCommands(sto, func.variablesDeclarations)
|
|
return this.executeCommands(sto, func.variablesDeclarations)
|
|
- .then(stoWithVars => outerRef.executeCommands(stoWithVars, func.commands)).then(finalSto => {
|
|
|
|
- outerRef.stores.pop();
|
|
|
|
- outerRef.context.pop();
|
|
|
|
|
|
+ .then(stoWithVars => this.executeCommands(stoWithVars, func.commands)).then(finalSto => {
|
|
|
|
+ this.stores.pop();
|
|
|
|
+ this.context.pop();
|
|
return finalSto;
|
|
return finalSto;
|
|
});
|
|
});
|
|
});
|
|
});
|
|
@@ -219,10 +215,9 @@ export class IVProgProcessor {
|
|
|
|
|
|
executeCommands (store, cmds) {
|
|
executeCommands (store, cmds) {
|
|
// helper to partially apply a function, in this case executeCommand
|
|
// helper to partially apply a function, in this case executeCommand
|
|
- const outerRef = this;
|
|
|
|
const partial = (fun, cmd) => (sto) => fun(sto, cmd);
|
|
const partial = (fun, cmd) => (sto) => fun(sto, cmd);
|
|
return cmds.reduce((lastCommand, next) => {
|
|
return cmds.reduce((lastCommand, next) => {
|
|
- const nextCommand = partial(outerRef.executeCommand.bind(outerRef), next);
|
|
|
|
|
|
+ const nextCommand = partial(this.executeCommand.bind(this), next);
|
|
return lastCommand.then(nextCommand);
|
|
return lastCommand.then(nextCommand);
|
|
}, Promise.resolve(store));
|
|
}, Promise.resolve(store));
|
|
}
|
|
}
|
|
@@ -293,18 +288,17 @@ export class IVProgProcessor {
|
|
|
|
|
|
executeSwitch (store, cmd) {
|
|
executeSwitch (store, cmd) {
|
|
this.context.push(Context.BREAKABLE);
|
|
this.context.push(Context.BREAKABLE);
|
|
- const outerRef = this;
|
|
|
|
const caseSequence = cmd.cases.reduce( (prev,next) => {
|
|
const caseSequence = cmd.cases.reduce( (prev,next) => {
|
|
return prev.then( tuple => {
|
|
return prev.then( tuple => {
|
|
- if(outerRef.ignoreSwitchCases(tuple[1])) {
|
|
|
|
|
|
+ if(this.ignoreSwitchCases(tuple[1])) {
|
|
return Promise.resolve(tuple);
|
|
return Promise.resolve(tuple);
|
|
} else if(tuple[0] || next.isDefault) {
|
|
} else if(tuple[0] || next.isDefault) {
|
|
- return outerRef.executeCommands(tuple[1], next.commands)
|
|
|
|
|
|
+ return this.executeCommands(tuple[1], next.commands)
|
|
.then(nSto => Promise.resolve([true, nSto]));
|
|
.then(nSto => Promise.resolve([true, nSto]));
|
|
} else {
|
|
} else {
|
|
const equalityInfixApp = new Expressions.InfixApp(Operators.EQ, cmd.expression, next.expression);
|
|
const equalityInfixApp = new Expressions.InfixApp(Operators.EQ, cmd.expression, next.expression);
|
|
equalityInfixApp.sourceInfo = next.sourceInfo;
|
|
equalityInfixApp.sourceInfo = next.sourceInfo;
|
|
- return outerRef.evaluateExpression(tuple[1],equalityInfixApp).then(stoObj => stoObj.get())
|
|
|
|
|
|
+ return this.evaluateExpression(tuple[1],equalityInfixApp).then(stoObj => stoObj.get())
|
|
.then(isEqual => {
|
|
.then(isEqual => {
|
|
if (isEqual) {
|
|
if (isEqual) {
|
|
return this.executeCommands(tuple[1], next.commands)
|
|
return this.executeCommands(tuple[1], next.commands)
|
|
@@ -317,7 +311,7 @@ export class IVProgProcessor {
|
|
});
|
|
});
|
|
}, Promise.resolve([false, store]));
|
|
}, Promise.resolve([false, store]));
|
|
return caseSequence.then(tuple => {
|
|
return caseSequence.then(tuple => {
|
|
- outerRef.context.pop();
|
|
|
|
|
|
+ this.context.pop();
|
|
const newStore = tuple[1];
|
|
const newStore = tuple[1];
|
|
if (newStore.mode === Modes.BREAK) {
|
|
if (newStore.mode === Modes.BREAK) {
|
|
newStore.mode = Modes.RUN;
|
|
newStore.mode = Modes.RUN;
|
|
@@ -345,36 +339,35 @@ export class IVProgProcessor {
|
|
}
|
|
}
|
|
|
|
|
|
executeDoWhile (store, cmd) {
|
|
executeDoWhile (store, cmd) {
|
|
- const outerRef = this;
|
|
|
|
try {
|
|
try {
|
|
- outerRef.loopTimers.push(Date.now());
|
|
|
|
- outerRef.context.push(Context.BREAKABLE);
|
|
|
|
- const $newStore = outerRef.executeCommands(store, cmd.commands);
|
|
|
|
|
|
+ this.loopTimers.push(Date.now());
|
|
|
|
+ this.context.push(Context.BREAKABLE);
|
|
|
|
+ const $newStore = this.executeCommands(store, cmd.commands);
|
|
return $newStore.then(sto => {
|
|
return $newStore.then(sto => {
|
|
if(sto.mode === Modes.BREAK) {
|
|
if(sto.mode === Modes.BREAK) {
|
|
- outerRef.context.pop();
|
|
|
|
|
|
+ this.context.pop();
|
|
sto.mode = Modes.RUN;
|
|
sto.mode = Modes.RUN;
|
|
- outerRef.loopTimers.pop();
|
|
|
|
|
|
+ this.loopTimers.pop();
|
|
return sto;
|
|
return sto;
|
|
}
|
|
}
|
|
- const $value = outerRef.evaluateExpression(sto, cmd.expression);
|
|
|
|
|
|
+ const $value = this.evaluateExpression(sto, cmd.expression);
|
|
return $value.then(vl => {
|
|
return $value.then(vl => {
|
|
if (!vl.type.isCompatible(Types.BOOLEAN)) {
|
|
if (!vl.type.isCompatible(Types.BOOLEAN)) {
|
|
return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
|
|
}
|
|
}
|
|
if (vl.get()) {
|
|
if (vl.get()) {
|
|
- outerRef.context.pop();
|
|
|
|
- if(outerRef.loopTimers.length > 0) {
|
|
|
|
- const time = outerRef.loopTimers[0];
|
|
|
|
|
|
+ this.context.pop();
|
|
|
|
+ if(this.loopTimers.length > 0) {
|
|
|
|
+ const time = this.loopTimers[0];
|
|
if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
|
|
if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
|
|
- outerRef.forceKill = true;
|
|
|
|
|
|
+ this.forceKill = true;
|
|
return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return outerRef.executeCommand(sto, cmd);
|
|
|
|
|
|
+ return this.executeCommand(sto, cmd);
|
|
} else {
|
|
} else {
|
|
- outerRef.context.pop();
|
|
|
|
- outerRef.loopTimers.pop();
|
|
|
|
|
|
+ this.context.pop();
|
|
|
|
+ this.loopTimers.pop();
|
|
return sto;
|
|
return sto;
|
|
}
|
|
}
|
|
})
|
|
})
|
|
@@ -385,34 +378,33 @@ export class IVProgProcessor {
|
|
}
|
|
}
|
|
|
|
|
|
executeWhile (store, cmd) {
|
|
executeWhile (store, cmd) {
|
|
- const outerRef = this;
|
|
|
|
try {
|
|
try {
|
|
- outerRef.loopTimers.push(Date.now());
|
|
|
|
- outerRef.context.push(Context.BREAKABLE);
|
|
|
|
- const $value = outerRef.evaluateExpression(store, cmd.expression);
|
|
|
|
|
|
+ this.loopTimers.push(Date.now());
|
|
|
|
+ this.context.push(Context.BREAKABLE);
|
|
|
|
+ const $value = this.evaluateExpression(store, cmd.expression);
|
|
return $value.then(vl => {
|
|
return $value.then(vl => {
|
|
if(vl.type.isCompatible(Types.BOOLEAN)) {
|
|
if(vl.type.isCompatible(Types.BOOLEAN)) {
|
|
if(vl.get()) {
|
|
if(vl.get()) {
|
|
- const $newStore = outerRef.executeCommands(store, cmd.commands);
|
|
|
|
|
|
+ const $newStore = this.executeCommands(store, cmd.commands);
|
|
return $newStore.then(sto => {
|
|
return $newStore.then(sto => {
|
|
- outerRef.context.pop();
|
|
|
|
|
|
+ this.context.pop();
|
|
if (sto.mode === Modes.BREAK) {
|
|
if (sto.mode === Modes.BREAK) {
|
|
- outerRef.loopTimers.pop();
|
|
|
|
|
|
+ this.loopTimers.pop();
|
|
sto.mode = Modes.RUN;
|
|
sto.mode = Modes.RUN;
|
|
return sto;
|
|
return sto;
|
|
}
|
|
}
|
|
- if (outerRef.loopTimers.length > 0) {
|
|
|
|
- const time = outerRef.loopTimers[0];
|
|
|
|
|
|
+ if (this.loopTimers.length > 0) {
|
|
|
|
+ const time = this.loopTimers[0];
|
|
if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
|
|
if(Date.now() - time >= IVProgProcessor.LOOP_TIMEOUT) {
|
|
- outerRef.forceKill = true;
|
|
|
|
|
|
+ this.forceKill = true;
|
|
return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.endless_loop_full(cmd.sourceInfo));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return outerRef.executeCommand(sto, cmd);
|
|
|
|
|
|
+ return this.executeCommand(sto, cmd);
|
|
});
|
|
});
|
|
} else {
|
|
} else {
|
|
- outerRef.context.pop();
|
|
|
|
- outerRef.loopTimers.pop();
|
|
|
|
|
|
+ this.context.pop();
|
|
|
|
+ this.loopTimers.pop();
|
|
return store;
|
|
return store;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
@@ -452,24 +444,28 @@ export class IVProgProcessor {
|
|
|
|
|
|
executeReturn (store, cmd) {
|
|
executeReturn (store, cmd) {
|
|
try {
|
|
try {
|
|
- const funcType = store.applyStore('$').type;
|
|
|
|
|
|
+ const return_type_ord = store.applyStore('$type').get();
|
|
|
|
+ const return_dim = store.applyStore('$dim').get();
|
|
|
|
+ let funcType = fromOrdToType(return_type_ord).getOrElse(Types.UNDEFINED);
|
|
|
|
+ if(return_dim > 0) {
|
|
|
|
+ funcType = new ArrayType(funcType, return_dim);
|
|
|
|
+ }
|
|
const $value = this.evaluateExpression(store, cmd.expression);
|
|
const $value = this.evaluateExpression(store, cmd.expression);
|
|
const funcName = store.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
const funcName = store.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
LanguageDefinedFunction.getMainFunctionName() : store.name;
|
|
LanguageDefinedFunction.getMainFunctionName() : store.name;
|
|
- return $value.then(vl => {
|
|
|
|
|
|
+ return $value.then(value => {
|
|
|
|
|
|
- if(vl === null && funcType.isCompatible(Types.VOID)) {
|
|
|
|
|
|
+ if(value === null && funcType.isCompatible(Types.VOID)) {
|
|
store.mode = Modes.RETURN;
|
|
store.mode = Modes.RETURN;
|
|
return Promise.resolve(store);
|
|
return Promise.resolve(store);
|
|
}
|
|
}
|
|
|
|
|
|
- if (vl === null || !funcType.isCompatible(vl.type)) {
|
|
|
|
|
|
+ if (value === null || !funcType.isCompatible(value.type)) {
|
|
const stringInfo = funcType.stringInfo();
|
|
const stringInfo = funcType.stringInfo();
|
|
const info = stringInfo[0];
|
|
const info = stringInfo[0];
|
|
return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
|
|
} else {
|
|
} else {
|
|
- const realValue = vl;
|
|
|
|
- store.updateStore('$', realValue);
|
|
|
|
|
|
+ store.insertStore('$', value);
|
|
store.mode = Modes.RETURN;
|
|
store.mode = Modes.RETURN;
|
|
return Promise.resolve(store);
|
|
return Promise.resolve(store);
|
|
}
|
|
}
|
|
@@ -720,11 +716,7 @@ export class IVProgProcessor {
|
|
}
|
|
}
|
|
const val = sto.applyStore('$');
|
|
const val = sto.applyStore('$');
|
|
sto.destroy();
|
|
sto.destroy();
|
|
- if (val instanceof StoreObjectArray) {
|
|
|
|
- return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null,null), val));
|
|
|
|
- } else {
|
|
|
|
- return val;
|
|
|
|
- }
|
|
|
|
|
|
+ return Promise.resolve(val);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|