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';
import { StoreValue } from './value/store_value';
export class StoreObjectArray extends StoreObject {
constructor (type: ArrayType, private _lines:number, private _columns:number, private loc_addresses: number[], readOnly = false) {
super(type, -1, readOnly);
}
get lines () {
return this._lines;
}
get columns () {
return this._columns;
}
isCompatible (another: IStoreValue): boolean {
if(another instanceof ArrayStoreValue) {
const cols = another.columns == null ? 0 : another.columns;
if(this.lines === another.lines && this.columns === cols) {
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;
}
/**
* @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 invoke locAddress on StoreObjectArray");
}
protected get addresses (): number[] {
return this.loc_addresses;
}
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: 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) {
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.get());
}
protected getIndexOf (line: number, column: number): number {
return line * this.columns + 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];
}
}