feat(operator): add operator_index_get/set to Array and Slice with generic monomorphization
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user