mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Make type checking builtins also accept just a type argument
This commit is contained in:
parent
8ffc7d463d
commit
dcc0e284fb
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
152
src/builtins.ts
152
src/builtins.ts
@ -105,118 +105,46 @@ export function compileCall(
|
||||
|
||||
// types
|
||||
|
||||
case "isInteger": {
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
); // recoverable
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
let type = compiler.currentType;
|
||||
case "isInteger": { // isInteger<T!>() / isInteger<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
if (!type) return module.createUnreachable();
|
||||
return type.is(TypeFlags.INTEGER) && !type.is(TypeFlags.REFERENCE)
|
||||
? module.createI32(1)
|
||||
: module.createI32(0);
|
||||
}
|
||||
case "isFloat": {
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
); // recoverable
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
let type = compiler.currentType;
|
||||
case "isFloat": { // isFloat<T!>() / isFloat<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
if (!type) return module.createUnreachable();
|
||||
return type.is(TypeFlags.FLOAT)
|
||||
? module.createI32(1)
|
||||
: module.createI32(0);
|
||||
}
|
||||
case "isReference": {
|
||||
case "isReference": { // isReference<T!>() / isReference<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
); // recoverable
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
let type = compiler.currentType;
|
||||
if (!type) return module.createUnreachable();
|
||||
compiler.currentType = Type.bool;
|
||||
return type.is(TypeFlags.REFERENCE)
|
||||
? module.createI32(1)
|
||||
: module.createI32(0);
|
||||
}
|
||||
case "isString": {
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
); // recoverable
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
let type = compiler.currentType;
|
||||
case "isString": { // isString<T!>() / isString<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
if (!type) return module.createUnreachable();
|
||||
let classType = type.classReference;
|
||||
if (classType) {
|
||||
let stringInstance = compiler.program.stringInstance;
|
||||
if (!stringInstance) return module.createUnreachable();
|
||||
if (classType.isAssignableTo(stringInstance)) {
|
||||
return module.createI32(1);
|
||||
}
|
||||
if (stringInstance && classType.isAssignableTo(stringInstance)) return module.createI32(1);
|
||||
}
|
||||
return module.createI32(0);
|
||||
}
|
||||
case "isArray": {
|
||||
compiler.currentType = Type.bool;
|
||||
if (typeArguments) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Type_0_is_not_generic,
|
||||
reportNode.range, prototype.internalName
|
||||
); // recoverable
|
||||
}
|
||||
if (operands.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
let type = compiler.currentType;
|
||||
case "isArray": { // isArray<T!>() / isArray<T?>(value: T) -> bool
|
||||
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
|
||||
compiler.currentType = Type.bool;
|
||||
if (!type) return module.createUnreachable();
|
||||
let classType = type.classReference;
|
||||
return classType != null && classType.prototype.fnIndexedGet != null
|
||||
? module.createI32(1)
|
||||
@ -2546,6 +2474,54 @@ export function compileCall(
|
||||
return module.createUnreachable();
|
||||
}
|
||||
|
||||
function evaluateConstantType(
|
||||
compiler: Compiler,
|
||||
typeArguments: Type[] | null,
|
||||
operands: Expression[],
|
||||
reportNode: Node
|
||||
): Type | null {
|
||||
if (operands.length == 0) { // requires type argument
|
||||
if (!typeArguments || typeArguments.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments ? typeArguments.length.toString(10) : "0"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
return typeArguments[0];
|
||||
}
|
||||
if (operands.length == 1) { // optional type argument
|
||||
if (typeArguments) {
|
||||
if (typeArguments.length == 1) {
|
||||
compiler.compileExpression(operands[0], typeArguments[0], ConversionKind.IMPLICIT, false);
|
||||
} else {
|
||||
if (typeArguments.length) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments.length.toString(10)
|
||||
);
|
||||
return null;
|
||||
}
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
}
|
||||
} else {
|
||||
compiler.compileExpressionRetainType(operands[0], Type.i32, false);
|
||||
}
|
||||
return compiler.currentType;
|
||||
}
|
||||
if (typeArguments && typeArguments.length > 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments.length.toString(10)
|
||||
);
|
||||
}
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
function evaluateConstantOffset(compiler: Compiler, expression: Expression): i32 {
|
||||
var expr: ExpressionRef;
|
||||
var value: i32;
|
||||
|
10
std/assembly.d.ts
vendored
10
std/assembly.d.ts
vendored
@ -236,15 +236,15 @@ declare function isNaN<T = f32 | f64>(value: T): bool;
|
||||
/** Tests if a 32-bit or 64-bit float is finite, that is not `NaN` or +/-`Infinity`. */
|
||||
declare function isFinite<T = f32 | f64>(value: T): bool;
|
||||
/** Tests if the specified expression is of an integer type and not a reference. Compiles to a constant. */
|
||||
declare function isInteger(value: any): value is number;
|
||||
declare function isInteger<T>(value?: any): value is number;
|
||||
/** Tests if the specified expression is of a float type. Compiles to a constant. */
|
||||
declare function isFloat(value: any): value is number;
|
||||
declare function isFloat<T>(value?: any): value is number;
|
||||
/** Tests if the specified expression is of a reference type. Compiles to a constant. */
|
||||
declare function isReference(value: any): value is object | string;
|
||||
declare function isReference<T>(value?: any): value is object | string;
|
||||
/** Tests if the specified expression can be used ass a string. Compiles to a constant. */
|
||||
declare function isString(value: any): value is string | String;
|
||||
declare function isString<T>(value?: any): value is string | String;
|
||||
/** Tests if the specified expression can be used as an array. Compiles to a constant. */
|
||||
declare function isArray(value: any): value is Array<any>;
|
||||
declare function isArray<T>(value?: any): value is Array<any>;
|
||||
/** Traps if the specified value is not true-ish, otherwise returns the (non-nullable) value. */
|
||||
declare function assert<T>(isTrueish: T, message?: string): T & object; // any better way to model `: T != null`?
|
||||
/** Parses an integer string to a 64-bit float. */
|
||||
|
@ -1,12 +1,12 @@
|
||||
export declare function isInteger(value: void): bool;
|
||||
export declare function isInteger<T>(value?: T): bool;
|
||||
|
||||
export declare function isFloat(value: void): bool;
|
||||
export declare function isFloat<T>(value?: T): bool;
|
||||
|
||||
export declare function isReference(value: void): bool;
|
||||
export declare function isReference<T>(value?: T): bool;
|
||||
|
||||
export declare function isString(value: void): bool;
|
||||
export declare function isString<T>(value?: T): bool;
|
||||
|
||||
export declare function isArray(value: void): bool;
|
||||
export declare function isArray<T>(value?: T): bool;
|
||||
|
||||
export declare const NaN: f64; // | f32
|
||||
|
||||
|
@ -79,7 +79,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 34)
|
||||
(i32.const 43)
|
||||
(i32.const 19)
|
||||
)
|
||||
(unreachable)
|
||||
@ -106,7 +106,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 35)
|
||||
(i32.const 44)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -131,7 +131,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 36)
|
||||
(i32.const 45)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -176,7 +176,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 52)
|
||||
(i32.const 61)
|
||||
(i32.const 19)
|
||||
)
|
||||
(unreachable)
|
||||
@ -205,7 +205,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 53)
|
||||
(i32.const 62)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -230,7 +230,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 54)
|
||||
(i32.const 63)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -657,7 +657,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 244)
|
||||
(i32.const 253)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -674,7 +674,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 245)
|
||||
(i32.const 254)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -700,7 +700,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 246)
|
||||
(i32.const 255)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -726,7 +726,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 247)
|
||||
(i32.const 256)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -752,7 +752,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 248)
|
||||
(i32.const 257)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -778,7 +778,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 249)
|
||||
(i32.const 258)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -806,7 +806,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 250)
|
||||
(i32.const 259)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -834,7 +834,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 4)
|
||||
(i32.const 251)
|
||||
(i32.const 260)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
|
@ -1,12 +1,21 @@
|
||||
var b: bool;
|
||||
|
||||
// types
|
||||
// type checks
|
||||
|
||||
assert(isInteger<i32>());
|
||||
assert(!isInteger<f32>());
|
||||
assert(isFloat<f32>());
|
||||
assert(!isFloat<i32>());
|
||||
assert(isReference<string>());
|
||||
assert(!isReference<usize>());
|
||||
assert(isArray<i32[]>());
|
||||
assert(!isArray<usize>());
|
||||
|
||||
assert(isInteger(<i32>1));
|
||||
assert(!isInteger(<f32>1));
|
||||
assert(isFloat(<f32>1));
|
||||
assert(!isFloat(<i32>1));
|
||||
assert(isReference(changetype<String>(null)));
|
||||
assert(isReference(changetype<string>(null)));
|
||||
assert(!isReference(changetype<usize>(null)));
|
||||
assert(isString("1"));
|
||||
assert(!isString(1));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6404,7 +6404,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 34)
|
||||
(i32.const 43)
|
||||
(i32.const 19)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6431,7 +6431,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 35)
|
||||
(i32.const 44)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6456,7 +6456,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 36)
|
||||
(i32.const 45)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6501,7 +6501,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 52)
|
||||
(i32.const 61)
|
||||
(i32.const 19)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6530,7 +6530,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 53)
|
||||
(i32.const 62)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6555,7 +6555,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 54)
|
||||
(i32.const 63)
|
||||
(i32.const 20)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6982,7 +6982,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 244)
|
||||
(i32.const 253)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -6999,7 +6999,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 245)
|
||||
(i32.const 254)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -7025,7 +7025,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 246)
|
||||
(i32.const 255)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -7051,7 +7051,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 247)
|
||||
(i32.const 256)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -7077,7 +7077,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 248)
|
||||
(i32.const 257)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -7103,7 +7103,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 249)
|
||||
(i32.const 258)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -7131,7 +7131,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 250)
|
||||
(i32.const 259)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
@ -7159,7 +7159,7 @@
|
||||
(call $abort
|
||||
(i32.const 0)
|
||||
(i32.const 28)
|
||||
(i32.const 251)
|
||||
(i32.const 260)
|
||||
(i32.const 0)
|
||||
)
|
||||
(unreachable)
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user