Skip to content

Commit a114d59

Browse files
committed
parse but ignore index signatures, unify typedarray
1 parent 5965c54 commit a114d59

19 files changed

+500
-297
lines changed

src/ast.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export enum NodeKind {
8787
FIELDDECLARATION,
8888
FUNCTIONDECLARATION,
8989
IMPORTDECLARATION,
90+
INDEXDECLARATION,
9091
INTERFACEDECLARATION,
9192
METHODDECLARATION,
9293
NAMESPACEDECLARATION,
@@ -873,6 +874,18 @@ export abstract class Node {
873874
return stmt;
874875
}
875876

877+
static createIndexDeclaration(
878+
keyType: TypeNode,
879+
valueType: CommonTypeNode,
880+
range: Range
881+
): IndexDeclaration {
882+
var elem = new IndexDeclaration();
883+
elem.range = range;
884+
elem.keyType = keyType; keyType.parent = elem;
885+
elem.valueType = valueType; valueType.parent = elem;
886+
return elem;
887+
}
888+
876889
static createMethodDeclaration(
877890
name: IdentifierExpression,
878891
typeParameters: TypeParameterNode[] | null,
@@ -1626,6 +1639,16 @@ export abstract class DeclarationStatement extends Statement {
16261639
}
16271640
}
16281641

1642+
/** Represents an index declaration. */
1643+
export class IndexDeclaration extends DeclarationStatement {
1644+
kind = NodeKind.INDEXDECLARATION;
1645+
1646+
/** Key type. */
1647+
keyType: TypeNode;
1648+
/** Value type. */
1649+
valueType: CommonTypeNode;
1650+
}
1651+
16291652
/** Base class of all variable-like declaration statements. */
16301653
export abstract class VariableLikeDeclarationStatement extends DeclarationStatement {
16311654

src/extra/ast.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import {
6868
FieldDeclaration,
6969
FunctionDeclaration,
7070
ImportDeclaration,
71+
IndexDeclaration,
7172
InterfaceDeclaration,
7273
MethodDeclaration,
7374
NamespaceDeclaration,
@@ -295,6 +296,10 @@ export class ASTBuilder {
295296
this.visitImportDeclaration(<ImportDeclaration>node);
296297
break;
297298
}
299+
case NodeKind.INDEXDECLARATION: {
300+
this.visitIndexDeclaration(<IndexDeclaration>node);
301+
break;
302+
}
298303
case NodeKind.INTERFACEDECLARATION: {
299304
this.visitInterfaceDeclaration(<InterfaceDeclaration>node);
300305
break;
@@ -1181,6 +1186,14 @@ export class ASTBuilder {
11811186
this.visitStringLiteralExpression(node.path);
11821187
}
11831188

1189+
visitIndexDeclaration(node: IndexDeclaration): void {
1190+
var sb = this.sb;
1191+
sb.push("[key: ");
1192+
this.visitTypeNode(node.keyType);
1193+
sb.push("]: ");
1194+
this.visitTypeNode(node.valueType);
1195+
}
1196+
11841197
visitInterfaceDeclaration(node: InterfaceDeclaration): void {
11851198
var decorators = node.decorators;
11861199
if (decorators) {

src/parser.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1737,7 +1737,7 @@ export class Parser extends DiagnosticEmitter {
17371737
}
17381738
} else if (tn.skip(Token.SET)) {
17391739
if (tn.peek(true, IdentifierHandling.PREFER) == Token.IDENTIFIER && !tn.nextTokenOnNewLine) {
1740-
flags |= CommonFlags.SET | CommonFlags.SET;
1740+
flags |= CommonFlags.SET;
17411741
isSetter = true;
17421742
setStart = tn.tokenPos;
17431743
setEnd = tn.pos;
@@ -1779,6 +1779,66 @@ export class Parser extends DiagnosticEmitter {
17791779
name = Node.createConstructorExpression(tn.range());
17801780
} else {
17811781
// TODO: handle symbols, i.e. '[' 'Symbol' '.' Identifier ']'
1782+
if (tn.skip(Token.OPENBRACKET)) {
1783+
// TODO: reject decorators and keywords
1784+
let indexStart = tn.tokenPos;
1785+
if (tn.skipIdentifier()) {
1786+
let id = tn.readIdentifier();
1787+
if (id == "key") {
1788+
if (tn.skip(Token.COLON)) {
1789+
let keyType = this.parseType(tn);
1790+
if (!keyType) return null;
1791+
if (keyType.kind != NodeKind.TYPE) {
1792+
this.error(
1793+
DiagnosticCode.Type_expected,
1794+
tn.range()
1795+
);
1796+
return null;
1797+
}
1798+
if (tn.skip(Token.CLOSEBRACKET)) {
1799+
if (tn.skip(Token.COLON)) {
1800+
let valueType = this.parseType(tn);
1801+
if (!valueType) return null;
1802+
let ret = Node.createIndexDeclaration(<TypeNode>keyType, valueType, tn.range(indexStart, tn.pos));
1803+
tn.skip(Token.SEMICOLON);
1804+
return ret;
1805+
} else {
1806+
this.error(
1807+
DiagnosticCode._0_expected,
1808+
tn.range(), ":"
1809+
);
1810+
return null;
1811+
}
1812+
} else {
1813+
this.error(
1814+
DiagnosticCode._0_expected,
1815+
tn.range(), "]"
1816+
);
1817+
return null;
1818+
}
1819+
} else {
1820+
this.error(
1821+
DiagnosticCode._0_expected,
1822+
tn.range(), ":"
1823+
);
1824+
return null;
1825+
}
1826+
} else {
1827+
this.error(
1828+
DiagnosticCode._0_expected,
1829+
tn.range(), "key"
1830+
);
1831+
return null;
1832+
}
1833+
} else {
1834+
this.error(
1835+
DiagnosticCode.Identifier_expected,
1836+
tn.range()
1837+
);
1838+
return null;
1839+
}
1840+
}
1841+
17821842
if (!tn.skipIdentifier()) {
17831843
this.error(
17841844
DiagnosticCode.Identifier_expected,

src/program.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,7 @@ export class Program extends DiagnosticEmitter {
965965
}
966966
break;
967967
}
968+
case NodeKind.INDEXDECLARATION: break; // not supported, skipped for now
968969
default: {
969970
assert(false); // should have been reported while parsing
970971
return;

std/assembly/array.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
} from "./builtins";
3333

3434
export class Array<T> {
35+
[key: number]: T; // compatibility only
3536

3637
/* @internal */ buffer_: ArrayBuffer;
3738
/* @internal */ length_: i32;

std/assembly/internal/typedarray.ts

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import {
88

99
import {
1010
insertionSort,
11-
weakHeapSort,
12-
defaultComparator
11+
weakHeapSort
1312
} from "./array";
1413

1514
/** Typed array base class. Not a global object. */
1615
export abstract class TypedArray<T> {
16+
[key: number]: T; // compatibility only
1717

1818
readonly buffer: ArrayBuffer;
1919
readonly byteOffset: i32;
@@ -58,64 +58,73 @@ export abstract class TypedArray<T> {
5858
}
5959

6060
// copyWithin(target: i32, start: i32, end: i32 = this.length): this
61+
}
6162

62-
fill(value: NATIVE<T>, start: i32 = 0, end: i32 = i32.MAX_VALUE): this /* ! */ {
63-
var buffer = this.buffer;
64-
var byteOffset = this.byteOffset;
65-
var len = this.length;
66-
start = start < 0 ? max(len + start, 0) : min(start, len);
67-
end = end < 0 ? max(len + end, 0) : min(end, len);
68-
if (sizeof<T>() == 1) {
69-
if (start < end) {
70-
memory.fill(
71-
changetype<usize>(buffer) + start + byteOffset + AB_HEADER_SIZE,
72-
<u8>value,
73-
<usize>(end - start)
74-
);
75-
}
76-
} else {
77-
for (; start < end; ++start) {
78-
STORE_OFFSET<T,NATIVE<T>>(buffer, start, value, byteOffset);
79-
}
63+
@inline
64+
export function FILL<TArray extends TypedArray<T>, T>(
65+
array: TArray,
66+
value: NATIVE<T>,
67+
start: i32,
68+
end: i32
69+
): TArray {
70+
var buffer = array.buffer;
71+
var byteOffset = array.byteOffset;
72+
var len = array.length;
73+
start = start < 0 ? max(len + start, 0) : min(start, len);
74+
end = end < 0 ? max(len + end, 0) : min(end, len);
75+
if (sizeof<T>() == 1) {
76+
if (start < end) {
77+
memory.fill(
78+
changetype<usize>(buffer) + start + byteOffset + AB_HEADER_SIZE,
79+
<u8>value,
80+
<usize>(end - start)
81+
);
82+
}
83+
} else {
84+
for (; start < end; ++start) {
85+
STORE_OFFSET<T,NATIVE<T>>(buffer, start, value, byteOffset);
8086
}
81-
return this;
8287
}
88+
return array;
89+
}
8390

84-
sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): this /* ! */ {
85-
var byteOffset = this.byteOffset;
86-
var length = this.length;
87-
if (length <= 1) return this;
88-
var buffer = this.buffer;
89-
if (length == 2) {
90-
let a = LOAD_OFFSET<T>(buffer, 1, byteOffset);
91-
let b = LOAD_OFFSET<T>(buffer, 0, byteOffset);
92-
if (comparator(a, b) < 0) {
93-
STORE_OFFSET<T>(buffer, 1, b, byteOffset);
94-
STORE_OFFSET<T>(buffer, 0, a, byteOffset);
95-
}
96-
return this;
91+
@inline
92+
export function SORT<TArray extends TypedArray<T>, T>(
93+
array: TArray,
94+
comparator: (a: T, b: T) => i32
95+
): TArray {
96+
var byteOffset = array.byteOffset;
97+
var length = array.length;
98+
if (length <= 1) return array;
99+
var buffer = array.buffer;
100+
if (length == 2) {
101+
let a = LOAD_OFFSET<T>(buffer, 1, byteOffset);
102+
let b = LOAD_OFFSET<T>(buffer, 0, byteOffset);
103+
if (comparator(a, b) < 0) {
104+
STORE_OFFSET<T>(buffer, 1, b, byteOffset);
105+
STORE_OFFSET<T>(buffer, 0, a, byteOffset);
97106
}
98-
99-
if (isReference<T>()) {
100-
// TODO replace this to faster stable sort (TimSort) when it implemented
107+
return array;
108+
}
109+
if (isReference<T>()) {
110+
// TODO replace this to faster stable sort (TimSort) when it implemented
111+
insertionSort<T>(buffer, byteOffset, length, comparator);
112+
return array;
113+
} else {
114+
if (length < 256) {
101115
insertionSort<T>(buffer, byteOffset, length, comparator);
102-
return this;
103116
} else {
104-
if (length < 256) {
105-
insertionSort<T>(buffer, byteOffset, length, comparator);
106-
} else {
107-
weakHeapSort<T>(buffer, byteOffset, length, comparator);
108-
}
109-
return this;
117+
weakHeapSort<T>(buffer, byteOffset, length, comparator);
110118
}
119+
return array;
111120
}
112121
}
113122

114123
@inline
115-
export function SUBARRAY<TArray, T>(
124+
export function SUBARRAY<TArray extends TypedArray<T>, T>(
116125
array: TArray,
117-
begin: i32 = 0,
118-
end: i32 = i32.MAX_VALUE
126+
begin: i32,
127+
end: i32
119128
): TArray {
120129
var length = <i32>array.length;
121130
if (begin < 0) begin = max(length + begin, 0);
@@ -130,7 +139,7 @@ export function SUBARRAY<TArray, T>(
130139
}
131140

132141
@inline
133-
export function REDUCE<TArray, T, TRet>(
142+
export function REDUCE<TArray extends TypedArray<T>, T, TRet>(
134143
array: TArray,
135144
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
136145
initialValue: TRet
@@ -140,7 +149,7 @@ export function REDUCE<TArray, T, TRet>(
140149
while (index != length) {
141150
initialValue = callbackfn(
142151
initialValue,
143-
unchecked(array[index]), // tslint:disable-line
152+
unchecked(array[index]),
144153
index,
145154
array,
146155
);
@@ -150,7 +159,7 @@ export function REDUCE<TArray, T, TRet>(
150159
}
151160

152161
@inline
153-
export function REDUCE_RIGHT<TArray, T, TRet>(
162+
export function REDUCE_RIGHT<TArray extends TypedArray<T>, T, TRet>(
154163
array: TArray,
155164
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
156165
initialValue: TRet
@@ -160,7 +169,7 @@ export function REDUCE_RIGHT<TArray, T, TRet>(
160169
while (index != length) {
161170
initialValue = callbackfn(
162171
initialValue,
163-
unchecked(array[index]), // tslint:disable-line
172+
unchecked(array[index]),
164173
index,
165174
array,
166175
);

0 commit comments

Comments
 (0)