mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Add initial std Symbol; Fix some type inference issues
This commit is contained in:
parent
1626e50b0f
commit
c74eed2bd8
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
2
dist/asc.js.map
vendored
2
dist/asc.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -520,10 +520,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// infer from initializer if not annotated
|
||||
} else if (declaration.initializer) { // infer type using void/NONE for literal inference
|
||||
initExpr = this.compileExpression( // reports
|
||||
initExpr = this.compileExpressionRetainType( // reports
|
||||
declaration.initializer,
|
||||
Type.void,
|
||||
ConversionKind.NONE,
|
||||
WrapMode.WRAP
|
||||
);
|
||||
if (this.currentType == Type.void) {
|
||||
@ -1964,10 +1963,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
);
|
||||
}
|
||||
} else if (declaration.initializer) { // infer type using void/NONE for proper literal inference
|
||||
initExpr = this.compileExpression( // reports
|
||||
initExpr = this.compileExpressionRetainType( // reports
|
||||
declaration.initializer,
|
||||
Type.void,
|
||||
ConversionKind.NONE,
|
||||
WrapMode.NONE
|
||||
);
|
||||
if (this.currentType == Type.void) {
|
||||
@ -4577,6 +4575,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
// compile the value and do the assignment
|
||||
assert(targetType != Type.void);
|
||||
var valueExpr = this.compileExpression(valueExpression, targetType, ConversionKind.IMPLICIT, WrapMode.NONE);
|
||||
return this.compileAssignmentWithValue(
|
||||
expression,
|
||||
@ -4597,6 +4596,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
switch (target.kind) {
|
||||
case ElementKind.LOCAL: {
|
||||
let type = (<Local>target).type;
|
||||
assert(type != Type.void);
|
||||
this.currentType = tee ? type : Type.void;
|
||||
if ((<Local>target).is(CommonFlags.CONST)) {
|
||||
this.error(
|
||||
@ -6304,11 +6304,25 @@ export class Compiler extends DiagnosticEmitter {
|
||||
return this.module.createUnreachable();
|
||||
}
|
||||
var classPrototype = <ClassPrototype>target;
|
||||
var classInstance = classPrototype.resolveUsingTypeArguments( // reports
|
||||
expression.typeArguments,
|
||||
currentFunction.flow.contextualTypeArguments,
|
||||
expression
|
||||
);
|
||||
var classInstance: Class | null = null;
|
||||
var typeArguments = expression.typeArguments;
|
||||
var classReference: Class | null;
|
||||
if (
|
||||
!typeArguments &&
|
||||
(classReference = contextualType.classReference) !== null &&
|
||||
classReference.is(CommonFlags.GENERIC)
|
||||
) {
|
||||
classInstance = classPrototype.resolve(
|
||||
classReference.typeArguments,
|
||||
currentFunction.flow.contextualTypeArguments
|
||||
);
|
||||
} else {
|
||||
classInstance = classPrototype.resolveUsingTypeArguments( // reports
|
||||
typeArguments,
|
||||
currentFunction.flow.contextualTypeArguments,
|
||||
expression
|
||||
);
|
||||
}
|
||||
if (!classInstance) return module.createUnreachable();
|
||||
|
||||
var expr: ExpressionRef;
|
||||
@ -7020,9 +7034,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
: contextualType.is(TypeFlags.FLOAT)
|
||||
? Type.i64
|
||||
: contextualType,
|
||||
contextualType == Type.void
|
||||
? ConversionKind.NONE
|
||||
: ConversionKind.IMPLICIT,
|
||||
ConversionKind.NONE,
|
||||
WrapMode.NONE
|
||||
);
|
||||
|
||||
@ -7041,6 +7053,13 @@ export class Compiler extends DiagnosticEmitter {
|
||||
expression.range
|
||||
);
|
||||
return module.createUnreachable();
|
||||
} else {
|
||||
expr = this.convertExpression(
|
||||
expr,
|
||||
this.currentType, this.currentType.intType,
|
||||
ConversionKind.IMPLICIT, WrapMode.NONE,
|
||||
expression.operand
|
||||
);
|
||||
}
|
||||
|
||||
switch (this.currentType.kind) {
|
||||
|
@ -348,6 +348,7 @@ export function tokenIsAlsoIdentifier(token: Token): bool {
|
||||
case Token.DECLARE:
|
||||
case Token.DELETE:
|
||||
case Token.FROM:
|
||||
case Token.FOR:
|
||||
case Token.GET:
|
||||
case Token.IS:
|
||||
case Token.KEYOF:
|
||||
|
24
src/types.ts
24
src/types.ts
@ -114,19 +114,21 @@ export class Type {
|
||||
this.nonNullableType = this;
|
||||
}
|
||||
|
||||
/** Returns the int type of this type. Defaults to `Type.i32` if this is not an int type. */
|
||||
/** Returns the closest int type representing this type. */
|
||||
get intType(): Type {
|
||||
switch (this.kind) {
|
||||
case TypeKind.I8:
|
||||
case TypeKind.I16:
|
||||
case TypeKind.I32:
|
||||
case TypeKind.I64:
|
||||
case TypeKind.ISIZE:
|
||||
case TypeKind.U8:
|
||||
case TypeKind.U16:
|
||||
case TypeKind.U32:
|
||||
case TypeKind.U64:
|
||||
case TypeKind.USIZE: return this;
|
||||
case TypeKind.I8: return Type.i8;
|
||||
case TypeKind.I16: return Type.i16;
|
||||
case TypeKind.F32:
|
||||
case TypeKind.I32: return Type.i32;
|
||||
case TypeKind.F64:
|
||||
case TypeKind.I64: return Type.i64;
|
||||
case TypeKind.ISIZE: return this.size == 64 ? Type.isize64 : Type.isize32;
|
||||
case TypeKind.U8: return Type.u8;
|
||||
case TypeKind.U16: return Type.u16;
|
||||
case TypeKind.U32: return Type.u32;
|
||||
case TypeKind.U64: return Type.u64;
|
||||
case TypeKind.USIZE: return this.size == 64 ? Type.usize64 : Type.usize32;
|
||||
case TypeKind.BOOL:
|
||||
default: return Type.i32;
|
||||
}
|
||||
|
14
std/assembly.d.ts
vendored
14
std/assembly.d.ts
vendored
@ -451,6 +451,14 @@ interface Number {}
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
|
||||
declare class Map<K,V> {
|
||||
readonly size: i32;
|
||||
has(key: K): bool;
|
||||
set(key: K, value: V): void;
|
||||
delete(key: K): bool;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
declare class Set<T> {
|
||||
readonly size: i32;
|
||||
has(value: T): bool;
|
||||
@ -459,6 +467,12 @@ declare class Set<T> {
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
declare class Symbol {
|
||||
constructor(description?: string | null);
|
||||
static for(key: string): Symbol;
|
||||
static keyFor(sym: Symbol): string | null;
|
||||
}
|
||||
|
||||
interface IMath<T> {
|
||||
/** The base of natural logarithms, e, approximately 2.718. */
|
||||
readonly E: T;
|
||||
|
27
std/assembly/symbol.ts
Normal file
27
std/assembly/symbol.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { Map } from "./map";
|
||||
|
||||
var nextId: usize = 1;
|
||||
var stringToId: Map<string, usize>;
|
||||
var idToString: Map<usize, string>;
|
||||
|
||||
export class Symbol {
|
||||
|
||||
static for(key: string): Symbol {
|
||||
if (!stringToId) { stringToId = new Map(); idToString = new Map(); }
|
||||
else if (stringToId.has(key)) return changetype<Symbol>(stringToId.get(key));
|
||||
var id = nextId++;
|
||||
stringToId.set(key, id);
|
||||
idToString.set(id, key);
|
||||
return changetype<Symbol>(id);
|
||||
}
|
||||
|
||||
static keyFor(sym: Symbol): string | null {
|
||||
return idToString !== null && idToString.has(changetype<usize>(sym))
|
||||
? idToString.get(changetype<usize>(sym))
|
||||
: null;
|
||||
}
|
||||
|
||||
constructor(description: string | null = null) {
|
||||
return changetype<Symbol>(nextId++);
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
(global $std/pointer/two (mut i32) (i32.const 0))
|
||||
(global $std/pointer/add (mut i32) (i32.const 0))
|
||||
(global $std/pointer/sub (mut i32) (i32.const 0))
|
||||
(global $std/pointer/nextOne (mut i32) (i32.const 0))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\0e\00\00\00s\00t\00d\00/\00p\00o\00i\00n\00t\00e\00r\00.\00t\00s")
|
||||
(export "_setargc" (func $~setargc))
|
||||
@ -214,6 +215,24 @@
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
(set_global $std/pointer/nextOne
|
||||
(get_global $std/pointer/one)
|
||||
)
|
||||
(if
|
||||
(i32.ne
|
||||
(get_global $std/pointer/nextOne)
|
||||
(get_global $std/pointer/one)
|
||||
)
|
||||
(block
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 70)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.ne
|
||||
(call $std/pointer/Pointer<Entry>#get:offset
|
||||
@ -225,7 +244,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 70)
|
||||
(i32.const 71)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -242,7 +261,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 72)
|
||||
(i32.const 73)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -271,7 +290,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 75)
|
||||
(i32.const 76)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -290,7 +309,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 76)
|
||||
(i32.const 77)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -309,7 +328,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 77)
|
||||
(i32.const 78)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
|
@ -66,7 +66,8 @@ var sub = two - one;
|
||||
assert(sub.offset == 16);
|
||||
|
||||
assert(one.offset == 8);
|
||||
++one; // FIXME: assigning to a var yields an 'auto to void' error
|
||||
var nextOne = ++one;
|
||||
assert(nextOne === one);
|
||||
assert(one.offset == 16);
|
||||
|
||||
assert(two.offset == 24);
|
||||
|
@ -10,6 +10,7 @@
|
||||
(global $std/pointer/two (mut i32) (i32.const 0))
|
||||
(global $std/pointer/add (mut i32) (i32.const 0))
|
||||
(global $std/pointer/sub (mut i32) (i32.const 0))
|
||||
(global $std/pointer/nextOne (mut i32) (i32.const 0))
|
||||
(global $HEAP_BASE i32 (i32.const 40))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\0e\00\00\00s\00t\00d\00/\00p\00o\00i\00n\00t\00e\00r\00.\00t\00s\00")
|
||||
@ -254,17 +255,39 @@
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(set_global $std/pointer/one
|
||||
(block $std/pointer/Pointer<Entry>#inc|inlined.0 (result i32)
|
||||
(set_local $0
|
||||
(get_global $std/pointer/one)
|
||||
)
|
||||
(br $std/pointer/Pointer<Entry>#inc|inlined.0
|
||||
(i32.add
|
||||
(get_local $0)
|
||||
(i32.const 8)
|
||||
(set_global $std/pointer/nextOne
|
||||
(block (result i32)
|
||||
(set_global $std/pointer/one
|
||||
(block $std/pointer/Pointer<Entry>#inc|inlined.0 (result i32)
|
||||
(set_local $0
|
||||
(get_global $std/pointer/one)
|
||||
)
|
||||
(br $std/pointer/Pointer<Entry>#inc|inlined.0
|
||||
(i32.add
|
||||
(get_local $0)
|
||||
(i32.const 8)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_global $std/pointer/one)
|
||||
)
|
||||
)
|
||||
(if
|
||||
(i32.eqz
|
||||
(i32.eq
|
||||
(get_global $std/pointer/nextOne)
|
||||
(get_global $std/pointer/one)
|
||||
)
|
||||
)
|
||||
(block
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 70)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
(if
|
||||
@ -280,7 +303,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 70)
|
||||
(i32.const 71)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -299,7 +322,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 72)
|
||||
(i32.const 73)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -344,7 +367,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 75)
|
||||
(i32.const 76)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -365,7 +388,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 76)
|
||||
(i32.const 77)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -386,7 +409,7 @@
|
||||
(call $~lib/env/abort
|
||||
(i32.const 0)
|
||||
(i32.const 8)
|
||||
(i32.const 77)
|
||||
(i32.const 78)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
|
1856
tests/compiler/std/symbol.optimized.wat
Normal file
1856
tests/compiler/std/symbol.optimized.wat
Normal file
File diff suppressed because it is too large
Load Diff
23
tests/compiler/std/symbol.ts
Normal file
23
tests/compiler/std/symbol.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import "allocator/arena";
|
||||
|
||||
var sym1 = new Symbol("123");
|
||||
var sym2 = new Symbol("123");
|
||||
|
||||
assert(sym1 !== sym2);
|
||||
|
||||
var sym3 = Symbol.for("123");
|
||||
var sym4 = Symbol.for("123");
|
||||
|
||||
assert(sym3 === sym4);
|
||||
|
||||
var key1 = Symbol.keyFor(sym1);
|
||||
var key2 = Symbol.keyFor(sym2);
|
||||
|
||||
assert(key1 === null);
|
||||
assert(key2 === null);
|
||||
|
||||
var key3 = Symbol.keyFor(sym3);
|
||||
var key4 = Symbol.keyFor(sym4);
|
||||
|
||||
assert(key3 == "123");
|
||||
assert(key3 == key4);
|
2225
tests/compiler/std/symbol.untouched.wat
Normal file
2225
tests/compiler/std/symbol.untouched.wat
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user