Bladeren bron

Undo modifications regarding array assignments. Arrays can only be assigned to other arrays with same dimension and number of elements

Lucas de Souza 4 jaren geleden
bovenliggende
commit
6466193602

+ 3 - 1
i18n/pt/error.json

@@ -104,5 +104,7 @@
   "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.",
   "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_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"
 }

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

@@ -399,5 +399,17 @@ export const ProcessorErrorFactory  = Object.freeze({
   invalid_const_ref: (fun_name, exp) => {
     const context = [exp, LanguageDefinedFunction.getLocalName(fun_name)];
     return new SemanticError(LocalizedStrings.getError("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));
+    } 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));
   }
 });

+ 51 - 83
js/processor/ivprogProcessor.js

@@ -468,7 +468,7 @@ export class IVProgProcessor {
           const info = stringInfo[0];
           return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
         } else {
-          const realValue = this.parseStoreObjectValue(vl);
+          const realValue = vl;
           store.updateStore('$', realValue);
           store.mode = Modes.RETURN;
           return Promise.resolve(store);
@@ -491,9 +491,12 @@ export class IVProgProcessor {
   executeAssign (store, cmd) {
     try {
       const inStore = store.applyStore(cmd.id);
+      if(inStore.isConst) {
+        throw ProcessorErrorFactory.invalid_const_assignment_full(cmd.id, cmd.sourceInfo);
+      }
       const $value = this.evaluateExpression(store, cmd.expression);
       return $value.then( vl => {
-        let realValue = this.parseStoreObjectValue(vl);
+        let realValue = vl;
         if(!inStore.type.isCompatible(realValue.type)) {
           if(Config.enable_type_casting && Store.canImplicitTypeCast(inStore.type, vl.type)) {
             realValue = Store.doImplicitCasting(inStore.type, realValue);
@@ -503,6 +506,14 @@ export class IVProgProcessor {
             return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
           }
         }
+
+        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");
+          }
+        }
         
         store.updateStore(cmd.id, realValue) 
         return store;
@@ -514,27 +525,30 @@ export class IVProgProcessor {
 
   executeArrayIndexAssign (store, cmd) {
     const mustBeArray = store.applyStore(cmd.id);
+    let used_dims = 0;
+    if(mustBeArray.isConst) {
+      throw ProcessorErrorFactory.invalid_const_assignment_full(cmd.id, cmd.sourceInfo);
+    }
     if(!(mustBeArray.type instanceof ArrayType)) {
       return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(cmd.id, cmd.sourceInfo));
     }
     const line$ = this.evaluateExpression(store, cmd.line);
     const column$ = this.evaluateExpression(store, cmd.column);
     const value$ =  this.evaluateExpression(store, cmd.expression);
-    return Promise.all([line$, column$, value$]).then(results => {
-      const lineSO = results[0];
-      if(!Types.INTEGER.isCompatible(lineSO.type)) {
+    return Promise.all([line$, column$, value$]).then(([line_sv, column_sv, value]) => {
+      if(!Types.INTEGER.isCompatible(line_sv.type)) {
         return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
       }
-      const line = lineSO.get();
-      const columnSO = results[1];
-      let column = null
-      if (columnSO !== null) {
-        if(!Types.INTEGER.isCompatible(columnSO.type)) {
+      const line = line_sv.get().toNumber();
+      used_dims += 1;
+      let column = undefined;
+      if (column_sv != null) {
+        if(!Types.INTEGER.isCompatible(column_sv.type)) {
           return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
         }
-        column = columnSO.get();
+        column = column_sv.get().toNumber();
+        used_dims += 1;
       }
-      const value = this.parseStoreObjectValue(results[2]);
       let actualValue = value;
       if (line >= mustBeArray.lines) {
         if(mustBeArray.isVector) {
@@ -545,10 +559,10 @@ export class IVProgProcessor {
       } else if (line < 0) {
         throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
       }
-      if (column !== null && mustBeArray.columns === null ){
+      if (column != null && mustBeArray.columns === 0 ){
         return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(cmd.id, cmd.sourceInfo));
       }
-      if(column !== null ) {
+      if(column != null ) {
         if (column >= mustBeArray.columns) {
           return Promise.reject(ProcessorErrorFactory.matrix_column_outbounds_full(cmd.id, column,mustBeArray.columns, cmd.sourceInfo));
         } else if (column < 0) {
@@ -556,35 +570,29 @@ export class IVProgProcessor {
         }
       }
 
-      const newArray = Object.assign(new StoreObjectArray(null,null,null), mustBeArray);
-      if (column !== null) {
-        if (!newArray.type.canAccept(value.type)) {
-          if(!Config.enable_type_casting || !Store.canImplicitTypeCast(mustBeArray.type.innerType, value.type)) {
-            const type = mustBeArray.type.innerType;
-            const stringInfo = type.stringInfo();
-            const info = stringInfo[0];
-            // const exp = cmd.expression.toString();
-            return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
-          }
-          actualValue = Store.doImplicitCasting(mustBeArray.type.innerType, value);
+      if (!mustBeArray.type.canAccept(value.type, used_dims)) {
+        if(!Config.enable_type_casting || !Store.canImplicitTypeCast(mustBeArray.type.innerType, value.type)) {
+          const type = mustBeArray.type.innerType;
+          const stringInfo = type.stringInfo();
+          const info = stringInfo[0];
+          // const exp = cmd.expression.toString();
+          return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
         }
-        newArray.value[line].value[column] = actualValue;
-        store.updateStore(cmd.id, newArray);
-      } else {
-        if(!newArray.type.canAccept(value.type)) {
-          if(!Config.enable_type_casting || !Store.canImplicitTypeCast(mustBeArray.type.innerType, value.type)) {
-            const type = mustBeArray.type;
-            const stringInfo = type.stringInfo();
-            const info = stringInfo[0];
-            const exp = cmd.expression.toString();
-            return Promise.reject(ProcessorErrorFactory.incompatible_types_array_full(exp,info.type, info.dim-1, cmd.sourceInfo));
-          }
-          actualValue = Store.doImplicitCasting(mustBeArray.type.innerType, value);
+        actualValue = Store.doImplicitCasting(mustBeArray.type.innerType, value);
+      }
+
+      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
+          throw new Error("exp exceeds the number of elements of the vector");
         }
-        newArray.value[line] = actualValue;
-        store.updateStore(cmd.id, newArray);
       }
-      return store;
+
+      // mustBeArray.setAt(actualValue, line, column);
+      // store.updateStore(cmd.id, mustBeArray);
+      return store.updateStoreArray(cmd.id,actualValue, line, column);
     });
   }
 
@@ -762,7 +770,7 @@ export class IVProgProcessor {
     const actual_values = Promise.all(values.map( exp => this.evaluateExpression(store, exp)));
     return actual_values.then( values => {
       return values.map((v, index) => {
-        if(!type.canAccept(v.type)) {
+        if(!type.canAccept(v.type, 1)) {
           if (!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, v.type)) {
             // const stringInfo = v.type.stringInfo();
             // const info = stringInfo[0];
@@ -804,11 +812,6 @@ export class IVProgProcessor {
     try {
       const val = store.applyStore(exp.id);
       return Promise.resolve(val);
-      // if (val instanceof StoreObjectArray) {
-      //   return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
-      // } else {
-      //   return Promise.resolve(val);
-      // }
     } catch (error) {
       return Promise.reject(error);
     }
@@ -856,20 +859,14 @@ export class IVProgProcessor {
       const result = mustBeArray.getAt(line, column);
       const type = mustBeArray.type.innerType;
       if(Array.isArray(result)) {
-        let l = 0;
-        const values = result.map(v => {
-          if(!Array.isArray(v)) {
-            return new StoreValueAddress(type.innerType, v, l++, undefined, mustBeArray.id, mustBeArray.readOnly);  
-          } else {
-            throw new Error("Indexing 3D structure....");
-          }
+        const values = result.map((v, c) => {
+          return new StoreValueAddress(type, v, line, c, mustBeArray.id, mustBeArray.readOnly);
         });
         return Promise.resolve(new ArrayStoreValue(new ArrayType(type, 1),
           values, mustBeArray.columns, null, mustBeArray.id, mustBeArray.readOnly))
       } else {
         return Promise.resolve(new StoreValueAddress(type, result, line, column, mustBeArray.id, mustBeArray.readOnly));
       }
-      //return Promise.resolve(mustBeArray.getAt(line, column));
     });
   }
 
@@ -932,9 +929,6 @@ export class IVProgProcessor {
           return new StoreValue(resultType, (left.get().minus(right.get())));
         case Operators.MULT.ord: {
           result = left.get().times(right.get());
-          // if(result.dp() > Config.decimalPlaces) {
-          //   result = new Decimal(result.toFixed(Config.decimalPlaces));
-          // }
           return new StoreValue(resultType, result);
         }
         case Operators.DIV.ord: {
@@ -942,9 +936,6 @@ export class IVProgProcessor {
             result = left.get().divToInt(right.get());
           else
             result = left.get().div(right.get());
-          // if(result.dp() > Config.decimalPlaces) {
-          //   result = new Decimal(result.toFixed(Config.decimalPlaces));
-          // }
           return new StoreValue(resultType, (result));
         }
         case Operators.MOD.ord: {
@@ -956,9 +947,6 @@ export class IVProgProcessor {
             rightValue = rightValue.trunc();
           }
           result = leftValue.modulo(rightValue);
-          // if(result.dp() > Config.decimalPlaces) {
-          //   result = new Decimal(result.toFixed(Config.decimalPlaces));
-          // }
           return new StoreValue(resultType, (result));
         }          
         case Operators.GT.ord: {
@@ -1061,24 +1049,4 @@ export class IVProgProcessor {
     });
   }
 
-  parseStoreObjectValue (vl) {
-    let realValue = vl;
-    if(vl instanceof StoreObjectArrayAddress) {
-      if(vl.type instanceof ArrayType) {
-        switch(vl.type.dimensions) {
-          case 1: {
-            realValue = new StoreObjectArray(vl.type, vl.get().length, null, vl.get());
-            break;
-          }
-          default: {
-            throw new RuntimeError("Three dimensional array address...");
-          }
-        }
-      } else {
-        realValue = new StoreValue(vl.type, vl.get());
-      }
-    }
-    return realValue;
-  }
-
 }

+ 23 - 11
js/processor/semantic/semanticAnalyser.js

@@ -104,7 +104,8 @@ export class SemanticAnalyser {
   assertDeclaration (declaration) {
     if (declaration instanceof ArrayDeclaration) {
       this.assertArrayDeclaration(declaration);
-      this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines, columns: declaration.columns, type: declaration.type});
+      this.insertSymbol(declaration.id, {id: declaration.id, lines: declaration.lines,
+        columns: declaration.columns, type: declaration.type, isConst: declaration.isConst});
 
     } else {
       if(declaration.initial === null) {
@@ -353,10 +354,14 @@ export class SemanticAnalyser {
 
     } else if (cmd instanceof ArrayIndexAssign) {
       // TODO - rework!!!!!
+      let used_dims = 0;
       const typeInfo = this.findSymbol(cmd.id, this.symbolMap);
       if(typeInfo === null) {
         throw ProcessorErrorFactory.symbol_not_found_full(cmd.id, cmd.sourceInfo);
       }
+      if(typeInfo.isConst) {
+        throw ProcessorErrorFactory.invalid_const_assignment_full(cmd.id, cmd.sourceInfo);
+      }
       if(!(typeInfo.type instanceof ArrayType)) {
         throw ProcessorErrorFactory.invalid_array_access_full(cmd.id, cmd.sourceInfo);
       }
@@ -366,31 +371,35 @@ export class SemanticAnalyser {
       if (!lineType.isCompatible(Types.INTEGER)) {
         throw ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo);
       }
+      used_dims += 1;
       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);
         }
+        used_dims += 1;
       }
       // 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");
-      }
+      const access_type = typeInfo.type;
+
       let compatible = false;
       if(exp_type instanceof MultiType) {
-        compatible = exp_type.isCompatible(typeInfo.type.innerType);
+        let type = access_type;
+        if(access_type.dimensions - used_dims == 0) {
+          type = access_type.innerType
+        } else {
+          type = new ArrayType(access_type.innerType, Math.max(0, access_type.dimensions - used_dims));
+        }
+        compatible = exp_type.isCompatible(type);
       } else {
-        compatible = typeInfo.type.canAccept(exp_type);
+        compatible = access_type.canAccept(exp_type, used_dims);
       }
       if(!compatible) {
-        if(!Config.enable_type_casting || !Store.canImplicitTypeCast(typeInfo.type.innerType, exp_type)) {
+        if(!Config.enable_type_casting || !Store.canImplicitTypeCast(access_type, exp_type)) {
           throw new Error("invalid vector element type");
         }
       }
@@ -401,6 +410,9 @@ export class SemanticAnalyser {
       if(typeInfo === null) {
         throw ProcessorErrorFactory.symbol_not_found_full(cmd.id, cmd.sourceInfo);
       }
+      if(typeInfo.isConst) {
+        throw ProcessorErrorFactory.invalid_const_assignment_full(cmd.id, cmd.sourceInfo);
+      }
       const exp = cmd.expression;
       const exp_type = this.evaluateExpressionType(exp);
       if(exp_type instanceof ArrayType) {
@@ -552,7 +564,7 @@ export class SemanticAnalyser {
       if(expType instanceof MultiType) {
         compatible = expType.isCompatible(type.innerType);
       } else {
-        compatible = type.canAccept(expType);
+        compatible = type.canAccept(expType, 1);
       }
       if(!compatible) {
         // vector wrong type

+ 93 - 15
js/processor/store/store.ts

@@ -74,6 +74,7 @@ export class Store {
           return new StoreValueAddress(array_type.innerType, v, l, c++, array.id, array.readOnly);  
         }
       });
+      console.log("applyStore", values);
       result = new ArrayStoreValue(array_type, values, array.lines, array.columns, val.id, val.readOnly);
     } else {
       result = new StoreValue(val.type, val.value, val.id, val.readOnly);
@@ -82,7 +83,7 @@ export class Store {
     return result;
   }
 
-  updateStore (id: String, stoValue: IStoreValue): Store {
+  updateStore (id: string, stoValue: IStoreValue): Store {
     if (!this.store.has(id)) {
       if (this.nextStore != null) {
         this.nextStore.updateStore(id, stoValue);
@@ -98,25 +99,98 @@ export class Store {
         throw new Error("Cannot change value of a read only variable: " + id);
       }
 
-      if (oldObj.type instanceof ArrayType) {
-        // oldObj.updateRef(stoValue);
-        return this;
+      if (oldObj instanceof StoreObjectArray) {
+        const array_value = stoValue as ArrayStoreValue;
+        if(oldObj.isCompatible(array_value)) {
+          if(oldObj.isVector) {
+            array_value.get().forEach((val, index) => {
+              console.log(val);
+              oldObj.setAt(val, index, undefined);
+            });
+          } else {
+            let line = 0;
+            let column = 0;
+            array_value.get().forEach((val) => {
+              oldObj.setAt(val, line, column);
+              column += 1;
+              if(column >= oldObj.columns) {
+                line += 1;
+                column = 0;
+              }
+            });
+          }
+          return this;
+        }
       } else if (oldObj.isCompatible(stoValue)) {
-        // TODO check for array....
-        // const loc_address = Location.allocate(stoValue.get());
-        // const newObj = new StoreObject(stoValue.type, loc_address, stoValue.isConst);
-        // newObj.setID(id);
-        // this.store.get(id)!.destroy();
-        // this.store.set(id, newObj);
         const loc_address = oldObj.locAddress;
         Location.updateAddress(loc_address, stoValue.get());
         return this;
+      }
+      const oldType = oldObj.type;
+      const stoType = stoValue.type;
+      // TODO: better error message
+      throw new Error(`${oldType.value} is not compatible with type ${stoType.value} given`);
+      
+    }
+  }
+
+  /**
+   * Method used to update regions of an array (vector or matrix). The should only be used when update an specific
+   * possition since it will only update the required addresses.
+   * @param {string} id the variable id to be updated
+   * @param {IStoreValue} sto_value the value to be used in the update process
+   * @param {number} line the line address of the vector/matrix
+   * @param {number} column the matrix column, which can be undefined
+   */
+  updateStoreArray (id:string, sto_value: IStoreValue, line:number, column?:number): Store {
+    if (!this.store.has(id)) {
+      if (this.nextStore != null) {
+        this.nextStore.updateStoreArray(id, sto_value, line, column);
+        return this;
       } else {
-        const oldType = oldObj.type;
-        const stoType = stoValue.type;
         // TODO: better error message
-        throw new Error(`${oldType} is not compatible with type ${stoType} given`);
+        throw new Error(`Variable ${id} not found.`);
+      }
+    } else {
+      const oldObj = this.store.get(id)!;
+      if (oldObj.readOnly) {
+        // TODO: better error message
+        throw new Error("Cannot change value of a read only variable: " + id);
+      }
+
+      if (oldObj instanceof StoreObjectArray) {
+        if(sto_value instanceof ArrayStoreValue) {
+          // this must be a vector  or matrix line update
+          const actual_values =  sto_value.get();
+          if(oldObj.isVector && sto_value.isVector()) {
+            for(let i = 0;i < sto_value.lines; i += 1) {
+              const val = actual_values[i]
+              oldObj.setAt(val, i, undefined);
+            }
+          } else if(!oldObj.isVector && column == null && sto_value.isVector()) {
+            for(let i = 0;i < oldObj.columns; i += 1) {
+              const val = actual_values[i]
+              oldObj.setAt(val, line, i);
+            }
+          } else {
+            // TODO: better error message
+            throw new Error(`Attempting to assign an invalid value to array ${id}`);
+          }
+        } else {
+          if(!oldObj.isVector && column == null) {
+            // TODO: better error message
+            throw new Error(`Attempting to assign an invalid value to array ${id}`);
+          }
+          oldObj.setAt(sto_value as StoreValue, line, column);
+        }
+      } else {
+        throw new Error("Cannot update a non-array variable using updateStoreArray");
       }
+      // const oldType = oldObj.type;
+      // const stoType = sto_value.type;
+      // // TODO: better error message
+      // throw new Error(`${oldType.value} is not compatible with type ${stoType.value} given`);
+      return this;
     }
   }
 
@@ -134,9 +208,12 @@ export class Store {
     if(stoValue instanceof StoreValueRef) {
       newObj = new StoreObjectRef(stoValue);
     } else if (stoValue instanceof ArrayStoreValueRef) {
-      newObj = new StoreObjectArrayRef(stoValue);
+      newObj = new StoreObjectArrayRef(stoValue,0,0,false);
     } else if (stoValue instanceof ArrayStoreValue) {
       const columns = stoValue.isVector() ? 0 : stoValue.columns!;
+      const line_address = Location.allocate(stoValue.lines);
+      const column_address = Location.allocate(columns);
+      const values_address = Location.allocate([]);
       const addresses: number[] = [];
       const all_values = stoValue.get();
       if(all_values.length > 0) {
@@ -151,7 +228,8 @@ export class Store {
           addresses.push(Location.allocate(null));
         }
       }
-      newObj = new StoreObjectArray(stoValue.type as ArrayType, stoValue.lines, columns, addresses, stoValue.isConst);
+      Location.updateAddress(values_address, addresses);
+      newObj = new StoreObjectArray(stoValue.type as ArrayType, line_address, column_address, values_address, stoValue.isConst);
     } else {
       const loc_address = Location.allocate(stoValue.get());
       newObj = new StoreObject(stoValue.type, loc_address, stoValue.isConst);

+ 36 - 16
js/processor/store/storeObjectArray.ts

@@ -3,30 +3,36 @@ import { ArrayType } from '../../typeSystem/array_type';
 import { ArrayStoreValue } from './value/array_store_value';
 import { Location } from "../../memory/location";
 import { IStoreValue } from './value/istore_value';
+import { StoreValue } from './value/store_value';
 
 export class StoreObjectArray extends StoreObject {
 
-  static get WRONG_LINE_NUMBER () {
-    return 1;
+  constructor (type: ArrayType, private _lines:number, private _columns:number, loc_address: number, readOnly = false) {
+    super(type, loc_address, readOnly);
   }
 
-  static get WRONG_TYPE () {
-    return 2;
+  get lines () {
+    const num = Location.find(this._lines)!.value;
+    return num;
   }
 
-  static get WRONG_COLUMN_NUMBER () {
-    return 3;
+  getLineAddress () {
+    return this._lines;
   }
 
-  constructor (type: ArrayType, public lines:number, public columns:number, private addresses:number[], readOnly = false) {
-    super(type, -1, readOnly);
+  get columns () {
+    const num = Location.find(this._columns)!.value;
+    return num;
+  }
 
+  getColumnAddress () {
+    return this._columns;
   }
 
   isCompatible (another: IStoreValue): boolean {
     if(another instanceof ArrayStoreValue) {
-      if((this.isVector && another.isVector) ||
-        (!this.isVector && !another.isVector)) {
+      const cols = another.columns == null ? 0 :  another.columns;
+      if(this.lines === another.lines && this.columns === cols) {
           return super.isCompatible(another);
       }
     }
@@ -36,6 +42,7 @@ export class StoreObjectArray extends StoreObject {
   get isVector () {
     return (this.type as ArrayType).dimensions === 1;
   }
+
   /**@override 
      * Returns the list of values stored by this array.
      * All returned values are compatible with @prop{StoreObject.type}
@@ -61,8 +68,17 @@ export class StoreObjectArray extends StoreObject {
     return bool;
   }
 
+  /**
+   * @override
+   * 
+   * Returns the address that contains a list of all addresses of the values present in the array
+   */
   get locAddress (): number {
-    throw new Error("!!!Internal Error: Cannot access locAddress property of StoreObjectArray");
+    return super.locAddress;
+  }
+
+  protected get addresses (): number[] {
+    return Location.find(this.locAddress)!.value;
   }
 
   getAt (line: number, column?: number): any {
@@ -87,8 +103,12 @@ export class StoreObjectArray extends StoreObject {
     return address.value;
   }
 
-  setAt (value: any, line:number, column?: number): void {
-    if(!(this.type as ArrayType).canAccept(value.type)) {
+  setAt (value: StoreValue, line:number, column?: number): void {
+    let used_dims = 1;
+    if(column != null) {
+      used_dims += 1;
+    }
+    if(!(this.type as ArrayType).canAccept(value.type, used_dims)) {
       throw new Error("!!!Internal Error: Attempting to insert an invalid value inside array "+this.id);
     }
     if(this.isVector) {
@@ -101,11 +121,11 @@ export class StoreObjectArray extends StoreObject {
       throw new Error("!!!Internal Error: Attempting to insert a line into matrix "+ this.id );
     }
     const pos = this.getIndexOf(line, column);
-    Location.updateAddress(this.addresses[pos], value);
+    Location.updateAddress(this.addresses[pos], value.get());
   }
 
-  private getIndexOf (line: number, column: number): number {
-    return line * this.lines + column;
+  protected getIndexOf (line: number, column: number): number {
+    return line * this.columns + column;
   }
 
   getLocAddressOf (line: number, column?: number): number | number[] {

+ 26 - 2
js/processor/store/store_object_array_ref.ts

@@ -1,13 +1,23 @@
 import { StoreObjectArray } from "./storeObjectArray";
 import { ArrayStoreValueRef } from "./value/array_store_value_ref";
+import { Location } from "../../memory/location";
+import { IStoreValue } from "./value/istore_value";
 
 export class StoreObjectArrayRef extends StoreObjectArray {
 
   private refObj: String;
+  private indexes: number[];
+  private line_address: number;
+  private column_address?: number;
+  private source_matrix: boolean;
 
-  constructor(stoValue: ArrayStoreValueRef) {
-    super(stoValue.type, stoValue.lines, stoValue.columns, stoValue.getRefAddresses(), false);
+  constructor(stoValue: ArrayStoreValueRef, line_address:number, column_address:number, source_matrix:boolean) {
+    super(stoValue.type, line_address, column_address, stoValue.getRefAddress(), false);
     this.refObj = stoValue.id;
+    this.indexes = stoValue.getIndexes();
+    this.line_address = stoValue.line_address;
+    this.column_address = stoValue.column_address;
+    this.source_matrix = source_matrix;
   }
 
   get isRef () {
@@ -18,6 +28,20 @@ export class StoreObjectArrayRef extends StoreObjectArray {
     return this.refObj;
   }
 
+  updateValues (values: IStoreValue[]) {
+    if(this.indexes.length !== values.length) {
+      throw new Error("!!!Internal Error: updating ref array with a different number of values in relation to addresses");
+    }
+    const addresses = Location.find(this.locAddress)!.value as number[];
+    this.indexes.forEach(i => {
+      Location.updateAddress(addresses[i], values[i].get());
+    })
+  }
+
+  sourceIsMatrix () {
+    return this.source_matrix;
+  }
+
   destroy () {
     return false;
   }

+ 24 - 15
js/processor/store/value/array_store_value.ts

@@ -33,7 +33,8 @@ export class ArrayStoreValue implements IStoreValue {
    * @param column 
    */
   getAt (line: number, column?: number): IStoreValue {
-    if(this.isVector) {
+    console.log("Column ", column);
+    if(this.isVector()) {
       if(column != null) {
         throw new Error(this.id + " is not a matrix!");
       }
@@ -47,35 +48,43 @@ export class ArrayStoreValue implements IStoreValue {
       }
       const array_type = this.type as ArrayType
       const vector_type = new ArrayType(array_type.innerType as Type, array_type.dimensions - 1);
-      return new ArrayStoreValue(vector_type, values, this.columns!, undefined, this.id, this.isConst);
+      return new ArrayStoreValue(vector_type, values, this.columns!, 0, this.id, this.isConst);
     }
     const index = line * this.lines + column;
     console.log("Get at: ",index);
     return this.values[index];
   }
 
-  /**
-   * @deprecated
-   * Potential not necessary since array access is occuring directly in the StoreObject
-   * @param line 
-   * @param column 
-   */
   setAt (value: IStoreValue, line:number, column?: number): void {
-    if(!(this.type as ArrayType).canAccept(value.type)) {
+    let used_dims = 1;
+    if(column != null) {
+      used_dims += 1;
+    }
+    let actual_line = line;
+    let actual_column = column;
+    if(!(this.type as ArrayType).canAccept(value.type, used_dims)) {
       throw new Error("!!!Internal Error: Attempting to insert an invalid value inside array "+this.id);
     }
     if(this.isVector) {
       if(column != null) {
         throw new Error(this.id + " is not a matrix!");
       }
-      column = line;
-      line = 0;
+      actual_column = actual_line;
+      actual_line = 0;
     } else if (column == null) {
-      throw new Error("!!!Internal Error: Attempting to insert line into matrix "+ this.id );
+      if(!(value instanceof ArrayStoreValue)) {
+        throw new Error("Attempting to insert a single value as a line of matrix " + this.id);
+      }
+      const actual_values = value.get()
+      for(let i = 0; i < this.columns!; i += 1) {
+        const pos = actual_line * this.columns! + i;
+        const val = actual_values[i]
+        this.values[pos] = new StoreValueAddress(value.type, val.get(), actual_line, i, this.id, this.isConst);
+      }
     }
-    const pos = line * this.lines + column;
-    // TODO - fix this casting
-    this.values[pos] = value as StoreValueAddress;
+    const columns =  this.columns == null ? 0 : this.columns;
+    const pos = actual_line * columns + actual_column!;
+    this.values[pos] = new StoreValueAddress(value.type, value.get(), line, column, this.id, this.isConst);
   }
 
   inStore () {

+ 15 - 4
js/processor/store/value/array_store_value_ref.ts

@@ -6,15 +6,26 @@ export class ArrayStoreValueRef implements IStoreValue {
 
   public isConst = false;
 
-  constructor(public type: ArrayType, public values: StoreValueAddress[],
-    private loc_address: number[], public lines: number, public columns:number, public id:String) { }
+  constructor(public type: ArrayType, private values: StoreValueAddress[],
+    public lines: number, public columns:number, public id:String,
+    public line_address: number, public column_address?: number) { }
 
   get () {
     return this.values;
   }
 
-  getRefAddresses () : number[] {
-    return this.loc_address;
+  getIndexes (): number[] {
+    return this.values.map(val => {
+      if(this.type.dimensions == 1) {
+        return val.line;
+      } else {
+        return val.line * this.lines + this.columns;
+      }
+    })
+  }
+
+  getRefAddress () : number {
+    return 0//this.values_address;
   }
 
   inStore () {

+ 4 - 3
js/typeSystem/array_type.ts

@@ -39,11 +39,12 @@ export class ArrayType implements IType {
     return undefined;
   }
 
-  canAccept (another: IType) {
+  canAccept (another: IType, used_dims: number) {
+    const free_dims = this.dimensions - used_dims;
     if(another instanceof ArrayType) {
-      return false; // return this.dimensions > another.dimensions && this.innerType.isCompatible(another.innerType);
+      return free_dims == another.dimensions && this.innerType.isCompatible(another.innerType);
     } else {
-      return this.dimensions == 1 && this.innerType.isCompatible(another);
+      return free_dims == 0 && this.innerType.isCompatible(another);
     }
   }
 }