X-Git-Url: https://git.distorted.org.uk/~mdw/sod/blobdiff_plain/abdf50aad1a95f1df8d11c54ff1623077eb84193..1f1d88f5234188f70548a04fd117ac6e251fe8de:/sod-tut.tex diff --git a/sod-tut.tex b/sod-tut.tex new file mode 100644 index 0000000..cff9859 --- /dev/null +++ b/sod-tut.tex @@ -0,0 +1,228 @@ +%%% -*-latex-*- +%%% +%%% Tutorial information +%%% +%%% (c) 2009 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Simple Object Definition system. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% 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} + +This chapter provides a tutorial introduction to the Sod object system. It +intentionally misses out nitty-gritty details. If you want those, the +remaining chapters provide a complete reference to Sod. + +The author isn't terribly good at writing tutorial-style documentation. +You'll have to bear with him. If you think you can do a better job, I'm sure +that he'll be grateful for your contribution. + +%%%-------------------------------------------------------------------------- +\section{Introduction} \label{sec:tut.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. +But Sod is a Sensible Object Design, and C doesn't have any of those. + +What does that mean when the author's not off on one of his tirades? It +means that is has the following features. +\begin{itemize} +\item It has a \emph{minimal runtime system}. Sod isn't likely to interfere + with other language runtimes or be difficult to deal with from a practical + point of view. +\item It provides \emph{multiple inheritance}. Rather than having a single + superclass, Sod allows a class to specify any number of superclasses. + Moreover, it implements multiple inheritance using \emph{superclass + linearization}, which means that it's not a nightmare to deal with. +\item It provides multiple \emph{method rôles}, including `before', `after' + and `around' methods, which makes constructing object protocols rather more + straightforward. +\item It provides a number of \emph{method combinations}. For those coming + from languages other than Lisp, a method combination is a rule for deciding + how to invoke the various methods which might be used to respond to a + message. (This might still sound like a strange idea. We'll deal with it + in detail later.) +\item It allows \emph{user-defined method combinations}. It does a whole lot + more: there's an entire translation-time \emph{meta-object protocol}, so + that extensions can modify many different aspects of the object system. + The downside is that you have to learn Common Lisp and roll up your sleeves + if you want to do any of this. +\end{itemize} +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} + +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 +files which are actually C code (both header files and standalone sources), +and which contain chunks of the input files verbatim. + +The main consequences of this are as follows. +\begin{itemize} +\item The output is completely portable between different machines and + compilers. If you're preparing a source distribution for general release, + it's probably a good idea to provide the generated C~source as well as your + Sod sources. +\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);% + \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 + you're getting. A common complaint about \Cplusplus\ is that it has a + tendency to hide arbitrarily complicated runtime behaviour behind + apparently innocent syntax: you don't get any of that with Sod. Some + people might even think this is a benefit. +\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) -gc -o \$@@ \$< + .sod.h:; \$(SOD) -gh -o \$@@ \$< % +\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 +\#include +\} + +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 % +\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); \- +\} % +\end{prog} +Compare this to the traditional +\begin{prog}\quad\=\kill% +\#include + +int main(void) \+ + \{ 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 @".sod" file was almost comprehensible. There are two important parts to +it (after the comment which tells Emacs how to cope with it). + +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" % +\end{prog} +needs to appear in the generated @|greeter.c| file; the second says that +\begin{prog}% + \#include + \#include % +\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 +@"fputs") from somewhere, and the generated @".c" file will need the +declarations from the corresponding @".h" file. Sod takes a very simple +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 @ : @
\{ + \> @ + \} % +\end{prog} +The @ is either @"c" or @"h", and says which output file the code +wants to be written to. The @
is a name which explains where in the +output file to place the code. The @"includes" section is the usual choice: +it's the `right' place for @`\#include' directives and similar declarations. + +The remaining part, the `meat' of the file, defines a class called +@"greeter". The class can respond to a single message, named @"greet", and +in response, it writes a traditional greeting to the file passed in with the +message. + +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; % +\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); % +\end{prog} +Taking it slowly: @"Greeter__class" is a pointer to the object that +represents our class @"Greeter". This object contains a member, named +@"cls.init", which points to a function whose job is to turn uninitialized +storage space into working instances of the class. It returns a pointer to +the instance, which we use in preference to grovelling about in the +@"ilayout" structure. + +Having done this, we `send the instance a message': +\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 +the first: we have to tell it who it is. (Sod doesn't extend C's syntax, so +this is the sort of thing we just have to put up with.) The lowercase +@"greeter" is our class's `nickname': we didn't choose one explicitly, so Sod +picked one by forcing the classname to lowercase. + +%%%----- That's all, folks -------------------------------------------------- + +%%% Local variables: +%%% mode: LaTeX +%%% TeX-master: "sod.tex" +%%% TeX-PDF-mode: t +%%% End: