summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-08-24 17:33:04 +0200
committerAraq <rumpf_a@web.de>2012-08-24 17:33:04 +0200
commitd17caa86e841489d92165d9caa13c2d8bc86afd5 (patch)
tree9504e5dd71501887da52fbc1f0fd39294ef913ea
parentafcff024a1ab335032aa8a98d844f6fbc701170e (diff)
downloadNim-d17caa86e841489d92165d9caa13c2d8bc86afd5.tar.gz
objects with no ancestor are not implicitely final
-rwxr-xr-xcompiler/ast.nim5
-rwxr-xr-xcompiler/condsyms.nim1
-rwxr-xr-xcompiler/pragmas.nim8
-rwxr-xr-xcompiler/semtypes.nim2
-rwxr-xr-xdoc/manual.txt13
-rwxr-xr-xdoc/tut2.txt6
-rwxr-xr-xlib/pure/pegs.nim2
-rwxr-xr-xlib/pure/xmldom.nim2
-rwxr-xr-xlib/system.nim7
-rwxr-xr-xlib/system/alloc.nim2
-rwxr-xr-xlib/wrappers/gtk/glib2.nim6
-rwxr-xr-xlib/wrappers/python.nim2
-rwxr-xr-xtests/run/tpegs.nim2
-rwxr-xr-xtodo.txt5
-rwxr-xr-xweb/news.txt3
15 files changed, 44 insertions, 22 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index bb78fcd57..ae8beace7 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -305,7 +305,7 @@ type
     tyBigNum, 
     tyConst, tyMutable, tyVarargs, 
     tyIter, # unused
-    tyProxy # currently unused
+    tyProxy # used as errornous type (for idetools)
     tyTypeClass,
 
 const
@@ -328,10 +328,11 @@ type
     nfSem       # node has been checked for semantics
 
   TNodeFlags* = set[TNodeFlag]
-  TTypeFlag* = enum   # keep below 15 for efficiency reasons (now: 13)
+  TTypeFlag* = enum   # keep below 15 for efficiency reasons (now: 14)
     tfVarargs,        # procedure has C styled varargs
     tfNoSideEffect,   # procedure type does not allow side effects
     tfFinal,          # is the object final?
+    tfInheritable,    # is the object inheritable?
     tfAcyclic,        # type is acyclic (for GC optimization)
     tfEnumHasHoles,   # enum cannot be mapped into a range
     tfShallow,        # type can be shallow copied on assignment
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index d273f5335..8c8d02612 100755
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -57,6 +57,7 @@ proc InitDefines*() =
   DefineSymbol("nimrod") # 'nimrod' is always defined
   # for bootstrapping purposes and old code:
   DefineSymbol("nimhygiene")
+  DefineSymbol("niminheritable")
   
   # add platform specific symbols:
   case targetCPU
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index cbdf63a1c..47abd0178 100755
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -48,7 +48,7 @@ const
   typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, 
     wPure, wHeader, wCompilerProc, wFinal, wSize, wExtern, wShallow, 
     wImportcpp, wImportobjc, wError, wIncompleteStruct, wByCopy, wByRef,
-    wGenSym, wInject}
+    wInheritable, wGenSym, wInject}
   fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, 
     wImportcpp, wImportobjc, wError}
   varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, 
@@ -584,7 +584,11 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
             else: incl(sym.typ.flags, tfFinal)
-          of wAcyclic: 
+          of wInheritable:
+            noVal(it)
+            if sym.typ == nil or tfFinal in sym.typ.flags: invalidPragma(it)
+            else: incl(sym.typ.flags, tfInheritable)
+          of wAcyclic:
             noVal(it)
             if sym.typ == nil: invalidPragma(it)
             else: incl(sym.typ.flags, tfAcyclic)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index d05adab3b..5b6183005 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -545,6 +545,8 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType): PType =
     var s = newSymS(skType, newIdentNode(getIdent("dummy"), n.info), c)
     s.typ = result
     pragma(c, s, n.sons[0], typePragmas)
+  if base == nil and tfInheritable notin result.flags:
+    incl(result.flags, tfFinal)
   
 proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
   if kind == skMacro and param.typ.kind in {tyTypeDesc, tyExpr, tyStmt}:
diff --git a/doc/manual.txt b/doc/manual.txt
index e0fee2a31..6fccd0ca3 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -970,9 +970,10 @@ in future versions of the compiler.
   person = ("Peter", 30)

 

 The implementation aligns the fields for best access performance. The alignment

