Browse Source

Implement array assignment rules as defined in Issue #83

Rename CompoundType to ArrayType and implement property isVector
Lucas de Souza 4 years ago
parent
commit
3ff8fc3024

+ 8 - 8
js/ast/ivprogParser.js

@@ -4,7 +4,7 @@ import * as Commands from './commands/';
 import * as AstHelpers from "./ast_helpers";
 import { toInt, toString, toBool, toReal } from './../typeSystem/parsers';
 import { Types } from "./../typeSystem/types";
-import { CompoundType } from "./../typeSystem/compoundType";
+import { ArrayType } from "../typeSystem/array_type";
 import { SourceInfo } from './sourceInfo';
 import { convertFromString } from './operators';
 import { SyntaxErrorFactory } from './error/syntaxErrorFactory';
@@ -358,10 +358,10 @@ export class IVProgParser {
       }
     }
 
-    if(dimensions === 1 && !initial.isVector) {
+    if(dimensions === 1 && initial != null && !initial.isVector) {
       const expString = initial.toString();
       throw SyntaxErrorFactory.matrix_to_vector_attr(idString, expString, initial.sourceInfo);
-    } else if (dimensions > 1 && initial.isVector) {
+    } else if (dimensions > 1 && initial != null && initial.isVector) {
       const expString = initial.toString();
       throw SyntaxErrorFactory.vector_to_matrix_attr(idString, expString, initial.sourceInfo);
     }
@@ -378,7 +378,7 @@ export class IVProgParser {
       } 
     }
     const declaration = new Commands.ArrayDeclaration(idString,
-      new CompoundType(typeString, dimensions), n_lines, n_columns, initial, isConst);
+      new ArrayType(typeString, dimensions), n_lines, n_columns, initial, isConst);
     declaration.sourceInfo = sourceInfo;
     const commaToken = this.getToken();
     if(commaToken.type === this.lexerClass.COMMA) {
@@ -489,7 +489,7 @@ export class IVProgParser {
     } else if(data.length == 1) {
       console.log("Talvez uma variável seja uma melhor opção");
     }
-    const type = new CompoundType(typeString, dataDim);
+    const type = new ArrayType(typeString, dataDim);
     const exp = new Expressions.ArrayLiteral(type, data);
     exp.sourceInfo = sourceInfo;
     return exp;
@@ -524,7 +524,7 @@ export class IVProgParser {
         const expString = this.inputStream.getText(beginArray.start, endArray.stop);
         throw SyntaxErrorFactory.invalid_matrix_literal_line(expString, sourceInfo);
       }
-      const type = new CompoundType(typeString, 1);
+      const type = new ArrayType(typeString, 1);
       const exp = new Expressions.ArrayLiteral(type, data);
       exp.sourceInfo = sourceInfo;
       list.push(exp);
@@ -598,7 +598,7 @@ export class IVProgParser {
     const commandsBlock = this.parseCommandBlock();
     let returnType = funType;
     if(dimensions > 0) {
-      returnType = new CompoundType(funType, dimensions);
+      returnType = new ArrayType(funType, dimensions);
     }
     const func = new Commands.Function(functionID, returnType, formalParams, commandsBlock);
     if (functionID === null && !func.isMain) {
@@ -638,7 +638,7 @@ export class IVProgParser {
       }
       let type = null;
       if(dimensions > 0) {
-        type = new CompoundType(typeString, dimensions);
+        type = new ArrayType(typeString, dimensions);
       } else {
         type = typeString;
       }

+ 14 - 14
js/processor/ivprogProcessor.js

@@ -12,7 +12,7 @@ import * as Commands from './../ast/commands/';
 import * as Expressions from './../ast/expressions/';
 import { StoreObjectArrayAddress } from './store/storeObjectArrayAddress';
 import { StoreObjectArrayAddressRef } from './store/storeObjectArrayAddressRef';
-import { CompoundType } from './../typeSystem/compoundType';
+import { ArrayType } from './../typeSystem/array_type';
 import { convertToString } from '../typeSystem/parsers';
 import { Config } from '../util/config';
 import Decimal from 'decimal.js';
@@ -127,7 +127,7 @@ export class IVProgProcessor {
     let funcStore = new Store(funcName);
     funcStore.extendStore(this.globalStore);
     let returnStoreObject = null;
-    if(func.returnType instanceof CompoundType) {
+    if(func.returnType instanceof ArrayType) {
       if(func.returnType.dimensions > 1) {
         returnStoreObject = new StoreObjectArray(func.returnType,-1,-1,[[]]);
       } else {
@@ -496,7 +496,7 @@ export class IVProgProcessor {
 
   executeArrayIndexAssign (store, cmd) {
     const mustBeArray = store.applyStore(cmd.id);
-    if(!(mustBeArray.type instanceof CompoundType)) {
+    if(!(mustBeArray.type instanceof ArrayType)) {
       return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(cmd.id, cmd.sourceInfo));
     }
     const line$ = this.evaluateExpression(store, cmd.line);
@@ -539,7 +539,7 @@ export class IVProgProcessor {
 
       const newArray = Object.assign(new StoreObjectArray(null,null,null), mustBeArray);
       if (column !== null) {
-        if (value.type instanceof CompoundType || !newArray.type.canAccept(value.type)) {
+        if (value.type instanceof ArrayType || !newArray.type.canAccept(value.type)) {
           const type = mustBeArray.type.innerType;
           const stringInfo = type.stringInfo()
           const info = stringInfo[0]
@@ -548,7 +548,7 @@ export class IVProgProcessor {
         newArray.value[line].value[column] = value;
         store.updateStore(cmd.id, newArray);
       } else {
-        if((mustBeArray.columns !== null && value.type instanceof CompoundType) || !newArray.type.canAccept(value.type)) {
+        if((mustBeArray.columns !== null && value.type instanceof ArrayType) || !newArray.type.canAccept(value.type)) {
           const type = mustBeArray.type;
           const stringInfo = type.stringInfo()
           const info = stringInfo[0]
@@ -594,7 +594,7 @@ export class IVProgProcessor {
           let realValue = value;
           if (value !== null) {
             if(value instanceof StoreObjectArrayAddress) {
-              if(value.type instanceof CompoundType) {
+              if(value.type instanceof ArrayType) {
                 realValue = Object.assign(new StoreObjectArray(null,null,null), value.refValue);
               } else {
                 realValue = Object.assign(new StoreObject(null,null), value.refValue);
@@ -604,7 +604,7 @@ export class IVProgProcessor {
             realValue = new StoreObjectArray(cmd.type, line, column, [])
             if(column !== null) {
               for (let i = 0; i < line; i++) {
-                realValue.value.push(new StoreObjectArray(new CompoundType(cmd.type.innerType, 1), column, null, []));
+                realValue.value.push(new StoreObjectArray(new ArrayType(cmd.type.innerType, 1), column, null, []));
               }
             }
           }
@@ -629,8 +629,8 @@ export class IVProgProcessor {
               }
             }
             if(vl instanceof StoreObjectArrayAddress) {
-              if(vl.type instanceof CompoundType) {
-                return Promise.reject(new Error("!!!Critical Error: Compatibility check failed, a Type accepts a CompoundType"))
+              if(vl.type instanceof ArrayType) {
+                return Promise.reject(new Error("!!!Critical Error: Compatibility check failed, a Type accepts a ArrayType"))
               } else {
                 realValue = Object.assign(new StoreObject(null,null), vl.refValue);
               }
@@ -725,7 +725,7 @@ export class IVProgProcessor {
     if(!exp.isVector) {
       const $matrix = this.evaluateMatrix(store, exp.value);
       return $matrix.then(list => {
-        const type = new CompoundType(list[0].type.innerType, 2);
+        const type = new ArrayType(list[0].type.innerType, 2);
         const arr = new StoreObjectArray(type, list.length, list[0].lines, list);
         const checkResult = arr.isValid;
         if(checkResult.length == 0)
@@ -736,7 +736,7 @@ export class IVProgProcessor {
       });
     } else {
       return this.evaluateVector(store, exp.value).then(list => {
-        const type = new CompoundType(list[0].type, 1);
+        const type = new ArrayType(list[0].type, 1);
         const stoArray = new StoreObjectArray(type, list.length, null, list);
         const checkResult = stoArray.isValid;
         if(checkResult.length == 0)
@@ -756,7 +756,7 @@ export class IVProgProcessor {
     return Promise.all(exps.map( vector => {
       const $vector = this.evaluateVector(store, vector.value)
       return $vector.then(list => {
-        const type = new CompoundType(list[0].type, 1);
+        const type = new ArrayType(list[0].type, 1);
         return new StoreObjectArray(type, list.length, null, list)
       });
     } ));
@@ -781,7 +781,7 @@ export class IVProgProcessor {
 
   evaluateArrayAccess (store, exp) {
     const mustBeArray = store.applyStore(exp.id);
-    if (!(mustBeArray.type instanceof CompoundType)) {
+    if (!(mustBeArray.type instanceof ArrayType)) {
       return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo));
     }
     const $line = this.evaluateExpression(store, exp.line);
@@ -1016,7 +1016,7 @@ export class IVProgProcessor {
   parseStoreObjectValue (vl) {
     let realValue = vl;
     if(vl instanceof StoreObjectArrayAddress) {      
-      if(vl.type instanceof CompoundType) {
+      if(vl.type instanceof ArrayType) {
         switch(vl.type.dimensions) {
           case 1: {
             realValue = new StoreObjectArray(vl.type, vl.value);

+ 4 - 4
js/processor/lib/arrays.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 { CompoundType } from '../../typeSystem/compoundType';
+import { ArrayType } from '../../typeSystem/array_type';
 import { Modes } from '../modes';
 
 /**
@@ -21,7 +21,7 @@ export function createNumElementsFun () {
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(numElementsFun)]);
   const func = new Commands.Function('$numElements', Types.INTEGER,
-    [new Commands.FormalParameter(new CompoundType(Types.ALL, 1), 'vector', false)],
+    [new Commands.FormalParameter(new ArrayType(Types.ALL, 1), 'vector', false)],
     block);
   return func;
  }
@@ -36,7 +36,7 @@ export function createMatrixLinesFun () {
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(matrixLinesFun)]);
   const func = new Commands.Function('$matrixLines', Types.INTEGER,
-    [new Commands.FormalParameter(new CompoundType(Types.ALL, 2), 'matrix', false)],
+    [new Commands.FormalParameter(new ArrayType(Types.ALL, 2), 'matrix', false)],
     block);
   return func;
  }
@@ -51,7 +51,7 @@ export function createMatrixColumnsFun () {
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(matrixColumnsFun)]);
   const func = new Commands.Function('$matrixColumns', Types.INTEGER,
-    [new Commands.FormalParameter(new CompoundType(Types.ALL, 2), 'matrix', false)],
+    [new Commands.FormalParameter(new ArrayType(Types.ALL, 2), 'matrix', false)],
     block);
   return func;
  }

+ 3 - 3
js/processor/lib/math.js

@@ -4,7 +4,7 @@ import { Types } from './../../typeSystem/types';
 import { toReal } from "./../../typeSystem/parsers";
 import { Decimal } from 'decimal.js';
 import { MultiType } from '../../typeSystem/multiType';
-import { CompoundType } from '../../typeSystem/compoundType';
+import { ArrayType } from '../../typeSystem/array_type';
 import { Modes } from '../modes';
 import { Config } from '../../util/config';
 
@@ -229,7 +229,7 @@ export function createMaxFun () {
     sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
- const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
+ const paramType = new ArrayType(new MultiType([Types.INTEGER, Types.REAL]), 1);
  const block = new Commands.CommandBlock([],  [new Commands.SysCall(maxFun)]);
  const func = new Commands.Function('$max', new MultiType([Types.INTEGER, Types.REAL]),
    [new Commands.FormalParameter(paramType, 'x', false)],
@@ -246,7 +246,7 @@ export function createMinFun () {
     sto.mode = Modes.RETURN;
     return Promise.resolve(sto.updateStore('$', temp));
   };
- const paramType = new CompoundType(new MultiType([Types.INTEGER, Types.REAL]), 1);
+ const paramType = new ArrayType(new MultiType([Types.INTEGER, Types.REAL]), 1);
  const block = new Commands.CommandBlock([],  [new Commands.SysCall(minFun)]);
  const func = new Commands.Function('$min', new MultiType([Types.INTEGER, Types.REAL]),
    [new Commands.FormalParameter(paramType, 'x', false)],

+ 92 - 110
js/processor/semantic/semanticAnalyser.js

@@ -6,7 +6,7 @@ import { InfixApp, UnaryApp, FunctionCall, IntLiteral, RealLiteral, StringLitera
 import { Literal } from '../../ast/expressions/literal';
 import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from '../compatibilityTable';
 import { Types } from '../../typeSystem/types';
-import { CompoundType } from '../../typeSystem/compoundType';
+import { ArrayType } from '../../typeSystem/array_type';
 import { MultiType } from '../../typeSystem/multiType';
 import { Config } from '../../util/config';
 import { Store } from '../store/store';
@@ -103,21 +103,7 @@ export class SemanticAnalyser {
 
   assertDeclaration (declaration) {
     if (declaration instanceof ArrayDeclaration) {
-      if(declaration.initial === null) {
-        const lineType = this.evaluateExpressionType(declaration.lines);
-        if (!lineType.isCompatible(Types.INTEGER)) {
-          throw ProcessorErrorFactory.array_dimension_not_int_full(declaration.sourceInfo);
-        }
-        if (declaration.columns !== null) {
-          const columnType = this.evaluateExpressionType(declaration.columns);
-          if (!columnType.isCompatible(Types.INTEGER)) {
-            throw ProcessorErrorFactory.array_dimension_not_int_full(declaration.sourceInfo);
-          }
-        }
-        this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines, columns: declaration.columns, type: declaration.type});
-        return;
-      }
-      this.evaluateArrayLiteral(declaration.id, declaration.lines, declaration.columns, declaration.type, declaration.initial);
+      this.assertArrayDeclaration(declaration);
       this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines, columns: declaration.columns, type: declaration.type});
 
     } else {
@@ -145,6 +131,25 @@ export class SemanticAnalyser {
     }
   }
 
+  assertArrayDeclaration (declaration) {
+    if(declaration.initial === null) {
+      const lineType = this.evaluateExpressionType(declaration.lines);
+      if (!lineType.isCompatible(Types.INTEGER)) {
+        throw ProcessorErrorFactory.array_dimension_not_int_full(declaration.sourceInfo);
+      }
+      if (declaration.columns !== null) {
+        const columnType = this.evaluateExpressionType(declaration.columns);
+        if (!columnType.isCompatible(Types.INTEGER)) {
+          throw ProcessorErrorFactory.array_dimension_not_int_full(declaration.sourceInfo);
+        }
+      }  
+    } else {
+      this.evaluateArrayLiteral(declaration);
+    }
+    this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines, columns: declaration.columns, type: declaration.type});
+    return;
+  }
+
   evaluateExpressionType (expression) {
     // TODO: Throw operator error in case type == UNDEFINED
     if(expression instanceof UnaryApp) {
@@ -192,7 +197,7 @@ export class SemanticAnalyser {
       if(arrayTypeInfo === null) {
         throw ProcessorErrorFactory.symbol_not_found_full(expression.id, expression.sourceInfo);
       }
-      if (!(arrayTypeInfo.type instanceof CompoundType)) {
+      if (!(arrayTypeInfo.type instanceof ArrayType)) {
         throw ProcessorErrorFactory.invalid_array_access_full(expression.id, expression.sourceInfo);
       }
       const lineType = this.evaluateExpressionType(expression.line);
@@ -216,7 +221,7 @@ export class SemanticAnalyser {
         if(arrayTypeInfo.columns === null) {
           return arrType.innerType;
         }
-        return new CompoundType(arrType.innerType, 1);
+        return new ArrayType(arrType.innerType, 1);
       }
     }
   }
@@ -235,7 +240,7 @@ export class SemanticAnalyser {
       if(typeInfo === null) {
         throw ProcessorErrorFactory.symbol_not_found_full(literal.id, literal.sourceInfo);
       }
-      if (typeInfo.type instanceof CompoundType) {
+      if (typeInfo.type instanceof ArrayType) {
         return typeInfo.type;
       }
       return typeInfo.type;
@@ -257,83 +262,25 @@ export class SemanticAnalyser {
           }
         }
       }
-      if(last instanceof CompoundType) {
-        return new CompoundType(last.innerType, last.dimensions + 1);
+      if(last instanceof ArrayType) {
+        return new ArrayType(last.innerType, last.dimensions + 1);
       }
-      return new CompoundType(last, 1);
+      return new ArrayType(last, 1);
     }
   }
 
-  evaluateArrayLiteral (id, lines, columns, type, literal) {
-    /* if (literal instanceof ArrayLiteral) {
-      const dimType = this.evaluateExpressionType(lines);
-      if (!dimType.isCompatible(Types.INTEGER)) {
-        throw ProcessorErrorFactory.array_dimension_not_int_full(literal.sourceInfo);
-      }
-      if ((lines instanceof IntLiteral)) {
-        if (!lines.value.eq(literal.value.length)) {
-          if(type.dimensions > 1) {
-            throw ProcessorErrorFactory.matrix_line_outbounds_full(id, literal.value.length, lines.value.toNumber(), literal.sourceInfo)
-          } else {
-            throw ProcessorErrorFactory.vector_line_outbounds_full(id, literal.value.length, lines.value.toNumber(), literal.sourceInfo)
-          }
-        } else if (lines.value.isNeg()) {
-          throw ProcessorErrorFactory.array_dimension_not_positive_full(literal.sourceInfo);
-        }
-      }
-      if (columns === null) {
-        // it's a vector...
-        literal.value.reduce((last, next) => {
-          const eType = this.evaluateExpressionType(next);
-          if (!last.canAccept(eType)) {
-            const strInfo = last.stringInfo();
-            const info = strInfo[0];
-            const strExp = literal.toString();
-            throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
-          }
-          return last;
-        }, type);
-        return true;
-      } else {
-        const dimType = this.evaluateExpressionType(columns);
-        if (!dimType.isCompatible(Types.INTEGER)) {
-          throw ProcessorErrorFactory.array_dimension_not_int_full(literal.sourceInfo);
-        }
-        if ((columns instanceof IntLiteral)) {
-          const columnValue = literal.value[0].value.length;
-          if (!columns.value.eq(columnValue)) {
-            if(type.dimensions > 1) {
-              throw ProcessorErrorFactory.matrix_column_outbounds_full(id, literal.value.length, columns.value.toNumber(), literal.sourceInfo)
-            } else {
-              throw ProcessorErrorFactory.invalid_matrix_access_full(id, literal.sourceInfo);
-            }
-          } else if (columns.value.isNeg()) {
-            throw ProcessorErrorFactory.array_dimension_not_positive_full(literal.sourceInfo);
-          }
-          for (let i = 0; i < columns; i++) {
-            const anotherArray = literal.value[i];
-            this.evaluateArrayLiteral(id, columns, null, type, anotherArray)
-          }
-        }
-      }
-
+  evaluateArrayLiteral (arrayDeclaration) {
+    const type =  arrayDeclaration.type;
+    const literal = arrayDeclaration.initial;
+    if(arrayDeclaration.isVector) {
+      this.evaluateVectorLiteralType(literal, type);
     } else {
-
-      const resultType = this.evaluateExpressionType(literal);
-      if (!(resultType instanceof CompoundType)) {
-        const strInfo = type.stringInfo();
-        const info = strInfo[0];
-        const strExp = literal.toString();
-        throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
-      }
-      if (!type.isCompatible(resultType)) {
-        const strInfo = type.stringInfo();
-        const info = strInfo[0];
-        const strExp = literal.toString();
-        throw ProcessorErrorFactory.incompatible_types_array_full(strExp,info.type, info.dim, literal.sourceInfo);
-      }
-      return true;
-    } */
+      // TODO matrix type check
+      for(let i = 0; i < literal.columns; ++i) {
+        const line_literal = literal.value[i];
+        this.evaluateVectorLiteralType(line_literal, new ArrayType(type.innerType, 1));
+      }
+    }
     return true;
   }
 
@@ -341,7 +288,7 @@ export class SemanticAnalyser {
     this.pushMap();
     this.currentFunction = fun;
     fun.formalParameters.forEach(formalParam => {
-      if(formalParam.type instanceof CompoundType) {
+      if(formalParam.type instanceof ArrayType) {
         if(formalParam.type.dimensions > 1) {
           this.insertSymbol(formalParam.id, {id: formalParam.id, lines: -1, columns: -1, type: formalParam.type});
         } else {
@@ -405,11 +352,12 @@ export class SemanticAnalyser {
       return result && hasDefault;
 
     } else if (cmd instanceof ArrayIndexAssign) {
+      // TODO - rework!!!!!
       const typeInfo = this.findSymbol(cmd.id, this.symbolMap);
       if(typeInfo === null) {
         throw ProcessorErrorFactory.symbol_not_found_full(cmd.id, cmd.sourceInfo);
       }
-      if(!(typeInfo.type instanceof CompoundType)) {
+      if(!(typeInfo.type instanceof ArrayType)) {
         throw ProcessorErrorFactory.invalid_array_access_full(cmd.id, cmd.sourceInfo);
       }
       const exp = cmd.expression;
@@ -421,37 +369,50 @@ export class SemanticAnalyser {
       const columnExp = cmd.column;
       if (typeInfo.columns === null && columnExp !== null) {
         throw ProcessorErrorFactory.invalid_matrix_access_full(cmd.id, cmd.sourceInfo);
+      } else if (!typeInfo.type.isVector && columnExp == null) {
+        throw new Error("Cannot assign to matrix line");
       } else if (columnExp !== null) {
         const columnType = this.evaluateExpressionType(columnExp);
         if (!columnType.isCompatible(Types.INTEGER)) {
           throw ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo);
         }
       }
-      // exp can be a arrayLiteral, a single value exp or an array access
-      if(exp instanceof ArrayLiteral) {
-        this.evaluateArrayLiteral(cmd.id, typeInfo.lines, (columnExp ? typeInfo.columns : null), typeInfo.type, exp);
+      // exp a single value exp or an array access
+      const exp_type = this.evaluateExpressionType(exp);
+      if(exp_type instanceof ArrayType) {
+        // TODO better error message
+        throw new Error("Cannot assign a matrix/vector");
+      }
+      let compatible = false;
+      if(exp_type instanceof MultiType) {
+        compatible = exp_type.isCompatible(typeInfo.type.innerType);
       } else {
-        // cannot properly evaluate since type system is poorly constructed
+        compatible = typeInfo.type.canAccept(exp_type);
+      }
+      if(!compatible) {
+        if(!Config.enable_type_casting || !Store.canImplicitTypeCast(typeInfo.type.innerType, exp_type)) {
+          throw new Error("invalid vector element type");
+        }
       }
       return optional;
     } else if (cmd instanceof Assign) {
+      // TODO - rework since there is no literal array assignment
       const typeInfo = this.findSymbol(cmd.id, this.symbolMap);
       if(typeInfo === null) {
         throw ProcessorErrorFactory.symbol_not_found_full(cmd.id, cmd.sourceInfo);
       }
+      if(typeInfo.type instanceof ArrayType) {
+        // TODO better error message
+        throw new Error("Cannot assign to matrix/vector");
+      }
       const exp = cmd.expression;
-      if(exp instanceof ArrayLiteral) {
-        if(!(typeInfo.type instanceof CompoundType)) {
-          const stringInfo = typeInfo.type.stringInfo();
-          const info = stringInfo[0];
-          throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo);
-        }
-        this.evaluateArrayLiteral(cmd.id, typeInfo.lines, typeInfo.columns, typeInfo.type, exp);
-      } else {
-        const resultType = this.evaluateExpressionType(exp);
-        if((!resultType.isCompatible(typeInfo.type) && !Config.enable_type_casting)
-          || (!resultType.isCompatible(typeInfo.type) && Config.enable_type_casting
-          && !Store.canImplicitTypeCast(typeInfo.type, resultType))) {
+      const exp_type = this.evaluateExpressionType(exp);
+      if(exp_type instanceof ArrayType) {
+        // TODO better error message
+        throw new Error("Cannot assign a matrix/vector");
+      }
+      if(!exp_type.isCompatible(typeInfo.type)) {
+        if(!Config.enable_type_casting || !Store.canImplicitTypeCast(typeInfo.type, exp_type)) {
           const stringInfo = typeInfo.type.stringInfo();
           const info = stringInfo[0];
           throw ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo);
@@ -531,7 +492,7 @@ export class SemanticAnalyser {
         for (let j = 0; j < resultType.types.length; ++j) {
           const element = resultType.types[j];
           if(formalParam.type.types.indexOf(element) !== -1) {
-            shared++;
+            shared += 1;
           }
         }
         if(shared <= 0) {
@@ -566,4 +527,25 @@ export class SemanticAnalyser {
 
     }
   }
+
+  evaluateVectorLiteralType (literal, type) {
+    for(let i = 0; i < literal.value; i+=1) {
+      const exp = literal.value[i];
+      const expType = this.evaluateExpressionType(exp);
+      let compatible = false;
+      if(expType instanceof MultiType) {
+        compatible = expType.isCompatible(type.innerType);
+      } else {
+        compatible = type.canAccept(expType);
+      }
+      if(!compatible) {
+        // vector wrong type
+        // TODO better error message
+        if(!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, expType)) {
+          throw new Error("invalid vector element type");
+        }
+      }
+    }
+    return type;
+  }
 }

+ 4 - 4
js/processor/store/storeObjectArrayAddress.js

@@ -1,6 +1,6 @@
 import { StoreObject } from './storeObject';
 import { StoreObjectArray } from './storeObjectArray';
-import { CompoundType } from '../../typeSystem/compoundType';
+import { ArrayType } from '../../typeSystem/array_type';
 import { ProcessorErrorFactory } from '../error/processorErrorFactory';
 
 export class StoreObjectArrayAddress extends StoreObject {
@@ -53,7 +53,7 @@ export class StoreObjectArrayAddress extends StoreObject {
   }
 
   get lines () {
-    if(!(this.type instanceof CompoundType)) {
+    if(!(this.type instanceof ArrayType)) {
       return null;
     }
     return this.refValue.value.length;
@@ -77,7 +77,7 @@ export class StoreObjectArrayAddress extends StoreObject {
     const newArray = Object.assign(new StoreObjectArray(null,null,null), anArray);
     if(!stoObj.type.isCompatible(this.type)) {
       throw new Error(`Invalid operation: cannot assign the value given to ${this.refID}`);
-    } else if (this.type instanceof CompoundType && this.type.canAccept(stoObj.type)) {
+    } else if (this.type instanceof ArrayType && this.type.canAccept(stoObj.type)) {
       throw new Error(`Invalid operation: cannot assign the value given to ${this.refID}`);
     }
     if (this.column !== null) {
@@ -91,7 +91,7 @@ export class StoreObjectArrayAddress extends StoreObject {
 
   isCompatible (another) {
     if(this.type.isCompatible(another.type)) {
-      if(another.type instanceof CompoundType) {
+      if(another.type instanceof ArrayType) {
         return this.lines === another.lines && this.columns === another.columns;
       } else {
         this.refValue.isCompatible(another);

+ 8 - 4
js/typeSystem/compoundType.js

@@ -1,6 +1,6 @@
 import { Type } from "./type";
 
-export class CompoundType extends Type {
+export class ArrayType extends Type {
 
   constructor (type, dimensions) {
     super(null);
@@ -8,8 +8,12 @@ export class CompoundType extends Type {
     this.dimensions = dimensions;
   }
 
+  get isVector () {
+    return this.dimensions == 1;
+  }
+
   isCompatible (another) {
-    if(another instanceof CompoundType){
+    if(another instanceof ArrayType){
       if(this.dimensions !== another.dimensions) {
         return false;
       }
@@ -27,10 +31,10 @@ export class CompoundType extends Type {
   }
 
   canAccept (another) {
-    if(another instanceof CompoundType) {
+    if(another instanceof ArrayType) {
       return this.dimensions > another.dimensions && this.innerType.isCompatible(another.innerType);
     } else {
-      return this.innerType.isCompatible(another);
+      return this.dimensions == 1 && this.innerType.isCompatible(another);
     }
   }
 }

+ 1 - 0
templates/runner.html

@@ -1,6 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
+  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
   <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.0/semantic.min.css" integrity="sha256-9mbkOfVho3ZPXfM7W8sV2SndrGDuh7wuyLjtsWeTI1Q=" crossorigin="anonymous" />
   <link rel="stylesheet" type="text/css" href="css/ivprog-visual-1.0.css">