Ver código fonte

Implement error messages for array initialization and assignment

Lucas de Souza 4 anos atrás
pai
commit
da4a836f6c

+ 14 - 3
i18n/pt/error.json

@@ -101,10 +101,21 @@
   "cannot_infer_matrix_line": "Não é possível inferir o número de linhas da matriz $0 na linha $1. É necessário que ela seja inicializada ou que o valor seja informado de forma explícita.",
   "cannot_infer_matrix_column": "Não é possível inferir o número de colunas da matriz $0 na linha $1. É necessário que ela seja inicializada ou que o valor seja informado de forma explícita.",
   "cannot_infer_vector_size": "Não é possível inferir o número de elementos do vetor $0 na linha $1. É necessário que ele seja inicializado ou que o valor seja informado de forma explícita",
-  "matrix_to_vector_attr":  "Erro na linha $0: $1 representa uma matriz e não pode ser atribuída ao vetor $2.",
-  "vector_to_matrix_attr":  "Err na linha $0: $1 representa um vetor e não pode ser atribuído a matriz $2.",
+  "matrix_to_vector_literal_attr":  "Erro na linha $0: A expressão $1 representa uma matriz e não pode ser atribuída ao vetor $2.",
+  "vector_to_matrix_literal_attr":  "Erro na linha $0: A expressão $1 representa um vetor e não pode ser atribuído a matriz $2.",
   "invalid_const_ref_full": "A variável $0 fornecida como parâmetro para a função $1 na linha $2 é uma constante e não pode ser usada neste contexto. Use uma variável ou posição de vetor.",
   "invalid_const_ref": "A variável $0 fornecida como parâmetro para a função $1 é uma constante e não pode ser usada neste contexto. Use uma variável ou posição de vetor.",
   "invalid_const_assignment_full": "Erro na linha $0: $1 é uma constante e portanto não pode ter seu valor alterado",
-  "invalid_const_assignment": "$0 é uma constante e portanto não pode ter seu valor alterado"
+  "invalid_const_assignment": "$0 é uma constante e portanto não pode ter seu valor alterado",
+  "array_init_not_literal": "Erro na linha $0: Vetor/Matriz só pode ser inicializado por literal. Ex: real vetor[] <- {1,2,3}",
+  "array_exceeds_2d": "Erro na linha $0: O número máximo de dimensões que um arranjo pode ter é 2. Elemento de 3 ou mais dimensões encontrado!",
+  "invalid_matrix_id_dimension": "Erro na linha $0: Você deve definir todas as dimensões da matriz quando uma delas é definida por uma variável! Ex: real mat1[var][5], mat2[5][var]",
+  "invalid_vector_init": "Erro na linha $0: Não se pode inicializar um vetor que teve seu tamanho declarado utilizando uma variável! Utilize uma atribuição de vetores ou use um laço de repetição.",
+  "invalid_matrix_init": "Erro na linha $0: Não se pode inicializar uma matrix que teve ao menos uma das suas dimensões declaradas utilizando uma variável! Utilize uma atribuição de matrizes ou use um laço de repetição.",
+  "invalid_vector_assignment_full": "Erro na linha $0: Só se pode atribuir um vetor a outro desde que eles comportem o mesmo número de elementos. $1 comporta $2 e $3 comporta $4!",
+  "invalid_vector_assignment": "Só se pode atribuir um vetor a outro desde que eles comportem o mesmo número de elementos. $0 comporta $1 e $2 comporta $3!",
+  "invalid_matrix_assignment_full": "Erro na linha $0: Só se pode atribuir uma matriz a outra desde que ambas possuam dimensões de mesmo tamanho. $1 tem $2 linhas e $3 colunas, enquanto $4 possui $5 linhas e $6 colunas!",
+  "invalid_matrix_assignment": "Só se pode atribuir uma matriz a outra desde que ambas possuam dimensões de mesmo tamanho. $0 tem $1 linhas e $2 colunas, enquanto $3 possui $4 linhas e $5 colunas!",
+  "matrix_to_vector_attr":  "Erro na linha $0: $1 representa uma matriz e não pode ser atribuída ao vetor $2.",
+  "vector_to_matrix_attr":  "Erro na linha $0: $1 representa um vetor e não pode ser atribuído a matriz $2."
 }

+ 24 - 4
js/ast/error/syntaxErrorFactory.js

