summary refs log tree commit diff stats
path: root/compiler/semstmts.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-08-01 23:40:48 +0200
committerAraq <rumpf_a@web.de>2014-08-01 23:40:48 +0200
commit9673e4f2df941bfeeb3e1fe8e66d89fddea1145b (patch)
treeb7178daacba45beb51b3afb453fa256a0d6285d2 /compiler/semstmts.nim
parent821fe72ff55866737c5b1d9f356b8d142f8836c3 (diff)
downloadNim-9673e4f2df941bfeeb3e1fe8e66d89fddea1145b.tar.gz
progress on deepCopy
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r--compiler/semstmts.nim24
1 files changed, 23 insertions, 1 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 4d06b201e..1d913dc00 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1009,6 +1009,28 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
     addResult(c, s.typ.sons[0], n.info, s.kind)
     addResultNode(c, n)
 
+proc semOverride(c: PContext, s: PSym, n: PNode) =
+  case s.name.s.normalize
+  of "destroy": doDestructorStuff(c, s, n)
+  of "deepcopy":
+    if s.typ.len == 2 and
+        s.typ.sons[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and
+        sameType(s.typ.sons[1], s.typ.sons[0]):
+      # Note: we store the deepCopy in the base of the pointer to mitigate
+      # the problem that pointers are structural types:
+      let t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst)
+      if t.kind in {tyObject, tyDistinct, tyEnum}:
+        t.deepCopy = s
+      else:
+        localError(n.info, errGenerated,
+                   "cannot bind 'deepCopy' to: " & typeToString(t))
+    else:
+      localError(n.info, errGenerated,
+                 "signature for 'deepCopy' must be proc[T: ptr|ref](x: T): T")
+  of "=": discard
+  else: localError(n.info, errGenerated,
+                   "'destroy' or 'deepCopy' expected for 'override'")
+
 type
   TProcCompilationSteps = enum
     stepRegisterSymbol,
@@ -1125,7 +1147,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     popOwner()
     pushOwner(s)
   s.options = gOptions
-  if sfDestructor in s.flags: doDestructorStuff(c, s, n)
+  if sfOverriden in s.flags: semOverride(c, s, n)
   if n.sons[bodyPos].kind != nkEmpty:
     # for DLL generation it is annoying to check for sfImportc!
     if sfBorrow in s.flags: