summary refs log tree commit diff stats
path: root/rod
diff options
context:
space:
mode:
Diffstat (limited to 'rod')
-rwxr-xr-xrod/ast.nim34
-rwxr-xr-xrod/astalgo.nim6
-rwxr-xr-xrod/sigmatch.nim26
-rwxr-xr-xrod/transf.nim110
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