@@ -97,12 +97,32 @@ export const SyntaxErrorFactory = Object.freeze({
     const context = [name, sourceInfo.line];
     return createError("cannot_infer_vector_size", context);
   },
-  matrix_to_vector_attr: (name, exp, sourceInfo) => {
+  matrix_to_vector_literal_attr: (name, exp, sourceInfo) => {
     const context = [sourceInfo.line, exp, name];
-    return createError("matrix_to_vector_attr", context);
+    return createError("matrix_to_vector_literal_attr", context);
   },
-  vector_to_matrix_attr: (name, exp, sourceInfo) => {
+  vector_to_matrix_literal_attr: (name, exp, sourceInfo) => {
     const context = [sourceInfo.line, exp, name];
-    return createError("vector_to_matrix_attr", context);
+    return createError("vector_to_matrix_literal_attr", context);
+  },
+  array_init_not_literal: (sourceInfo) => {
+    const context = [sourceInfo.line];
+    return createError("array_init_not_literal", context);
+  },
+  array_exceeds_2d: (sourceInfo) => {
+    const context = [sourceInfo.line];
+    return createError("array_exceeds_2d", context);
+  },
+  invalid_matrix_id_dimension: (sourceInfo) => {
+    const context = [sourceInfo.line];
+    return createError("invalid_matrix_id_dimension", context);
+  },
+  invalid_vector_init: (sourceInfo) => {
+    const context = [sourceInfo.line];
+    return createError("invalid_vector_init", context);
+  },
+  invalid_matrix_init: (sourceInfo) => {
+    const context = [sourceInfo.line];
+    return createError("invalid_matrix_init", context);
   }
 });

+ 13 - 13
js/ast/ivprogParser.js

@@ -294,7 +294,7 @@ export class IVProgParser {
     // Check for array or vector
     // ID[int/IDi?][int/IDj?]
     if (this.checkOpenBrace(true)) {
-      this.pos += 1;
+      this.pos += 1;    
       this.consumeNewLines();
       dim1 = this.parseArrayDimension();
       this.consumeNewLines();
@@ -343,8 +343,7 @@ export class IVProgParser {
     if(dim1 instanceof Expressions.VariableLiteral || dim2 instanceof Expressions.VariableLiteral) {
       dim_is_id = true;
       if(dimensions > 1 && (dim1 == null || dim2 == null)) {
-        // TODO better error message
-        throw new Error("array with id dimension must have all dims");
+        throw SyntaxErrorFactory.invalid_matrix_id_dimension(SourceInfo.createSourceInfo(equalsToken));
       }
     }
     if(isConst && equalsToken.type !== this.lexerClass.EQUAL ) {
@@ -352,8 +351,11 @@ export class IVProgParser {
     }
     if(equalsToken.type === this.lexerClass.EQUAL) {
       if(dim_is_id) {
-        // TODO better error message
-        throw new Error("Cannot init array with a variable as dimesion");
+        if(dimensions == 1) {
+          throw SyntaxErrorFactory.invalid_vector_init(SourceInfo.createSourceInfo(equalsToken));
+        } else {
+          throw SyntaxErrorFactory.invalid_matrix_init(SourceInfo.createSourceInfo(equalsToken));
+        }
       }
       this.pos += 1
       initial = this.parseArrayLiteral(typeString);
@@ -372,10 +374,10 @@ export class IVProgParser {
 
     if(dimensions === 1 && initial != null && !initial.isVector) {
       const expString = initial.toString();
-      throw SyntaxErrorFactory.matrix_to_vector_attr(idString, expString, initial.sourceInfo);
+      throw SyntaxErrorFactory.matrix_to_vector_literal_attr(idString, expString, initial.sourceInfo);
     } else if (dimensions > 1 && initial != null && initial.isVector) {
       const expString = initial.toString();
-      throw SyntaxErrorFactory.vector_to_matrix_attr(idString, expString, initial.sourceInfo);
+      throw SyntaxErrorFactory.vector_to_matrix_literal_attr(idString, expString, initial.sourceInfo);
     }
 
     if(dim1 == null) {
@@ -474,13 +476,12 @@ export class IVProgParser {
   parseArrayLiteral (typeString) {
     const openCurly = this.checkOpenCurly(true);
     if(!openCurly) {
-      // const invalid_token = this.getToken();
-      throw new Error("Array can only be init with a literal");
+      const invalid_token = this.getToken();
+      throw SyntaxErrorFactory.array_init_not_literal(SourceInfo.createSourceInfo(invalid_token));
     }
     const beginArray = this.getToken();
     if (this.parsingArrayDimension >= 2) {
-      // TODO better message
-      throw SyntaxErrorFactory.token_missing_list(`Array dimensions exceed maximum size of 2 at line ${beginArray.line}`);
+      throw SyntaxErrorFactory.array_exceeds_2d(SourceInfo.createSourceInfo(beginArray));
     }
     this.pos += 1;
     this.parsingArrayDimension += 1;
@@ -521,8 +522,7 @@ export class IVProgParser {
       this.checkOpenCurly();
       const beginArray = this.getToken();
       if (this.parsingArrayDimension >= 2) {
-        // TODO better message
-        throw SyntaxErrorFactory.token_missing_list(`Array dimensions exceed maximum size of 2 at line ${beginArray.line}`);
+        throw SyntaxErrorFactory.array_exceeds_2d(SourceInfo.createSourceInfo(beginArray));
       }
       this.pos += 1;
       this.parsingArrayDimension += 1;

+ 114 - 72
js/processor/error/processorErrorFactory.js

@@ -5,411 +5,453 @@ import { LanguageDefinedFunction } from '../definedFunctions';
 
 const LocalizedStrings = LocalizedStringsService.getInstance();
 
+function createRuntimeError (i18n_id, context = []) {
+  return new RuntimeError(LocalizedStrings.getError(i18n_id, context))
+}
+
+function createSemanticError (i18n_id, context = []) {
+  return new SemanticError(LocalizedStrings.getError(i18n_id, context))
+}
+
 export const ProcessorErrorFactory  = Object.freeze({
   symbol_not_found_full: (id, sourceInfo) => {
     if(sourceInfo) {
       const context = [id, sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("symbol_not_found_full", context));
+      return createSemanticError("symbol_not_found_full", context);
     } else {
       return ProcessorErrorFactory.symbol_not_found(id);
     }
   },
   symbol_not_found: (id) => {
     const context = [id];
-    return new SemanticError(LocalizedStrings.getError("symbol_not_found", context));
+    return createSemanticError("symbol_not_found", context);
   },
   function_missing_full: (id, sourceInfo) => {
     if(sourceInfo) {
       const context = [id, sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("function_missing_full", context));
+      return createSemanticError("function_missing_full", context);
     } else {
       return ProcessorErrorFactory.function_missing(id);
     }
   },
   function_missing: (id) => {
     const context = [id];
-    return new SemanticError(LocalizedStrings.getError("function_missing", context));
+    return createSemanticError("function_missing", context);
   },
   main_missing: () => {
-    return new SemanticError(LocalizedStrings.getError("main_missing"));
-  },        // TODO: better urgent error message
+    return createSemanticError("main_missing");
+  },
   array_dimension_not_int_full: (sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line];
-      return new SemanticError(LocalizedStrings.getError("array_dimension_not_int_full", context));
+      return createSemanticError("array_dimension_not_int_full", context);
     } else {
       return ProcessorErrorFactory.array_dimension_not_int();
     }
   },
   array_dimension_not_int: () => {
-    return new SemanticError(LocalizedStrings.getError("array_dimension_not_int"));
+    return createSemanticError("array_dimension_not_int");
   },
   unknown_command_full: (sourceInfo)=> {
     if(sourceInfo) {
       const context = [sourceInfo.line];
-      return new RuntimeError(LocalizedStrings.getError("unknown_command_full", context));
+      return createRuntimeError("unknown_command_full", context);
     } else {
       return ProcessorErrorFactory.unknown_command();
     }
     
   },
   unknown_command: ()=> {
-    return new RuntimeError(LocalizedStrings.getError("unknown_command"));
+    return createRuntimeError("unknown_command");
   },
   incompatible_types_full: (type, dim, sourceInfo) => {
     if(sourceInfo) {
       const context = [LocalizedStrings.translateType(type, dim), sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("incompatible_types_full", context));
+      return createSemanticError("incompatible_types_full", context);
     } else {
       return ProcessorErrorFactory.incompatible_types(type, dim);
     }
   },
   incompatible_types: (type, dim) => {
     const context = [LocalizedStrings.translateType(type, dim)];
-    return new SemanticError(LocalizedStrings.getError("incompatible_types", context));
+    return createSemanticError("incompatible_types", context);
   },
   incompatible_types_array_full: (exp, type, dim, sourceInfo) => {
     if(sourceInfo) {
       const context = [exp, LocalizedStrings.translateType(type, dim), sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("incompatible_types_array_full", context));
+      return createSemanticError("incompatible_types_array_full", context);
     } else {
       return ProcessorErrorFactory.incompatible_types_array(exp, type, dim);
     }
   },
   incompatible_types_array: (exp, type, dim) => {
     const context = [exp, LocalizedStrings.translateType(type, dim)];
-    return new SemanticError(LocalizedStrings.getError("incompatible_types_array", context));
+    return createSemanticError("incompatible_types_array", context);
   },
   loop_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, sourceInfo.column, exp];
-      return new SemanticError(LocalizedStrings.getError("loop_condition_type_full", context));
+      return createSemanticError("loop_condition_type_full", context);
     } else {
       return ProcessorErrorFactory.loop_condition_type(exp);
     }
   },
   loop_condition_type: (exp) => {
     const context = [exp];
-    return new SemanticError(LocalizedStrings.getError("loop_condition_type", context));
+    return createSemanticError("loop_condition_type", context);
   },
   endless_loop_full: (sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line];
-      return new SemanticError(LocalizedStrings.getError("endless_loop_full", context));
+      return createSemanticError("endless_loop_full", context);
     } else {
       return ProcessorErrorFactory.endless_loop();
     }
   },
   endless_loop: () => {
-    return new SemanticError(LocalizedStrings.getError("endless_loop"));
+    return createSemanticError("endless_loop");
   },
   for_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, sourceInfo.column, exp];
-      return new SemanticError(LocalizedStrings.getError("for_condition_type_full", context));
+      return createSemanticError("for_condition_type_full", context);
     } else {
       return ProcessorErrorFactory.for_condition_type(exp);
     }
   },
   for_condition_type: (exp) => {
     const context = [exp];
-    return new SemanticError(LocalizedStrings.getError("for_condition_type", context));
+    return createSemanticError("for_condition_type", context);
   },
   if_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, sourceInfo.column, exp];
-      return new SemanticError(LocalizedStrings.getError("if_condition_type_full", context));
+      return createSemanticError("if_condition_type_full", context);
     } else {
       return ProcessorErrorFactory.if_condition_type(exp);
     }
   },
   if_condition_type: (exp) => {
     const context = [exp];
-    return new SemanticError(LocalizedStrings.getError("if_condition_type", context));
+    return createSemanticError("if_condition_type", context);
   },
   invalid_global_var: () => {
-    return new RuntimeError(LocalizedStrings.getError("invalid_global_var"))
+    return createRuntimeError("invalid_global_var")
   },
   not_implemented: (id) => {
     const context  = [id]
-    return new RuntimeError(LocalizedStrings.getError("not_implemented", context))
+    return createRuntimeError("not_implemented", context)
   },
   invalid_case_type_full: (exp, type, dim, sourceInfo) => {
     if(sourceInfo) {
       const context = [exp, LocalizedStrings.translateType(type, dim), sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("invalid_case_type_full", context));
+      return createSemanticError("invalid_case_type_full", context);
     } else {
       return ProcessorErrorFactory.invalid_case_type(exp, type, dim);
     }
   },
   invalid_case_type: (exp, type, dim) => {
     const context = [exp, LocalizedStrings.translateType(type, dim)];
-    return new SemanticError(LocalizedStrings.getError("invalid_case_type", context));
+    return createSemanticError("invalid_case_type", context);
   },
   void_in_expression_full: (id, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, sourceInfo.column, id];
