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