mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-26 07:22:21 +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
|
// infer from initializer if not annotated
|
||||||
} else if (declaration.initializer) { // infer type using void/NONE for literal inference
|
} else if (declaration.initializer) { // infer type using void/NONE for literal inference
|
||||||
initExpr = this.compileExpression( // reports
|
initExpr = this.compileExpressionRetainType( // reports
|
||||||
declaration.initializer,
|
declaration.initializer,
|
||||||
Type.void,
|
Type.void,
|
||||||
ConversionKind.NONE,
|
|
||||||
WrapMode.WRAP
|
WrapMode.WRAP
|
||||||
);
|
);
|
||||||
if (this.currentType == Type.void) {
|
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
|
} else if (declaration.initializer) { // infer type using void/NONE for proper literal inference
|
||||||
initExpr = this.compileExpression( // reports
|
initExpr = this.compileExpressionRetainType( // reports
|
||||||
declaration.initializer,
|
declaration.initializer,
|
||||||
Type.void,
|
Type.void,
|
||||||
ConversionKind.NONE,
|
|
||||||
WrapMode.NONE
|
WrapMode.NONE
|
||||||
);
|
);
|
||||||
if (this.currentType == Type.void) {
|
if (this.currentType == Type.void) {
|
||||||
@ -4577,6 +4575,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compile the value and do the assignment
|
// compile the value and do the assignment
|
||||||
|
assert(targetType != Type.void);
|
||||||
var valueExpr = this.compileExpression(valueExpression, targetType, ConversionKind.IMPLICIT, WrapMode.NONE);
|
var valueExpr = this.compileExpression(valueExpression, targetType, ConversionKind.IMPLICIT, WrapMode.NONE);
|
||||||
return this.compileAssignmentWithValue(
|
return this.compileAssignmentWithValue(
|
||||||
expression,
|
expression,
|
||||||
@ -4597,6 +4596,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
switch (target.kind) {
|
switch (target.kind) {
|
||||||
case ElementKind.LOCAL: {
|
case ElementKind.LOCAL: {
|
||||||
let type = (<Local>target).type;
|
let type = (<Local>target).type;
|
||||||
|
assert(type != Type.void);
|
||||||
this.currentType = tee ? type : Type.void;
|
this.currentType = tee ? type : Type.void;
|
||||||
if ((<Local>target).is(CommonFlags.CONST)) {
|
if ((<Local>target).is(CommonFlags.CONST)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -6304,11 +6304,25 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.module.createUnreachable();
|
return this.module.createUnreachable();
|
||||||
}
|
}
|
||||||
var classPrototype = <ClassPrototype>target;
|
var classPrototype = <ClassPrototype>target;
|
||||||
var classInstance = classPrototype.resolveUsingTypeArguments( // reports
|
var classInstance: Class | null = null;
|
||||||
expression.typeArguments,
|
var typeArguments = expression.typeArguments;
|
||||||
currentFunction.flow.contextualTypeArguments,
|
var classReference: Class | null;
|
||||||
expression
|
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();
|
if (!classInstance) return module.createUnreachable();
|
||||||
|
|
||||||
var expr: ExpressionRef;
|
var expr: ExpressionRef;
|
||||||
@ -7020,9 +7034,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
: contextualType.is(TypeFlags.FLOAT)
|
: contextualType.is(TypeFlags.FLOAT)
|
||||||
? Type.i64
|
? Type.i64
|
||||||
: contextualType,
|
: contextualType,
|
||||||
contextualType == Type.void
|
ConversionKind.NONE,
|
||||||
? ConversionKind.NONE
|
|
||||||
: ConversionKind.IMPLICIT,
|
|
||||||
WrapMode.NONE
|
WrapMode.NONE
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -7041,6 +7053,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
expression.range
|
expression.range
|
||||||
);
|
);
|
||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
|
} else {
|
||||||
|
expr = this.convertExpression(
|
||||||
|
expr,
|
||||||
|
this.currentType, this.currentType.intType,
|
||||||
|
ConversionKind.IMPLICIT, WrapMode.NONE,
|
||||||
|
expression.operand
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (this.currentType.kind) {
|
switch (this.currentType.kind) {
|
||||||
|
@ -348,6 +348,7 @@ export function tokenIsAlsoIdentifier(token: Token): bool {
|
|||||||
case Token.DECLARE:
|
case Token.DECLARE:
|
||||||
case Token.DELETE:
|
case Token.DELETE:
|
||||||
case Token.FROM:
|
case Token.FROM:
|
||||||
|
case Token.FOR:
|
||||||
case Token.GET:
|
case Token.GET:
|
||||||
case Token.IS:
|
case Token.IS:
|
||||||
case Token.KEYOF:
|
case Token.KEYOF:
|
||||||
|
24
src/types.ts
24
src/types.ts
@ -114,19 +114,21 @@ export class Type {
|
|||||||
this.nonNullableType = this;
|
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 {
|
get intType(): Type {
|
||||||
switch (this.kind) {
|
switch (this.kind) {
|
||||||
case TypeKind.I8:
|
case TypeKind.I8: return Type.i8;
|
||||||
case TypeKind.I16:
|
case TypeKind.I16: return Type.i16;
|
||||||
case TypeKind.I32:
|
case TypeKind.F32:
|
||||||
case TypeKind.I64:
|
case TypeKind.I32: return Type.i32;
|
||||||
case TypeKind.ISIZE:
|
case TypeKind.F64:
|
||||||
case TypeKind.U8:
|
case TypeKind.I64: return Type.i64;
|
||||||
case TypeKind.U16:
|
case TypeKind.ISIZE: return this.size == 64 ? Type.isize64 : Type.isize32;
|
||||||
case TypeKind.U32:
|
case TypeKind.U8: return Type.u8;
|
||||||
case TypeKind.U64:
|
case TypeKind.U16: return Type.u16;
|
||||||
case TypeKind.USIZE: return this;
|
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:
|
case TypeKind.BOOL:
|
||||||
default: return Type.i32;
|
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 Object {}
|
||||||
interface RegExp {}
|
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> {
|
declare class Set<T> {
|
||||||
readonly size: i32;
|
readonly size: i32;
|
||||||
has(value: T): bool;
|
has(value: T): bool;
|
||||||
@ -459,6 +467,12 @@ declare class Set<T> {
|
|||||||
clear(): void;
|
clear(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare class Symbol {
|
||||||
|
constructor(description?: string | null);
|
||||||
|
static for(key: string): Symbol;
|
||||||
|
static keyFor(sym: Symbol): string | null;
|
||||||
|
}
|
||||||
|
|
||||||
interface IMath<T> {
|
interface IMath<T> {
|
||||||
/** The base of natural logarithms, e, approximately 2.718. */
|
/** The base of natural logarithms, e, approximately 2.718. */
|
||||||
readonly E: T;
|
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/two (mut i32) (i32.const 0))
|
||||||
(global $std/pointer/add (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/sub (mut i32) (i32.const 0))
|
||||||
|
(global $std/pointer/nextOne (mut i32) (i32.const 0))
|
||||||
(memory $0 1)
|
(memory $0 1)
|
||||||
(data (i32.const 8) "\0e\00\00\00s\00t\00d\00/\00p\00o\00i\00n\00t\00e\00r\00.\00t\00s")
|
(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))
|
(export "_setargc" (func $~setargc))
|
||||||
@ -214,6 +215,24 @@
|
|||||||
(i32.const 8)
|
(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
|
(if
|
||||||
(i32.ne
|
(i32.ne
|
||||||
(call $std/pointer/Pointer<Entry>#get:offset
|
(call $std/pointer/Pointer<Entry>#get:offset
|
||||||
@ -225,7 +244,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 70)
|
(i32.const 71)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -242,7 +261,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 72)
|
(i32.const 73)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -271,7 +290,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 75)
|
(i32.const 76)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -290,7 +309,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 76)
|
(i32.const 77)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -309,7 +328,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 77)
|
(i32.const 78)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
|
@ -66,7 +66,8 @@ var sub = two - one;
|
|||||||
assert(sub.offset == 16);
|
assert(sub.offset == 16);
|
||||||
|
|
||||||
assert(one.offset == 8);
|
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(one.offset == 16);
|
||||||
|
|
||||||
assert(two.offset == 24);
|
assert(two.offset == 24);
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
(global $std/pointer/two (mut i32) (i32.const 0))
|
(global $std/pointer/two (mut i32) (i32.const 0))
|
||||||
(global $std/pointer/add (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/sub (mut i32) (i32.const 0))
|
||||||
|
(global $std/pointer/nextOne (mut i32) (i32.const 0))
|
||||||
(global $HEAP_BASE i32 (i32.const 40))
|
(global $HEAP_BASE i32 (i32.const 40))
|
||||||
(memory $0 1)
|
(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")
|
(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)
|
(unreachable)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(set_global $std/pointer/one
|
(set_global $std/pointer/nextOne
|
||||||
(block $std/pointer/Pointer<Entry>#inc|inlined.0 (result i32)
|
(block (result i32)
|
||||||
(set_local $0
|
(set_global $std/pointer/one
|
||||||
(get_global $std/pointer/one)
|
(block $std/pointer/Pointer<Entry>#inc|inlined.0 (result i32)
|
||||||
)
|
(set_local $0
|
||||||
(br $std/pointer/Pointer<Entry>#inc|inlined.0
|
(get_global $std/pointer/one)
|
||||||
(i32.add
|
)
|
||||||
(get_local $0)
|
(br $std/pointer/Pointer<Entry>#inc|inlined.0
|
||||||
(i32.const 8)
|
(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
|
(if
|
||||||
@ -280,7 +303,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 70)
|
(i32.const 71)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -299,7 +322,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 72)
|
(i32.const 73)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -344,7 +367,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 75)
|
(i32.const 76)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -365,7 +388,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 76)
|
(i32.const 77)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
@ -386,7 +409,7 @@
|
|||||||
(call $~lib/env/abort
|
(call $~lib/env/abort
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 77)
|
(i32.const 78)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
(unreachable)
|
(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