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