Object Layer
The Object Layer implements the containers for So-o classes and instances and all the functions needed by the Object class.
The data types are defined in the file OL.h. All the code is in the file OL.c.
- #include "list.h"
- #include "alist.h"
So-o uses simple lists and associative lists.
The files list.h and alist.h declare the data types list
and alist
and the functions to manage them.
The code is in the files list.c and alist.c.
It's compiled in the library libso-o.a.
- typedef char *property;
- typedef char *message;
- typedef union _value {
- int i;
- long l;
- float f;
- double d;
- void *p;
- } value;
- typedef value (*method)();
- #define METHOD(f) (value (*)())f
- typedef struct _selector {
- message msg;
- method func;
- } selector;
- typedef struct _attribute {
- property name;
- value value;
- } attribute;
A property or a message is a character string terminated by a '\0'
.
The data type value
is a union which is used to contain all the different values a method can return.
Sending a message always returns a type value
.
To assign the value returned by a message or pass it to another function, access the appropriate member of the union.
A method is a pointer to a function with a return type value
.
The macron METHOD is used to cast a function which implements a message.
A selector associates a message to a method. An attribute is a property with a value.
- #define CLASS 'C'
- #define INSTANCE 'I'
- typedef struct _class {
- char type;
- const char *name;
- unsigned int revision;
- struct _class *superclass;
- list c_properties;
- list i_properties;
- alist c_messages;
- alist i_messages;
- alist attributes;
- } *class;
- typedef struct _instance {
- char type;
- class class;
- alist attributes;
- } *instance;
A class has a name and a revision number. It inherits its behavior from a superclass, except the Object class. It has properties. It implements class messages. The instances of a class have properties. They implement instance messages. The properties of a class which have a value are its attributes.
An instance belongs to a class. The properties of an instance which have a value are its attributes.
The field type
is used by the interface to determine whether the object which receives a message is a class or an instance.
A class has the type CLASS
. An instance has the type INSTANCE
.
The Object class is the only class with a NULL
superclass.
All the other classes inherit, at least, from the class Object.
All lists can be NULL
.
The rest of the file OL.h declares all the functions of the Object Layer.
The functions which start with class_
deal with a class.
The functions which start with object_
deal with an instance.
IMPORTANT: In principle, all the functions of the Object Layer are private. Only the functions of the class Object and the functions of the interface of So-o can call them.
- #define CNAMEMAXLEN 64
- #define CNAMEREGEXP "^[:alpha:]?[[:alnum:]_-]{0,62}[:alnum:]?$"
CNAMEMAXLEN
specifies the maximum length of a class name.
CNAMEREGEXP
defines the regular expression used to validate a class name.
- class class_alloc( void ) {
- return (class)calloc( 1, sizeof ( struct _class ));
- }
class_alloc
allocates the space necessary to hold a class and returns it.
- class class_init( class self, const char *cname, class superclass, unsigned int rev, property *c_props, property *i_props, selector *c_msgs, selector *i_msgs ) {
- static regex_t regexp;
- regcomp(®exp, CNAMEREGEXP, REG_EXTENDED | REG_NOSUB);
- if ( regexec(®exp, cname, 0, 0, 0) != 0 )
- return 0;
- extern class Object;
- self->type = CLASS;
- self->name = cname;
- self->revision = rev;
- self->superclass = strcmp("Object", cname) != 0 ? (superclass ? superclass : Object) : 0;
- if ( c_msgs )
- class_set_class_messages(self, c_msgs);
- if ( i_msgs )
- class_set_instance_messages(self, i_msgs);
- if ( c_props )
- class_set_class_properties(self, c_props);
- if ( i_props )
- class_set_instance_properties(self, i_props);
- return self;
- }
class_init
initializes the definition of the class self
.
name
speficies the name of the class. name
is validated with the regular expression CNAMEREGEXP
.
superclass
is the global reference of the superclass of the new class.
If superclass
is 0
, the new class inherits by default from the Object class defined by the global variable Object
.
IMPORTANT: superclass
must contain the address of the definiton of a constructed class.
rev
gives the revision number of the class. rev
is an int
> 0 which can be used to differentiate successive versions of the class.
class_properties
and instance_properties
list the properties of the class and instances of the class.
A property is a string terminated by a '\0'
.
A list of properties is an array terminated by a NULL
pointer.
A NULL
array defines an empty list.
class_messages
and instance_messages
are associative lists of messages and methods of the class and instances of the class.
A message is a string terminated by a '\0'
.
A method is a function pointer cast with the macro METHOD
defined in OL.h.
A selector associates a method to a message.
A list of messages and methods is an array terminated by two NULL
pointers.
A NULL
array defines an empty list.
- class class_new( const char *name, class superclass, unsigned revision, property *class_properties, property *instance_properties, selector *class_messages, selector *instance_messages ) {
- return class_init( class_alloc(), name, superclass, revision, class_properties, instance_properties, class_messages, instance_messages );
- }
class_new
allocates the space necessary for the definition of a class, initializes it and returns it.
- void class_free( class self ) {
- if (self->c_properties)
- list_free( self->c_properties );
- if (self->i_properties)
- list_free( self->i_properties );
- if (self->c_messages)
- alist_free( self->c_messages );
- if (self->i_messages)
- alist_free( self->i_messages );
- if (self->attributes)
- alist_free( self->attributes );
- free( self );
- }
class_free
frees the space allocated by self
,
i.e. all the lists allocated by the class and the container of the class.
IMPORTANT: class_free
doesn't free the space which might be allocated for the values of the attributes of the class.
- char *class_tostring( class self ) {
- static char s[CNAMEMAXLEN+7+1];
- sprintf(s, "class(%s)", self->name);
- return s;
- }
class_tostring
returns a string representation of self
, i.e. the word class
followed by the name of the class between parenthesis.
IMPORTANT: The string is formatted in a static area. It must be used before this method is called again.
- instance class_make(class self) {
- return object_new( self );
- }
class_make
returns of new instance of self
.
- instance object_alloc( void ) {
- return (instance)calloc( 1, sizeof ( struct _instance ));
- }
object_alloc
allocates the space necessary to hold an instance and returns it.
- instance object_init( instance self, class c ) {
- self->type = INSTANCE;
- self->class = c;
- return self;
- }
object_init
initializes the definition of the instance self
.
c
is the global reference of the class of self
.
- instance object_new( class c ) {
- return object_init(object_alloc(), c);
- }
object_new
allocates the space necessary for the definition of an instance, initializes it and returns it.
- void object_free( instance self ) {
- if (self->attributes)
- alist_free( self->attributes );
- free( self );
- }
object_free
frees the space allocated by self
,
i.e. the list of attributes allocated by the instance and the container of the instance.
IMPORTANT: object_free
doesn't free the space which might be allocated for the values of the attributes of the instance.
- instance object_copy(instance self) {
- instance newself = object_new(object_class(self));
- if (self->attributes)
- newself->attributes = alist_copy(self->attributes);
- return newself;
- }
object_copy
returns a copy of self
.
IMPORTANT: object_copy
doesn't duplicate the space which might be allocated for the values of the attributes of the instance; self
and its copy have independent lists of attributes which share the same values.
- char *object_tostring( instance self ) {
- static char s[CNAMEMAXLEN+8+1];
- sprintf(s, "object(%s)", self->class->name);
- return s;
- }
object_tostring
returns a string representation of self
, i.e. the word object
followed by the name of the instance between parenthesis.
IMPORTANT: The string is formatted in a static area. It must be used before this method is called again.
The rest of the code implements all the functions of the Object Layer which are needed by the Object class.
- class_name
- Returns the name of a class.
- class_revision
- Returns the revision number of a class.
- class_superclass
- Returns the superclass of a class.
- class_class_properties
- Returns the class properties defined by a class.
- class_instance_properties
- Returns the instance properties defined by a class.
- class_class_messages
- Returns the class messages defined by a class.
- class_instance_messages
- Returns the instance messages defined by a class.
- class_set_class_properties
- Initializes the class properties of a class.
- class_set_instance_properties
- Initializes the instance properties of a class.
- class_set_class_messages
- Initializes the class messages of a class.
- class_set_instance_messages
- Initializes the instance messages of a class.
- class_add_class_message
- Adds a class message to a class.
- class_remove_class_message
- Removes a class message from a class.
- class_add_instance_message
- Adds an instance message to a class.
- class_remove_instance_message
- Removes an instance message from a class.
- class_add_class_property
- Adds a class property to a class.
- class_remove_class_property
- Removes a class property from a class.
- class_add_instance_property
- Adds an instance property to a class.
- class_remove_instance_property
- Removes an instance property from a class.
- class_attributes
- Returns the values of the properties of a class.
- class_set_attributes
- Initializes the values of the properties of a class.
- class_is_kind_of
- Checks if a class is a subclass of another class.
- class_get
- Returns the value of a property of a class.
- class_set
- Modifies the value of a property of a class.
- object_class
- Returns the class of an instance.
- object_superclass
- Returns the superclass of an instance.
- object_assume
- Changes the class of an instance.
- object_attributes
- Returns the values of the properties of an instance.
- object_set_attributes
- Initializes the values of the properties of an instance.
- object_get
- Returns the value of a property of an instance.
- object_set
- Initializes the value of a property of an instance.
- class_find_class_property
- Checks if a class property of a class exists.
- class_find_instance_property
- Checks if an instance property of a class exists.
- class_find_class_method_class
- Returns the class which implements a class message.
- class_find_class_method
- Returns the function which implements a class message.
- class_find_instance_method_class
- Returns the class which implements an instance message.
- class_find_instance_method
- Returns the function which implements an instance message.
- class_send_message
- Executes a class message.
- class_super_send_message
- Executes a class message inherited from a superclass.
- object_send_message
- Executes an instance message.
- object_super_send_message
- Executes an instance message inherited from a superclass.
Comments