-      return new SemanticError(LocalizedStrings.getError("void_in_expression_full", context));
+      return createSemanticError("void_in_expression_full", context);
     } else {
       return ProcessorErrorFactory.void_in_expression(id);
     }
   },
   void_in_expression: (id) => {
     const context = [id];
-    return new SemanticError(LocalizedStrings.getError("void_in_expression", context));
+    return createSemanticError("void_in_expression", context);
   },
   invalid_array_access_full: (id, sourceInfo) => {
     if(sourceInfo) {
       const context = [id, sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("invalid_array_access_full", context));
+      return createSemanticError("invalid_array_access_full", context);
     } else {
       return ProcessorErrorFactory.invalid_array_access(id);
     }
   },
   invalid_array_access: (id) => {
     const context = [id];
-    return new SemanticError(LocalizedStrings.getError("invalid_array_access", context));
+    return createSemanticError("invalid_array_access", context);
   },
   invalid_matrix_access_full: (id, sourceInfo) => {
     if(sourceInfo) {
       const context = [id, sourceInfo.line, sourceInfo.column];
-      return new SemanticError(LocalizedStrings.getError("invalid_matrix_access_full", context));
+      return createSemanticError("invalid_matrix_access_full", context);
     } else {
       return ProcessorErrorFactory.invalid_matrix_access(id);
     }
   },
   invalid_matrix_access: (id) => {
     const context = [id];
-    return new SemanticError(LocalizedStrings.getError("invalid_matrix_access", context));
+    return createSemanticError("invalid_matrix_access", context);
   },
   matrix_column_outbounds_full: (id, value, columns, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, value, id, columns];