-is compatible with the way the C compiler does it. For consistency 
-with ``object`` declarations, tuples in a ``type`` section can also be defined
-with indentation instead of ``[]``:
+is compatible with the way the C compiler does it. 
+
+For consistency  with ``object`` declarations, tuples in a ``type`` section
+can also be defined with indentation instead of ``[]``:
 

 .. code-block:: nimrod

 

@@ -988,7 +989,7 @@ the ``of`` operator can be used to determine the object's type.
 .. code-block:: nimrod

 

   type

-    TPerson = object

+    TPerson {.inheritable.} = object

       name*: string   # the * means that `name` is accessible from other modules

       age: int        # no * means that the field is hidden

 

@@ -1002,7 +1003,9 @@ the ``of`` operator can be used to determine the object's type.
 

 Object fields that should be visible from outside the defining module, have to

 be marked by ``*``. In contrast to tuples, different object types are

-never *equivalent*.

+never *equivalent*. Objects that have no ancestor are implicitely ``final``
+and thus have no hidden type field. One can use the ``inheritable`` pragma to
+introduce new object roots apart from ``system.TObject``.
 

 

 Object variants

diff --git a/doc/tut2.txt b/doc/tut2.txt
index d897319fc..96507bcb1 100755
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -74,7 +74,11 @@ section.
 
 Inheritance is done with the ``object of`` syntax. Multiple inheritance is
 currently not supported. If an object type has no suitable ancestor, ``TObject``
-can be used as its ancestor, but this is only a convention.
+can be used as its ancestor, but this is only a convention. Objects that have 
+no ancestor are implicitely ``final``. You can use the ``inheritable`` pragma 
+to introduce new object roots apart from ``system.TObject``. (This is used
+in the GTK wrapper for instance.)
+
 
 **Note**: Composition (*has-a* relation) is often preferable to inheritance
 (*is-a* relation) for simple code reuse. Since objects are value types in
diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim
index e37c072f1..4e31ffc0c 100755
--- a/lib/pure/pegs.nim
+++ b/lib/pure/pegs.nim
@@ -1057,7 +1057,7 @@ type
     charset: set[char]       ## if kind == tkCharSet
     index: int               ## if kind == tkBackref
   
-  TPegLexer = object          ## the lexer object.
+  TPegLexer {.inheritable.} = object          ## the lexer object.
     bufpos: int               ## the current position within the buffer
     buf: cstring              ## the buffer itself
     LineNumber: int           ## the current line number
diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim
index 97cf3caeb..47e94243e 100755
--- a/lib/pure/xmldom.nim
+++ b/lib/pure/xmldom.nim
@@ -58,7 +58,7 @@ type
     Features: seq[Feature] # Read-Only
 
   PNode* = ref Node
-  Node = object
+  Node = object of TObject
     attributes*: seq[PAttr]
     childNodes*: seq[PNode]
     FLocalName: string # Read-only
diff --git a/lib/system.nim b/lib/system.nim
index 01b85a4d6..b40f161f1 100755
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -171,9 +171,12 @@ proc `..`*[T](b: T): TSlice[T] {.noSideEffect, inline.} =
 proc contains*[T](s: TSlice[T], value: T): bool {.noSideEffect, inline.} = 
   result = value >= s.a and value <= s.b
 
+when not defined(niminheritable):
+  {.pragma: inheritable.}
+
 when not defined(EcmaScript) and not defined(NimrodVM):
   type
-    TGenericSeq {.compilerproc, pure.} = object
+    TGenericSeq {.compilerproc, pure, inheritable.} = object
       len, reserved: int
     PGenericSeq {.exportc.} = ptr TGenericSeq
     # len and space without counting the terminating zero:
@@ -197,7 +200,7 @@ type
     ## is an int type ranging from one to the maximum value
     ## of an int. This type is often useful for documentation and debugging.
 
-  TObject* {.exportc: "TNimObject".} =
+  TObject* {.exportc: "TNimObject", inheritable.} =
     object ## the root of Nimrod's object hierarchy. Objects should
            ## inherit from TObject or one of its descendants. However,
            ## objects that have no ancestor are allowed.
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim
index 53c20316c..5182d5ccf 100755
--- a/lib/system/alloc.nim
+++ b/lib/system/alloc.nim
@@ -113,7 +113,7 @@ type
   PChunk = ptr TBaseChunk
   PBigChunk = ptr TBigChunk
   PSmallChunk = ptr TSmallChunk
