diff --git a/src/hir_lower.nim b/src/hir_lower.nim index 2995d3f..2ace5fc 100644 --- a/src/hir_lower.nim +++ b/src/hir_lower.nim @@ -227,7 +227,10 @@ proc resolveTypeExpr(ctx: var LowerCtx, te: TypeExpr): Type = of "float": return makeFloat64() of "float32": return makeFloat32() of "float64": return makeFloat64() - else: return makeNamed(te.typeName) + else: + if ctx.typeSubst.hasKey(te.typeName): + return ctx.typeSubst[te.typeName] + return makeNamed(te.typeName) of tekPointer: return makePointer(ctx.resolveTypeExpr(te.pointerPointee)) of tekSlice: return makeSlice(ctx.resolveTypeExpr(te.sliceElement)) else: return makeUnknown() @@ -404,6 +407,15 @@ proc getReceiverTypeExpr(ctx: LowerCtx, expr: Expr): TypeExpr = proc generateMethodInstance(ctx: var LowerCtx, baseMethodName: string, typeArgs: seq[TypeExpr]): string +proc findMethodEntry(ctx: LowerCtx, typeName: string): (string, seq[MethodInfo]) = + if ctx.methodTable.hasKey(typeName): + return (typeName, ctx.methodTable[typeName]) + for i in countdown(typeName.len - 1, 1): + let prefix = typeName[0.. 0 and receiverType.inner[0].kind == tkNamed: + receiverTypeName = receiverType.inner[0].name - # Try to find the method in methodTable - for typeName, methods in ctx.methodTable: + # Look up method for receiver type specifically + let (typeName, methods) = ctx.findMethodEntry(receiverTypeName) + if typeName != "": for minfo in methods: if minfo.name == methodName: var calleeName = typeName & "_" & methodName @@ -455,7 +474,6 @@ proc lowerExpr(ctx: var LowerCtx, expr: Expr): HirNode = calleeName = ctx.generateMethodInstance(calleeName, typeArgs) var args: seq[HirNode] = @[] let loweredReceiver = ctx.lowerExpr(receiverExpr) - let receiverType = ctx.resolveExprType(receiverExpr) # Auto-address if method expects pointer but receiver is value if minfo.params.len > 0 and minfo.params[0].kind == tkPointer and receiverType.kind != tkPointer: args.add(hirUnary(tkAmp, loweredReceiver, makePointer(receiverType), loc)) diff --git a/stdlib/Std/Array.bux b/stdlib/Std/Array.bux index 42609b6..1c3e022 100644 --- a/stdlib/Std/Array.bux +++ b/stdlib/Std/Array.bux @@ -5,40 +5,40 @@ extern func bux_realloc(ptr: *void, size: uint) -> *void; extern func bux_free(ptr: *void); extern func bux_bounds_check(index: uint, len: uint); -struct Array { - data: *int, +struct Array { + data: *T, len: uint, cap: uint, } -func Array_New(cap: uint) -> Array { - let data = bux_alloc(cap * 8) as *int; - return Array { data: data, len: 0, cap: cap }; +func Array_New(cap: uint) -> Array { + let data = bux_alloc(cap * sizeof(T)) as *T; + return Array { data: data, len: 0, cap: cap }; } -func Array_Push(arr: *Array, value: int) { - if arr.len >= arr.cap { - arr.cap = arr.cap * 2; - arr.data = bux_realloc(arr.data as *void, arr.cap * 8) as *int; +func Array_Push(self: *Array, value: T) { + if self.len >= self.cap { + self.cap = self.cap * 2; + self.data = bux_realloc(self.data as *void, self.cap * sizeof(T)) as *T; } - arr.data[arr.len] = value; - arr.len = arr.len + 1; + self.data[self.len] = value; + self.len = self.len + 1; } -func Array_Get(arr: *Array, index: uint) -> int { - bux_bounds_check(index, arr.len); - return arr.data[index]; +func Array_Get(self: *Array, index: uint) -> T { + bux_bounds_check(index, self.len); + return self.data[index]; } -func Array_Len(arr: *Array) -> uint { - return arr.len; +func Array_Len(self: *Array) -> uint { + return self.len; } -func Array_Free(arr: *Array) { - bux_free(arr.data as *void); - arr.data = null as *int; - arr.len = 0; - arr.cap = 0; +func Array_Free(self: *Array) { + bux_free(self.data as *void); + self.data = null as *T; + self.len = 0; + self.cap = 0; } }