diff options
author | Araq <rumpf_a@web.de> | 2011-05-02 20:42:29 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-05-02 20:42:29 +0200 |
commit | 7d2b3dd6db07203d7ff7a083ddae62aa8e7942c8 (patch) | |
tree | 620ab756043b848bd202f96223664e6695be8215 | |
parent | 4d5c3ebd468fa17a02a9abb9814c04e18baef309 (diff) | |
download | Nim-7d2b3dd6db07203d7ff7a083ddae62aa8e7942c8.tar.gz |
fixes #12
-rwxr-xr-x | compiler/cgmeth.nim | 101 | ||||
-rw-r--r-- | tests/accept/run/tmethods1.nim | 10 | ||||
-rwxr-xr-x | todo.txt | 4 |
3 files changed, 54 insertions, 61 deletions
diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index 12d58cdc1..dff844489 100755 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -13,13 +13,10 @@ import options, ast, astalgo, msgs, idents, renderer, types, magicsys proc genConv(n: PNode, d: PType, downcast: bool): PNode = - var - dest, source: PType - diff: int - dest = skipTypes(d, abstractPtrs) - source = skipTypes(n.typ, abstractPtrs) + var dest = skipTypes(d, abstractPtrs) + var source = skipTypes(n.typ, abstractPtrs) if (source.kind == tyObject) and (dest.kind == tyObject): - diff = inheritanceDiff(dest, source) + var diff = inheritanceDiff(dest, source) if diff == high(int): InternalError(n.info, "cgmeth.genConv") if diff < 0: result = newNodeIT(nkObjUpConv, n.info, d) @@ -36,9 +33,8 @@ proc genConv(n: PNode, d: PType, downcast: bool): PNode = result = n proc methodCall*(n: PNode): PNode = - var disp: PSym result = n - disp = lastSon(result.sons[0].sym.ast).sym + var disp = lastSon(result.sons[0].sym.ast).sym result.sons[0].sym = disp for i in countup(1, sonsLen(result) - 1): result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true) @@ -46,15 +42,14 @@ proc methodCall*(n: PNode): PNode = var gMethods: seq[TSymSeq] proc sameMethodBucket(a, b: PSym): bool = - var aa, bb: PType result = false if a.name.id != b.name.id: return if sonsLen(a.typ) != sonsLen(b.typ): return # check for return type: if not sameTypeOrNil(a.typ.sons[0], b.typ.sons[0]): return for i in countup(1, sonsLen(a.typ) - 1): - aa = a.typ.sons[i] - bb = b.typ.sons[i] + var aa = a.typ.sons[i] + var bb = b.typ.sons[i] while true: aa = skipTypes(aa, {tyGenericInst}) bb = skipTypes(bb, {tyGenericInst}) @@ -71,18 +66,15 @@ proc sameMethodBucket(a, b: PSym): bool = return result = true -proc methodDef*(s: PSym) = - var - L, q: int - disp: PSym - L = len(gMethods) +proc methodDef*(s: PSym) = + var L = len(gMethods) for i in countup(0, L - 1): if sameMethodBucket(gMethods[i][0], s): add(gMethods[i], s) # store a symbol to the dispatcher: addSon(s.ast, lastSon(gMethods[i][0].ast)) return add(gMethods, @[s]) # create a new dispatcher: - disp = copySym(s) + var disp = copySym(s) disp.typ = copyType(disp.typ, disp.typ.owner, false) if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault disp.ast = copyTree(s.ast) @@ -92,9 +84,8 @@ proc methodDef*(s: PSym) = addSon(s.ast, newSymNode(disp)) proc relevantCol(methods: TSymSeq, col: int): bool = - var t: PType # returns true iff the position is relevant - t = methods[0].typ.sons[col] + var t = methods[0].typ.sons[col] result = false if skipTypes(t, skipPtrs).kind == tyObject: for i in countup(1, high(methods)): @@ -102,33 +93,27 @@ proc relevantCol(methods: TSymSeq, col: int): bool = return true proc cmpSignatures(a, b: PSym, relevantCols: TIntSet): int = - var - d: int - aa, bb: PType result = 0 for col in countup(1, sonsLen(a.typ) - 1): if intSetContains(relevantCols, col): - aa = skipTypes(a.typ.sons[col], skipPtrs) - bb = skipTypes(b.typ.sons[col], skipPtrs) - d = inheritanceDiff(aa, bb) + var aa = skipTypes(a.typ.sons[col], skipPtrs) + var bb = skipTypes(b.typ.sons[col], skipPtrs) + var d = inheritanceDiff(aa, bb) if (d != high(int)): return d proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) = # we use shellsort here; fast and simple - var - N, j, h: int - v: PSym - N = len(a) - h = 1 + var N = len(a) + var h = 1 while true: h = 3 * h + 1 if h > N: break while true: h = h div 3 for i in countup(h, N - 1): - v = a[i] - j = i + var v = a[i] + var j = i while cmpSignatures(a[j - h], v, relevantCols) >= 0: a[j] = a[j - h] j = j - h @@ -136,51 +121,51 @@ proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) = a[j] = v if h == 1: break -proc genDispatcher(methods: TSymSeq, relevantCols: TIntSet): PSym = - var - disp, cond, call, ret, a, isn: PNode - base, curr, ands, iss: PSym - paramLen: int - base = lastSon(methods[0].ast).sym +proc genDispatcher(methods: TSymSeq, relevantCols: TIntSet): PSym = + var base = lastSon(methods[0].ast).sym result = base - paramLen = sonsLen(base.typ) - disp = newNodeI(nkIfStmt, base.info) - ands = getSysSym("and") - iss = getSysSym("is") - for meth in countup(0, high(methods)): - curr = methods[meth] # generate condition: - cond = nil - for col in countup(1, paramLen - 1): - if IntSetContains(relevantCols, col): - isn = newNodeIT(nkCall, base.info, getSysType(tyBool)) + var paramLen = sonsLen(base.typ) + var disp = newNodeI(nkIfStmt, base.info) + var ands = getSysSym("and") + var iss = getSysSym("is") + for meth in countup(0, high(methods)): + var curr = methods[meth] # generate condition: + var cond: PNode = nil + for col in countup(1, paramLen - 1): + if IntSetContains(relevantCols, col): + var isn = newNodeIT(nkCall, base.info, getSysType(tyBool)) addSon(isn, newSymNode(iss)) addSon(isn, newSymNode(base.typ.n.sons[col].sym)) addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col])) if cond != nil: - a = newNodeIT(nkCall, base.info, getSysType(tyBool)) + var a = newNodeIT(nkCall, base.info, getSysType(tyBool)) addSon(a, newSymNode(ands)) addSon(a, cond) addSon(a, isn) cond = a - else: + else: cond = isn - call = newNodeI(nkCall, base.info) + var call = newNodeI(nkCall, base.info) addSon(call, newSymNode(curr)) for col in countup(1, paramLen - 1): addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym), curr.typ.sons[col], false)) - if base.typ.sons[0] != nil: - a = newNodeI(nkAsgn, base.info) + var ret: PNode + if base.typ.sons[0] != nil: + var a = newNodeI(nkAsgn, base.info) addSon(a, newSymNode(base.ast.sons[resultPos].sym)) addSon(a, call) ret = newNodeI(nkReturnStmt, base.info) addSon(ret, a) - else: + else: ret = call - a = newNodeI(nkElifBranch, base.info) - addSon(a, cond) - addSon(a, ret) - addSon(disp, a) + if cond != nil: + var a = newNodeI(nkElifBranch, base.info) + addSon(a, cond) + addSon(a, ret) + addSon(disp, a) + else: + disp = ret result.ast.sons[codePos] = disp proc generateMethodDispatchers*(): PNode = diff --git a/tests/accept/run/tmethods1.nim b/tests/accept/run/tmethods1.nim new file mode 100644 index 000000000..adcca9e19 --- /dev/null +++ b/tests/accept/run/tmethods1.nim @@ -0,0 +1,10 @@ +discard """ + output: "do nothing" +""" + +method somethin(obj: TObject) = + echo "do nothing" + +var o: TObject +o.somethin() + diff --git a/todo.txt b/todo.txt index 2d4ce4c60..75a347e5d 100755 --- a/todo.txt +++ b/todo.txt @@ -6,7 +6,7 @@ High priority (version 0.9.0) ============================= -- tests: run modules that contain "when isMainModule", compile the other +- tests: run modules that contain "#RUN_ME", compile the other modules; run the GC tests - fix implicit generic routines - fix the streams implementation so that it uses methods @@ -44,8 +44,6 @@ Low priority ------------ - resizing of strings/sequences could take into account the memory that is allocated -- implicit conversions from ``ptr/ref T`` to ``var T`` (from - ``ptr/ref T`` to ``T``)? - typeAllowed() for parameters... - find a way to reintroduce the cleanup() pass for C code generation: this is hard because of partial evaluation --> symbol files will fix this as |