diff --git a/lib/Array.bux b/lib/Array.bux index 3b5c348..9ed355c 100644 --- a/lib/Array.bux +++ b/lib/Array.bux @@ -50,4 +50,12 @@ func Array_Drop(self: *Array) { Array_Free(self); } +func Array_operator_index_get(self: *Array, idx: uint) -> T { + return Array_Get(self, idx); +} + +func Array_operator_index_set(self: *Array, idx: uint, value: T) { + Array_Set(self, idx, value); +} + } diff --git a/lib/Slice.bux b/lib/Slice.bux index 8598c76..b6fb2b3 100644 --- a/lib/Slice.bux +++ b/lib/Slice.bux @@ -28,4 +28,12 @@ func Slice_Len(self: *Slice) -> uint { return self.len; } +func Slice_operator_index_get(self: *Slice, idx: uint) -> T { + return Slice_Get(self, idx); +} + +func Slice_operator_index_set(self: *Slice, idx: uint, value: T) { + Slice_Set(self, idx, value); +} + } diff --git a/src/hir_lower.bux b/src/hir_lower.bux index 05a88e5..cd0181a 100644 --- a/src/hir_lower.bux +++ b/src/hir_lower.bux @@ -844,14 +844,40 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { } } 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); - 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.strValue = funcName; let recv: *HirNode = Lcx_LowerExpr(ctx, expr.child1); // 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 { let addrNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; addrNode.kind = hUnary; @@ -937,9 +963,35 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { } } 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); - 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; callNode.kind = hCall; callNode.strValue = funcName; @@ -947,7 +999,7 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { callNode.column = col; let recv: *HirNode = Lcx_LowerExpr(ctx, objExpr); // 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 { let addrNode: *HirNode = bux_alloc(sizeof(HirNode)) as *HirNode; addrNode.kind = hUnary;