Browse Source

Merge branch 'fixRead' of LInE/ivprog into master

Lucas de Souza 5 years ago
parent
commit
9d0db948de

+ 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];
+  }
 }

+ 17 - 4
js/visualUI/functions.js

@@ -24,6 +24,7 @@ const globalChangeListeners = [];
 const functionsChangeListeners = [];
 let domConsole = null;
 let _testCases = [];
+let isRunning = false;
 window.studentGrade = null;
 window.LocalizedStrings = LocalizedStrings;
 const program = new Models.Program();
@@ -875,6 +876,9 @@ function updateSequenceFunction (oldIndex, newIndex) {
 }
 
 function runCodeAssessment () {
+  if (isRunning) {
+    return;
+  }
   
   window.studentGrade = null;
   const strCode = CodeManagement.generate();
@@ -888,19 +892,25 @@ function runCodeAssessment () {
     domConsole = new DOMConsole("#ivprog-term");
   $("#ivprog-term").slideDown(500);
   const runner = new IVProgAssessment(strCode, _testCases, domConsole);
-
+  isRunning = true;
   runner.runTest().then(grade => {
     if (!is_iassign) {
       parent.getEvaluationCallback(grade);
     } else {
       is_iassign = false;
     }
-  }).catch( err => console.log(err));
+    isRunning = false;
+  }).catch( err => {
+    console.log(err);
+    isRunning = false;
+  });
   
 }
 
 function runCode () {
-  
+  if (isRunning) {
+    return;
+  }
   const strCode = CodeManagement.generate();
   if (strCode == null) {
     return;
@@ -917,15 +927,18 @@ function runCode () {
     proc.registerInput(domConsole);
     proc.registerOutput(domConsole);
     $("#ivprog-term").addClass('ivprog-term-active');
-
+    isRunning = true;
     proc.interpretAST().then( _ => {
       domConsole.info("Programa executado com sucesso!");
       $("#ivprog-term").removeClass('ivprog-term-active');
+      isRunning = false;
     }).catch(err => {
       domConsole.err(err.message);
       $("#ivprog-term").removeClass('ivprog-term-active');
+      isRunning = false;
     }) 
   } catch (error) {
+    isRunning = false;
     domConsole.err(error.message);
     console.log(error);
   }