[PATCH] Add instance variables when using extend

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] Add instance variables when using extend

Paolo Bonzini
This makes sure that after

Object subclass: A [
   | a |
]

A extend [
   | b |
]

Class A has *two* instance variables.  I found out we need this while
using GNU Smalltalk for other projects.

Paolo

* looking for [hidden email]--2004b/smalltalk--devo--2.2--patch-602 to compare with
* auto-adding [hidden email]--2004b/smalltalk--devo--2.2--patch-602 to greedy revision library /Users/bonzinip/Archives/revlib
* found immediate ancestor revision in library ([hidden email]--2004b/smalltalk--devo--2.2--patch-601)
* patching for this revision ([hidden email]--2004b/smalltalk--devo--2.2--patch-602)
* comparing to [hidden email]--2004b/smalltalk--devo--2.2--patch-602
M  doc/tutorial.texi
M  libgst/gst-parse.c

* modified files

--- orig/doc/tutorial.texi
+++ mod/doc/tutorial.texi
@@ -804,7 +804,7 @@ Account extend [
 @end example
 
 This instructs Smalltalk to pick an existing class, rather than
-trying to subclass it.
+trying to create a subclass.
 
 @node Defining methods, Instance methods, Documenting the class, Creating classes
 @subsection Defining a method for the class
@@ -863,7 +863,7 @@ how to process this message.  It finds o
 starts running it.  The first line, @code{| r |}, creates a local
 variable named @code{r} which can be used as a placeholder for
 the objects we create.  @code{r} will go away as soon as the message
-is done being processed; note the parallel with @code{balance}, who
+is done being processed; note the parallel with @code{balance}, which
 goes away as soon as the object is not used anymore.  And note that
 here you have to declare local variables explicitly, unlike what
 you did in previous examples.
@@ -1410,22 +1410,20 @@ class.
 
 @example
 Checking extend [
-    | checknum checksleft history |
+    | history |
 @end example
 
-This is the same syntax as the last time we defined a
-checking account, except that we start with @code{extend}
-(since the class is already there) and have three instance variables:
-the @code{checknum} and @code{checksleft} which have always been
-there, and our new @code{history} variable; since we have removed no
-instance variables, the old method will be recompiled without
-errors.  We must now feed in our definitions for each of the
-messages our object can handle, since we are basically
-defining a new class under an old name.
-
-With our new Checking instance variable, we are all set
-to start recording our checking history.  Our first change
-will be in the handling of the @code{init} message:
+This is the same syntax as the last time we defined a checking account,
+except that we start with @code{extend} (since the class is already
+there).  Then, the two instance variables we had defined remain, and we
+add a new @code{history} variable; the old methods will be recompiled
+without errors.  We must now feed in our definitions for each of the
+messages our object can handle, since we are basically defining a new
+class under an old name.
+
+With our new Checking instance variable, we are all set to start recording
+our checking history.  Our first change will be in the handling of the
+@code{init} message:
 @example
        init [
            <category: 'initialization'>


--- orig/libgst/gst-parse.c
+++ mod/libgst/gst-parse.c
@@ -108,13 +108,15 @@ static void parse_eval_definition (gst_p
 static mst_Boolean parse_namespace_definition (gst_parser *p,
        tree_node first_stmt);
 static mst_Boolean parse_class_definition (gst_parser *p,
-   OOP classOOP);
+   OOP classOOP,
+   mst_Boolean extend);
 static OOP parse_namespace (tree_node name);
 static OOP parse_class (tree_node list);
 static void parse_scoped_method (gst_parser *p,
  OOP classOOP);
 static void parse_instance_variables (gst_parser *p,
-      OOP classOOP);
+      OOP classOOP,
+      mst_Boolean extend);
 
 static void parse_method_list (gst_parser *p);
 static void parse_method (gst_parser *p,
@@ -515,7 +517,7 @@ parse_scoped_definition (gst_parser *p,
   if (IS_NIL (classOOP))
     _gst_had_error = true;
   else
-    return parse_class_definition (p, classOOP);  
+    return parse_class_definition (p, classOOP, false);  
  }
     }
 
@@ -547,7 +549,7 @@ parse_scoped_definition (gst_parser *p,
     _gst_msg_sendf (NULL, "%v %o current: %o",
     _gst_namespace_class, namespace_new);
   
-  ret_value = parse_class_definition (p, classOrMetaclassOOP);
+  ret_value = parse_class_definition (p, classOrMetaclassOOP, true);
 
   if (namespace_new != namespace_old)
     _gst_msg_sendf (NULL, "%v %o current: %o",
@@ -617,9 +619,10 @@ parse_namespace_definition (gst_parser *
 }
 
 static mst_Boolean
-parse_class_definition (gst_parser *p, OOP classOOP)
+parse_class_definition (gst_parser *p, OOP classOOP, mst_Boolean extend)
 {
   int t1, t2, t3;
+  mst_Boolean add_inst_vars = extend;
 
   for (;;)
     {
@@ -802,7 +805,7 @@ parse_class_definition (gst_parser *p, O
   else
     {
       lex_consume (p, 3);
-      parse_class_definition (p, OOP_CLASS (classOOP));
+      parse_class_definition (p, OOP_CLASS (classOOP), extend);
       lex_skip_mandatory (p, ']');
     }
   continue;
@@ -826,7 +829,8 @@ parse_class_definition (gst_parser *p, O
 #if 0
   printf ("parse instance variables\n");
 #endif
-  parse_instance_variables (p, classOOP);
+  parse_instance_variables (p, classOOP, add_inst_vars);
+  add_inst_vars = true;
   continue;
  }
       else if (t3 == '[')
@@ -1008,11 +1012,24 @@ parse_namespace (tree_node list)
    | empty */
 
 static void
-parse_instance_variables (gst_parser *p, OOP classOOP)
+parse_instance_variables (gst_parser *p, OOP classOOP, mst_Boolean extend)
 {
   char *vars;
   Filament *fil = filnew (NULL, 0);
   
+  if (extend)
+    {
+      gst_behavior class = (gst_behavior) OOP_TO_OBJ (classOOP);
+      OOP *instVars = OOP_TO_OBJ (class->instanceVariables)->data;
+      int n = NUM_INDEXABLE_FIELDS (class->instanceVariables);
+      for (; n--; instVars++)
+ {
+  char *s = _gst_to_cstring (*instVars);
+          filprintf (fil, "%s ", s);
+  xfree (s);
+ }
+    }
+
   lex_skip_mandatory (p, '|');
   while (!lex_skip_if (p, '|', true))
     {




_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk