Initial element access compilation; Carefully approaching std array

This commit is contained in:
dcodeIO
2018-01-13 23:38:07 +01:00
parent dd596b015d
commit 2c009c67d3
21 changed files with 9914 additions and 88 deletions

19
std/assembly.d.ts vendored
View File

@ -202,6 +202,12 @@ declare class Array<T> {
constructor(capacity?: i32);
}
/** Class representing a C-like array of values of type `T` with limited capabilities. */
declare class CArray<T> {
[key: number]: T;
private constructor();
}
/** Class representing a sequence of characters. */
declare class String {
@ -281,13 +287,16 @@ interface Number {}
interface Object {}
interface RegExp {}
// Internal decorators (not yet implemented)
// Internal decorators
/** Annotates an element being part of the global namespace. */
/** Annotates an element as a program global. */
declare function global(target: Function): any;
/** Annotates a method being an operator overload. */
/** Annotates a method as an operator overload. */
declare function operator(token: string): any;
declare function struct(target: Function): any;
declare function size(size: usize): any;
/** Annotates a class as explicitly layed out and allocated. */
declare function explicit(target: Function): any;
/** Annoates a class field with an explicit offset. */
declare function offset(offset: usize): any;

View File

@ -1,44 +1,92 @@
export class Array<T> {
private ptr: usize;
readonly capacity: i32;
private __memory: usize;
private __capacity: i32;
length: i32;
constructor(capacity: i32 = 0) {
if (capacity < 0)
throw new RangeError("invalid array length");
this.capacity = this.length = capacity;
if (capacity > 0) {
this.ptr = Heap.allocate(<usize>capacity);
} else {
this.ptr = 0;
}
this.__capacity = this.length = capacity;
this.__memory = capacity > 0 ? Heap.allocate(<usize>capacity * sizeof<T>()) : 0;
}
@operator("[]")
private __get(index: i32): T {
assert(index > 0 && index < this.capacity);
throw new Error("not implemented");
if (<u32>index >= this.__capacity)
throw new RangeError("index out of range");
return load<T>(this.__memory + <usize>index * sizeof<T>());
}
@operator("[]=")
private __set(index: i32, value: T): void {
assert(index > 0 && index < this.capacity);
throw new Error("not implemented");
if (<u32>index >= this.__capacity)
throw new RangeError("index out of range");
store<T>(this.__memory + <usize>index * sizeof<T>(), value);
}
dispose(): void {
store<i64>(changetype<usize>(this), 0);
Heap.dispose(this.ptr);
this.ptr = 0;
Heap.dispose(changetype<usize>(this));
indexOf(searchElement: T, fromIndex: i32 = 0): i32 {
if (<u32>fromIndex >= this.__capacity)
throw new RangeError("fromIndex out of range");
for (var index: usize = <usize>fromIndex, length: usize = min<u32>(this.length, this.__capacity); index < length; ++index)
if (load<T>(this.__memory + index * sizeof<T>()) == searchElement)
return index;
return -1;
}
// TODO
private __grow(capacity: i32): void {
assert(capacity > this.__capacity);
var newMemory = Heap.allocate(<usize>(capacity * sizeof<T>()));
if (this.__memory)
Heap.copy(newMemory, this.__memory, this.__capacity * sizeof<T>());
Heap.dispose(this.__memory);
this.__memory = newMemory;
this.__capacity = capacity;
}
push(element: T): i32 {
if (<u32>this.length >= this.__capacity)
this.__grow(max(this.length + 1, this.__capacity * 2));
store<T>(this.__memory + <usize>this.length * sizeof<T>(), element);
return ++this.length;
}
pop(): T {
if (this.length < 1 || <u32>this.length > this.__capacity)
throw new RangeError("index out of range");
--this.length;
return load<T>(this.__memory + <usize>this.length * sizeof<T>());
}
shift(): T {
if (this.length < 1 || <u32>this.length > this.__capacity)
throw new RangeError("index out of range");
var element = load<T>(this.__memory);
Heap.copy(this.__memory, this.__memory + sizeof<T>(), (this.__capacity - 1) * sizeof<T>());
Heap.fill(this.__memory + (this.__capacity - 1) * sizeof<T>(), 0, sizeof<T>());
--this.length;
return element;
}
unshift(element: T): i32 {
var capacity = this.__capacity;
if (<u32>this.length >= capacity)
this.__grow(max(this.length + 1, capacity * 2));
// FIXME: needs memmove (Heap.copy is just memcpy). it's also inefficient because
// __grow copies and then unshift copies again.
// Heap.copy(this.__memory + sizeof<T>(), this.__memory, capacity * sizeof<T>());
if (capacity)
for (var index: usize = capacity; index > 0; --index)
store<T>(this.__memory + index * sizeof<T>(), load<T>(this.__memory + (index - 1) * sizeof<T>()));
store<T>(this.__memory, element);
return ++this.length;
}
}
@struct
@explicit
export class CArray<T> {
private constructor() {}