[comp.lang.c++] Trueeeee OOP using plain C part2

mist@wmt.UUCP (Michiel Steltman) (02/15/90)

Again, after the posting on CO2 two weeks ago, I post this (long) reply on
request of a friend who has no access to usenet facilities.
So, please, respond to him directly:

pkr@media01.uucp ,  uunet!hp4nl!media01!pkr

###############################################################

Dear readers
The posting about CO2 of 2 weeks ago raised some
questions that I would like to answer with this posting.

>That looks pretty hot, but is it "CO2" or "Co2"?
>James "Greenhouse" Salsman

The name is derived from C Object Oriented,
and is thus CO2. If you could see my original Macintosh
derived file, you could also see the subscript. Unfortunately
subscripts are a luxury in most computer systems. About
the greenhouse effect, I can assure you that it is very hot, but
of the kind which does not harm the environment.

>Organization: Gore Enterprises

>CO2 looks interesting, but I don't see any major differences between it and
>Objective C.  For example:
>
>> Objective C solves some of the problems but has the drawback
>> that it is not available on all computers and needs special
>> pre-processing.
>
>I suppose "special pre-processing" means compiling those parts of a
>program that are in the Objective C language but not in the C language into
>C code.  For instance, converting
>	[rectangle moveBy:1.0 :2.0]
>into something like
>	_msg(rectangle, "moveBy::", 1.0, 2.0)
>and so on.
>
>If that's what was meant, that's certainly true---Objective C is a
>different language than C, you can't just run an Objective C program
>through a C compiler.  But:
>
>> How is this CO2 used?  It is very easy to use Co2, it is just
>> like normal C and it consists of standard libraries with
>> methods and a program called SYNTOR.
>
>Doesn't Syntor also perform "special pre-processing" on a CO2 program?
>So, what exactly are the fundamental differences between CO2 and Objective C?
>
>Jacob Gore

As I told in my message about CO2, there are not
many differences between CO2 & Objective-C. But there
is one very important difference, which is that
the sources are NOT preprocessed. You can use any
C-source and compile and link it in any CO2
application, I will try to explain how we did it by 
showing the activities to create a method in a class.

The main difference with Obj. C is that all the 
definitions are maintained in a separate file (a <app>.s
file). This file is run through Syntor which generates
a <app>.c file that can be processed by any C compiler.
The sources of the Syntor program are standard C again.

If I want to create the message foo(a,b,c) in class
Bar, the I enter the following definition in the .s
file:

>Object::Bar
	{
		data{int	xyz;}
		message	foo;
	};

	Object::Puppet
	{
		data{int	abc;};
		message	foo;
	};

This is translated by Syntor to the following: 
(functionally anyway)

	foo(self)
	{
		tableType t={ 
		Puppet, om_Puppet_foo,
		Bar,	om_Bar_foo };

		dispatch(self, t);
	}

 This means that methods from the same message are
grouped together. In objective C the methods of a class
are grouped together, which explains the need of message
routine.

It is true that you need syntor to preprocess the .s
file into a .c file. But when you are writing the
application code this is rarely needed. It is only
done when messages are added or instance variables are
changed. So the big advantage over Obj. C is that 
turbo-c, quick-c and those other easy to use development
environments with built-in editors can still be used.

        application     definition file
        code   
          +----+             syntor
	+-+--+ |       +----+     +----+
        |    | |       |    |     |    |
        | .c | |       |.s  | ->  |  .c|
        |    +-+       |    |     |    |
	+----+         +----+     +----+
           |                        /
 compiler  +-----------------------+
           |
          +----+ 
	+-+--+ | 
        |    | | 
        | .o | |
        |    +-+
	+----+

 
I hope that this explains your questions. If it is
still not clear, or if you disagree with my arguments,
please let me know.

