// types.bux — Type system definitions and factories module Types { // --------------------------------------------------------------------------- // TypeKind constants // --------------------------------------------------------------------------- const tkUnknown: int = 0; const tkVoid: int = 1; const tkBool: int = 2; const tkBool8: int = 3; const tkBool16: int = 4; const tkBool32: int = 5; const tkChar8: int = 6; const tkChar16: int = 7; const tkChar32: int = 8; const tkStr: int = 9; const tkInt8: int = 10; const tkInt16: int = 11; const tkInt32: int = 12; const tkInt64: int = 13; const tkInt: int = 14; const tkUInt8: int = 15; const tkUInt16: int = 16; const tkUInt32: int = 17; const tkUInt64: int = 18; const tkUInt: int = 19; const tkFloat32: int = 20; const tkFloat64: int = 21; const tkPointer: int = 22; const tkSlice: int = 23; const tkRange: int = 24; const tkTuple: int = 25; const tkNamed: int = 26; const tkTypeParam: int = 27; const tkFunc: int = 28; // --------------------------------------------------------------------------- // Type struct // --------------------------------------------------------------------------- struct Type { kind: int, name: String, // inner types stored as array of pointers (simplified) innerKind1: int, innerName1: String, innerKind2: int, innerName2: String, innerKind3: int, innerName3: String, innerCount: int, } // --------------------------------------------------------------------------- // Factories // --------------------------------------------------------------------------- func Type_MakeUnknown() -> Type { return Type { kind: tkUnknown, name: "", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeVoid() -> Type { return Type { kind: tkVoid, name: "void", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeBool() -> Type { return Type { kind: tkBool, name: "bool", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeInt() -> Type { return Type { kind: tkInt, name: "int", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeInt64() -> Type { return Type { kind: tkInt64, name: "int64", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeUInt() -> Type { return Type { kind: tkUInt, name: "uint", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeFloat64() -> Type { return Type { kind: tkFloat64, name: "float64", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeStr() -> Type { return Type { kind: tkStr, name: "String", innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakePointer(pointee: Type) -> Type { return Type { kind: tkPointer, name: "", innerCount: 1, innerKind1: pointee.kind, innerName1: pointee.name, innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeNamed(name: String) -> Type { return Type { kind: tkNamed, name: name, innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } func Type_MakeTypeParam(name: String) -> Type { return Type { kind: tkTypeParam, name: name, innerCount: 0, innerKind1: 0, innerName1: "", innerKind2: 0, innerName2: "", innerKind3: 0, innerName3: "" }; } // --------------------------------------------------------------------------- // Predicates // --------------------------------------------------------------------------- func Type_IsNumeric(t: Type) -> bool { let k: int = t.kind; if k == tkInt8 || k == tkInt16 || k == tkInt32 || k == tkInt64 || k == tkInt { return true; } if k == tkUInt8 || k == tkUInt16 || k == tkUInt32 || k == tkUInt64 || k == tkUInt { return true; } if k == tkFloat32 || k == tkFloat64 { return true; } if k == tkUnknown || k == tkNamed || k == tkTypeParam { return true; } return false; } func Type_IsInteger(t: Type) -> bool { let k: int = t.kind; if k == tkInt8 || k == tkInt16 || k == tkInt32 || k == tkInt64 || k == tkInt { return true; } if k == tkUInt8 || k == tkUInt16 || k == tkUInt32 || k == tkUInt64 || k == tkUInt { return true; } if k == tkUnknown || k == tkNamed || k == tkTypeParam { return true; } return false; } func Type_IsBool(t: Type) -> bool { let k: int = t.kind; return k == tkBool || k == tkBool8 || k == tkBool16 || k == tkBool32; } func Type_IsPointer(t: Type) -> bool { return t.kind == tkPointer; } func Type_IsSlice(t: Type) -> bool { return t.kind == tkSlice; } // --------------------------------------------------------------------------- // Comparison (structural, limited to kind + name for simplicity) // --------------------------------------------------------------------------- func Type_Eq(a: Type, b: Type) -> bool { if a.kind != b.kind { return false; } if a.kind == tkNamed || a.kind == tkTypeParam { return String_Eq(a.name, b.name); } return true; } // --------------------------------------------------------------------------- // toString // --------------------------------------------------------------------------- func Type_ToString(t: Type) -> String { if t.kind == tkVoid { return "void"; } if t.kind == tkBool { return "bool"; } if t.kind == tkStr { return "String"; } if t.kind == tkInt { return "int"; } if t.kind == tkInt64 { return "int64"; } if t.kind == tkUInt { return "uint"; } if t.kind == tkFloat64 { return "float64"; } if t.kind == tkNamed { return t.name; } if t.kind == tkTypeParam { return t.name; } if t.kind == tkPointer { return "*" + t.innerName1; } return "?"; } }