summary refs log tree commit diff stats
path: root/rod/transtmp.nim
diff options
context:
space:
mode:
Diffstat (limited to 'rod/transtmp.nim')
-rwxr-xr-xrod/transtmp.nim111
1 files changed, 111 insertions, 0 deletions
diff --git a/rod/transtmp.nim b/rod/transtmp.nim
new file mode 100755
index 000000000..44a462fea
--- /dev/null
+++ b/rod/transtmp.nim
@@ -0,0 +1,111 @@
+#
+#
+#           The Nimrod Compiler
+#        (c) Copyright 2008 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+# This module implements a transformator. It transforms the syntax tree 
+# to ease the work of the code generators. Does the transformation to 
+# introduce temporaries to split up complex expressions.
+# THIS MODULE IS NOT USED!
+
+proc transInto(c: PContext, dest: var PNode, father, src: PNode)
+  # transforms the expression `src` into the destination `dest`. Uses `father`
+  # for temorary statements. If dest = nil, the expression is put into a 
+  # temporary.
+proc transTmp(c: PContext, father, src: PNode): PNode = 
+  # convienence proc
+  result = nil
+  transInto(c, result, father, src)
+
+proc newLabel(c: PContext): PSym = 
+  inc(gTmpId)
+  result = newSym(skLabel, getIdent(genPrefix & $(gTmpId), c.transCon.owner))
+
+proc fewCmps(s: PNode): bool = 
+  # this function estimates whether it is better to emit code
+  # for constructing the set or generating a bunch of comparisons directly
+  assert(s.kind in {nkSetConstr, nkConstSetConstr})
+  if (s.typ.size <= platform.intSize) and (s.kind == nkConstSetConstr): 
+    result = false            # it is better to emit the set generation code
+  elif skipRange(s.typ.sons[0]).Kind in {tyInt..tyInt64}: 
+    result = true             # better not emit the set if int is basetype!
+  else: 
+    result = sonsLen(s) <=
+        8                     # 8 seems to be a good value
+  
+proc transformIn(c: PContext, father, n: PNode): PNode = 
+  var 
+    a, b, e, setc: PNode
+    destLabel, label2: PSym
+  if (n.sons[1].kind == nkSetConstr) and fewCmps(n.sons[1]): 
+    # a set constructor but not a constant set:
+    # do not emit the set, but generate a bunch of comparisons
+    result = newSymNode(newTemp(c, n.typ, n.info))
+    e = transTmp(c, father, n.sons[2])
+    setc = n.sons[1]
+    destLabel = newLabel(c)
+    for i in countup(0, sonsLen(setc) - 1): 
+      if setc.sons[i].kind == nkRange: 
+        a = transTmp(c, father, setc.sons[i].sons[0])
+        b = transTmp(c, father, setc.sons[i].sons[1])
+        label2 = newLabel(c)
+        addSon(father, newLt(result, e, a)) # e < a? --> goto end
+        addSon(father, newCondJmp(result, label2))
+        addSon(father, newLe(result, e, b)) # e <= b? --> goto set end
+        addSon(father, newCondJmp(result, destLabel))
+        addSon(father, newLabelNode(label2))
+      else: 
+        a = transTmp(c, father, setc.sons[i])
+        addSon(father, newEq(result, e, a))
+        addSon(father, newCondJmp(result, destLabel))
+    addSon(father, newLabelNode(destLabel))
+  else: 
+    result = n
+
+proc transformOp2(c: PContext, dest: var PNode, father, n: PNode) = 
+  var a, b: PNode
+  if dest == nil: dest = newSymNode(newTemp(c, n.typ, n.info))
+  a = transTmp(c, father, n.sons[1])
+  b = transTmp(c, father, n.sons[2])
+  addSon(father, newAsgnStmt(dest, newOp2(n, a, b)))
+
+proc transformOp1(c: PContext, dest: var PNode, father, n: PNode) = 
+  var a: PNode
+  if dest == nil: dest = newSymNode(newTemp(c, n.typ, n.info))
+  a = transTmp(c, father, n.sons[1])
+  addSon(father, newAsgnStmt(dest, newOp1(n, a)))
+
+proc genTypeInfo(c: PContext, initSection: PNode) = 
+  nil
+
+proc genNew(c: PContext, father, n: PNode) = 
+  # how do we handle compilerprocs?
+  
+proc transformCase(c: PContext, father, n: PNode): PNode = 
+  var 
+    ty: PType
+    e: PNode
+  ty = skipGeneric(n.sons[0].typ)
+  if ty.kind == tyString: 
+    # transform a string case to a bunch of comparisons:
+    result = newNodeI(nkIfStmt, n)
+    e = transTmp(c, father, n.sons[0])
+  else: 
+    result = n
+  
+proc transInto(c: PContext, dest: var PNode, father, src: PNode) = 
+  if src == nil: return 
+  if (src.typ != nil) and (src.typ.kind == tyGenericInst): 
+    src.typ = skipGeneric(src.typ)
+  case src.kind
+  of nkIdent..nkNilLit: 
+    if dest == nil: 
+      dest = copyTree(src)
+    else: 
+      # generate assignment:
+      addSon(father, newAsgnStmt(dest, src))
+  of nkCall, nkCommand, nkCallStrLit: 
+    nil