浏览代码

Fix function without a return command would not throw a runtime error

Lucas de Souza 5 年之前
父节点
当前提交
162f5c6424
共有 5 个文件被更改,包括 43 次插入7 次删除
  1. 11 6
      js/processor/ivprogProcessor.js
  2. 4 0
      js/processor/lib/arrays.js
  3. 10 0
      js/processor/lib/lang.js
  4. 12 0
      js/processor/lib/math.js
  5. 6 1
      js/processor/lib/strings.js

+ 11 - 6
js/processor/ivprogProcessor.js

@@ -146,11 +146,6 @@ export class IVProgProcessor {
             calleeStore.insertStore(formalParameter.id, realValue);
           }
         } else {
-          console.log("######");
-          console.log(stoObj);
-          console.log(stoObj.value);
-          console.log(stoObj.type);
-          console.log(stoObj.refValue);
           throw new Error(`Parameter ${formalParameter.id} is not compatible with the value given.`);
         }
       }
@@ -217,7 +212,14 @@ export class IVProgProcessor {
     return new Promise((resolve, reject) => {
       const func = this.findFunction(cmd.id);
       this.runFunction(func, cmd.actualParameters, store)
-        .then(_ => resolve(store))
+        .then(sto => {
+          if(!Types.VOID.isCompatible(func.returnType) && sto.mode !== Modes.RETURN) {
+            // TODO: better error message
+            reject(new Error(`Function ${func.name} must have a return command`));
+          } else {
+            resolve(store);
+          }
+        })
         .catch(err => reject(err));
     }); 
   }
@@ -600,6 +602,9 @@ 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));
+      }
       const val = sto.applyStore('$');
       if (val instanceof StoreObjectArray) {
         return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null,null), val));

+ 4 - 0
js/processor/lib/arrays.js

@@ -3,6 +3,7 @@ import * as Commands from './../../ast/commands';
 import { Types } from './../../typeSystem/types';
 import { toInt } from "./../../typeSystem/parsers";
 import { CompoundType } from '../../typeSystem/compoundType';
