diff options
Diffstat (limited to 'rod')
-rwxr-xr-x | rod/ast.nim | 34 | ||||
-rwxr-xr-x | rod/astalgo.nim | 6 | ||||
-rwxr-xr-x | rod/sigmatch.nim | 26 | ||||
-rwxr-xr-x | rod/transf.nim | 110 |
4 files changed, 111 insertions, 65 deletions
diff --git a/rod/ast.nim b/rod/ast.nim index a2d35044e..f63bba43a 100755 --- a/rod/ast.nim +++ b/rod/ast.nim @@ -537,8 +537,8 @@ const var gId*: int -proc getID*(): int -proc setID*(id: int) +proc getID*(): int {.inline.} +proc setID*(id: int) {.inline.} proc IDsynchronizationPoint*(idRange: int) # creator procs: @@ -568,10 +568,10 @@ proc copyStrTable*(dest: var TStrTable, src: TStrTable) proc copyTable*(dest: var TTable, src: TTable) proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) proc copyIdTable*(dest: var TIdTable, src: TIdTable) -proc sonsLen*(n: PNode): int -proc sonsLen*(n: PType): int -proc lastSon*(n: PNode): PNode -proc lastSon*(n: PType): PType +proc sonsLen*(n: PNode): int {.inline.} +proc sonsLen*(n: PType): int {.inline.} +proc lastSon*(n: PNode): PNode {.inline.} +proc lastSon*(n: PType): PType {.inline.} proc newSons*(father: PNode, length: int) proc newSons*(father: PType, length: int) proc addSon*(father, son: PNode) @@ -903,6 +903,21 @@ proc copyNode(src: PNode): PNode = of nkStrLit..nkTripleStrLit: result.strVal = src.strVal else: nil +proc shallowCopy*(src: PNode): PNode = + # does not copy its sons, but provides space for them: + if src == nil: return nil + result = newNode(src.kind) + result.info = src.info + result.typ = src.typ + result.flags = src.flags * PersistentNodeFlags + case src.Kind + of nkCharLit..nkInt64Lit: result.intVal = src.intVal + of nkFloatLit, nkFloat32Lit, nkFloat64Lit: result.floatVal = src.floatVal + of nkSym: result.sym = src.sym + of nkIdent: result.ident = src.ident + of nkStrLit..nkTripleStrLit: result.strVal = src.strVal + else: newSons(result, sonsLen(src)) + proc copyTree(src: PNode): PNode = # copy a whole syntax tree; performs deep copying if src == nil: @@ -920,7 +935,8 @@ proc copyTree(src: PNode): PNode = else: result.sons = nil newSons(result, sonsLen(src)) - for i in countup(0, sonsLen(src) - 1): result.sons[i] = copyTree(src.sons[i]) + for i in countup(0, sonsLen(src) - 1): + result.sons[i] = copyTree(src.sons[i]) proc lastSon(n: PNode): PNode = result = n.sons[sonsLen(n) - 1] @@ -986,11 +1002,11 @@ proc getStrOrChar*(a: PNode): string = internalError(a.info, "getStrOrChar") result = "" -proc mustRehash(length, counter: int): bool = +proc mustRehash(length, counter: int): bool {.inline.} = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) -proc nextTry(h, maxHash: THash): THash = +proc nextTry(h, maxHash: THash): THash {.inline.} = result = ((5 * h) + 1) and maxHash # For any initial h in range(maxHash), repeating that maxHash times # generates each int in range(maxHash) exactly once (see any text on diff --git a/rod/astalgo.nim b/rod/astalgo.nim index 596531d0c..894af5b05 100755 --- a/rod/astalgo.nim +++ b/rod/astalgo.nim @@ -767,15 +767,13 @@ proc IdNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = data[h].val = val proc IdNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) = - var - index: int - n: TIdNodePairSeq - index = IdNodeTableRawGet(t, key) + var index = IdNodeTableRawGet(t, key) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): + var n: TIdNodePairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: diff --git a/rod/sigmatch.nim b/rod/sigmatch.nim index 6cb1632e3..6a91550e6 100755 --- a/rod/sigmatch.nim +++ b/rod/sigmatch.nim @@ -14,20 +14,20 @@ type TCandidateState = enum csEmpty, csMatch, csNoMatch TCandidate{.final.} = object - exactMatches*: int - subtypeMatches*: int - intConvMatches*: int # conversions to int are not as expensive - convMatches*: int - genericMatches*: int - state*: TCandidateState - callee*: PType # may not be nil! - calleeSym*: PSym # may be nil - call*: PNode # modified call - bindings*: TIdTable # maps sym-ids to types - baseTypeMatch*: bool # needed for conversions from T to openarray[T] - # for example + exactMatches: int + subtypeMatches: int + intConvMatches: int # conversions to int are not as expensive + convMatches: int + genericMatches: int + state: TCandidateState + callee: PType # may not be nil! + calleeSym: PSym # may be nil + call: PNode # modified call + bindings: TIdTable # maps sym-ids to types + baseTypeMatch: bool # needed for conversions from T to openarray[T] + # for example - TTypeRelation = enum # order is important! + TTypeRelation = enum # order is important! isNone, isConvertible, isIntConv, isSubtype, isGeneric, isEqual proc initCandidateAux(c: var TCandidate, callee: PType) {.inline.} = diff --git a/rod/transf.nim b/rod/transf.nim index 16c279c80..616f5ed77 100755 --- a/rod/transf.nim +++ b/rod/transf.nim @@ -29,20 +29,23 @@ proc transfPass*(): TPass type PTransCon = ref TTransCon TTransCon{.final.} = object # part of TContext; stackable - mapping*: TIdNodeTable # mapping from symbols to nodes - owner*: PSym # current owner - forStmt*: PNode # current for stmt - next*: PTransCon # for stacking + mapping: TIdNodeTable # mapping from symbols to nodes + owner: PSym # current owner + forStmt: PNode # current for stmt + next: PTransCon # for stacking TTransfContext = object of passes.TPassContext - module*: PSym - transCon*: PTransCon # top of a TransCon stack + module: PSym + transCon: PTransCon # top of a TransCon stack + inlining: int # > 0 if we are in inlining context (copy vars) PTransf = ref TTransfContext -proc newTransCon(): PTransCon = +proc newTransCon(owner: PSym): PTransCon = + assert owner != nil new(result) initIdNodeTable(result.mapping) + result.owner = owner proc pushTransCon(c: PTransf, t: PTransCon) = t.next = c.transCon @@ -209,9 +212,50 @@ proc transformYield(c: PTransf, n: PNode): PNode = else: e = transform(c, copyTree(e)) addSon(result, newAsgnStmt(c, c.transCon.forStmt.sons[0], e)) + + #var tc = newTransCon(c.transCon.owner) + #tc.forStmt = c.transCon.forStmt + #pushTransCon(c, tc) + inc(c.inlining) addSon(result, transform(c, lastSon(c.transCon.forStmt))) + dec(c.inlining) + #popTransCon(c) + +proc transformVarSection(c: PTransf, v: PNode): PNode = + result = copyTree(v) + for i in countup(0, sonsLen(result) - 1): + var it = result.sons[i] + if it.kind == nkCommentStmt: continue + if it.kind == nkIdentDefs: + if (it.sons[0].kind != nkSym): + InternalError(it.info, "transformVarSection") + var newVar = copySym(it.sons[0].sym) + if identEq(newVar.name, "titer2TestVar"): + echo "created a copy of titer2TestVar ", newVar.id, " ", + it.sons[0].sym.id + + incl(newVar.flags, sfFromGeneric) + # fixes a strange bug for rodgen: + #include(it.sons[0].sym.flags, sfFromGeneric); + newVar.owner = getCurrOwner(c) + IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) + it.sons[0].sym = newVar + it.sons[2] = transform(c, it.sons[2]) + else: + if it.kind != nkVarTuple: + InternalError(it.info, "transformVarSection: not nkVarTuple") + var L = sonsLen(it) + for j in countup(0, L - 3): + var newVar = copySym(it.sons[j].sym) + incl(newVar.flags, sfFromGeneric) + newVar.owner = getCurrOwner(c) + IdNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar)) + it.sons[j] = newSymNode(newVar) + assert(it.sons[L - 2] == nil) + it.sons[L - 1] = transform(c, it.sons[L - 1]) proc inlineIter(c: PTransf, n: PNode): PNode = + # n: iterator body result = n if n == nil: return case n.kind @@ -220,32 +264,7 @@ proc inlineIter(c: PTransf, n: PNode): PNode = of nkYieldStmt: result = transformYield(c, n) of nkVarSection: - result = copyTree(n) - for i in countup(0, sonsLen(result) - 1): - var it = result.sons[i] - if it.kind == nkCommentStmt: continue - if it.kind == nkIdentDefs: - if (it.sons[0].kind != nkSym): InternalError(it.info, "inlineIter") - var newVar = copySym(it.sons[0].sym) - incl(newVar.flags, sfFromGeneric) - # fixes a strange bug for rodgen: - #include(it.sons[0].sym.flags, sfFromGeneric); - newVar.owner = getCurrOwner(c) - IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) - it.sons[0] = newSymNode(newVar) - it.sons[2] = transform(c, it.sons[2]) - else: - if it.kind != nkVarTuple: - InternalError(it.info, "inlineIter: not nkVarTuple") - var L = sonsLen(it) - for j in countup(0, L - 3): - var newVar = copySym(it.sons[j].sym) - incl(newVar.flags, sfFromGeneric) - newVar.owner = getCurrOwner(c) - IdNodeTablePut(c.transCon.mapping, it.sons[j].sym, newSymNode(newVar)) - it.sons[j] = newSymNode(newVar) - assert(it.sons[L - 2] == nil) - it.sons[L - 1] = transform(c, it.sons[L - 1]) + result = transformVarSection(c, n) else: result = copyNode(n) for i in countup(0, sonsLen(n) - 1): addSon(result, inlineIter(c, n.sons[i])) @@ -388,11 +407,11 @@ proc transformFor(c: PTransf, n: PNode): PNode = for i in countup(0, length - 3): addVar(v, copyTree(n.sons[i])) # declare new vars addSon(result, v) - var newC = newTransCon() var call = n.sons[length - 2] if (call.kind != nkCall) or (call.sons[0].kind != nkSym): InternalError(call.info, "transformFor") - newC.owner = call.sons[0].sym + + var newC = newTransCon(call.sons[0].sym) newC.forStmt = n if (newC.owner.kind != skIterator): InternalError(call.info, "transformFor") @@ -486,7 +505,7 @@ proc transformLambda(c: PTransf, n: PNode): PNode = # all variables that are accessed should be accessed by the new closure # parameter: if sonsLen(closure) > 0: - var newC = newTransCon() + var newC = newTransCon(c.transCon.owner) for i in countup(0, sonsLen(closure) - 1): IdNodeTablePut(newC.mapping, closure.sons[i].sym, indirectAccess(param, closure.sons[i].sym)) @@ -613,22 +632,35 @@ proc transform(c: PTransf, n: PNode): PNode = of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = transformConv(c, n) of nkDiscardStmt: - for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i]) + for i in countup(0, sonsLen(n) - 1): + result.sons[i] = transform(c, n.sons[i]) if isConstExpr(result.sons[0]): result = newNode(nkCommentStmt) of nkCommentStmt, nkTemplateDef: return of nkConstSection: # do not replace ``const c = 3`` with ``const 3 = 3`` return - else: - for i in countup(0, sonsLen(n) - 1): result.sons[i] = transform(c, n.sons[i]) + of nkVarSection: + if c.inlining > 0: + # we need to copy the variables for multiple yield statements: + result = transformVarSection(c, n) + else: + result = shallowCopy(n) + for i in countup(0, sonsLen(n) - 1): + result.sons[i] = transform(c, n.sons[i]) + else: + result = shallowCopy(n) + for i in countup(0, sonsLen(n) - 1): + result.sons[i] = transform(c, n.sons[i]) var cnst = getConstExpr(c.module, result) if cnst != nil: result = cnst # do not miss an optimization proc processTransf(context: PPassContext, n: PNode): PNode = var c = PTransf(context) + pushTransCon(c, newTransCon(getCurrOwner(c))) result = transform(c, n) + popTransCon(c) proc openTransf(module: PSym, filename: string): PPassContext = var n: PTransf |