Filler implementation for std Set

This commit is contained in:
dcodeIO 2018-01-15 00:08:06 +01:00
parent 49d29fc9f2
commit f2ba4b4a76
13 changed files with 7637 additions and 3 deletions

View File

@ -3027,6 +3027,15 @@ export class Compiler extends DiagnosticEmitter {
} }
break; break;
case Token.TYPEOF:
// it might make sense to implement typeof in a way that a generic function can detect whether
// its type argument is a class type or string. that could then be used, for example, to
// generate hash codes for sets and maps, depending on the kind of type parameter we have.
// ideally the comparison would not involve actual string comparison and limit available
// operations to hard-coded string literals.
this.error(DiagnosticCode.Operation_not_supported, expression.range);
throw new Error("not implemented");
default: default:
this.error(DiagnosticCode.Operation_not_supported, expression.range); this.error(DiagnosticCode.Operation_not_supported, expression.range);
throw new Error("unary operator expected"); throw new Error("unary operator expected");

View File

@ -309,6 +309,7 @@ export namespace Token {
case Token.AS: case Token.AS:
case Token.CONSTRUCTOR: case Token.CONSTRUCTOR:
case Token.DECLARE: case Token.DECLARE:
case Token.DELETE:
case Token.FROM: case Token.FROM:
case Token.GET: case Token.GET:
case Token.IS: case Token.IS:

8
std/assembly.d.ts vendored
View File

@ -271,6 +271,14 @@ interface Number {}
interface Object {} interface Object {}
interface RegExp {} interface RegExp {}
declare class Set<T> {
readonly size: i32;
has(value: T): bool;
add(value: T): void;
delete(value: T): bool;
clear(): void;
}
// Internal decorators // Internal decorators
/** Annotates an element as a program global. */ /** Annotates an element as a program global. */

View File

@ -214,7 +214,7 @@ export function set_memory(dest: usize, c: u8, n: usize): void {
// based on musl's implementation of memset // based on musl's implementation of memset
// becomes obsolete once https://github.com/WebAssembly/bulk-memory-operations lands // becomes obsolete once https://github.com/WebAssembly/bulk-memory-operations lands
// fill head and tail wwith minimal branching // fill head and tail with minimal branching
if (!n) if (!n)
return; return;
store<u8>(dest, c); store<u8>(dest, c);

View File

@ -1,3 +1,60 @@
// const prime1: u32 = 73;
// const prime2: u32 = 5009;
export class Set<T> { export class Set<T> {
// TODO
private __memory: usize;
private __capacity: u32;
private __size: u32;
constructor() {
this.__memory = 0;
this.__capacity = this.__size = 0;
}
get size(): i32 {
return this.__size;
}
// FIXME: not a proper set implementation, just a filler
has(value: T): bool {
for (var index: usize = 0, limit: usize = this.__size; index < limit; ++index)
if (load<T>(this.__memory + index * sizeof<T>()) == value)
return true;
return false;
}
add(value: T): Set<T> {
if (this.__size >= this.__capacity) {
var newCapacity = max(this.__capacity << 1, 8);
var newMemory = allocate_memory(<usize>newCapacity * sizeof<T>());
if (this.__memory) {
move_memory(newMemory, this.__memory, <usize>this.__capacity * sizeof<T>());
free_memory(this.__memory);
}
this.__capacity = newCapacity;
this.__memory = newMemory;
}
store<T>(this.__memory + <usize>this.__size * sizeof<T>(), value);
++this.__size;
return this;
}
delete(value: T): bool {
for (var index: usize = 0, limit: usize = this.__size; index < limit; ++index)
if (load<T>(this.__memory + index * sizeof<T>()) == value) {
if (index + 1 < this.__size)
move_memory(this.__memory + index * sizeof<T>(), this.__memory + (index + 1) * sizeof<T>(), this.__size - index - 1);
--this.__size;
return true;
}
return false;
}
clear(): void {
this.__size = 0;
}
// TODO: think about iterators
} }

4
std/portable.d.ts vendored
View File

@ -214,14 +214,16 @@ declare class Symbol {
declare class Set<T> { declare class Set<T> {
constructor(entries?: T[]); constructor(entries?: T[]);
add(value: T): void;
has(value: T): bool; has(value: T): bool;
add(value: T): void;
delete(value: T): bool;
clear(): void; clear(): void;
[Symbol.iterator](): Iterator<T>; [Symbol.iterator](): Iterator<T>;
} }
declare class Map<K,V> { declare class Map<K,V> {
constructor(entries?: [K, V][]); constructor(entries?: [K, V][]);
readonly size: i32;
set(key: K, value: V): void; set(key: K, value: V): void;
has(key: K): bool; has(key: K): bool;
get(key: K): V | null; get(key: K): V | null;

View File

@ -4086,6 +4086,7 @@
CLASS_PROTOTYPE: RegExp CLASS_PROTOTYPE: RegExp
CLASS_PROTOTYPE: std:set/Set CLASS_PROTOTYPE: std:set/Set
CLASS_PROTOTYPE: Set CLASS_PROTOTYPE: Set
PROPERTY: std:set/Set#size
GLOBAL: std:string/EMPTY GLOBAL: std:string/EMPTY
CLASS_PROTOTYPE: std:string/String CLASS_PROTOTYPE: std:string/String
CLASS_PROTOTYPE: String CLASS_PROTOTYPE: String

View File

@ -279,6 +279,7 @@
CLASS_PROTOTYPE: RegExp CLASS_PROTOTYPE: RegExp
CLASS_PROTOTYPE: std:set/Set CLASS_PROTOTYPE: std:set/Set
CLASS_PROTOTYPE: Set CLASS_PROTOTYPE: Set
PROPERTY: std:set/Set#size
GLOBAL: std:string/EMPTY GLOBAL: std:string/EMPTY
CLASS_PROTOTYPE: std:string/String CLASS_PROTOTYPE: std:string/String
CLASS_PROTOTYPE: String CLASS_PROTOTYPE: String

View File

@ -2870,6 +2870,7 @@
CLASS_PROTOTYPE: RegExp CLASS_PROTOTYPE: RegExp
CLASS_PROTOTYPE: std:set/Set CLASS_PROTOTYPE: std:set/Set
CLASS_PROTOTYPE: Set CLASS_PROTOTYPE: Set
PROPERTY: std:set/Set#size
GLOBAL: std:string/EMPTY GLOBAL: std:string/EMPTY
CLASS_PROTOTYPE: std:string/String CLASS_PROTOTYPE: std:string/String
CLASS_PROTOTYPE: String CLASS_PROTOTYPE: String

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

28
tests/compiler/std/set.ts Normal file
View File

@ -0,0 +1,28 @@
// note that this doesn't test a real set implementation yet, see std/assembly/set.ts
var set = changetype<Set<i32>>(allocate_memory(sizeof<usize>() + 2 * sizeof<i32>()));
assert(set.size == 0);
set.add(1);
set.add(0);
set.add(2);
assert(set.size == 3);
assert(set.has(1));
assert(set.has(0));
assert(set.has(2));
assert(!set.has(3));
set.delete(0);
assert(set.size == 2);
assert(set.has(1));
assert(!set.has(0));
assert(set.has(2));
set.clear();
assert(set.size == 0);
assert(!set.has(1));

2790
tests/compiler/std/set.wast Normal file

File diff suppressed because it is too large Load Diff