feat: multi-instance closures, richer stdlib, and Rust-style diagnostics
Introduce fat function pointers (BuxFn {code, env}) so capturing closures
are heap-allocated per value in both bootstrap and selfhost. Expand
Array/Map/Set/String/Test/Result APIs, add proper tuple codegen and
error snippets with multi-char underlines, golden diagnostic tests, and
LSP diagnostics via buxc check.
This commit is contained in:
@@ -186,4 +186,94 @@ func Type_ToString(t: Type) -> String {
|
||||
if t.kind == tyFunc { return t.name; }
|
||||
return "?";
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Type_FromName — central type-name → kind mapping (used by sema, hir_lower)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func Type_FromName(name: String) -> int {
|
||||
if String_Eq(name, "void") { return tyVoid; }
|
||||
if String_Eq(name, "bool") { return tyBool; }
|
||||
if String_Eq(name, "bool8") { return tyBool8; }
|
||||
if String_Eq(name, "bool16") { return tyBool16; }
|
||||
if String_Eq(name, "bool32") { return tyBool32; }
|
||||
if String_Eq(name, "char8") { return tyChar8; }
|
||||
if String_Eq(name, "char16") { return tyChar16; }
|
||||
if String_Eq(name, "char32") { return tyChar32; }
|
||||
if String_Eq(name, "String") { return tyStr; }
|
||||
if String_Eq(name, "str") { return tyStr; }
|
||||
if String_Eq(name, "int8") { return tyInt8; }
|
||||
if String_Eq(name, "int16") { return tyInt16; }
|
||||
if String_Eq(name, "int32") { return tyInt32; }
|
||||
if String_Eq(name, "int64") { return tyInt64; }
|
||||
if String_Eq(name, "int") { return tyInt; }
|
||||
if String_Eq(name, "uint8") { return tyUInt8; }
|
||||
if String_Eq(name, "uint16") { return tyUInt16; }
|
||||
if String_Eq(name, "uint32") { return tyUInt32; }
|
||||
if String_Eq(name, "uint64") { return tyUInt64; }
|
||||
if String_Eq(name, "uint") { return tyUInt; }
|
||||
if String_Eq(name, "float32") { return tyFloat32; }
|
||||
if String_Eq(name, "float64") { return tyFloat64; }
|
||||
if String_Eq(name, "float") { return tyFloat64; }
|
||||
return tyNamed;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Type_ToCName — type kind → C type name (used by C backend)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func Type_ToCName(kind: int) -> String {
|
||||
if kind == tyVoid { return "void"; }
|
||||
if kind == tyBool || kind == tyBool8 || kind == tyBool16 || kind == tyBool32 { return "bool"; }
|
||||
if kind == tyChar8 { return "char"; }
|
||||
if kind == tyChar16 { return "uint16"; }
|
||||
if kind == tyChar32 { return "uint32"; }
|
||||
if kind == tyStr { return "String"; }
|
||||
if kind == tyInt8 { return "int8"; }
|
||||
if kind == tyInt16 { return "int16"; }
|
||||
if kind == tyInt32 { return "int32"; }
|
||||
if kind == tyInt64 { return "int64"; }
|
||||
if kind == tyInt { return "int"; }
|
||||
if kind == tyUInt8 { return "uint8"; }
|
||||
if kind == tyUInt16 { return "uint16"; }
|
||||
if kind == tyUInt32 { return "uint32"; }
|
||||
if kind == tyUInt64 { return "uint64"; }
|
||||
if kind == tyUInt { return "uint"; }
|
||||
if kind == tyFloat32 { return "float32"; }
|
||||
if kind == tyFloat64 { return "float64"; }
|
||||
if kind == tyPointer { return "void*"; }
|
||||
// Fat function pointer — concrete BuxFn_* name comes from typeName field
|
||||
if kind == tyFunc { return "BuxFn"; }
|
||||
return "";
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Signed / Unsigned / Float predicates
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func Type_IsSigned(kind: int) -> bool {
|
||||
return kind == tyInt8 || kind == tyInt16 || kind == tyInt32 || kind == tyInt64 || kind == tyInt;
|
||||
}
|
||||
|
||||
func Type_IsUnsigned(kind: int) -> bool {
|
||||
return kind == tyUInt8 || kind == tyUInt16 || kind == tyUInt32 || kind == tyUInt64 || kind == tyUInt;
|
||||
}
|
||||
|
||||
func Type_IsFloat(kind: int) -> bool {
|
||||
return kind == tyFloat32 || kind == tyFloat64;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Type_SizeOf — byte size of a primitive type (0 for non-primitive)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
func Type_SizeOf(kind: int) -> int {
|
||||
if kind == tyBool || kind == tyBool8 || kind == tyChar8 || kind == tyInt8 || kind == tyUInt8 { return 1; }
|
||||
if kind == tyBool16 || kind == tyChar16 || kind == tyInt16 || kind == tyUInt16 { return 2; }
|
||||
if kind == tyBool32 || kind == tyChar32 || kind == tyInt32 || kind == tyUInt32 || kind == tyFloat32 { return 4; }
|
||||
if kind == tyInt64 || kind == tyUInt64 || kind == tyFloat64 { return 8; }
|
||||
if kind == tyInt || kind == tyUInt { return 8; }
|
||||
if kind == tyPointer { return 8; }
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user