-      return new RuntimeError(LocalizedStrings.getError("matrix_column_outbounds_full", context));
+      return createRuntimeError("matrix_column_outbounds_full", context);
     } else {
       return ProcessorErrorFactory.matrix_column_outbounds(id, value, columns);
     }
   },
   matrix_column_outbounds: (id, value, columns) => {
     const context = [value, id, columns];
-    return new RuntimeError(LocalizedStrings.getError("matrix_column_outbounds", context));
+    return createRuntimeError("matrix_column_outbounds", context);
   },
   matrix_line_outbounds_full: (id, value, lines, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, value, id, lines];
-      return new RuntimeError(LocalizedStrings.getError("matrix_line_outbounds_full", context));
+      return createRuntimeError("matrix_line_outbounds_full", context);
     } else {
       return ProcessorErrorFactory.matrix_line_outbounds(id, value, lines);
     }
   },
   matrix_line_outbounds: (id, value, lines) => {
     const context = [value, id, lines];
-    return new RuntimeError(LocalizedStrings.getError("matrix_line_outbounds", context));
+    return createRuntimeError("matrix_line_outbounds", context);
   },
   vector_line_outbounds_full: (id, value, lines, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, value, id, lines];
-      return new RuntimeError(LocalizedStrings.getError("vector_line_outbounds_full", context));
+      return createRuntimeError("vector_line_outbounds_full", context);
     } else {
       return ProcessorErrorFactory.vector_line_outbounds(id, value, lines);
     }
   },
   vector_line_outbounds: (id, value, lines) => {
     const context = [value, id, lines];
-    return new RuntimeError(LocalizedStrings.getError("vector_line_outbounds", context));
+    return createRuntimeError("vector_line_outbounds", context);
   },
   vector_not_matrix_full: (id, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, id];