>From: kumamoto@sj.ate.slb.com  (Danny Kumamoto)
>I'm interested in your CO2.  I don't care for C++ either.
>
>I'm using sort of an oo technique with plain C, but I don't
>like the idea of writing everything from scratch, what is normally
>available in Smalltalk (the latter really spoiled me in what I
>now expect from a programming language).  Sigh.
>Thanks for any info.
>Danny

As I explained in the original story, CO2 is not a 
product. We have used it to develop a page-make up
terminal for the newspaper market. Unfortunately we are
not in the business of selling this kind of software. We
have a debugger, windows system, collections and much
more. 

But only a part of it is documented good enough to
sell. We have therefore taken a part, the basic object
system with: Bags, Sets, Ordered collections, Sorted
collections, Array, Bytecollections, Strings, Dictionary
and some other minor classes, and made a dos-diskette
of it. If this generates enough interest, or if some
componay would like to make it into a product then
we are willing to supply the remainder of the code.

>Peter-
>
>Your scheme for doing object-oriented programming in C is very
>intriguing.  I started to consider how I would implement this and
>reached an impasse.  Can you possibly send me the output from SYNTOR
>on the ACCOUNT.S file you included in your example?
>
>			Thanks,
>			Ralph (attunix.att.com!grk)

The scheme we have been using is intriguing. It uses
a mental switch because the way we have done it is
90 degrees from the smalltalk, C++ and objective C
approach. Smalltalk started by grouping the messsages
into a class

	Class Foo (Anybody knows where Foo comes from?)
	  abc
	  def

	Class Bar
	  abc

To find the correct method for a message Smalltalk looks
into the dictionary of the class of the receiver:

	receiver -> class -> method dictionary
				   |
		     message  ->   +
			           |
				method 

In CO2 which grouped the methods with the same name
and indexed them on class.

	abc
	  Foo	om_Foo_abc
	  Bar	om_Bar_abc

	def
	  Foo	om_Foo_def

The grouping is done by using the C linker. A message
is a procedure. This procedure looks like:

	abc(self)
	{
		tableType t={ 
		Foo om_Foo_abc,
		Bar,om_Bar_abc };

		dispatch(self, t);
	}
	

The dispatch routine looks in the table, locates the
class of self in that table and finds the correct
procedure (method). In real life it is a little bit
more complex because the dispatching is done using a 
packed trie that is optimized with some tricks. This
means that the lookup is done with 2 indexes. This lookup
also handles the super send, does not understand and the
full inheritance. 

The advantage this way are plenty. First a normal C
compiler can be used because a message has become 
a normal procedure call. Second there are much less 
methods per message (CO2) than methods per class.
(Smalltalk).

I have included the sources of Syntor at the end.
These are not the sources of account.s but of a 
comparable program. It put them at the end because
it is pretty much and quite unreadable. I also
included the file syntor.h so that you can translate
the macro's. Goodluck.

>Could Your Please Send me information ,price and availability 
>of CO2 environment
>
>              1) UNIX (?)
> 	       2) DOS  (?)
>Thanks................
>Rodrigo Laurens (Secretary)
  
CO2 is not a standard product, shrinked wrapped and the
like. I have prepared a DOS floppy for the turbo C
compiler that contains the sources of a basic system.
Received: From the interest that this generates depend our action
to make it a full blown product. (I would love to see
it in a shrink wrapped version!). 

About Unix and other environments I can tell you that
we have it running under RMX (one of the best O.S. in the
world), Sun road runner, Macintosh, DOS (turbo-C) and the Watcom
C compiler for the phar lap tools. Portability is very
good because we use a subset of ANSI that is almost
completely compatible with Kernighan  & Ritchie. We
use full prototypes but they can be removed by defining
some macro's.

>In a recent article in comp.lang.c++ I read about
>CO2.  The article mentioned source code availability
>for $50.
>Is this the complete package, or a crippled version
>that demonstrates the system, but is no good for
>real work?
>
>I am very interested in CO2 and would like to try
>porting it to my Amiga.
>
>Please let me know what is included in the distribution.
>Also, please indicate what form of payment is acceptable
>to you.
>

