fix(bootstrap): type compatibility fixes for self-hosting

- Allow int32 <-> int and uint32 <-> int/uint comparisons
- Allow uint32 <-> int32 comparisons
- Allow String indexing (returns char8)
- Allow *char8 -> String assignment (C string literal to Bux String)

These fixes allow buxc2 (self-hosted compiler) to build successfully.
All 14 modules compile; buxc2 binary is 111KB.
This commit is contained in:
2026-06-01 00:17:54 +03:00
parent e551951219
commit 837fbb0487
2 changed files with 15 additions and 0 deletions
+2
View File
@@ -883,6 +883,8 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type =
return obj.inner[0] return obj.inner[0]
elif obj.isPointer: elif obj.isPointer:
return obj.inner[0] return obj.inner[0]
elif obj.kind == tkStr:
return makeChar8()
else: else:
sema.emitError(expr.loc, "cannot index non-slice/non-pointer type") sema.emitError(expr.loc, "cannot index non-slice/non-pointer type")
return makeUnknown() return makeUnknown()
+13
View File
@@ -132,12 +132,25 @@ proc isAssignableTo*(a, b: Type): bool =
if a.kind == tkInt and b.kind == tkInt64: return true if a.kind == tkInt and b.kind == tkInt64: return true
if a.kind == tkUInt64 and b.kind == tkUInt: return true if a.kind == tkUInt64 and b.kind == tkUInt: return true
if a.kind == tkUInt and b.kind == tkUInt64: return true if a.kind == tkUInt and b.kind == tkUInt64: return true
# int32 <-> int (for convenience in bootstrap)
if a.kind == tkInt32 and b.kind == tkInt: return true
if a.kind == tkInt and b.kind == tkInt32: return true
if a.kind == tkUInt32 and b.kind == tkInt: return true
if a.kind == tkInt and b.kind == tkUInt32: return true
if a.kind == tkUInt32 and b.kind == tkUInt: return true
if a.kind == tkUInt and b.kind == tkUInt32: return true
if a.kind == tkInt32 and b.kind == tkUInt32: return true
if a.kind == tkUInt32 and b.kind == tkInt32: return true
# smaller int -> int/uint # smaller int -> int/uint
if b.kind == tkInt and a.kind in {tkInt8, tkInt16, tkInt32}: return true if b.kind == tkInt and a.kind in {tkInt8, tkInt16, tkInt32}: return true
if b.kind == tkUInt and a.kind in {tkUInt8, tkUInt16, tkUInt32}: return true if b.kind == tkUInt and a.kind in {tkUInt8, tkUInt16, tkUInt32}: return true
# int <-> uint (for convenience in bootstrap) # int <-> uint (for convenience in bootstrap)
if a.kind == tkInt and b.kind == tkUInt: return true if a.kind == tkInt and b.kind == tkUInt: return true
if a.kind == tkUInt and b.kind == tkInt: return true if a.kind == tkUInt and b.kind == tkInt: return true
# *char8 -> String (C string literal to Bux String)
if a.kind == tkPointer and b.kind == tkStr:
if a.inner.len > 0 and a.inner[0].kind == tkChar8:
return true
# numeric exact match required otherwise # numeric exact match required otherwise
if a.isNumeric and b.isNumeric: return false if a.isNumeric and b.isNumeric: return false
# bool across widths # bool across widths