Next: Return values, Previous: Scoping, Up: Methods [Index]
Templates are simplified methods that are defined as macros and written in C. They provide a method-compatible wrapper to C functions.
Template methods can appear in place of C functions in complex
expressions, and they must be used if a C function writes to its
arguments (e.g., like scanf(3) or sscanf(3)). For
example, if we have a template defined for the function
myPrintMsg
, then Ctalk subsitutes the method expression
wherever myPrintMsg
appears in an expression like this one.
if ((myInt = myPrintMsg (someMsg)) != 0) { ... do something... }
After compilation, the expression looks like this.
if ((myInt = CFunction cMyPrintMsg (someMsg)) != 0) { ...
You can also use myPrintMsg
on the left-hand side of an assignment,
like this.
myInt = myPrintMsg (someMsg); -or- self = myPrintMsg (someMsg);
Additionally, you can use templates on their own, by prefacing the method’s name (the template function’s alias) with its class object.
CFuntion myPrintMsg (someMsg);
As the last example implies, templates are class methods in the
pseudo-class CFunction
. Ctalk loads and caches templates where
necessary when compiling the input file, so you won’t see any methods
of the CFunction
class unless the program calls for one or more
of them.
If the template wraps a C function of the same name, then, of course, you can also use the C function on its own. However, templates don’t necessarily need to correspond to a C function; they can provide any set of C expressions with a method compatible interface.
Ctalk defines a number of built-in templates for the standard C
library. You can determine if Ctalk substitutes a template for a C
function by giving the --printtemplates
option to
ctalk
when it compiles a source file. This displays the
templates that the compiler loads and caches (but doesn’t necessarily
send to the output).
You can define templates for application-specific C functions and
routines also. Ctalk retrieves and caches them similarly to its
built-in templates, but they are cataloged and stored separately in
each user’s ~/.ctalk/templates
directory.
As mentioned above, templates don’t need to wrap a function of the
same name as the template. That is, myPrintMsg
, above, does not
have to be an actual function (although you need to prototype it that
way). Templates for C library functions always correspond to an
actual library function. Program specific templates can serve as a
wrapper for any function or set of routines.
When compiling templates, the Ctalk compiler checks the user template registry first. If a user defines a template with the same name as one of Ctalk’s C library templates, then the compiler uses the user’s template instead of Ctalk’s built-in template. That means you can define a template that replaces a C library template.
When creating a template for a function, you need to follow these steps.
OBJECT *myPrintMsg (char *text);
Ctalk uses the prototype’s argument list to check the number and type of arguments. The prototype’s argument list must be the same as the template’s argument list.
myFloat = rand () + 0.33 + (float)my_dbl;
template
command. The following
sections describe the format that templates use.
Templates are basically multiple line macros that provide a method selector and method body in a #define preprocessor statement. When Ctalk finds a function name that has a template defined for it, it subsitutes the template name for the function name in the expression, adds the template’s body to the output, and adds the template to the CFunction classes’ initialization.
Templates can accept arguments similarly to methods, and, like
methods, they return a C OBJECT *
, or NULL.
Here is the template for the myPrintMsg() C function. The
template provides a wrapper for the printf(3) function, and,
like printf(3), returns an integer value (as an Integer
object). The template contains a few features that are part of the
template protocol.
#define myPrintMsg \n\ cMyPrintMsg (char *text) {\n\ char buf[255]; \n\ int result; \n\ OBJECT *objresult; \n\ if (__ctalkIsObject(ARG(0))) {\n\ result = printf ("myPrintMsg: %s\n", \n\ __ctalkToCCharPtr(ARG(0), 1)); \n\ __ctalkDecimalIntegerToASCII (result, buf); \n\ return __ctalkCreateObjectInit ("result", "Integer", \n\ "Magnitude", LOCAL_VAR, buf); \n\ } else { \n\ __ctalkDecimalIntegerToASCII (-1, buf); \n\ objresult = __ctalkCreateObjectInit ("result", "Integer", \n\ "Magnitude", LOCAL_VAR, buf); \n\ __ctalkRegisterUserObject (objresult); \n\ return objresult; \n\ }\n\ }
__ctalkIsObject(ARG(0))
checks that the
argument to the template is a valid object. You can acccess
the template’s arguments with the ARG
macro. The first
argument is ARG(0)
, the second argment is ARG(1)
,
and so on.
char *
string that printf(3) expects as
its argument.
char *
to store the
value of the object, which is why many templates declare a buffer for
the C function’s result and use __ctalkDecimalIntegerToASCII (). If
the result is more complex, then the template might need to format it
with a function like sprintf (3). Templates can also return
NULL, but if a program uses such a templated function in an assignment
statement, it causes a program to generate a NULL argument object
warning when the program is run.
LOCAL_VAR
. The most convenient
way to define macros is to ‘#include <ctalk/ctalkdefs.h>’
somewhere in the input. Many classes already do this, and the
template can use the same set of macro definitions as the class
libraries.
When looking up templates, Ctalk looks in the template registry file,
which is normally ~/.ctalk/templates/fnnames
for the name
given in the input. If the function is aliased to another name by
a macro substitution, fnnames
contains the name of the alias
also.
For example, on some systems, the function getc(3) is a macro
that expands to ‘_IO_getc’. The fnnames
file would then
contain ‘_IO_getc’ as the templated function’s name.
When the compiler finds the function’s name or alias in fnnames
,
it looks in the directory for the template file, which is named for
the first letter of the function’s name. That is, when looking for
myPrintMsg's
template, Ctalk looks for a file named
~/.ctalk/templates/m
.
The C library templates that come with Ctalk use the same scheme,
except that the template files are stored in a subdirectory of
the class library called libc
. The registry is part
or the run-time library, so C library templates do not need a
separate registry file.
The manual page, fnnames(5ctalk) contains more information
about the fnnames
file. The templates(5ctalk) manual
page describes the format of individual templates.
Next: Return values, Previous: Scoping, Up: Methods [Index]