fix(selfhost): collection-based for-in with Std::Array + monomorphization fixes
- Fix Fmt_Format name conflict between lib/Fmt.bux and src/fmt.bux by renaming selfhost formatter function to Fmt_FormatSource. - Fix collection-based for-in loops to handle already-monomorphized types like Array_int and Iter_string (typeArgCount=0 cases). - Fix ekSizeOf and ekCast in HIR lowering to apply Lcx_SubstituteType during generic monomorphization, so sizeof(T) and *T casts emit correct concrete types in C output. - Fix sema to infer stmt.refStmtType from initializer expression when no explicit type annotation is given, ensuring C backend emits correct pointer types for let data = ... as *T.
This commit is contained in:
+2
-2
@@ -73,7 +73,7 @@ func Fmt_CountBraceDelta(line: String) -> int {
|
||||
return delta;
|
||||
}
|
||||
|
||||
func Fmt_Format(source: String) -> String {
|
||||
func Fmt_FormatSource(source: String) -> String {
|
||||
let sb: StringBuilder = StringBuilder_NewCap(8192);
|
||||
var indent: int = 0;
|
||||
var i: uint = 0;
|
||||
@@ -130,7 +130,7 @@ func Fmt_Format(source: String) -> String {
|
||||
func Fmt_FormatFile(path: String) -> bool {
|
||||
let source: String = bux_read_file(path);
|
||||
if source == null as String || String_Eq(source, "") { return false; }
|
||||
let formatted: String = Fmt_Format(source);
|
||||
let formatted: String = Fmt_FormatSource(source);
|
||||
if String_Eq(formatted, "") { return false; }
|
||||
return bux_write_file(path, formatted);
|
||||
}
|
||||
|
||||
+45
-6
@@ -2,6 +2,8 @@
|
||||
// Transforms the typed AST into a lower-level IR suitable for code generation.
|
||||
module HirLower {
|
||||
|
||||
extern func bux_str_slice(s: String, start: uint, len: uint) -> String;
|
||||
extern func bux_strlen(s: String) -> uint;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Lowering context
|
||||
@@ -619,8 +621,13 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
|
||||
if kind == ekSizeOf {
|
||||
n.kind = hSizeOf;
|
||||
if expr.refType != null as *TypeExpr {
|
||||
let substTe: *TypeExpr = Lcx_SubstituteType(ctx, expr.refType);
|
||||
if substTe != null as *TypeExpr {
|
||||
n.typeName = substTe.typeName;
|
||||
} else {
|
||||
n.typeName = expr.refType.typeName;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -704,13 +711,15 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
|
||||
n.kind = hCast;
|
||||
n.child1 = Lcx_LowerExpr(ctx, expr.child1);
|
||||
if expr.refType != null as *TypeExpr {
|
||||
let resolvedKind: int = Lcx_ResolveTypeKind(expr.refType);
|
||||
let substTe: *TypeExpr = Lcx_SubstituteType(ctx, expr.refType);
|
||||
if substTe == null as *TypeExpr { substTe = expr.refType; }
|
||||
let resolvedKind: int = Lcx_ResolveTypeKind(substTe);
|
||||
n.typeKind = resolvedKind;
|
||||
// For pointer types, construct "PointeeType*"
|
||||
if expr.refType.kind == tekPointer && expr.refType.pointerPointee != null as *TypeExpr {
|
||||
n.typeName = String_Concat(expr.refType.pointerPointee.typeName, "*");
|
||||
} else if !String_Eq(expr.refType.typeName, "") {
|
||||
n.typeName = expr.refType.typeName;
|
||||
if substTe.kind == tekPointer && substTe.pointerPointee != null as *TypeExpr {
|
||||
n.typeName = String_Concat(substTe.pointerPointee.typeName, "*");
|
||||
} else if !String_Eq(substTe.typeName, "") {
|
||||
n.typeName = substTe.typeName;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
@@ -1082,10 +1091,40 @@ func Lcx_LowerStmt(ctx: *LowerCtx, stmt: *Stmt) -> *HirNode {
|
||||
elemTypeKind = Lcx_ResolveTypeKindFromName(elemTypeName);
|
||||
}
|
||||
|
||||
if !String_Eq(elemTypeName, "") {
|
||||
// Handle already-monomorphized types like Array_int, Iter_string
|
||||
var isArray: bool = String_Eq(collTypeName, "Array");
|
||||
var isIter: bool = String_Eq(collTypeName, "Iter");
|
||||
if String_Eq(elemTypeName, "") {
|
||||
// Manual prefix check for "Array_"
|
||||
var isArrayPrefix: bool = false;
|
||||
var isIterPrefix: bool = false;
|
||||
let collName: String = collTypeName;
|
||||
if collName[0] as int == 65 && collName[1] as int == 114 && collName[2] as int == 114 && collName[3] as int == 97 && collName[4] as int == 121 && collName[5] as int == 95 {
|
||||
isArrayPrefix = true;
|
||||
}
|
||||
if collName[0] as int == 73 && collName[1] as int == 116 && collName[2] as int == 101 && collName[3] as int == 114 && collName[4] as int == 95 {
|
||||
isIterPrefix = true;
|
||||
}
|
||||
if isArrayPrefix {
|
||||
isArray = true;
|
||||
let prefixLen: uint = 6; // len("Array_")
|
||||
let totalLen: uint = bux_strlen(collTypeName);
|
||||
if totalLen > prefixLen {
|
||||
elemTypeName = bux_str_slice(collTypeName, prefixLen, totalLen - prefixLen);
|
||||
elemTypeKind = Lcx_ResolveTypeKindFromName(elemTypeName);
|
||||
}
|
||||
} else if isIterPrefix {
|
||||
isIter = true;
|
||||
let prefixLen: uint = 5; // len("Iter_")
|
||||
let totalLen: uint = bux_strlen(collTypeName);
|
||||
if totalLen > prefixLen {
|
||||
elemTypeName = bux_str_slice(collTypeName, prefixLen, totalLen - prefixLen);
|
||||
elemTypeKind = Lcx_ResolveTypeKindFromName(elemTypeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !String_Eq(elemTypeName, "") {
|
||||
if isArray || isIter {
|
||||
let iterVarName: String = String_Concat("__iter_", varName);
|
||||
let iterTypeName: String = Lcx_MangleName("Iter", elemTypeName, "", 1);
|
||||
|
||||
@@ -756,6 +756,15 @@ func Sema_CheckStmt(sema: *Sema, stmt: *Stmt) {
|
||||
} else {
|
||||
sym.typeName = stmt.refStmtType.typeName;
|
||||
}
|
||||
} else if stmt.child1 != null as *Expr && stmt.child1.refType != null as *TypeExpr {
|
||||
// Infer type from initializer expression
|
||||
sym.refType = stmt.child1.refType;
|
||||
stmt.refStmtType = stmt.child1.refType;
|
||||
if stmt.child1.refType.kind == tekPointer && stmt.child1.refType.pointerPointee != null as *TypeExpr {
|
||||
sym.typeName = String_Concat(stmt.child1.refType.pointerPointee.typeName, "*");
|
||||
} else {
|
||||
sym.typeName = stmt.child1.refType.typeName;
|
||||
}
|
||||
}
|
||||
sym.isMutable = stmt.boolValue;
|
||||
sym.isPublic = false;
|
||||
|
||||
Reference in New Issue
Block a user