+import { Modes } from '../modes';
 
 /**
  * num_elements
@@ -14,6 +15,7 @@ export function createNumElementsFun () {
   const numElementsFun = (sto, _) => {
     const vector  = sto.applyStore("vector");
     const temp = new StoreObject(Types.INTEGER, toInt(vector.lines));
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -28,6 +30,7 @@ export function createMatrixLinesFun () {
   const matrixLinesFun = (sto, _) => {
     const matrix  = sto.applyStore("matrix");
     const temp = new StoreObject(Types.INTEGER, toInt(matrix.lines));
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -42,6 +45,7 @@ export function createMatrixColumnsFun () {
   const matrixColumnsFun = (sto, _) => {
     const matrix  = sto.applyStore("matrix");
     const temp = new StoreObject(Types.INTEGER, toInt(matrix.columns));
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
 

+ 10 - 0
js/processor/lib/lang.js

@@ -4,6 +4,7 @@ import { Types } from './../../typeSystem/types';
 import { toReal, convertToString } from "./../../typeSystem/parsers";
 import { IVProgParser } from '../../ast/ivprogParser';
 import { RealLiteral, IntLiteral, BoolLiteral } from '../../ast/expressions';
+import { Modes } from '../modes';
 
 /**
  * 
@@ -28,6 +29,7 @@ export function createIsRealFun () {
       }
     } catch (error) { }
     const temp = new StoreObject(Types.BOOLEAN, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -50,6 +52,7 @@ export function createIsIntFun () {
       }
     } catch (error) { }
     const temp = new StoreObject(Types.BOOLEAN, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -72,6 +75,7 @@ export function createIsBoolFun () {
       }
     } catch (error) { }
     const temp = new StoreObject(Types.BOOLEAN, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
 
@@ -88,6 +92,7 @@ export function createCastRealFun () {
     switch (val.type.ord) {
       case Types.INTEGER.ord: {
         const temp = new StoreObject(Types.REAL, toReal(val.number));
+        sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
@@ -96,6 +101,7 @@ export function createCastRealFun () {
           const result = parser.parseTerm();
           if (result instanceof RealLiteral) {
             const temp = new StoreObject(Types.REAL, result.value);
+            sto.mode = Modes.RETURN;
             return Promise.resolve(sto.updateStore("$", temp));
           }
         } catch (error) { 
@@ -118,6 +124,7 @@ export function createCastIntFun () {
     switch (val.type.ord) {
       case Types.REAL.ord: {
         const temp = new StoreObject(Types.INTEGER, Math.floor(val.number));
+        sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
@@ -126,6 +133,7 @@ export function createCastIntFun () {
           const result = parser.parseTerm();
           if (result instanceof IntLiteral) {
             const temp = new StoreObject(Types.INTEGER, result.value);
+            sto.mode = Modes.RETURN;
             return Promise.resolve(sto.updateStore("$", temp));
           }
         } catch (error) { 
@@ -150,6 +158,7 @@ export function createCastBoolFun () {
       const val = parser.parseTerm();
       if (val instanceof BoolLiteral) {
         const temp = new StoreObject(Types.BOOLEAN, val.value);
+        sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
     } catch (error) { }
@@ -168,6 +177,7 @@ export function createCastStringFun () {
     const val = store.applyStore('str');
     let result = convertToString(val)
     const temp = new StoreObject(Types.STRING, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
   const block = new Commands.CommandBlock([], [new Commands.SysCall(castStringFun)]);

+ 12 - 0
js/processor/lib/math.js

@@ -5,6 +5,7 @@ import { toReal } from "./../../typeSystem/parsers";
 import { BigNumber } from 'bignumber.js';
 import { MultiType } from '../../typeSystem/multiType';
 import { CompoundType } from '../../typeSystem/compoundType';
+import { Modes } from '../modes';
 
 /**
  * sin
@@ -25,6 +26,7 @@ export function createSinFun () {
      const x = sto.applyStore('x');
      const result = toReal(Math.sin(x.number));
      const temp = new StoreObject(Types.REAL, result);
+     sto.mode = Modes.RETURN;
      return Promise.resolve(sto.updateStore('$', temp));
    };
 
@@ -40,6 +42,7 @@ export function createCosFun () {
     const x = sto.applyStore('x');
     const result = toReal(Math.cos(x.number));
     const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -55,6 +58,7 @@ export function createTanFun () {
     const x = sto.applyStore('x');
     const result = toReal(Math.tan(x.number));
     const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -70,6 +74,7 @@ export function createSqrtFun () {
     const x = sto.applyStore('x');
     const result = x.value.sqrt();
     const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -86,6 +91,7 @@ export function createPowFun () {
     const y = sto.applyStore('y');
     const result = toReal(Math.pow(x.number, y.number));
     const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -105,6 +111,7 @@ export function createLogFun () {
     }
     const result = toReal(Math.log10(x.number));
     const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -120,6 +127,7 @@ export function createAbsFun () {
     const x = sto.applyStore('x');
     const result = x.value.abs();
     const temp = new StoreObject(x.type, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -135,6 +143,7 @@ export function createNegateFun () {
     const x = sto.applyStore('x');
     const result = x.value.negated();
     const temp = new StoreObject(x.type, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -150,6 +159,7 @@ export function createInvertFun () {
     const x = sto.applyStore('x');
     const result = toReal(1).dividedBy(x.value);
     const temp = new StoreObject(Types.REAL, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
 
@@ -166,6 +176,7 @@ export function createMaxFun () {
     const numbers = x.value.map(stoObj => stoObj.number);
     const result = BigNumber.max(numbers);
     const temp = new StoreObject(x.type.innerType, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
  const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
@@ -182,6 +193,7 @@ export function createMinFun () {
     const numbers = x.value.map(stoObj => stoObj.value.toNumber());
     const result = BigNumber.min(numbers);
     const temp = new StoreObject(x.type.innerType, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
  const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);

+ 6 - 1
js/processor/lib/strings.js

@@ -2,7 +2,7 @@ import { StoreObject } from '../store/storeObject';
 import * as Commands from './../../ast/commands';
 import { Types } from './../../typeSystem/types';
 import { toInt } from "./../../typeSystem/parsers";
-
+import { Modes } from '../modes';
 
 /*
 *  substring
@@ -19,6 +19,7 @@ export function createSubstringFun () {
     const end = sto.applyStore("end");
     const result = str.value.substring(start.value, end.value);
     const temp = new StoreObject(Types.STRING, result);
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   };
 
@@ -35,6 +36,7 @@ export function createLengthFun () {
   const lengthFun = (sto, _) => {
     const str = sto.applyStore("str");
     const temp = new StoreObject(Types.INTEGER, toInt(str.value.length));
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(lengthFun)]);
@@ -48,6 +50,7 @@ export function createUppercaseFun () {
   const uppercaseFun = (sto, _) => {
     const str = sto.applyStore("str");
     const temp = new StoreObject(Types.STRING, str.value.toUpperCase());
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(uppercaseFun)]);
@@ -61,6 +64,7 @@ export function createLowercaseFun () {
   const lowercaseFun = (sto, _) => {
     const str = sto.applyStore("str");
     const temp = new StoreObject(Types.STRING, str.value.toLowerCase());
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(lowercaseFun)]);
@@ -78,6 +82,7 @@ export function createrCharAtFun () {
       return Promise.reject(new Error("invalid string position"));
     }
     const temp = new StoreObject(Types.STRING, str.value.charAt(idx.value.toNumber()));
+    sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore("$", temp));
   }
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(charAtFun)]);