-  TBaseChunk {.pure.} = object
+  TBaseChunk {.pure, inheritable.} = object
     prevSize: int        # size of previous chunk; for coalescing
     size: int            # if < PageSize it is a small chunk
     used: bool           # later will be optimized into prevSize...
diff --git a/lib/wrappers/gtk/glib2.nim b/lib/wrappers/gtk/glib2.nim
index b69b708fe..4151ba954 100755
--- a/lib/wrappers/gtk/glib2.nim
+++ b/lib/wrappers/gtk/glib2.nim
@@ -107,7 +107,7 @@ type
     g_class*: PGTypeClass
 
   PGTypeInterface* = ptr TGTypeInterface
-  TGTypeInterface*{.pure.} = object 
+  TGTypeInterface*{.pure, inheritable.} = object 
     g_type*: GType
     g_instance_type*: GType
 
@@ -993,7 +993,7 @@ proc plugin_complete_interface_info*(plugin: PGTypePlugin,
     dynlib: gliblib, importc: "g_type_plugin_complete_interface_info".}
 type 
   PGObject* = ptr TGObject
-  TGObject*{.pure.} = object 
+  TGObject*{.pure, inheritable.} = object 
     g_type_instance*: TGTypeInstance
     ref_count*: guint
     qdata*: PGData
@@ -1006,7 +1006,7 @@ type
   TGWeakNotify* = proc (data: gpointer, where_the_object_was: PGObject){.cdecl.}
   PGObjectConstructParam* = ptr TGObjectConstructParam
   PGObjectClass* = ptr TGObjectClass
-  TGObjectClass*{.pure.} = object 
+  TGObjectClass*{.pure, inheritable.} = object 
     g_type_class*: TGTypeClass
     construct_properties*: PGSList
     constructor*: proc (theType: GType, n_construct_properties: guint, 
diff --git a/lib/wrappers/python.nim b/lib/wrappers/python.nim
index 3d0b923e2..3e6543765 100755
--- a/lib/wrappers/python.nim
+++ b/lib/wrappers/python.nim
@@ -341,7 +341,7 @@ type
     float*: float64
     imag*: float64
 
-  TPyObject*{.pure.} = object 
+  TPyObject*{.pure, inheritable.} = object 
     ob_refcnt*: int
     ob_type*: PPyTypeObject
 
diff --git a/tests/run/tpegs.nim b/tests/run/tpegs.nim
index 315833326..e64cd8fef 100755
--- a/tests/run/tpegs.nim
+++ b/tests/run/tpegs.nim
@@ -1052,7 +1052,7 @@ type
     charset: set[char]       ## if kind == tkCharSet
     index: int               ## if kind == tkBackref
   
-  TPegLexer = object          ## the lexer object.
+  TPegLexer {.inheritable.} = object          ## the lexer object.
     bufpos: int               ## the current position within the buffer
     buf: cstring              ## the buffer itself
     LineNumber: int           ## the current line number
diff --git a/todo.txt b/todo.txt
index c49e80980..58e3e067e 100755
--- a/todo.txt
+++ b/todo.txt
@@ -1,13 +1,14 @@
 version 0.9.0
 =============
 
-- ``final`` should be the default for objects
 - implement "closure tuple consists of a single 'ref'" optimization
 - implement for loop transformation for first class iterators
 
 - implicit deref for parameter matching
 - optimize genericAssign in the code generator
-- the lookup rules for generics really are too permissive
+- the lookup rules for generics really are too permissive; global scope only
+  doesn't fly with closures though; for a start add a warning when processing
+  generic code
 - fix remaining closure bugs:
   - test evals.nim with closures
   - what about macros with closures?
diff --git a/web/news.txt b/web/news.txt
index bbac003f1..f67e4d74b 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -108,6 +108,9 @@ Changes affecting backwards compatibility
 - The Nimrod type system now distinguishes ``openarray`` from ``varargs``.
 - Templates are now ``hygienic``. Use the ``dirty`` pragma to get the old
   behaviour.
+- Objects that have no ancestor are now implicitely ``final``. Use 
+  the ``inheritable`` pragma to introduce new object roots apart 
+  from ``TObject``.
 
 
 Compiler Additions