-      return new RuntimeError(LocalizedStrings.getError("vector_not_matrix_full", context));
+      return createRuntimeError("vector_not_matrix_full", context);
     } else {
       return ProcessorErrorFactory.vector_not_matrix(id);
     }
   },
   vector_not_matrix: (id) => {
     const context = [id];
-    return new RuntimeError(LocalizedStrings.getError("vector_not_matrix", context));
+    return createRuntimeError("vector_not_matrix", context);
   },
   function_no_return: (id) => {
     const context = [id];
-    return new SemanticError(LocalizedStrings.getError("function_no_return", context));
+    return createSemanticError("function_no_return", context);
   },
   invalid_void_return_full: (id, type, dim, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, id, LocalizedStrings.translateType(type, dim)];
-      return new SemanticError(LocalizedStrings.getError("invalid_void_return_full", context));
+      return createSemanticError("invalid_void_return_full", context);
     } else {
       return ProcessorErrorFactory.invalid_void_return(id, type, dim);
     }
   },
   invalid_void_return: (id, type, dim) => {
     const context = [id, LocalizedStrings.translateType(type, dim)];
-    return new SemanticError(LocalizedStrings.getError("invalid_void_return_full", context));
+    return createSemanticError("invalid_void_return_full", context);
   },
   invalid_return_type_full: (id, type, dim, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, id, LocalizedStrings.translateType(type, dim)];
