NAME
Code::Class::C - Perl extension for creating ANSI C code from a set of class definitions to accomplish an object-oriented programming style.
SYNOPSIS
use Code::Class::C;
my $gen = Code::Class::C->new();
$gen->class('Shape',
subs => {
'getLargest(s:Shape):Shape' => 'c/Shape.getLargest.c',
'calcArea():float' => q{
return 0.0;
},
},
);
$gen->class('Circle',
isa => ['Shape'],
attr => {
'radius' => 'float',
},
subs => {
'calcArea():float' => q{
return 3.1415 * getRadius(self) * getRadius(self);
},
},
);
DESCRIPTION
This module lets you define a set of classes (consisting of attributes and methods) and then convert these definitions to ANSI C code. The module creates all the object oriented abstractions so that the application logic can be programmed in an object oriented fashion (create instances of classes, access attributes, destroy instances, method dispatch etc.).
Constructor
new()
my $gen = Code::Class::C->new();
The constructor of Code::Class::C takes no arguments and returns a new generator instance with the following methods.
Methods
class( name, options )
The class() method lets you define a new class:
$gen->class('Circle',
isa => ['Shape'],
attr => {
'radius' => 'float',
},
subs => {
'calcArea():float' => q{
return 3.1415 * getRadius(self) * getRadius(self);
},
},
);
The class() method takes as first argument the name of the class. The name has to start with a capitol letter and may be followed by an arbitrary amount of letters, numbers or underscore (to be compatible with the ANSI C standard).
The special class name Object is not allowed as a classname. A classname must not be longer than 256 characters.
After the first argument the optional parameters follow in any order:
isa => Arrayref of classnames
The isa
option lets you specify zero or more parent classes of the class that is to be defined.
attr => Hashref of attributes
The attr
option lets you define the attributes of the class that is to be defined.
The hash key is the name of the attribute (starting with a small letter and followed by zero or more letters, numbers or underscore; note: attribute names are case-insensitive).
The hash value is the C-type of the attribute. Here you can use basic C types OR class names (because each class becomes available as a native C type when the C code is generated).
subs => Hashref of methods
The subs
option lets you define the methods of the class that is to be defined.
The hash key is the signature of the method, e.g.
calcArea(float x, MyClass y):int
The hash value is the C sourcecode of the method (s.b. for details). The hash value can optionally be a filename. In this case, the file's content is used as the method's body.
attr( classname, attribute-name, attribute-type )
Defines an attribute in a class with the given name and type.
$gen->attr('Shape','width','float');
meth( classname, method-signature, c-code )
Defines a method in a class of the given signature using the given piece of C code (or filename).
$gen->meth('Shape','calcArea():float','...');
parent( classname, parent-classname, ... )
Defines the parent class(es) of a given class.
$gen->parent('Shape','BaseClass1','BaseClass2');
readFile( filename )
readFile() takes one argument, a filename, loads this file and extracts class, attribute and method definitions from it.
$gen->readFile('c/Triangle.c');
Here is an example file:
//------------------------------------------------------------------------------
@class Triangle: Shape, Rectangle
//------------------------------------------------------------------------------
@attr prop:int
//------------------------------------------------------------------------------
// calculates the area of the triangle
//
@sub calcArea():float
return self->width * self->height;
//------------------------------------------------------------------------------
// calculates the length of the outline of the triangle
//
@sub calcOutline():float
return getWidth(self) * 2 + getHeight(self) * 2;
A line starting with '//' is ignored. A line that starts with an '@' is treated as a class or attribute definition line or as the start of a method definition. I hope this is self-explanatory?
Such files can be saved with an ".c" extension so that you can open them in your favourite C code editor and have fun with the highlighting.
func( signature, c-code-or-filename )
The func() method defines a normal C function. It takes as parameters the signature of the function and the code (which can be a code string or a filename):
$gen->func('doth(float f, Shape s):int', '/* do sth... */');
generate( options )
$gen->generate(
file => './main.c',
headers => ['stdio','opengl'],
main => 'c/main.c',
top => 'c/top.c',
bottom => 'c/bottom.c',
);
The generate() method generates a single ANSI C compliant source file out of the given class definitions.
The options are:
file => filename
This defines the name of the C output file. This option is mandatory.
headers => Arrayref of headernames
This defines C headers that are to be included in the generated C file.
main => Source or filename of main function body
This defines the body (C code) of the main function of the generated C file. This can be either C code given as a string OR a filename which is loaded.
top => Source or filename of C code
This method adds arbitrary C code to the generated C file. The code is added after the class structs/typedefs and before the method (function) declarations.
bottom => Source or filename of C code
This method adds arbitrary C code to the generated C file. The code is added to the end of the file, but before the main function.
toDot()
This method generates a Graphviz *.dot string out of the class hierarchy and additional information (attributes, methods). The dot string is returned.
toHtml()
This method creates a HTML API documentation to the class hierarchy that is defined. The HTML string is returned.
Object oriented features & C programming style
Throughout this document the style of programming that module lets the programmer use, is called object oriented, but this is just the canonical name, actually it is class oriented programming.
So you have defined a bunch of classes with attributes and methods. But how do you program the method logic in C? This module promises to make it possible to do this in an object-oriented fashion, so this is the section where this fashion is described.
For a more complete example, see the t/ directory in the module dictribution.
Class definition
This module lets you define classes and their methods and attributes. Class definition is not possible from within the C code.
Instanciation
Arbitrary instances of classes can be created from within the C code.
Suppose you defined a class named 'Circle'. You can then create an instance of that class like so (C code):
Object c = new_Circle();
Important: All class instances in C are of the type "Object"!
Instance destruction
Since there is a way to create instances, there is also a way to destroy them (free the memory they occupy).
A generic C function delete() is generated which can be used to destruct any object/instance:
Object c = new_Circle();
delete(c); // c now points to NULL
Inheritance
A class inherits all attributes and methods from its parent class or classes. So multiple inheritance (multiple parent classes) is allowed.
Attribute access
Suppose you defined a class named 'Circle' with an attribute (could also be inherited). Then you can access this attribute the following:
float r;
Object c = new_Circle();
r = getRadius(c);
setRadius(c, 42.0);
As you can see, all methods (either getter or setter or other ones) need to get the object/instance as first parameter. This "self" parameter need not be written when defining the method, remember to define a method, only the addtional parameters are to be written:
calcArea(int param):float
Remember: Always access the instance/object attributes via the getter or setter methods!.
Attribute overloading
Attributes once defined, must not be re-defined by child classes.
Method invocation
To invoke a method on an object/instance:
Object c = new_Circle();
printf("area = %f\n", calcArea(c));
The first argument of the method call is the object/instance the method is invoked on.
Method overloading
Methods once defined, can be overloaded by methods of the same class. Methods in a class can also be re-defined by child classes.
If a child class overwrites the method of one of its parent classes, the signatures must be the same, regarding the non-class typed parameters.
To illustrate this, here is an example of a parent class method signature: doSth(Shape s, float f):void
- the first parameter is an object of class 'Shape', the second a native C float.
Suppose another classes tries to overwrite this method. In this case the first parameter's type is allowed to change (to any other class type!), but the second not, because its a native type. This will work: doSth(Circle s, float f):void
but this not: doSth(int s, float f):void
Access "self" from within methods
When writing methods you need access to the object instance. This variable is "magically" available and is named "self". Here is an example of a method body:
printf("radius of instance is %f\n", getRadius(self));
Default attributes
The following attributes are present in all classes. These attributes differ compared to user-defined attributes in the way that they can be accessed directly by dereferencing the instance/object pointer:
int classid
Each class has a globally unique ID, a positive number greater than zero.
Object c = new_Circle();
printf("c.classid = %d\n", c->classid);
char* classname
This is the name of the class of the object/instance. To access the classname, use accessor methods like for all other attributes, e.g.:
Object c = new_Circle();
printf("c.classname = %s\n", c->classname);
Beware, that, when you change the classname at runtime, methods may not be able to determine the actual implementation of a method to be applied to an object/instance.
LIMITATIONS & BUGS
This module is an early stage of development and has therefor some limitations and bugs. If you think, this module needs a certain feature, I would be glad to hear from you, also, if you find a bug, I would be glad to hear from you.
EXPORT
None by default.
SEE ALSO
Please send any hints on other modules trying to accomplish the same or a similar thing. I haven't found one, yet.
AUTHOR
Tom Kirchner, <tom@tomkirchner.com>
COPYRIGHT AND LICENSE
Copyright (C) 2011 by Tom Kirchner
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available.