Skip to content

Commit c74eed2

Browse files
committed
Add initial std Symbol; Fix some type inference issues
1 parent 1626e50 commit c74eed2

File tree

15 files changed

+4256
-46
lines changed

15 files changed

+4256
-46
lines changed

dist/asc.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/asc.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compiler.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,9 @@ export class Compiler extends DiagnosticEmitter {
520520

521521
// infer from initializer if not annotated
522522
} else if (declaration.initializer) { // infer type using void/NONE for literal inference
523-
initExpr = this.compileExpression( // reports
523+
initExpr = this.compileExpressionRetainType( // reports
524524
declaration.initializer,
525525
Type.void,
526-
ConversionKind.NONE,
527526
WrapMode.WRAP
528527
);
529528
if (this.currentType == Type.void) {
@@ -1964,10 +1963,9 @@ export class Compiler extends DiagnosticEmitter {
19641963
);
19651964
}
19661965
} else if (declaration.initializer) { // infer type using void/NONE for proper literal inference
1967-
initExpr = this.compileExpression( // reports
1966+
initExpr = this.compileExpressionRetainType( // reports
19681967
declaration.initializer,
19691968
Type.void,
1970-
ConversionKind.NONE,
19711969
WrapMode.NONE
19721970
);
19731971
if (this.currentType == Type.void) {
@@ -4577,6 +4575,7 @@ export class Compiler extends DiagnosticEmitter {
45774575
}
45784576

45794577
// compile the value and do the assignment
4578+
assert(targetType != Type.void);
45804579
var valueExpr = this.compileExpression(valueExpression, targetType, ConversionKind.IMPLICIT, WrapMode.NONE);
45814580
return this.compileAssignmentWithValue(
45824581
expression,
@@ -4597,6 +4596,7 @@ export class Compiler extends DiagnosticEmitter {
45974596
switch (target.kind) {
45984597
case ElementKind.LOCAL: {
45994598
let type = (<Local>target).type;
4599+
assert(type != Type.void);
46004600
this.currentType = tee ? type : Type.void;
46014601
if ((<Local>target).is(CommonFlags.CONST)) {
46024602
this.error(
@@ -6304,11 +6304,25 @@ export class Compiler extends DiagnosticEmitter {
63046304
return this.module.createUnreachable();
63056305
}
63066306
var classPrototype = <ClassPrototype>target;
6307-
var classInstance = classPrototype.resolveUsingTypeArguments( // reports
6308-
expression.typeArguments,
6309-
currentFunction.flow.contextualTypeArguments,
6310-
expression
6311-
);
6307+
var classInstance: Class | null = null;
6308+
var typeArguments = expression.typeArguments;
6309+
var classReference: Class | null;
6310+
if (
6311+
!typeArguments &&
6312+
(classReference = contextualType.classReference) !== null &&
6313+
classReference.is(CommonFlags.GENERIC)
6314+
) {
6315+
classInstance = classPrototype.resolve(
6316+
classReference.typeArguments,
6317+
currentFunction.flow.contextualTypeArguments
6318+
);
6319+
} else {
6320+
classInstance = classPrototype.resolveUsingTypeArguments( // reports
6321+
typeArguments,
6322+
currentFunction.flow.contextualTypeArguments,
6323+
expression
6324+
);
6325+
}
63126326
if (!classInstance) return module.createUnreachable();
63136327

63146328
var expr: ExpressionRef;
@@ -7020,9 +7034,7 @@ export class Compiler extends DiagnosticEmitter {
70207034
: contextualType.is(TypeFlags.FLOAT)
70217035
? Type.i64
70227036
: contextualType,
7023-
contextualType == Type.void
7024-
? ConversionKind.NONE
7025-
: ConversionKind.IMPLICIT,
7037+
ConversionKind.NONE,
70267038
WrapMode.NONE
70277039
);
70287040

@@ -7041,6 +7053,13 @@ export class Compiler extends DiagnosticEmitter {
70417053
expression.range
70427054
);
70437055
return module.createUnreachable();
7056+
} else {
7057+
expr = this.convertExpression(
7058+
expr,
7059+
this.currentType, this.currentType.intType,
7060+
ConversionKind.IMPLICIT, WrapMode.NONE,
7061+
expression.operand
7062+
);
70447063
}
70457064

70467065
switch (this.currentType.kind) {

src/tokenizer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ export function tokenIsAlsoIdentifier(token: Token): bool {
348348
case Token.DECLARE:
349349
case Token.DELETE:
350350
case Token.FROM:
351+
case Token.FOR:
351352
case Token.GET:
352353
case Token.IS:
353354
case Token.KEYOF:

src/types.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,21 @@ export class Type {
114114
this.nonNullableType = this;
115115
}
116116

117-
/** Returns the int type of this type. Defaults to `Type.i32` if this is not an int type. */
117+
/** Returns the closest int type representing this type. */
118118
get intType(): Type {
119119
switch (this.kind) {
120-
case TypeKind.I8:
121-
case TypeKind.I16:
122-
case TypeKind.I32:
123-
case TypeKind.I64:
124-
case TypeKind.ISIZE:
125-
case TypeKind.U8:
126-
case TypeKind.U16:
127-
case TypeKind.U32:
128-
case TypeKind.U64:
129-
case TypeKind.USIZE: return this;
120+
case TypeKind.I8: return Type.i8;
121+
case TypeKind.I16: return Type.i16;
122+
case TypeKind.F32:
123+
case TypeKind.I32: return Type.i32;
124+
case TypeKind.F64:
125+
case TypeKind.I64: return Type.i64;
126+
case TypeKind.ISIZE: return this.size == 64 ? Type.isize64 : Type.isize32;
127+
case TypeKind.U8: return Type.u8;
128+
case TypeKind.U16: return Type.u16;
129+
case TypeKind.U32: return Type.u32;
130+
case TypeKind.U64: return Type.u64;
131+
case TypeKind.USIZE: return this.size == 64 ? Type.usize64 : Type.usize32;
130132
case TypeKind.BOOL:
131133
default: return Type.i32;
132134
}

std/assembly.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,14 @@ interface Number {}
451451
interface Object {}
452452
interface RegExp {}
453453

454+
declare class Map<K,V> {
455+
readonly size: i32;
456+
has(key: K): bool;
457+
set(key: K, value: V): void;
458+
delete(key: K): bool;
459+
clear(): void;
460+
}
461+
454462
declare class Set<T> {
455463
readonly size: i32;
456464
has(value: T): bool;
@@ -459,6 +467,12 @@ declare class Set<T> {
459467
clear(): void;
460468
}
461469

470+
declare class Symbol {
471+
constructor(description?: string | null);
472+
static for(key: string): Symbol;
473+
static keyFor(sym: Symbol): string | null;
474+
}
475+
462476
interface IMath<T> {
463477
/** The base of natural logarithms, e, approximately 2.718. */
464478
readonly E: T;

std/assembly/symbol.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Map } from "./map";
2+
3+
var nextId: usize = 1;
4+
var stringToId: Map<string, usize>;
5+
var idToString: Map<usize, string>;
6+
7+
export class Symbol {
8+
9+
static for(key: string): Symbol {
10+
if (!stringToId) { stringToId = new Map(); idToString = new Map(); }
11+
else if (stringToId.has(key)) return changetype<Symbol>(stringToId.get(key));
12+
var id = nextId++;
13+
stringToId.set(key, id);
14+
idToString.set(id, key);
15+
return changetype<Symbol>(id);
16+
}
17+
18+
static keyFor(sym: Symbol): string | null {
19+
return idToString !== null && idToString.has(changetype<usize>(sym))
20+
? idToString.get(changetype<usize>(sym))
21+
: null;
22+
}
23+
24+
constructor(description: string | null = null) {
25+
return changetype<Symbol>(nextId++);
26+
}
27+
}

tests/compiler/std/pointer.optimized.wat

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
(global $std/pointer/two (mut i32) (i32.const 0))
1111
(global $std/pointer/add (mut i32) (i32.const 0))
1212
(global $std/pointer/sub (mut i32) (i32.const 0))
13+
(global $std/pointer/nextOne (mut i32) (i32.const 0))
1314
(memory $0 1)
1415
(data (i32.const 8) "\0e\00\00\00s\00t\00d\00/\00p\00o\00i\00n\00t\00e\00r\00.\00t\00s")
1516
(export "_setargc" (func $~setargc))
@@ -214,6 +215,24 @@
214215
(i32.const 8)
215216
)
216217
)
218+
(set_global $std/pointer/nextOne
219+
(get_global $std/pointer/one)
220+
)
221+
(if
222+
(i32.ne
223+
(get_global $std/pointer/nextOne)
224+
(get_global $std/pointer/one)
225+
)
226+
(block
227+
(call $~lib/env/abort
228+
(i32.const 0)
229+
(i32.const 8)
230+
(i32.const 70)
231+
(i32.const 0)
232+
)
233+
(unreachable)
234+
)
235+
)
217236
(if
218237
(i32.ne
219238
(call $std/pointer/Pointer<Entry>#get:offset
@@ -225,7 +244,7 @@
225244
(call $~lib/env/abort
226245
(i32.const 0)
227246
(i32.const 8)
228-
(i32.const 70)
247+
(i32.const 71)
229248
(i32.const 0)
230249
)
231250
(unreachable)
@@ -242,7 +261,7 @@
242261
(call $~lib/env/abort
243262
(i32.const 0)
244263
(i32.const 8)
245-
(i32.const 72)
264+
(i32.const 73)
246265
(i32.const 0)
247266
)
248267
(unreachable)
@@ -271,7 +290,7 @@
271290
(call $~lib/env/abort
272291
(i32.const 0)
273292
(i32.const 8)
274-
(i32.const 75)
293+
(i32.const 76)
275294
(i32.const 0)
276295
)
277296
(unreachable)
@@ -290,7 +309,7 @@
290309
(call $~lib/env/abort
291310
(i32.const 0)
292311
(i32.const 8)
293-
(i32.const 76)
312+
(i32.const 77)
294313
(i32.const 0)
295314
)
296315
(unreachable)
@@ -309,7 +328,7 @@
309328
(call $~lib/env/abort
310329
(i32.const 0)
311330
(i32.const 8)
312-
(i32.const 77)
331+
(i32.const 78)
313332
(i32.const 0)
314333
)
315334
(unreachable)

0 commit comments

Comments
 (0)