-      return new SemanticError(LocalizedStrings.getError("invalid_return_type_full", context));
+      return createSemanticError("invalid_return_type_full", context);
     } else {
       return ProcessorErrorFactory.invalid_return_type(id, type, dim);
     }
   },
   invalid_return_type: (id, type, dim) => {
     const context = [id, LocalizedStrings.translateType(type, dim)];
-    return new SemanticError(LocalizedStrings.getError("invalid_return_type", context));
+    return createSemanticError("invalid_return_type", context);
   },
   invalid_parameters_size_full: (id, expected, actual, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, id, expected, actual];
-      return new SemanticError(LocalizedStrings.getError("invalid_parameters_size_full", context));
+      return createSemanticError("invalid_parameters_size_full", context);
     } else {
       return ProcessorErrorFactory.invalid_parameters_size(id, expected, actual);
     }
   },
   invalid_parameters_size: (id, expected, actual) => {
     const context = [id, expected, actual];
-    return new SemanticError(LocalizedStrings.getError("invalid_parameters_size", context));
+    return createSemanticError("invalid_parameters_size", context);
   },
   invalid_parameter_type_full: (fun_name, exp, sourceInfo) => {
     if(sourceInfo) {
       const context = [exp, LanguageDefinedFunction.getLocalName(fun_name), sourceInfo.line];
-      return new SemanticError(LocalizedStrings.getError("invalid_parameter_type_full", context));
+      return createSemanticError("invalid_parameter_type_full", context);
     } else {
       return ProcessorErrorFactory.invalid_parameter_type(fun_name, exp);
     }
   },
   invalid_parameter_type: (fun_name, exp) => {
     const context = [exp, LanguageDefinedFunction.getLocalName(fun_name)];
-    return new SemanticError(LocalizedStrings.getError("invalid_parameter_type_full", context));
+    return createSemanticError("invalid_parameter_type_full", context);
   },
   invalid_ref_full: (id, exp, sourceInfo) => {
     if(sourceInfo) {
       const context = [exp, id , sourceInfo.line];
-      return new SemanticError(LocalizedStrings.getError("invalid_ref_full", context));
+      return createSemanticError("invalid_ref_full", context);
     } else {
       return ProcessorErrorFactory.invalid_ref(id, exp);
     }
   },
   invalid_ref: (id, exp) => {
     const context = [exp, id];
-    return new SemanticError(LocalizedStrings.getError("invalid_ref", context));
+    return createSemanticError("invalid_ref", context);
   },
   unexpected_break_command_full: (sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line];
-      return new RuntimeError(LocalizedStrings.getError("unexpected_break_command_full", context));
+      return createRuntimeError("unexpected_break_command_full", context);
     } else {
       return ProcessorErrorFactory.unexpected_break_command();
     }
   },
   unexpected_break_command: () => {
-    return new RuntimeError(LocalizedStrings.getError("unexpected_break_command"));
+    return createRuntimeError("unexpected_break_command");
   },
   invalid_array_literal_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, exp];
-      return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_type_full", context));
+      return createRuntimeError("invalid_array_literal_type_full", context);
     } else {
       return ProcessorErrorFactory.invalid_array_literal_type(exp);
     }
   },
   invalid_array_literal_type: (exp) => {
     const context = [exp];
-    return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_type", context));
+    return createRuntimeError("invalid_array_literal_type", context);
   },
   invalid_array_literal_line_full: (expected, actual, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, expected, actual];
-      return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_line_full", context));
+      return createRuntimeError("invalid_array_literal_line_full", context);
     } else {
       return ProcessorErrorFactory.invalid_array_literal_type(expected, actual);
     }
   },
   invalid_array_literal_line: (expected, actual) => {
     const context = [expected, actual];
-    return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_line", context));
+    return createRuntimeError("invalid_array_literal_line", context);
   },
   invalid_array_literal_column_full: (expected, actual, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, expected, actual];
-      return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_column_full", context));
+      return createRuntimeError("invalid_array_literal_column_full", context);
     } else {
       return ProcessorErrorFactory.invalid_array_literal_column(expected, actual);
     }
   },
   invalid_array_literal_column: (expected, actual) => {
     const context = [expected, actual];
-    return new RuntimeError(LocalizedStrings.getError("invalid_array_literal_column", context));
+    return createRuntimeError("invalid_array_literal_column", context);
   },
   invalid_unary_op_full: (expString, opName, type, dim, sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, expString, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(type, dim)];