It is not a crippled version. It demonstrates CO2 and
you can use it to build life systems, as I have done many
times. It is no complete product and has no manuals. So
you can get it at your own risk. But the first version
is only available for dos. To obtain the product
you can send a Fax to 

	Mediasystemen
	31-23-315210		(holland)
 
Please put the following words in the Fax

	We hereby ask you to send us a demo
	version of CO2 for dos. We will not use
	anything from this product for resale
	to any other party.

Please specify mastercard number and expiration date
for the $50.


>Is it available for ftp somewhere?  Could it become so?
>How large is it (that is, could it be shar'd and mailed to comp.sources)?
>
>					kipp hickman

Unfortunately we do not have such facilities. But please
refer to the previous question to see how you can 
obtain the demo diskette.

I sure hope that I have answered the questions 
in a way that is understandable. Please realize that
part of this work is hobby for me. As told before 
Mediasystemen  is in the business of selling editorial 
systems and not software. but we think that this
product is so nice that it should be shared by others.

If there are more areas where I have not been clear,
pleas send a mail to me and I will answer it
as soon as possible.

Peter Kriens

pkr@media01.uucp 
Mediasystemen Holland
Postbox 4932
2003 EX Haarlem
31-23-319075
Fax 31-23-315210

For the interested parties here is an output of syntor
and the include file

/*
   CO2 | SYNTOR MEDIASYSTEMEN (c) 1989 
   DATE : Sun Feb  4 07:58:39 1990
*/
#include "syntor.h"
/*     TYPEDEFS FOR CLASSES        */
typedef struct{ unsigned n ;
unsigned capacity ;
unsigned endPos ;
unsigned startPos ;
function sortBlock ;
 } typeSorted;
#define szSorted   sizeof(typeSorted) 
typedef struct{ unsigned n ;
unsigned capacity ;
 } typeObjCol;
#define szObjCol   sizeof(typeObjCol) 
#define szObject   0 
#define szCollect  0 
#define szClass    0 
#define szFactory  0 
typedef struct{ unsigned n ;
unsigned capacity ;
unsigned endPos ;
unsigned startPos ;
 } typeOrdered;
#define szOrdered  sizeof(typeOrdered) 
/**/
/*           PUBLIC TABLE          */
/* ------------------------------- */
/* F   3:                   Sorted */   PUBLIC(Sorted,3)
/* F   5:                   ObjCol */   PUBLIC(ObjCol,5)
/* F   7:                   Object */   PUBLIC(Object,7)
/* F   9:                  Collect */   PUBLIC(Collect,9)
/* F  11:                    Class */   PUBLIC(Class,11)
/* F  13:                  Factory */   PUBLIC(Factory,13)
/* F  15:                  Ordered */   PUBLIC(Ordered,15)
/* F   1:   Integer (dereferenced) */   PUBLIC(Integer,7)
/* C    :            Integer class */   PUBLIC(IntegerClass,6)
/* ------------------------------- */
/**/
/*          OBJECT-TABLE           */
/* ------------------------------- */ otBEGIN( 16)
/*     0: ILLEGAL OBJECT           */   otOBJCT(0,0,0)
/*     1: INTEGER DEREFERENCE      */ , otOBJCT(0,0,0)
/*C    2:                   Sorted */ , otOBJCT( 10, szSorted,      3 )
/*F    3:                   Sorted */ , otOBJCT(  3, szSorted  , 2 )
/*C    4:                   ObjCol */ , otOBJCT( 10, szObjCol,      5 )
/*F    5:                   ObjCol */ , otOBJCT(  5, szObjCol  , 4 )
/*C    6:                   Object */ , otOBJCT( 10, szObject,      7 )
/*F    7:                   Object */ , otOBJCT(  7, szObject  , 6 )
/*C    8:                  Collect */ , otOBJCT( 10, szCollect,      9 )
/*F    9:                  Collect */ , otOBJCT(  9, szCollect , 8 )
/*C   10:                    Class */ , otOBJCT( 10, szClass,     11 )
/*F   11:                    Class */ , otOBJCT( 11, szClass   , 10 )
/*C   12:                  Factory */ , otOBJCT( 10, szFactory,     13 )
/*F   13:                  Factory */ , otOBJCT( 13, szFactory , 12 )
/*C   14:                  Ordered */ , otOBJCT( 10, szOrdered,     15 )
/*F   15:                  Ordered */ , otOBJCT( 15, szOrdered , 14 )
/* ------------------------------- */ otEND(16)
/**/
/*           SUPER-TABLE           */
/* ------------------------------- */ stBEGIN(16)
/*     0: ILLEGAL OBJECT           */   stSUPER(0)
/*     1: INTEGER DEREFERENCE      */ , stSUPER(0)
/* C   2:    Ordered ::     Sorted */ , stSUPER(14)
/* F   3:    Ordered ::     Sorted */ , stSUPER(15)
/* C   4:    Collect ::     ObjCol */ , stSUPER(8)
/* F   5:    Collect ::     ObjCol */ , stSUPER(9)
/* C   6:            ::     Object */ , stSUPER(0)
/* F   7:            ::     Object */ , stSUPER(12)
/* C   8:     Object ::    Collect */ , stSUPER(6)
/* F   9:     Object ::    Collect */ , stSUPER(7)
/* C  10:     Object ::      Class */ , stSUPER(6)
/* F  11:     Object ::      Class */ , stSUPER(7)
/* C  12:      Class ::    Factory */ , stSUPER(10)
/* F  13:      Class ::    Factory */ , stSUPER(11)
/* C  14:     ObjCol ::    Ordered */ , stSUPER(4)
/* F  15:     ObjCol ::    Ordered */ , stSUPER(5)
/* ------------------------------- */ stEND(16)
/**/
/*          MESSAGE TABLE          */
/*                               - */ msEXTRN(om_Ordered_indexOf)
/*      0:                 indexOf */ msBEGIN(indexOf)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(14, om_Ordered_indexOf)
/*      0:                       - */ msEND(2,0,0)
/*                               - */ msEXTRN(om_Ordered_insertAt)
/*      1:                insertAt */ msBEGIN(insertAt)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(14, om_Ordered_insertAt)
/*      1:                       - */ msEND(2,1,1)
/*                               - */ msEXTRN(om_Object_initialize)
/*                               - */ msEXTRN(om_Sorted_initialize)
/*                               - */ msEXTRN(om_ObjCol_initialize)
/*                               - */ msEXTRN(om_Ordered_initialize)
/*      2:              initialize */ msBEGIN(initialize)
/*                               - */   msSTUB(6, om_Object_initialize)
/*                               - */ , msMETHD(2, om_Sorted_initialize)
/*                               - */ , msMETHD(4, om_ObjCol_initialize)
/*                               - */ , msMETHD(14, om_Ordered_initialize)
/*      2:                       - */ msEND(4,2,2)
/*                               - */ msEXTRN(om_Factory_newSize)
/*      3:                 newSize */ msBEGIN(newSize)
/*                               - */   msMETHD(12, om_Factory_newSize)
/*      3:                       - */ msEND(1,3,3)
/*                               - */ msEXTRN(om_Object_swap)
/*      4:                    swap */ msBEGIN(swap)
/*                               - */   msMETHD(6, om_Object_swap)
/*      4:                       - */ msEND(1,4,4)
/*                               - */ msEXTRN(om_Class_factoryOf)
/*      5:               factoryOf */ msBEGIN(factoryOf)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(10, om_Class_factoryOf)
/*      5:                       - */ msEND(2,5,14)
/*                               - */ msEXTRN(om_Factory_new)
/*      6:                     new */ msBEGIN(new)
/*                               - */   msMETHD(12, om_Factory_new)
/*      6:                       - */ msEND(1,6,5)
/*                               - */ msEXTRN(om_Ordered_addLast)
/*      7:                 addLast */ msBEGIN(addLast)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(14, om_Ordered_addLast)
/*      7:                       - */ msEND(2,7,6)
/*                               - */ msEXTRN(om_Ordered_addFirst)
/*      8:                addFirst */ msBEGIN(addFirst)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(14, om_Ordered_addFirst)
/*      8:                       - */ msEND(2,8,8)
/*                               - */ msEXTRN(om_Factory_classOf)
/*      9:                 classOf */ msBEGIN(classOf)
/*                               - */   msMETHD(12, om_Factory_classOf)
/*      9:                       - */ msEND(1,9,7)
/*                               - */ msEXTRN(om_ObjCol_size)
/*     10:                    size */ msBEGIN(size)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(4, om_ObjCol_size)
/*     10:                       - */ msEND(2,10,26)
/*                               - */ msEXTRN(om_Object_eq)
/*     11:                      eq */ msBEGIN(eq)
/*                               - */   msMETHD(6, om_Object_eq)
/*     11:                       - */ msEND(1,11,9)
/*                               - */ msEXTRN(om_Object_next)
/*                               - */ msEXTRN(om_ObjCol_next)
/*                               - */ msEXTRN(om_Ordered_next)
/*     12:                    next */ msBEGIN(next)
/*                               - */   msMETHD(6, om_Object_next)
/*                               - */ , msMETHD(4, om_ObjCol_next)
/*                               - */ , msMETHD(14, om_Ordered_next)
/*     12:                       - */ msEND(3,12,29)
/*                               - */ msEXTRN(om_Sorted_sortFromTo)
/*     13:              sortFromTo */ msBEGIN(sortFromTo)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(2, om_Sorted_sortFromTo)
/*     13:                       - */ msEND(2,13,10)
/*                               - */ msEXTRN(om_Object_reset)
/*     14:                   reset */ msBEGIN(reset)
/*                               - */   msSTUB(6, om_Object_reset)
/*     14:                       - */ msEND(1,14,11)
/*                               - */ msEXTRN(om_Collect_doIt)
/*     15:                    doIt */ msBEGIN(doIt)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(8, om_Collect_doIt)
/*     15:                       - */ msEND(2,15,30)
/*                               - */ msEXTRN(om_Object_doesNotUnderstand)
/*     16:       doesNotUnderstand */ msBEGIN(doesNotUnderstand)
/*                               - */   msMETHD(6, om_Object_doesNotUnderstand)
/*     16:                       - */ msEND(1,16,12)
/*                               - */ msEXTRN(om_Factory_elementSize)
/*                               - */ msEXTRN(of_ObjCol_elementSize)
/*     17:             elementSize */ msBEGIN(elementSize)
/*                               - */   msSTUB(12, om_Factory_elementSize)
/*                               - */ , msMETHD(5, of_ObjCol_elementSize)
/*     17:                       - */ msEND(2,17,32)
/*                               - */ msEXTRN(om_Object_release)
/*     18:                 release */ msBEGIN(release)
/*                               - */   msSTUB(6, om_Object_release)
/*     18:                       - */ msEND(1,18,13)
/*                               - */ msEXTRN(om_Object_dispose)
/*                               - */ msEXTRN(om_Collect_dispose)
/*     19:                 dispose */ msBEGIN(dispose)
/*                               - */   msMETHD(6, om_Object_dispose)
/*                               - */ , msMETHD(8, om_Collect_dispose)
/*     19:                       - */ msEND(2,19,37)
/*                               - */ msEXTRN(om_Object_hash)
/*     20:                    hash */ msBEGIN(hash)
/*                               - */   msMETHD(6, om_Object_hash)
/*     20:                       - */ msEND(1,20,15)
/*                               - */ msEXTRN(om_Object_error)
/*     21:                   error */ msBEGIN(error)
/*                               - */   msMETHD(6, om_Object_error)
/*     21:                       - */ msEND(1,21,16)
/*                               - */ msEXTRN(om_Collect_grow)
/*     22:                    grow */ msBEGIN(grow)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(8, om_Collect_grow)
/*     22:                       - */ msEND(2,22,44)
/*                               - */ msEXTRN(om_Sorted_add)
/*                               - */ msEXTRN(om_Ordered_add)
/*     23:                     add */ msBEGIN(add)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(2, om_Sorted_add)
/*                               - */ , msMETHD(14, om_Ordered_add)
/*     23:                       - */ msEND(3,23,40)
/*                               - */ msEXTRN(om_Object_species)
/*     24:                 species */ msBEGIN(species)
/*                               - */   msMETHD(6, om_Object_species)
/*     24:                       - */ msEND(1,24,17)
/*                               - */ msEXTRN(om_Ordered_addBefore)
/*     25:               addBefore */ msBEGIN(addBefore)
/*                                 */  msNOIMPLM()
/*                               - */ , msMETHD(14, om_Ordered_addBefore)
/*     25:                       - */ msEND(2,25,47)

/**/
/* --------------------------------- */
/* Use  8 bit table                  */ tr8()
/* --------------------------------- */
/*                                   */ trSTART(62)
/*  _                               0 */   trEMPTY(0,0)
/*  _                               1 */ , trEMPTY(0,0)
/* om Ordered indexOf               2 */ , trMETHOD(2,1)
/* om Ordered insertAt              3 */ , trMETHOD(2,1)
/* om Sorted  initialize            4 */ , trMETHOD(2,1)
/*  _                               5 */ , trEMPTY(0,0)
/* om ObjCol  initialize            6 */ , trMETHOD(4,2)
/*  _                               7 */ , trEMPTY(0,0)
/* om Ordered addLast               8 */ , trMETHOD(2,1)
/*  _                               9 */ , trEMPTY(0,0)
/* om Ordered addFirst             10 */ , trMETHOD(2,1)
/*  _                              11 */ , trEMPTY(0,0)
/* om Sorted  sortFromTo           12 */ , trMETHOD(2,1)
/*  _                              13 */ , trEMPTY(0,0)
/* om Ordered indexOf              14 */ , trMETHOD(14,1)
/* om Ordered insertAt             15 */ , trMETHOD(14,1)
/* om Ordered initialize           16 */ , trMETHOD(14,3)
/* om Class   factoryOf            17 */ , trMETHOD(3,1)
/*  _                              18 */ , trEMPTY(0,0)
/* om Class   factoryOf            19 */ , trMETHOD(5,1)
/* om Ordered addLast              20 */ , trMETHOD(14,1)
/* om Class   factoryOf            21 */ , trMETHOD(7,1)
/* om Ordered addFirst             22 */ , trMETHOD(14,1)
/* om Class   factoryOf            23 */ , trMETHOD(9,1)
/* om Class   factoryOf            24 */ , trMETHOD(10,1)
/* om Class   factoryOf            25 */ , trMETHOD(11,1)
/* om Class   factoryOf            26 */ , trMETHOD(12,1)
/* om Class   factoryOf            27 */ , trMETHOD(13,1)
/* om ObjCol  size                 28 */ , trMETHOD(2,1)
/* om Class   factoryOf            29 */ , trMETHOD(15,1)
/* om ObjCol  size                 30 */ , trMETHOD(4,1)
/* om Ordered next                 31 */ , trMETHOD(2,2)
/* om Collect doIt                 32 */ , trMETHOD(2,1)
/* om ObjCol  next                 33 */ , trMETHOD(4,1)
/* om Collect doIt                 34 */ , trMETHOD(4,1)
/* of ObjCol  elementSize          35 */ , trMETHOD(3,1)
/*  _                              36 */ , trEMPTY(0,0)
/* of ObjCol  elementSize          37 */ , trMETHOD(5,1)
/* om Collect doIt                 38 */ , trMETHOD(8,1)
/* om Collect dispose              39 */ , trMETHOD(2,1)
/* om ObjCol  size                 40 */ , trMETHOD(14,1)
/* om Collect dispose              41 */ , trMETHOD(4,1)
/* om Sorted  add                  42 */ , trMETHOD(2,1)
/* om Ordered next                 43 */ , trMETHOD(14,2)
/* om Collect doIt                 44 */ , trMETHOD(14,1)
/* om Collect dispose              45 */ , trMETHOD(8,1)
/* om Collect grow                 46 */ , trMETHOD(2,1)
/* of ObjCol  elementSize          47 */ , trMETHOD(15,1)
/* om Collect grow                 48 */ , trMETHOD(4,1)
/* om Ordered addBefore            49 */ , trMETHOD(2,1)
/*  _                              50 */ , trEMPTY(0,0)
/* om Collect dispose              51 */ , trMETHOD(14,1)
/* om Collect grow                 52 */ , trMETHOD(8,1)
/*  _                              53 */ , trEMPTY(0,0)
/* om Ordered add                  54 */ , trMETHOD(14,2)
/*  _                              55 */ , trEMPTY(0,0)
/*  _                              56 */ , trEMPTY(0,0)
/*  _                              57 */ , trEMPTY(0,0)
/* om Collect grow                 58 */ , trMETHOD(14,1)
/*  _                              59 */ , trEMPTY(0,0)
/*  _                              60 */ , trEMPTY(0,0)
/* om Ordered addBefore            61 */ , trMETHOD(14,1)
/*                                 - */ trEND()
/**/
/*          INITIAL PROCS          */
/* ------------------------------- */
/* ------------------------------- */ inBEGIN()
/* ------------------------------- */ inEND()
/**/
/*             SETTINGS            */
/* ------------------------------- */
/* objtable grow increment         */ INCREMENT(250)
/* Exception handler               */ EXCEPTION(doNothing)

#include "syntor.h"

The file syntor.h:

/* V1.4 */
#ifdef SYNTORFIRST
oj_tableType * oj_table = oj_startTable;
unsigned oj_count;
unsigned oj_free;

#else

#include "co2.h"
#include "point.h"

extern void doNothing();
extern void noMethod();

void (*oj_jump)();

typedef struct { char * method; } tT;
typedef struct { unsigned class:11; unsigned index:5; } trieRecord;

#define otBEGIN(l)        oj_tableType oj_startTable[ l ] = {
#define otOBJCT(cl,sz,p)  sz, cl, (char *) p
#define otEND(l)          }; unsigned oj_length = l;

#define stBEGIN(l)        object oj_super[ l + 1 ] = {
#define stSUPER(nr)       nr
#define stEND(l)          };

#define msEXTRN(name)     extern void name();
#define msBEGIN(name)     void name(self){static tT t[]={
#define msMETHD(id,name)  (char *)name
#define msSTUB(id,name)   (char *)doNothing
#define msEND(nr,seq,stat) }; (*oj_jump)(self,t,stat ); }
#define msNOIMPLM()        (char *) noMethod

#define tr8()
#define tr16()

#define trSTART(s)        trieRecord Trie[s] = {
#define trEMPTY(n,a)      0,0
#define trMETHOD(n,a)     n,a
#define trSTUB(n,a)       n,a
#define trEND()           };


#define inEXTRN(name)     extern void name();
#define inBEGIN()         void oj_initial() {
#define inPROCE(name)     name();
#define inEND()           }

#define PUBLIC(name,val)  object name = val;

#define INCREMENT(v)      unsigned oj_incr = v;
#define EXCEPTION(v)      extern void v(); char *exceptionHandler=(char *) v;

#define SYNTORFIRST       1

#endif

=======

-- 
Michiel Steltman            hp4nl!wmt!mist      +-----------------------------+
Westmount Technology B.V.                       | Phone:        +31 15 610815 |
Poortweg 8, 2612 PA Delft                       | Fax:          +31 15 565701 |
The Netherlands                                 +-----------------------------+