DragonFly On-Line Manual Pages
critcl::class(n) C Runtime In Tcl (CriTcl) critcl::class(n)
______________________________________________________________________________
NAME
critcl::class - CriTcl Utilities: C Classes
SYNOPSIS
package require Tcl 8.4
package require critcl ?3.1.6?
package require critcl::class ?1.0.6?
::critcl::class::define name script
include path
support code
type name
classconstructor body
classdestructor body
constructor body ?postbody?
destructor body
classvariable ctype name ?comment? ?constructor? ?destructor?
classmethod name command arguments body
classmethod name proc arguments resulttype body
classmethod name as funname ?arg...?
insvariable ctype name ?comment? ?constructor? ?destructor?
method name command arguments body
method name proc arguments resulttype body
method name as funname ?arg...?
method_introspection
______________________________________________________________________________
DESCRIPTION
Welcome to the C Runtime In Tcl, CriTcl for short, a system to build C
extension packages for Tcl on the fly, from C code embedded within Tcl
scripts, for all who wish to make their code go faster.
This document is the reference manpage for the critcl::class package.
This package provides convenience commands for advanced functionality
built on top of the core.
With it a user wishing to create a C level object with class and
instance commands can concentrate on specifying the class- and
instance-variables and -methods in a manner similar to a TclOO class,
while all the necessary boilerplate around it is managed by this
package.
Its intended audience are mainly developers wishing to write Tcl
packages with embedded C code.
This package resides in the Core Package Layer of CriTcl.
+----------------+
|Applications |
| critcl |
| critcl::app |
+----------------+
*================*
|Core Packages |
| critcl |
| critcl::util |
*================*
+----------------+
|Support Packages|
| stubs::* |
| md5, platform |
| ... |
+----------------+
API
::critcl::class::define name script
This is the main command to define a new class name, where name
is the name of the Tcl command representing the class, i.e. the
class command. The script provides the specification of the
class, i.e. information about included headers, class- and
instance variables, class- and instance-methods, etc. See the
section Class Specification API below for the detailed list of
the available commands and their semantics.
CLASS SPECIFICATION API
Here we documents all class specification commands available inside of
the class definition script argument of ::critcl::class::define.
GENERAL CONFIGURATION
include path
This command specifies the path of a header file to include
within the code generated for the class. This is separate from
the support because the generated include directives will be put
at the very beginning of the generated code. This is done to
allow the use of the imported declarations within the instance
type, and elsewhere.
The command can be used multiple times, each adding a header to
include. It is of course possible to not use this command at
all, for classing not making use of external definitions.
The result of the command is the empty string.
support code
This command specifies supporting C code, i.e. any definitions
(types, functions, etc.) needed by the whole class and not
fitting into class- and instance-methods. The code is embedded
at global level, outside of any function or other definition.
The command can be used multiple times, each adding another
segment of C code to insert. It is of course possible to not use
this command at all, for classes not requiring supporting code.
The result of the command is the empty string.
type name
This command specifies the name of an external C type to be used
as the type of the instance structure.
Initialization and release of the structure with the given type
are the responsibility of the user, through constructor and
destructor code fragments.
Attention: Using this command precludes the use of regular
class- and instance variables. It further precludes the use of
method-introspection as well, as this make use of generated
instance-variables.
If class- and/or instance-variable have to be used in
conjunction with an external C type, simply create and use a
class- or instance-variable with that type.
The result of the command is the empty string.
CLASS LIFETIME MANAGEMENT
classconstructor body
This command specifies a C code block surrounding the
initialization of the class variables, i.e. the fields of the
class structure. Note that allocation and release of the class
structure itself is done by the system andf not the
responsibility of the user.
For the initialization (and release) of a class variable it is
recommended to use the constructor and destructor arguments of
the variable's definition (See command classvariable) for this
instead of using a separate classconstructor.
This is an optional command. Using it more than once is allowed
too and each use will add another C code fragment to use during
construction. I.e. multiple calls aggregate.
The C code blocks of multiple calls (including the constructors
of classvariable definitions) are executed in order of
specification.
The result of the command is the empty string.
The C code in body has access to the following environment:
interp Pointer to the Tcl interpreter (Tcl_Interp*) the class
structure will be associated with. It enables the
generation of a Tcl error message should construction
fail.
class Pointer to the class structure to initialize.
error A C code label the constructor can jump to should it have
to signal a construction failure. It is the
responsibility of the constructor to release any
variables already initialized before jumping to this
label. This also why the 'execution in order of
specification' is documented and can be relied on. It
gives us the knowledge which other constructors have
already been run and initialized what other fields.
classdestructor body
This command specifies a C code block surrounding the release of
the class variables, i.e. the fields of the class structure.
Note that allocation and release of the class structure itself
is done by the system and not the responsibility of the user.
For the initialization (and release) of a class variable it is
recommended to use the constructor and destructor arguments of
the variable's definition (See command classvariable) for this
instead of using a separate classconstructor.
This is an optional command. Using it more than once is allowed
too and each use will add another C code fragment to use during
construction. I.e. multiple calls aggregate.
The C code blocks of multiple calls (including the constructors
of class variable definitions) are executed in order of
specification.
The result of the command is the empty string.
The C code in body has access to the same environment as the
class constructor code blocks.
INSTANCE LIFETIME MANAGEMENT
constructor body ?postbody?
This command specifies a C code block surrounding the
initialization of the instance variables, i.e. the fields of the
instance structure. Note that allocation and release of the
instance structure itself is done by the system and not the
responsibility of the user. On the other hand, if an external
type was specified for the instance structure, then instance
variables are not possible, and the system has no knowledge of
the type's structure. In that case it is the responsibility of
the body to allocate and free the structure itself too.
For the initialization (and release) of an instance variable it
is recommended to use the constructor and destructor arguments
of the variable's definition (See command insvariable) for this
instead of using a separate constructor.
This is an optional command. Using it more than once is allowed
too and each use will add another C code fragment to use during
construction. I.e. multiple calls aggregate.
The C code blocks of multiple calls (including the constructors
of instance variable definitions) are executed in order of
specification.
The result of the command is the empty string.
The C code in body has access to the following environment:
interp Pointer to the Tcl interpreter (Tcl_Interp*) the instance
structure will be associated with. It enables the
generation of a Tcl error message should construction
fail.
instance
Pointer to the instance structure to initialize.
error A C code label the constructor can jump to should it have
to signal a construction failure. It is the
responsibility of the constructor to release any
variables already initialized before jumping to this
label. This also why the 'execution in order of
specification' is documented and can be relied on. It
gives us the knowledge which other constructors have
already been run and initialized what other fields.
The C code in postbody is responsible construction action to be done
after the primary construction was done and the Tcl-level instance
command was successfully created. It has access to a slightly different
environment:
interp Pointer to the Tcl interpreter (Tcl_Interp*) the instance
structure will be associated with. It enables the
generation of a Tcl error message should construction
fail.
instance
Pointer to the instance structure to initialize.
cmd The Tcl_Command token of the Tcl-level instance command.
fqn The fully qualified name of the instance command, stored
in a Tcl_Obj*.
destructor body
This command specifies a C code block surrounding the release of
the instance variables, i.e. the fields of the instance
structure. Note that allocation and release of the instance
structure itself is done by the system and not the
responsibility of the user. On the other hand, if an external
type was specified for the instance structure, then instance
variables are not possible, and the system has no knowledge of
the type's structure. In that case it is the responsibility of
the body to allocate and free the structure itself too.
For the initialization (and release) of an instance variable it
is recommended to use the constructor and destructor arguments
of the variable's definition (See command insvariable) for this
instead of using a separate constructor.
This is an optional command. Using it more than once is allowed
too and each use will add another C code fragment to use during
construction. I.e. multiple calls aggregate.
The C code blocks of multiple calls (including the constructors
of instance variable definitions) are executed in order of
specification.
The result of the command is the empty string.
The C code in body has access to the following environment:
instance
Pointer to the instance structure to release.
CLASS VARIABLES AND METHODS
classvariable ctype name ?comment? ?constructor? ?destructor?
This command specifies a field in the class structure of the
class. Multiple fields can be specified, and are saved in the
order specified.
Attention: Specification of a class variable precludes the use
of an external C type for the instance structure.
Attention: Specification of a class variable automatically
causes the definition of an instance variable named class,
pointing to the class structure.
Beyond the basic name and C type of the new variable the
definition may also contain a comment describing it, and C code
blocks to initialize and release the variable. These are
effectively local forms of the commands classconstructor and
classdestructor. Please read their descriptions for details
regarding the C environment available to the code.
The comment, if specified will be embedded into the generated C
code for easier cross-referencing from generated ".c" file to
class specification.
classmethod name command arguments body
This command specifies a class method and the C code block
implementing its functionality. This is the first of three
forms. The method is specified like a critcl::ccommand, with a
fixed set of C-level arguments. The body has to perform
everything (i.e. argument extraction, checking, result return,
and of course the actual functionality) by itself.
For this the body has access to
class Pointer to the class structure.
interp Pointer to the Tcl interpreter (Tcl_Interp*) the class
structure is associated with
objc The number of method arguments.
objv The method arguments, as C array of Tcl_Obj pointers.
The arguments of the definition are only a human readable form
of the method arguments and syntax and are not used in the C
code, except as comments put into the generated code. Again, it
is the responsibility of the body to check the number of
arguments, extract them, check their types, etc.
classmethod name proc arguments resulttype body
This command specifies a class method and the C code block
implementing its functionality. This is the second of three
forms. The method is specified like a critcl::cproc. Contrary
to the first variant here the arguments are computer readable,
expected to be in the same format as the arguments of
critcl::cproc. The same is true for the resulttype. The system
automatically generates a wrapper doing argument checking and
conversion, and result conversion, like for critcl::cproc.
The body has access to
class Pointer to the class structure.
interp Pointer to the Tcl interpreter (Tcl_Interp*) the class
structure is associated with
... All arguments under their specified names and C types as
per their definition.
classmethod name as funname ?arg...?
This command specifies a class method and the C code block
implementing its functionality. This is the third and last of
three forms.
The class method is implemented by the external function
funname, i.e. a function which is declared outside of the class
code itself, or in a support block.
It is assumed that the first four arguments of that function
represent the parameters
class Pointer to the class structure.
interp Pointer to the Tcl interpreter (Tcl_Interp*) the class
structure is associated with
objc The number of method arguments.
objv The method arguments, as C array of Tcl_Obj pointers.
Any additional arguments specified will be added after these and
are passed into the C code as is, i.e. are considered to be C
expressions.
INSTANCE VARIABLES AND METHODS
insvariable ctype name ?comment? ?constructor? ?destructor?
This command specifies a field in the instance structure of the
class. Multiple fields can be specified, and are saved in the
order specified.
Attention: Specification of an instance variable precludes the
use of an external C type for the instance structure.
Attention: Specification of an instance variable automatically
causes the definition of an instance variable of type
Tcl_Command, and named cmd, holding the token of the instance
command, and the definition of an instance method named destroy.
This implicit instance variable is managed by the system.
Beyond the basic name and C type of the new variable the
definition may also contain a comment describing it, and C code
blocks to initialize and release the variable. These are
effectively local forms of the commands constructor and
destructor. Please read their descriptions for details regarding
the C environment available to the code.
The comment, if specified will be embedded into the generated C
code for easier cross-referencing from generated ".c" file to
class specification.
method name command arguments body
This command specifies an instance method and the C code block
implementing its functionality. This is the first of three
forms. The method is specified like a critcl::ccommand, with a
fixed set of C-level arguments. The body has to perform
everything (i.e. argument extraction, checking, result return,
and of course the actual functionality) by itself.
For this the body has access to
instance
Pointer to the instance structure.
interp Pointer to the Tcl interpreter (Tcl_Interp*) the instance
structure is associated with
objc The number of method arguments.
objv The method arguments, as C array of Tcl_Obj pointers.
The arguments of the definition are only a human readable form
of the method arguments and syntax and are not used in the C
code, except as comments put into the generated code. Again, it
is the responsibility of the body to check the number of
arguments, extract them, check their types, etc.
method name proc arguments resulttype body
This command specifies an instance method and the C code block
implementing its functionality. This is the second of three
forms. The method is specified like a critcl::cproc. Contrary
to the first variant here the arguments are computer readable,
expected to be in the same format as the arguments of
critcl::cproc. The same is true for the resulttype. The system
automatically generates a wrapper doing argument checking and
conversion, and result conversion, like for critcl::cproc.
The body has access to
instance
Pointer to the instance structure.
interp Pointer to the Tcl interpreter (Tcl_Interp*) the instance
structure is associated with
... All arguments under their specified names and C types as
per their definition.
method name as funname ?arg...?
This command specifies an instance method and the C code block
implementing its functionality. This is the third and last of
three forms.
The instance method is implemented by the external function
funname, i.e. a function which is declared outside of the
instance code itself, or in a support block.
It is assumed that the first four arguments of that function
represent the parameters
instance
Pointer to the instance structure.
interp Pointer to the Tcl interpreter (Tcl_Interp*) the instance
structure is associated with
objc The number of method arguments.
objv The method arguments, as C array of Tcl_Obj pointers.
Any additional arguments specified will be added after these and
are passed into the C code as is, i.e. are considered to be C
expressions.
method_introspection
This command generates one class- and one instance-method both
of which will return a list of the instance methods of the
class, and supporting structures, like the function to compute
the information, and a class variable caching it.
The two methods and the class variable are all named methods.
CONTEXT DEPENDENT INTERACTIONS
This section documents the various interactions between the
specification commands. While these are are all documented with the
individual commands here they are pulled together to see at a glance.
[1] If you are using the command type to specify an external C type
to use for the instance structure you are subject to the
following constraints and rules:
[1] You cannot define your own instance variables.
[2] You cannot define your own class variables.
[3] You cannot use method_introspection.
[4] You have to allocate and release the instance structure
on your own, through constructor and destructor code
blocks.
[2] If you declare class variables you are subject to the following
constraints and rules:
[1] You cannot use type.
[2] The system generates an instance variable class for you,
which points from instance to class structure. This makes
you also subject to the rules below, for instance
variables.
[3] If you declare instance variables (possibly automatic, see
above) you are subject to following constraints and rules:
[1] You cannot use type.
[2] The system generates and manages an instance variable cmd
for you, which holds the Tcl_Command token of the
instance command.
[3] The system generates an instance method destroy for you.
[4] The system manages allocation and release of the instance
structure for you. You have to care only about the
instance variables themselves.
EXAMPLE
The example shown below is the specification of queue data structure,
with most of the method implementations and support code omitted to
keep the size down.
The full implementation can be found in the directory "examples/queue"
of the critcl source distribution/repository.
package require Tcl 8.4
package require critcl 3.1
critcl::buildrequirement {
package require critcl::class ; # DSL, easy spec of Tcl class/object commands.
}
critcl::cheaders util.h
critcl::class::define ::queuec {
include util.h
insvariable Tcl_Obj* unget {
List object unget elements
} {
instance->unget = Tcl_NewListObj (0,NULL);
Tcl_IncrRefCount (instance->unget);
} {
Tcl_DecrRefCount (instance->unget);
}
insvariable Tcl_Obj* queue {
List object holding the main queue
} {
instance->queue = Tcl_NewListObj (0,NULL);
Tcl_IncrRefCount (instance->queue);
} {
Tcl_DecrRefCount (instance->queue);
}
insvariable Tcl_Obj* append {
List object holding new elements
} {
instance->append = Tcl_NewListObj (0,NULL);
Tcl_IncrRefCount (instance->append);
} {
Tcl_DecrRefCount (instance->append);
}
insvariable int at {
Index of next element to return from the main queue
} {
instance->at = 0;
}
support {... queue_peekget, queue_size, etc.}
method clear {} {...}
method destroy {...}
method get as queue_peekget 1
method peek as queue_peekget 0
method put {item ...}
method size {} {
if ((objc != 2)) {
Tcl_WrongNumArgs (interp, 2, objv, NULL);
return TCL_ERROR;
}
Tcl_SetObjResult (interp, Tcl_NewIntObj (queue_size (instance, NULL, NULL, NULL)));
return TCL_OK;
}
method unget {item} {...}
}
package provide queuec 1
AUTHORS
Andreas Kupries
BUGS, IDEAS, FEEDBACK
This document, and the package it describes, will undoubtedly contain
bugs and other problems. Please report such at
https://github.com/andreas-kupries/critcl. Please also report any
ideas for enhancements you may have for either package and/or
documentation.
KEYWORDS
C class, C code, C instance, C object, Embedded C Code, code generator,
compile & run, compiler, dynamic code generation, dynamic compilation,
generate package, linker, on demand compilation, on-the-fly compilation
CATEGORY
Glueing/Embedded C code
COPYRIGHT
Copyright (c) 2011-2015 Andreas Kupries
doc 1.0.6 critcl::class(n)