-      return new RuntimeError(LocalizedStrings.getError("invalid_unary_op_full", context));
+      return createRuntimeError("invalid_unary_op_full", context);
     } else {
       return ProcessorErrorFactory.invalid_unary_op(opName, type, dim);
     }
   },
   invalid_unary_op: (expString, opName, type, dim) => {
     const context = [expString, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(type, dim)];
-    return new RuntimeError(LocalizedStrings.getError("invalid_unary_op", context));
+    return createRuntimeError("invalid_unary_op", context);
   },
   invalid_infix_op_full: (expString, opName, typeLeft, dimLeft, typeRight, dimRight,  sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line, expString, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(typeLeft, dimLeft), LocalizedStrings.translateType(typeRight, dimRight)];
-      return new RuntimeError(LocalizedStrings.getError("invalid_infix_op_full", context));
+      return createRuntimeError("invalid_infix_op_full", context);
     } else {
       return ProcessorErrorFactory.invalid_infix_op(opName, typeLeft, dimLeft, typeRight, dimRight);
     }
   },
   invalid_infix_op: (expString, opName, typeLeft, dimLeft, typeRight, dimRight) => {
     const context = [expString, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(typeLeft, dimLeft), LocalizedStrings.translateType(typeRight, dimRight)];
-    return new RuntimeError(LocalizedStrings.getError("invalid_infix_op", context));
+    return createRuntimeError("invalid_infix_op", context);
   },
   array_dimension_not_positive_full: (sourceInfo) => {
     if(sourceInfo) {
       const context = [sourceInfo.line];
-      return new SemanticError(LocalizedStrings.getError("array_dimension_not_positive_full", context));
+      return createSemanticError("array_dimension_not_positive_full", context);
     } else {
       return ProcessorErrorFactory.array_dimension_not_positive();
     }
   },
   array_dimension_not_positive: () => {
-    return new SemanticError(LocalizedStrings.getError("array_dimension_not_positive"));
+    return createSemanticError("array_dimension_not_positive");
   },
   invalid_type_conversion: (value, type, dim) => {
     const context = [value, LocalizedStrings.translateType(type, dim)];
-    return new RuntimeError(LocalizedStrings.getError("invalid_type_conversion", context));
+    return createRuntimeError("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))
+    return createRuntimeError("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))
+    return createRuntimeError("invalid_read_type_array", context)
   },
   invalid_const_ref_full: (fun_name, exp, sourceInfo)=> {
     if(sourceInfo) {
       const context = [exp, LanguageDefinedFunction.getLocalName(fun_name), sourceInfo.line];
-      return new SemanticError(LocalizedStrings.getError("invalid_const_ref_full", context));
+      return createSemanticError("invalid_const_ref_full", context);
     } else {
       return ProcessorErrorFactory.invalid_const_ref(fun_name, exp);
     }
   },
   invalid_const_ref: (fun_name, exp) => {
     const context = [exp, LanguageDefinedFunction.getLocalName(fun_name)];
-    return new SemanticError(LocalizedStrings.getError("invalid_const_ref", context));
+    return createSemanticError("invalid_const_ref", context);
   },
   invalid_const_assignment_full: (var_id, source_info) => {
     if(source_info) {
       const context = [source_info.line, var_id];
-      return new SemanticError(LocalizedStrings.getError("invalid_const_assignment_full", context));
+      return createSemanticError("invalid_const_assignment_full", context);
     } else {
       return ProcessorErrorFactory.invalid_const_assignment(var_id);
     }
   },
   invalid_const_assignment: (var_id) => {
     const context = [var_id];
-    return new SemanticError(LocalizedStrings.getError("invalid_const_assignment", context));
+    return createSemanticError("invalid_const_assignment", context);
+  },
+  invalid_vector_assignment_full: (left_id, left_size, right_id, right_size, source_info) => {
+    if(source_info)  {
+      const context = [source_info.line, left_id, left_size, right_id, right_size]
+      return createRuntimeError("invalid_vector_assignment_full", context);
+    } else {
+      return ProcessorErrorFactory.invalid_vector_assignment(left_id, left_size, right_id, right_size);
+    }
+  },
+  invalid_vector_assignment: (left_id, left_size, right_id, right_size) => {
+    const context = [left_id, left_size, right_id, right_size]
+    return createRuntimeError("invalid_vector_assignment", context);
+  },
+  invalid_matrix_assignment_full: (left_id, left_line, left_column, right_id, right_line, right_column, source_info) => {
+    if(source_info)  {
+      const context = [source_info.line, left_id, left_line, left_column, right_id, right_line, right_column]
+      return createRuntimeError("invalid_matrix_assignment_full", context);
+    } else {
+      return ProcessorErrorFactory.invalid_matrix_assignment(left_id, left_line, left_column, right_id, right_line, right_column);
+    }
+  },
+  invalid_matrix_assignment: (left_id, left_line, left_column, right_id, right_line, right_column) => {
+    const context = [left_id, left_line, left_column, right_id, right_line, right_column]
+    return createRuntimeError("invalid_matrix_assignment", context);
+  },
+  matrix_to_vector_attr: (left_id, right_id, source_info) => {
+    // SourceInfo have to be valid...
+    const context = [source_info.line, right_id, left_id];
+    return createSemanticError("matrix_to_vector_attr", context);
+  },
+  vector_to_matrix_attr: (left_id, right_id, source_info) => {
+    // SourceInfo have to be valid...
+    const context = [source_info.line, right_id, left_id];
+    return createSemanticError("vector_to_matrix_attr", context);
   }
 });

