Pārlūkot izejas kodu

Fix read function type exception error messages

Improve type error during read
Lucas de Souza 5 gadi atpakaļ
vecāks
revīzija
e7f24d4791

+ 6 - 0
css/ivprog-visual-1.0.css

@@ -992,4 +992,10 @@ div.ui.checkbox.transition.visible {
 }
 .parentheses_in_expression {
 	cursor: pointer;
+}
+
+.ivprog-error-varname {
+	font-style: italic;
+	margin-left: 1px;
+	margin-right: 1px;
 }

+ 3 - 1
i18n/pt/error.json

@@ -86,5 +86,7 @@
   "test_case_few_reads": "Caso de teste $0 falhou: ainda restam entradas!",
   "test_case_failed": "Caso de teste $0 falhou: <ul> <li>entrada(s): $1</li> <li>saída(s) esperada(s): $2</li> <li>saída(s): $3</li></ul>",
   "test_case_failed_exception": "Caso de teste $0 falhou: $1",
-  "invalid_type_conversion": "O valor $0 não pode ser convertido para o tipo $1"
+  "invalid_type_conversion": "O valor $0 não pode ser convertido para o tipo $1",
+  "invalid_read_type":"A entrada \"$0\" não é do tipo $1, que é o tipo da variável <span class='ivprog-error-varname'>$2</span>.",
+  "invalid_read_type_array":"A entrada \"$0\" não é do tipo $1, que é o tipo aceito pela variável <span class='ivprog-error-varname'>$2</span> que é um $3."
 }

+ 8 - 0
js/processor/error/processorErrorFactory.js

@@ -378,5 +378,13 @@ export const ProcessorErrorFactory  = Object.freeze({
   invalid_type_conversion: (value, type, dim) => {
     const context = [value, LocalizedStrings.translateType(type, dim)];
     return new RuntimeError(LocalizedStrings.getError("invalid_type_conversion", context));
+  },
+  invalid_read_type: (exp, type, dim, name) => {
+    const context = [exp, LocalizedStrings.translateType(type, dim), name];
+    return new RuntimeError(LocalizedStrings.getError("invalid_read_type", context))
+  },
+  invalid_read_type_array: (exp, typePos, dimPos, name, typeArray, dimArray) => {
+    const context = [exp, LocalizedStrings.translateType(typePos, dimPos), name,LocalizedStrings.translateType(typeArray, dimArray)];
+    return new RuntimeError(LocalizedStrings.getError("invalid_read_type_array", context))
   }
 });

+ 28 - 9
js/processor/lib/io.js

@@ -1,12 +1,16 @@
 import { StoreObject } from './../store/storeObject';
 import * as Commands from './../../ast/commands';
+import { Modes } from '../modes';
 import {toInt, toString, toBool, toReal, convertToString} from './../../typeSystem/parsers';
 import { Types } from './../../typeSystem/types';
+import { ProcessorErrorFactory } from "./../error/processorErrorFactory";
+import { StoreObjectArrayAddressRef } from '../store/storeObjectArrayAddressRef';
 
 export function createOutputFun () {
   const writeFunction = function (store, _) {
     const val = store.applyStore('p1');
     this.output.sendOutput(convertToString(val.value, val.type));
+    store.mode = Modes.RETURN;
     return Promise.resolve(store);
   }
   const block = new Commands.CommandBlock([], [new Commands.SysCall(writeFunction)]);
@@ -24,18 +28,33 @@ export function createInputFun () {
     return request.then(text => {
       const typeToConvert = store.applyStore('p1').type;
       let stoObj = null;
-      if (typeToConvert.isCompatible(Types.INTEGER)) {
-        const val = toInt(text);
-        stoObj = new StoreObject(Types.INTEGER, val.trunc());
-      } else if (typeToConvert.isCompatible(Types.REAL)) {
-        stoObj = new StoreObject(Types.REAL, toReal(text));
-      } else if (typeToConvert.isCompatible(Types.BOOLEAN)) {
-        stoObj = new StoreObject(Types.BOOLEAN, toBool(text));
-      } else if (typeToConvert.isCompatible(Types.STRING)) {
-        stoObj = new StoreObject(Types.STRING, toString(text));
+      try {
+        if (typeToConvert.isCompatible(Types.INTEGER)) {
+          const val = toInt(text);
+          stoObj = new StoreObject(Types.INTEGER, val.trunc());
+        } else if (typeToConvert.isCompatible(Types.REAL)) {
+          stoObj = new StoreObject(Types.REAL, toReal(text));
+        } else if (typeToConvert.isCompatible(Types.BOOLEAN)) {
+          stoObj = new StoreObject(Types.BOOLEAN, toBool(text));
+        } else if (typeToConvert.isCompatible(Types.STRING)) {
+          stoObj = new StoreObject(Types.STRING, toString(text));
+        } else {
+          return Promise.reject(new Error("!!!!Critical error: Unknown type in readFunction!!!!"));
+        }  
+      } catch (_) {
+        const stringInfo = typeToConvert.stringInfo()[0]
+        const realObject = store.getStoreObject("p1");
+        if (realObject instanceof StoreObjectArrayAddressRef) {
+          const arrayInfo = realObject.address.getArrayObject().type.stringInfo()[0];
+          const error = ProcessorErrorFactory.invalid_read_type_array(text, stringInfo.type, stringInfo.dim, realObject.address.refID, arrayInfo.type, arrayInfo.dim);
+          return Promise.reject(error);
+        }
+        const error = ProcessorErrorFactory.invalid_read_type(text, stringInfo.type, stringInfo.dim, store.applyStore('p1').id);
+        return Promise.reject(error);
       }
       this.loopTimers.splice(0,this.loopTimers.length)
       store.updateStore('p1', stoObj);
+      store.mode = Modes.RETURN;
       return Promise.resolve(store);
     });
   }

+ 14 - 0
js/processor/store/store.js

@@ -94,4 +94,18 @@ export class Store {
     this.store[id] = Object.freeze(stoObj);
     return this;
   }
+  /**
+   * Helper function similar to applyStore. But it returns the actual object in the store be it ref or not
+   * applyStore will return the refferenced object if the object in the store is a ref
+   */
+  getStoreObject (id) {
+    if(!this.store[id]) {
+      if (this.nextStore !== null) {
+        return this.nextStore.getStoreObject(id);
+      } else {
+        throw new Error(`Variable ${id} not found.`);
+      }
+    }
+    return this.store[id];
+  }
 }