mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-20 18:26:40 +00:00
More stdlib setup
This commit is contained in:
78
src/types.ts
78
src/types.ts
@ -1,6 +1,7 @@
|
||||
import { Class } from "./program";
|
||||
import { Class, Function } from "./program";
|
||||
import { sb } from "./util/sb";
|
||||
|
||||
/** Indicates the kind of a type. */
|
||||
export const enum TypeKind {
|
||||
|
||||
// signed integers
|
||||
@ -22,18 +23,30 @@ export const enum TypeKind {
|
||||
F32,
|
||||
F64,
|
||||
|
||||
// other
|
||||
VOID
|
||||
// SYMBOL ?
|
||||
}
|
||||
|
||||
/** Represents a resolved type. */
|
||||
export class Type {
|
||||
|
||||
/** Type kind. */
|
||||
kind: TypeKind;
|
||||
/** Size in bits. */
|
||||
size: i32;
|
||||
/** Size in bytes. */
|
||||
byteSize: i32;
|
||||
/** Underlying class type, if a class type. */
|
||||
classType: Class | null;
|
||||
nullable: bool = false;
|
||||
nullableType: Type | null = null; // cached, of this type
|
||||
/** Underlying function type, if a function type. */
|
||||
functionType: Function | null;
|
||||
/** Whether nullable or not. */
|
||||
isNullable: bool = false;
|
||||
/** Respective nullable type, if nullable. */
|
||||
nullableType: Type | null = null;
|
||||
|
||||
/** Constructs a new resolved type. */
|
||||
constructor(kind: TypeKind, size: i32) {
|
||||
this.kind = kind;
|
||||
this.size = size;
|
||||
@ -41,31 +54,51 @@ export class Type {
|
||||
this.classType = null;
|
||||
}
|
||||
|
||||
/** Sign-extending 32-bit shift, if a small signed integer. */
|
||||
get smallIntegerShift(): i32 { return 32 - this.size; }
|
||||
/** Truncating 32-bit mask, if a small unsigned integer. */
|
||||
get smallIntegerMask(): i32 { return -1 >>> (32 - this.size); }
|
||||
|
||||
/** Tests if this type is of any integer kind. */
|
||||
get isAnyInteger(): bool { return this.kind >= TypeKind.I8 && this.kind <= TypeKind.BOOL; }
|
||||
/** Tests if this type is of any small integer kind. */
|
||||
get isSmallInteger(): bool { return this.size != 0 && this.size < 32; }
|
||||
/** Tests if this type is of any long integer kind. */
|
||||
get isLongInteger(): bool { return this.size == 64 && this.kind != TypeKind.F64; }
|
||||
/** Tests if this type is of any unsigned integer kind. */
|
||||
get isUnsignedInteger(): bool { return this.kind >= TypeKind.U8 && this.kind <= TypeKind.BOOL; }
|
||||
/** Tests if this type is of any signed integer kind. */
|
||||
get isSignedInteger(): bool { return this.kind >= TypeKind.I8 && this.kind <= TypeKind.ISIZE; }
|
||||
/** Tests if this type is of any size kind, i.e., `isize` or `usize`. */
|
||||
get isAnySize(): bool { return this.kind == TypeKind.ISIZE || this.kind == TypeKind.USIZE; }
|
||||
/** Tests if this type is of any float kind, i.e., `f32` or `f64`. */
|
||||
get isAnyFloat(): bool { return this.kind == TypeKind.F32 || this.kind == TypeKind.F64; }
|
||||
|
||||
/** Composes a class type from this type and a class. */
|
||||
asClass(classType: Class): Type {
|
||||
assert(this.kind == TypeKind.USIZE);
|
||||
const ret: Type = new Type(this.kind, this.size);
|
||||
ret.classType = classType;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Composes a function type from this type and a function. */
|
||||
asFunction(functionType: Function): Type {
|
||||
assert(this.kind == TypeKind.USIZE);
|
||||
const ret: Type = new Type(this.kind, this.size);
|
||||
ret.functionType = functionType;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Composes the respective nullable type of this type. */
|
||||
asNullable(): Type {
|
||||
if (this.kind != TypeKind.USIZE)
|
||||
throw new Error("unexpected non-usize nullable");
|
||||
if (!this.nullableType)
|
||||
(this.nullableType = new Type(this.kind, this.size)).nullable = true;
|
||||
assert(this.kind == TypeKind.USIZE);
|
||||
if (this.isNullable && !this.nullableType)
|
||||
(this.nullableType = new Type(this.kind, this.size)).isNullable = true;
|
||||
return <Type>this.nullableType;
|
||||
}
|
||||
|
||||
/** Converts this type to its TypeScript representation. */
|
||||
toString(kindOnly: bool = false): string {
|
||||
switch (this.kind) {
|
||||
case TypeKind.I8: return "i8";
|
||||
@ -77,35 +110,56 @@ export class Type {
|
||||
case TypeKind.U16: return "u16";
|
||||
case TypeKind.U32: return "u32";
|
||||
case TypeKind.U64: return "u64";
|
||||
case TypeKind.USIZE: return this.classType != null && !kindOnly ? this.classType.toString() : "usize";
|
||||
case TypeKind.USIZE:
|
||||
if (kindOnly) return "usize";
|
||||
return this.classType ? this.classType.toString()
|
||||
: this.functionType ? this.functionType.toTypeString()
|
||||
: "usize";
|
||||
case TypeKind.BOOL: return "bool";
|
||||
case TypeKind.F32: return "f32";
|
||||
case TypeKind.F64: return "f64";
|
||||
case TypeKind.VOID: return "void";
|
||||
default:
|
||||
throw new Error("unexpected type kind");
|
||||
default: assert(false); return "INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/** An 8-bit signed integer. */
|
||||
static readonly i8: Type = new Type(TypeKind.I8, 8);
|
||||
/** A 16-bit signed integer. */
|
||||
static readonly i16: Type = new Type(TypeKind.I16, 16);
|
||||
/** A 32-bit signed integer. */
|
||||
static readonly i32: Type = new Type(TypeKind.I32, 32);
|
||||
/** A 64-bit signed integer. */
|
||||
static readonly i64: Type = new Type(TypeKind.I64, 64);
|
||||
/** A 32-bit signed size. WASM32 only. */
|
||||
static readonly isize32: Type = new Type(TypeKind.I32, 32);
|
||||
/** A 64-bit signed size. WASM64 only. */
|
||||
static readonly isize64: Type = new Type(TypeKind.I64, 64);
|
||||
/** An 8-bit unsigned integer. */
|
||||
static readonly u8: Type = new Type(TypeKind.U8, 8);
|
||||
/** A 16-bit unsigned integer. */
|
||||
static readonly u16: Type = new Type(TypeKind.U16, 16);
|
||||
/** A 32-bit unsigned integer. */
|
||||
static readonly u32: Type = new Type(TypeKind.U32, 32);
|
||||
/** A 64-bit unsigned integer. */
|
||||
static readonly u64: Type = new Type(TypeKind.U64, 64);
|
||||
/** A 32-bit unsigned size. WASM32 only. */
|
||||
static readonly usize32: Type = new Type(TypeKind.U32, 32);
|
||||
/** A 64-bit unsigned size. WASM64 only. */
|
||||
static readonly usize64: Type = new Type(TypeKind.U64, 64);
|
||||
/** A 1-bit unsigned integer. */
|
||||
static readonly bool: Type = new Type(TypeKind.BOOL, 1);
|
||||
/** A 32-bit float. */
|
||||
static readonly f32: Type = new Type(TypeKind.F32, 32);
|
||||
/** A 64-bit float. */
|
||||
static readonly f64: Type = new Type(TypeKind.F64, 64);
|
||||
/** No return type. */
|
||||
static readonly void: Type = new Type(TypeKind.VOID, 0);
|
||||
static readonly infer: Type = Type.void;
|
||||
/** Special type used in type inference. Alias of {@link Type.void}. */
|
||||
static readonly auto: Type = Type.void;
|
||||
}
|
||||
|
||||
/** Converts an array of types to its combined string representation. Usually type arguments. */
|
||||
export function typesToString(types: Type[], prefix: string = "<", postfix: string = ">"): string {
|
||||
const k: i32 = types.length;
|
||||
if (!k)
|
||||
@ -113,5 +167,5 @@ export function typesToString(types: Type[], prefix: string = "<", postfix: stri
|
||||
sb.length = 0;
|
||||
for (let i: i32 = 0; i < k; ++i)
|
||||
sb[i] = types[i].toString();
|
||||
return prefix + sb.join(",") + postfix;
|
||||
return prefix + sb.join(", ") + postfix;
|
||||
}
|
||||
|
Reference in New Issue
Block a user