+ 8 - 3
js/processor/ivprogProcessor.js

@@ -497,8 +497,12 @@ export class IVProgProcessor {
         if(inStore instanceof ArrayStoreValue) {
           const columns = realValue.columns == null ? 0 : realValue.columns;
           if(inStore.lines !== realValue.lines || inStore.columns !== columns){
-            // TODO better error message
-            throw new Error("exp exceeds the number of elements of the vector");
+            const exp = cmd.expression.toString();
+            if(inStore.isVector()) {
+              return Promise.reject(ProcessorErrorFactory.invalid_vector_assignment_full(cmd.id, inStore.lines, exp, realValue.lines, cmd.sourceInfo));
+            } else {
+              return Promise.reject(ProcessorErrorFactory.invalid_matrix_assignment_full(cmd.id, inStore.lines, inStore.columns, exp, realValue.lines, realValue.columns, cmd.sourceInfo));
+            }            
           }
         }
         
@@ -569,7 +573,6 @@ export class IVProgProcessor {
       }
 
       const current_value = mustBeArray.getAt(line, column);
-      console.log(current_value);
       if(current_value instanceof ArrayStoreValue) {
         if(current_value.lines !== actualValue.lines || current_value.columns !== actualValue.columns){
           // TODO better error message
@@ -748,6 +751,7 @@ export class IVProgProcessor {
   evaluateVector (store, exps, type, n_elements) {
     const values =  exps.value;
     if(n_elements !== values.length) {
+      // TODO better error message
       throw new Error("invalid number of elements to array literal...");
     }
     const actual_values = Promise.all(values.map( exp => this.evaluateExpression(store, exp)));
@@ -779,6 +783,7 @@ export class IVProgProcessor {
   evaluateMatrix (store, exps, type, lines, columns) {
     const values = exps.value;
     if(values.length !== lines) {
+      // TODO better error message
       throw new Error("Invalid number of lines to matrix literal...");
     }
     return values.map( vector => {

+ 8 - 2
js/processor/semantic/semanticAnalyser.js

@@ -431,8 +431,14 @@ export class SemanticAnalyser {
               throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo);
             }
           } else {
-            // TODO better error message
-            throw new Error("Cannot assign a vector to matrix or matrix to vector");
+            switch(exp_type.dimensions) {
+              case 1: {
+                throw ProcessorErrorFactory.vector_to_matrix_attr(cmd.id, exp.toString(),cmd.sourceInfo);
+              }
+              case 2: {
+                throw ProcessorErrorFactory.matrix_to_vector_attr(cmd.id, exp.toString(),cmd.sourceInfo);
+              }
+            }
           }
         }
       } else if(!exp_type.isCompatible(typeInfo.type)) {

+ 1 - 1
js/services/localizedStringsService.js

@@ -16,7 +16,7 @@ class IVProgLocalizedStrings extends line_i18n.LocalizedStrings {
       case 0:
         return type_string;
       default:
-        if(dim === 1)
+        if(dim > 1)
           return this.getUI("matrix_info_string", [type_string])
         else
           return this.getUI("vector_info_string", [type_string])