%%% along with SOD; if not, write to the Free Software Foundation,
%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-\chapter{Tutorial}
-\label{ch:tut}
+\chapter{Tutorial} \label{ch:tutorial}
This chapter provides a tutorial introduction to the Sod object system. It
intentionally misses out nitty-gritty details. If you want those, the
that he'll be grateful for your contribution.
%%%--------------------------------------------------------------------------
-\section{Introduction} \label{sec:tut.intro}
+\section{Introduction} \label{sec:tutorial.intro}
Sod is an object system for the C~programming language. Because it doesn't
have enough already. Actually, that's not right: it's got plenty already.
There's a good chance that half of that didn't mean anything to you. Bear
with me, though, because we'll explain it all eventually.
-\subsection{Building programs with Sod} \label{sec:tut.intro.build}
+\subsection{Building programs with Sod} \label{sec:tutorial.intro.build}
Sod is basically a fancy preprocessor, in the same vein as Lex and Yacc. It
reads source files written in a vaguely C-like language. It produces output
\item Sod hasn't made any attempt to improve C's syntax. It's just as
hostile to object-oriented programming as it ever was. This means that
you'll end up writing ugly things like
- \begin{prog}%
- thing->_vt->foo.frob(thing, mumble);%
+ \begin{prog}
+ thing->_vt->foo.frob(thing, mumble);
\end{prog}
fairly frequently. This can be made somewhat less painful using macros,
but we're basically stuck with C. The upside is that you know exactly what
\end{itemize}
Of course, this means that your build system needs to become more
complicated. If you use \man{make}{1}, then something like
-\begin{prog}%
- SOD = sod
-
- .SUFFIXES: .sod .c .h
- .sod.c:; \$(SOD) -tc \$<
+\begin{prog}
+ SOD = sod \\
+ \\
+ .SUFFIXES: .sod .c .h \\
+ .sod.c:; \$(SOD) -tc \$< \\
.sod.h:; \$(SOD) -th \$<
\end{prog}
ought to do the job.
\section{A traditional trivial introduction}
The following is a simple Sod input file.
-\begin{prog}\quad\=\quad\=\kill%
-/* -*-sod-*- */
-
-code c : includes \{
-\#include "greeter.h"
-\}
-
-code h : includes \{
-\#include <stdio.h>
-\#include <sod.h>
+\begin{prog}
+/* -*-sod-*- */ \\
+\\
+code c : includes \{ \\
+\#include "greeter.h" \\
+\} \\
+\\
+code h : includes \{ \\
+\#include <stdio.h> \\
+\#include <sod/sod.h> \\
+\} \\
+\\
+class Greeter : SodObject \{ \\ \ind
+ void greet(FILE *fp) \{ \\ \ind
+ fputs("Hello, world!\textbackslash n", fp); \- \\
+ \} \- \\
\}
-
-class Greeter : SodObject \{ \+
- void greet(FILE *fp) \{ \+
- fputs("Hello, world!\textbackslash n", fp); \-
- \} \-
-\} %
\end{prog}
Save it as @"greeter.sod", and run
-\begin{prog}%
-sod --gc --gh greeter %
+\begin{prog}
+sod --gc --gh greeter
\end{prog}
This will create files @"greeter.c" and @"greeter.h" in the current
directory. Here's how we might use such a simple thing.
-\begin{prog}\quad\=\kill%
-\#include "greeter.h"
-
-int main(void)
-\{ \+
- struct Greeter__ilayout g_obj;
- Greeter *g = Greeter__class->cls.init(\&g_obj);
-
- g->_vt.greeter.greet(g, stdout);
- return (0); \-
-\} %
+\begin{prog}
+\#include "greeter.h" \\
+\\
+int main(void) \\
+\{ \\ \ind
+ SOD_DECL(Greeter, g); \\
+ \\
+ Greeter_greet(g, stdout); \\
+ return (0); \- \\
+\}
\end{prog}
Compare this to the traditional
-\begin{prog}\quad\=\kill%
-\#include <stdio.h>
-
-int main(void) \+
- \{ fputs("Hello, world\\n", stdout); return (0); \} %
+\begin{prog}
+\#include <stdio.h> \\
+\\
+int main(void) \\ \ind
+ \{ fputs("Hello, world@\\n", stdout); return (0); \}
\end{prog}
and I'm sure you'll appreciate the benefits of using Sod already -- mostly to
do with finger exercise. Trust me, it gets more useful.
The first part consists of the two @"code" stanzas. Both of them define
gobbets of raw C code to copy into output files. The first one, @"code~:
c"~\ldots, says that
-\begin{prog}%
- \#include "greeter.h" %
+\begin{prog}
+ \#include "greeter.h"
\end{prog}
needs to appear in the generated @|greeter.c| file; the second says that
-\begin{prog}%
- \#include <stdio.h>
- \#include <sod.h> %
+\begin{prog}
+ \#include <stdio.h> \\
+ \#include <sod/sod.h>
\end{prog}
needs to appear in the header file @|greeter.h|. The generated C files need
to get declarations for external types and functions (e.g., @"FILE" and
approach to all of this: it expects you, the programmer, to deal with it.
The basic syntax for @"code" stanzas is
-\begin{prog}\quad\=\kill%
- code @<file-label> : @<section> \{
- \> @<code>
- \} %
+\begin{prog}
+ code @<file-label> : @<section> \{ \\ \ind
+ @<code> \- \\
+ \}
\end{prog}
The @<file-label> is either @"c" or @"h", and says which output file the code
wants to be written to. The @<section> is a name which explains where in the
So far, so good. The C code, which we thought we understood, contains some
bizarre looking runes. Let's take it one step at a time.
-\begin{prog}%
- struct Greeter__ilayout g_obj; %
+\begin{prog}
+ struct Greeter__ilayout g_obj;
\end{prog}
allocates space for an instance of class @"Greeter". We're not going to use
this space directly. Instead, we do this frightening looking thing.
-\begin{prog}%
- Greeter *g = Greeter__class->cls.init(\&g_obj); %
+\begin{prog}
+ Greeter *g = Greeter__class->cls.init(\&g_obj);
\end{prog}
Taking it slowly: @"Greeter__class" is a pointer to the object that
represents our class @"Greeter". This object contains a member, named
@"ilayout" structure.
Having done this, we `send the instance a message':
-\begin{prog}%
- g->_vt->greeter.greet(g, stdout); %
+\begin{prog}
+ g->_vt->greeter.greet(g, stdout);
\end{prog}
This looks horrific, and seems to repeat itself quite unnecessarily. The
first @"g" is the recipient of our `message'. The second is indeed a copy of