feat(operator): add operator_index_get/set to Array and Slice with generic monomorphization

This commit is contained in:
2026-06-11 01:28:59 +03:00
parent aa2d6f9632
commit a4f25bc737
3 changed files with 74 additions and 6 deletions
+8
View File
@@ -50,4 +50,12 @@ func Array_Drop<T>(self: *Array<T>) {
Array_Free<T>(self); Array_Free<T>(self);
} }
func Array_operator_index_get<T>(self: *Array<T>, idx: uint) -> T {
return Array_Get<T>(self, idx);
}
func Array_operator_index_set<T>(self: *Array<T>, idx: uint, value: T) {
Array_Set<T>(self, idx, value);
}
} }
+8
View File
@@ -28,4 +28,12 @@ func Slice_Len<T>(self: *Slice<T>) -> uint {
return self.len; return self.len;
} }
func Slice_operator_index_get<T>(self: *Slice<T>, idx: uint) -> T {
return Slice_Get<T>(self, idx);
}
func Slice_operator_index_set<T>(self: *Slice<T>, idx: uint, value: T) {
Slice_Set<T>(self, idx, value);
}
} }
+58 -6
View File
@@ -844,14 +844,40 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
} }
} }
if !String_Eq(receiverTypeName, "") { if !String_Eq(receiverTypeName, "") {
let funcName: String = String_Concat(String_Concat(receiverTypeName, "_"), "operator_index_get"); var funcName: String = String_Concat(String_Concat(receiverTypeName, "_"), "operator_index_get");
let sym: Symbol = Scope_Lookup(ctx.scope, funcName); let sym: Symbol = Scope_Lookup(ctx.scope, funcName);
if sym.kind == skFunc && sym.decl != null as *Decl { var didMono: bool = false;
// Generic monomorphization: if not found or is generic, monomorphize
if sym.kind != skFunc || sym.decl == null as *Decl || sym.decl.typeParamCount > 0 {
var typeArg0: String = "";
if expr.child1 != null as *Expr && expr.child1.refType != null as *TypeExpr {
let refTe2: *TypeExpr = expr.child1.refType;
if refTe2.kind == tekNamed && refTe2.typeArgCount > 0 {
typeArg0 = refTe2.typeArgName0;
} else if refTe2.kind == tekPointer && refTe2.pointerPointee != null as *TypeExpr && refTe2.pointerPointee.typeArgCount > 0 {
typeArg0 = refTe2.pointerPointee.typeArgName0;
}
}
if !String_Eq(typeArg0, "") {
let genericFuncName: String = String_Concat(String_Concat(receiverTypeName, "_"), "operator_index_get");
let genDecl: *Decl = Lcx_FindGenericFunc(ctx, genericFuncName);
if genDecl != null as *Decl {
funcName = Lcx_GenerateFuncInstance(ctx, genDecl, typeArg0, "", 1);
didMono = true;
}
}
}
let sym2: Symbol = Scope_Lookup(ctx.scope, funcName);
let targetDecl: *Decl = sym2.decl;
if didMono {
targetDecl = sym.decl;
}
if sym2.kind == skFunc && sym2.decl != null as *Decl || didMono {
n.kind = hCall; n.kind = hCall;
n.strValue = funcName; n.strValue = funcName;
let recv: *HirNode = Lcx_LowerExpr(ctx, expr.child1); let recv: *HirNode = Lcx_LowerExpr(ctx, expr.child1);
// If method expects pointer but receiver is not pointer, add & // If method expects pointer but receiver is not pointer, add &
if sym.decl.paramCount > 0 && sym.decl.param0.refParamType != null as *TypeExpr && sym.decl.param0.refParamType.kind == tekPointer { if targetDecl != null as *Decl && targetDecl.paramCount > 0 && targetDecl.param0.refParamType != null as *TypeExpr && targetDecl.param0.refParamType.kind == tekPointer {
if expr.child1.refType != null as *TypeExpr && expr.child1.refType.kind != tekPointer { if expr.child1.refType != null as *TypeExpr && expr.child1.refType.kind != tekPointer {
let addrNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; let addrNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode;
addrNode.kind = hUnary; addrNode.kind = hUnary;
@@ -937,9 +963,35 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
} }
} }
if !String_Eq(receiverTypeName, "") { if !String_Eq(receiverTypeName, "") {
let funcName: String = String_Concat(String_Concat(receiverTypeName, "_"), "operator_index_set"); var funcName: String = String_Concat(String_Concat(receiverTypeName, "_"), "operator_index_set");
let sym: Symbol = Scope_Lookup(ctx.scope, funcName); let sym: Symbol = Scope_Lookup(ctx.scope, funcName);
if sym.kind == skFunc && sym.decl != null as *Decl { var didMono: bool = false;
// Generic monomorphization: if not found or is generic, monomorphize
if sym.kind != skFunc || sym.decl == null as *Decl || sym.decl.typeParamCount > 0 {
var typeArg0: String = "";
if objExpr != null as *Expr && objExpr.refType != null as *TypeExpr {
let refTe2: *TypeExpr = objExpr.refType;
if refTe2.kind == tekNamed && refTe2.typeArgCount > 0 {
typeArg0 = refTe2.typeArgName0;
} else if refTe2.kind == tekPointer && refTe2.pointerPointee != null as *TypeExpr && refTe2.pointerPointee.typeArgCount > 0 {
typeArg0 = refTe2.pointerPointee.typeArgName0;
}
}
if !String_Eq(typeArg0, "") {
let genericFuncName: String = String_Concat(String_Concat(receiverTypeName, "_"), "operator_index_set");
let genDecl: *Decl = Lcx_FindGenericFunc(ctx, genericFuncName);
if genDecl != null as *Decl {
funcName = Lcx_GenerateFuncInstance(ctx, genDecl, typeArg0, "", 1);
didMono = true;
}
}
}
let sym2: Symbol = Scope_Lookup(ctx.scope, funcName);
let targetDecl: *Decl = sym2.decl;
if didMono {
targetDecl = sym.decl;
}
if sym2.kind == skFunc && sym2.decl != null as *Decl || didMono {
let callNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; let callNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode;
callNode.kind = hCall; callNode.kind = hCall;
callNode.strValue = funcName; callNode.strValue = funcName;
@@ -947,7 +999,7 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
callNode.column = col; callNode.column = col;
let recv: *HirNode = Lcx_LowerExpr(ctx, objExpr); let recv: *HirNode = Lcx_LowerExpr(ctx, objExpr);
// If method expects pointer but receiver is not pointer, add & // If method expects pointer but receiver is not pointer, add &
if sym.decl.paramCount > 0 && sym.decl.param0.refParamType != null as *TypeExpr && sym.decl.param0.refParamType.kind == tekPointer { if targetDecl != null as *Decl && targetDecl.paramCount > 0 && targetDecl.param0.refParamType != null as *TypeExpr && targetDecl.param0.refParamType.kind == tekPointer {
if objExpr.refType != null as *TypeExpr && objExpr.refType.kind != tekPointer { if objExpr.refType != null as *TypeExpr && objExpr.refType.kind != tekPointer {
let addrNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; let addrNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode;
addrNode.kind = hUnary; addrNode.kind = hUnary;