import { StoreObject } from './storeObject'; import { ArrayType } from '../../typeSystem/array_type'; import { ArrayStoreValue } from './value/array_store_value'; import { Location } from "../../memory/location"; import { IStoreValue } from './value/istore_value'; export class StoreObjectArray extends StoreObject { static get WRONG_LINE_NUMBER () { return 1; } static get WRONG_TYPE () { return 2; } static get WRONG_COLUMN_NUMBER () { return 3; } constructor (type: ArrayType, public lines:number, public columns:number, private addresses:number[], readOnly = false) { super(type, -1, readOnly); } isCompatible (another: IStoreValue): boolean { if(another instanceof ArrayStoreValue) { if((this.isVector && another.isVector) || (!this.isVector && !another.isVector)) { return super.isCompatible(another); } } return false; } 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} */ get value () { const values = []; for(let i = 0; i < this.addresses.length; i += 1) { const address = Location.find(this.addresses[i]); if (address != null) { values.push(address.value); } else { throw new Error("!!!Critical Error: variable "+this.id+" does not have a valid address. Loc-Address "+ this.locAddress); } } return values; } destroy () { let bool = true; for(let i = 0; i < this.addresses.length; i += 1) { bool = bool && Location.deallocate(this.addresses[i]); } return bool; } get locAddress (): number { throw new Error("!!!Internal Error: Cannot access locAddress property of StoreObjectArray"); } getAt (line: number, column?: number): any { if(this.isVector) { if(column != null) { throw new Error(this.id + " is not a matrix!"); } column = line; line = 0; } else if (column == null) { // this is a whole line... const values = []; for(let col = 0; col < this.columns; col += 1) { const index = this.getIndexOf(line, col); const address = Location.find(this.addresses[index])!; values.push(address.value); } return values; } const index = this.getIndexOf(line, column); const address = Location.find(this.addresses[index])!; return address.value; } setAt (value: any, line:number, column?: number): void { if(!(this.type as ArrayType).canAccept(value.type)) { 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; } else if (column == null) { 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); } private getIndexOf (line: number, column: number): number { return line * this.lines + column; } getLocAddressOf (line: number, column?: number): number | number[] { if(this.isVector) { if(column != null) { throw new Error(this.id + " is not a matrix!"); } column = line; line = 0; } else if (column == null) { // this is a whole line... const values: number[] = []; for(let col = 0; col < this.columns; col += 1) { const index = this.getIndexOf(line, col); values.push(this.addresses[index]); } return values; } const index = this.getIndexOf(line, column); return this.addresses[index]; } }