1 /* -*- C -*-
2 // -------------------------------------------------------------------
3 // MiniExp - Library for handling lisp expressions
4 // Copyright (c) 2005  Leon Bottou
5 //
6 // This software is subject to, and may be distributed under, the GNU
7 // Lesser General Public License, either Version 2.1 of the license,
8 // or (at your option) any later version. The license should have
9 // accompanied the software or you may obtain a copy of the license
10 // from the Free Software Foundation at http://www.fsf.org .
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 // -------------------------------------------------------------------
17 */
18 
19 #ifndef MINIEXP_H
20 #define MINIEXP_H
21 
22 #ifdef __cplusplus
23 extern "C" {
24 # ifndef __cplusplus
25 }
26 # endif
27 #endif
28 
29 #ifndef MINILISPAPI
30 # ifdef _WIN32
31 #  ifdef MINILISPAPI_EXPORT
32 #   define MINILISPAPI __declspec(dllexport)
33 #  else
34 #   define MINILISPAPI __declspec(dllimport)
35 #  endif
36 # endif
37 #endif
38 #ifndef MINILISPAPI
39 # define MINILISPAPI /**/
40 #endif
41 
42 #ifndef __cplusplus
43 # ifndef inline
44 #  if defined(__GNUC__)
45 #   define inline __inline__
46 #  elif defined(_MSC_VER)
47 #   define inline __inline
48 #  else
49 #   define inline /**/
50 #  endif
51 # endif
52 #endif
53 
54 #include <stddef.h>
55 
56 /* -------------------------------------------------- */
57 /* LISP EXPRESSIONS                                   */
58 /* -------------------------------------------------- */
59 
60 /* miniexp_t --
61    Opaque pointer type representing a lisp expression,
62    also known as s-expression.
63    S-expressions can be viewed as a simple and powerful
64    alternative to XML.  DjVu uses s-expressions to handle
65    annotations. Both the decoding api <ddjvuapi.h> and
66    program <djvused> use s-expressions to describe the
67    hidden text information and the navigation
68    information */
69 
70 
71 typedef struct miniexp_s* miniexp_t;
72 
73 
74 /* There are four basic types of lisp expressions,
75    numbers, symbols, pairs, and objects.
76    The latter category can represent any c++ object
77    that inherits class <miniobj_t> defined later in this file.
78    Strings and floating point numbers are implemented this way.*/
79 
80 
81 /* -------- NUMBERS -------- */
82 
83 /* Minilisp numbers represent integers
84    covering at least range [-2^29...2^29-1] */
85 
86 
87 /* miniexp_numberp --
88    Tests if an expression is a number. */
89 
miniexp_numberp(miniexp_t p)90 static inline int miniexp_numberp(miniexp_t p) {
91   return (((size_t)(p)&3)==3);
92 }
93 
94 /* miniexp_to_int --
95    Returns the integer corresponding to a lisp expression.
96    Assume that the expression is indeed a number. */
97 
miniexp_to_int(miniexp_t p)98 static inline int miniexp_to_int(miniexp_t p) {
99   return (((int)(size_t)(p))>>2);
100 }
101 
102 /* miniexp_number --
103    Constructs the expression corresponding to an integer. */
104 
miniexp_number(int x)105 static inline miniexp_t miniexp_number(int x) {
106   return (miniexp_t) (size_t) ((x<<2)|3);
107 }
108 
109 
110 
111 /* -------- SYMBOLS -------- */
112 
113 /* The textual representation of a minilisp symbol is a
114    sequence of printable characters forming an identifier.
115    Each symbol has a unique representation and remain
116    permanently allocated. To compare two symbols,
117    simply compare the <miniexp_t> pointers. */
118 
119 
120 /* miniexp_symbolp --
121    Tests if an expression is a symbol. */
122 
miniexp_symbolp(miniexp_t p)123 static inline int miniexp_symbolp(miniexp_t p) {
124   return ((((size_t)p)&3)==2);
125 }
126 
127 /* miniexp_to_name --
128    Returns the symbol name as a string.
129    Returns NULL if the expression is not a symbol. */
130 
131 MINILISPAPI const char* miniexp_to_name(miniexp_t p);
132 
133 /* miniexp_symbol --
134    Returns the unique symbol expression with the specified name. */
135 
136 MINILISPAPI miniexp_t miniexp_symbol(const char *name);
137 
138 
139 
140 /* -------- PAIRS -------- */
141 
142 /* Pairs (also named "cons") are the basic building blocks for
143    minilisp lists. Each pair contains two expression:
144    - the <car> represents the first element of a list.
145    - the <cdr> usually is a pair representing the rest of the list.
146    The empty list is represented by a null pointer. */
147 
148 
149 /* miniexp_nil --
150    The empty list. */
151 
152 #define miniexp_nil ((miniexp_t)(size_t)0)
153 
154 /* miniexp_dummy --
155    An invalid expression used to represent
156    various exceptional conditions. */
157 
158 #define miniexp_dummy ((miniexp_t)(size_t)2)
159 
160 /* miniexp_listp --
161    Tests if an expression is either a pair or the empty list. */
162 
miniexp_listp(miniexp_t p)163 static inline int miniexp_listp(miniexp_t p) {
164   return ((((size_t)p)&3)==0);
165 }
166 
167 /* miniexp_consp --
168    Tests if an expression is a pair. */
169 
miniexp_consp(miniexp_t p)170 static inline int miniexp_consp(miniexp_t p) {
171   return p && miniexp_listp(p);
172 }
173 
174 /* miniexp_length --
175    Returns the length of a list.
176    Returns 0 for non lists, -1 for circular lists. */
177 
178 MINILISPAPI int miniexp_length(miniexp_t p);
179 
180 /* miniexp_car --
181    miniexp_cdr --
182    Returns the car or cdr of a pair. */
183 
miniexp_car(miniexp_t p)184 static inline miniexp_t miniexp_car(miniexp_t p) {
185   if (miniexp_consp(p))
186     return ((miniexp_t*)p)[0];
187   return miniexp_nil;
188 }
189 
miniexp_cdr(miniexp_t p)190 static inline miniexp_t miniexp_cdr(miniexp_t p) {
191   if (miniexp_consp(p))
192     return ((miniexp_t*)p)[1];
193   return miniexp_nil;
194 }
195 
196 /* miniexp_cXXr --
197    Represent common combinations of car and cdr. */
198 
199 MINILISPAPI miniexp_t miniexp_caar (miniexp_t p);
200 MINILISPAPI miniexp_t miniexp_cadr (miniexp_t p);
201 MINILISPAPI miniexp_t miniexp_cdar (miniexp_t p);
202 MINILISPAPI miniexp_t miniexp_cddr (miniexp_t p);
203 MINILISPAPI miniexp_t miniexp_caddr(miniexp_t p);
204 MINILISPAPI miniexp_t miniexp_cdddr(miniexp_t p);
205 
206 /* miniexp_nth --
207    Returns the n-th element of a list. */
208 
209 MINILISPAPI miniexp_t miniexp_nth(int n, miniexp_t l);
210 
211 /* miniexp_cons --
212    Constructs a pair. */
213 
214 MINILISPAPI miniexp_t miniexp_cons(miniexp_t car, miniexp_t cdr);
215 
216 /* miniexp_rplaca --
217    miniexp_rplacd --
218    Changes the car or the cdr of a pair. */
219 
220 MINILISPAPI miniexp_t miniexp_rplaca(miniexp_t pair, miniexp_t newcar);
221 MINILISPAPI miniexp_t miniexp_rplacd(miniexp_t pair, miniexp_t newcdr);
222 
223 /* miniexp_reverse --
224    Reverses a list in place. */
225 
226 MINILISPAPI miniexp_t miniexp_reverse(miniexp_t p);
227 
228 
229 /* -------- OBJECTS (GENERIC) -------- */
230 
231 /* Object expressions represent a c++ object
232    that inherits class <miniobj_t> defined later.
233    Each object expression has a symbolic class name
234    and a pointer to the c++ object. */
235 
236 /* miniexp_objectp --
237    Tests if an expression is an object. */
238 
miniexp_objectp(miniexp_t p)239 static inline int miniexp_objectp(miniexp_t p) {
240   return ((((size_t)p)&3)==1);
241 }
242 
243 /* miniexp_classof --
244    Returns the symbolic class of an expression.
245    Returns nil if the expression is not an object. */
246 
247 MINILISPAPI miniexp_t miniexp_classof(miniexp_t p);
248 
249 /* miniexp_isa --
250    If <p> is an instance of class named <c> or one of
251    its subclasses, returns the actual class name.
252    Otherwise returns miniexp_nil. */
253 
254 MINILISPAPI miniexp_t miniexp_isa(miniexp_t p, miniexp_t c);
255 
256 
257 /* -------- OBJECTS (STRINGS) -------- */
258 
259 /* miniexp_stringp --
260    Tests if an expression is a string. */
261 
262 MINILISPAPI int miniexp_stringp(miniexp_t p);
263 
264 /* miniexp_to_str --
265    Returns the c string represented by the expression.
266    Returns NULL if the expression is not a string.
267    The c string remains valid as long as the
268    corresponding lisp object exists. */
269 
270 MINILISPAPI const char *miniexp_to_str(miniexp_t p);
271 
272 /* miniexp_to_lstr ----
273    Returns the length of the string represented by the expression.
274    Optionally returns the c string into *sp.
275    Return 0 and makes *sp null if the expression is not a string. */
276 
277 MINILISPAPI size_t miniexp_to_lstr(miniexp_t p, const char **sp);
278 
279 /* miniexp_string --
280    Constructs a string expression by copying zero terminated string s. */
281 
282 MINILISPAPI miniexp_t miniexp_string(const char *s);
283 
284 /* miniexp_lstring --
285    Constructs a string expression by copying len bytes from s. */
286 
287 MINILISPAPI miniexp_t miniexp_lstring(size_t len, const char *s);
288 
289 /* miniexp_substring --
290    Constructs a string expression by copying at most len bytes
291    from zero terminated string s. */
292 
293 MINILISPAPI miniexp_t miniexp_substring(const char *s, int len);
294 
295 /* miniexp_concat --
296    Concat all the string expressions in list <l>. */
297 
298 MINILISPAPI miniexp_t miniexp_concat(miniexp_t l);
299 
300 
301 
302 /* -------- OBJECTS (FLOATNUM) -------- */
303 
304 /* miniexp_floatnump --
305    Tests if an expression is an object
306    representing a floating point number. */
307 
308 MINILISPAPI int miniexp_floatnump(miniexp_t p);
309 
310 /* miniexp_floatnum --
311    Returns a new floating point number object. */
312 
313 MINILISPAPI miniexp_t miniexp_floatnum(double x);
314 
315 /* miniexp_doublep --
316    Tests if an expression can be converted
317    to a double precision number. */
318 
319 MINILISPAPI int miniexp_doublep(miniexp_t p);
320 
321 /* miniexp_to_double --
322    Returns a double precision number corresponding to
323    a lisp expression. */
324 
325 MINILISPAPI double miniexp_to_double(miniexp_t p);
326 
327 /* miniexp_double --
328    Returns a lisp expression representing a double
329    precision number. This will be a number if it fits
330    and a floatnum otherwise.
331  */
332 
333 MINILISPAPI miniexp_t miniexp_double(double x);
334 
335 
336 /* -------------------------------------------------- */
337 /* GARBAGE COLLECTION                                 */
338 /* -------------------------------------------------- */
339 
340 
341 /* The garbage collector reclaims the memory allocated for
342    lisp expressions no longer in use.  It is automatically
343    invoked by the pair and object allocation functions when
344    the available memory runs low.  It is however possible to
345    temporarily disable it.
346 
347    The trick is to determine which lisp expressions are in
348    use at a given moment. This package takes a simplistic
349    approach. All objects of type <minivar_t> are chained and
350    can reference an arbitrary lisp expression.  Garbage
351    collection preserves all lisp expressions referenced by a
352    minivar, as well as all lisp expressions that can be
353    accessed from these. When called automatically,
354    garbage collection also preserves the sixteen most recently
355    created miniexps in order to make sure that temporaries do
356    not vanish in the middle of complicated C expressions.
357 
358    The minivar class is designed such that C++ program can
359    directly use instances of <minivar_t> as normal
360    <miniexp_t> variables.  There is almost no overhead
361    accessing or changing the lisp expression referenced by a
362    minivar. However, the minivar chain must be updated
363    whenever the minivar object is constructed or destructed.
364 
365    Example (in C++ only):
366      miniexp_t copy_in_reverse(miniexp_t p) {
367         minivar_t l = miniexp_nil;
368         while (miniexp_consp(p)) {
369           l = miniexp_cons(miniexp_car(p), l);
370           p = miniexp_cdr(p);
371         }
372         return l;
373      }
374 
375    When to use minivar_t instead of miniexp_t?
376 
377    * A function that only navigates properly secured
378      s-expressions without modifying them does not need to
379      bother about minivars.
380 
381    * Otherwise all functions should make sure that all useful
382      s-expression are directly or indirectly secured by a
383      minivar_t object. In case of doubt, use minivars
384      everywhere.
385 
386    * Function arguments should remain <miniexp_t> in order
387      to allow interoperability with the C language.
388      It is assumed that these arguments have been properly
389      secured by the caller and cannot disappear if a
390      garbage collection occurs.
391 
392    C programs cannot use minivars as easily as C++ programs.
393    Wrappers are provided to allocate minivars and to access
394    their value. This is somehow inconvenient.  It might be
395    more practical to control the garbage collector
396    invocations with <minilisp_acquire_gc_lock()> and
397    <minilisp_release_gc_lock()>...  */
398 
399 
400 /* minilisp_gc --
401    Invokes the garbage collector now. */
402 
403 MINILISPAPI void minilisp_gc(void);
404 
405 /* minilisp_info --
406    Prints garbage collector statistics. */
407 
408 MINILISPAPI void minilisp_info(void);
409 
410 /* minilisp_acquire_gc_lock --
411    minilisp_release_gc_lock --
412    Temporarily disables automatic garbage collection.
413    Acquire/release pairs may be nested.
414    Both functions return their argument unmodified.
415    This is practical because <minilisp_release_gc_lock>
416    can invoke the garbage collector. Before doing
417    so it stores its argument in a minivar to
418    preserve it.
419 
420    Example (in C):
421      miniexp_t copy_in_reverse(miniexp_t p) {
422         miniexp_t l = 0;
423         minilisp_acquire_gc_lock(0);
424         while (miniexp_consp(p)) {
425           l = miniexp_cons(miniexp_car(p), l);
426           p = miniexp_cdr(p);
427         }
428         return minilisp_release_gc_lock(l);
429      }
430 
431    Disabling garbage collection for a long time
432    increases the memory consumption. */
433 
434 MINILISPAPI miniexp_t minilisp_acquire_gc_lock(miniexp_t);
435 MINILISPAPI miniexp_t minilisp_release_gc_lock(miniexp_t);
436 
437 /* minivar_t --
438    The minivar type. */
439 #ifdef __cplusplus
440 class minivar_t;
441 #else
442 typedef struct minivar_s minivar_t;
443 #endif
444 
445 /* minivar_alloc --
446    minivar_free --
447    Wrappers for creating and destroying minivars in C. */
448 
449 MINILISPAPI minivar_t *minivar_alloc(void);
450 MINILISPAPI void minivar_free(minivar_t *v);
451 
452 /* minivar_pointer --
453    Wrappers to access the lisp expression referenced
454    by a minivar. This function returns a pointer
455    to the actual miniexp_t variable. */
456 
457 MINILISPAPI miniexp_t *minivar_pointer(minivar_t *v);
458 
459 /* minilisp_debug --
460    Setting the debug flag runs the garbage collector
461    very often. This is extremely slow, but can be
462    useful to debug memory allocation problems. */
463 
464 MINILISPAPI void minilisp_debug(int debugflag);
465 
466 /* minilisp_finish --
467    Deallocates everything.  This is only useful when using
468    development tools designed to check for memory leaks.
469    No miniexp function can be used after calling this. */
470 
471 MINILISPAPI void minilisp_finish(void);
472 
473 
474 /* -------------------------------------------------- */
475 /* INPUT/OUTPUT                                       */
476 /* -------------------------------------------------- */
477 
478 /* Notes about the textual representation of miniexps.
479 
480    - Special characters are:
481      * the parenthesis <(> and <)>,
482      * the double quote <">,
483      * the vertical bar <|>,
484      * any other ascii character with a non zero entry
485        in the macro character array.
486      * the dieze character <#>, when followed by another
487        dieze or by an ascii character with a non zero entry
488        in the dieze character array.
489 
490    - Symbols are represented by their name.
491      Symbols whose name contains blanks, special characters,
492      non printable characters, non ascii characters,
493      or can be confused for a number are delimited
494      by vertical bars <|> and can contain two consecutive
495      vertical bars to represent a single vertical bar character.
496 
497    - Numbers follow the syntax specified by the C
498      function strtol() with base=0, but are required
499      to start with a digit or with a sign character
500      followed by another character.
501 
502    - Floating point follow the syntax specified by the C
503      function strtod() with base=0, but are required
504      to start with a digit or with a sign character
505      followed by another character.
506 
507    - Strings are delimited by double quotes.
508      All non printable ASCII characters must be escaped.
509      Besides all the usual C string escape sequences,
510      UTF8-encoded Unicode characters in range 0..0x10ffff
511      can be represented by escape sequence <\u> followed
512      by four hexadecimal digits or escape sequence <\U>
513      followed by six hexadecimal digits. Surrogate pairs
514      are always recognized as a single Unicode character.
515      The effect of invalid escape sequences is unspecified.
516 
517    - List are represented by an open parenthesis <(>
518      followed by the space separated list elements,
519      followed by a closing parenthesis <)>.
520      When the cdr of the last pair is non zero,
521      the closed parenthesis is preceded by
522      a space, a dot <.>, a space, and the textual
523      representation of the cdr.
524 
525    - When the parser encounters an ascii character corresponding
526      to a non zero function pointer in the macro character array,
527      the function is invoked and must return a possibly empty
528      list of miniexps to be returned by subsequent
529      invocations of the parser. The same process happens when
530      the parser encounters a dieze character followed by an
531      ascii character corresponding to a non zero function pointer
532      int the dieze character array. */
533 
534 
535 /* miniexp_pname --
536    Returns a string containing the textual representation
537    of a minilisp expression. Set argument <width> to zero
538    to output a single line, or to a positive value to
539    perform pretty line breaks for this intended number of columns.
540    This function can cause a garbage collection to occur. */
541 
542 MINILISPAPI miniexp_t miniexp_pname(miniexp_t p, int width);
543 
544 
545 /* miniexp_io_t --
546    This structure is used to describe how to perform input/output
547    operations. Input/output operations are performed through function
548    pointers <fputs>, <fgetc>, and <ungetc>, which are similar to their
549    stdio counterparts. Variable <data> defines four pointers that can
550    be used as a closure by the I/O functions.
551       Variable <p_flags> optionally points to a flag word that customize the
552    printing operation. All ASCII control characters present in strings are
553    displayed using C escapes sequences. Flag <miniexp_io_print7bits> causes
554    all other non ASCII characters to be escaped. Flag <miniexp_io_u6escape>
555    and <miniexp_io_u4escape> respectively authorize using the long and
556    short utf8 escape sequences "\U" and "\u". Their absence may force
557    using surrogate short escape sequences or only octal sequences.
558    Flag <miniexp_io_quotemoresyms> causes the output code to also quote
559    all symbols that start with a digit or with a sign character followed
560    by another character.
561       When both <p_macrochar> and <p_macroqueue> are non zero, a non zero
562    entry in <p_macrochar[c]> defines a special parsing function that is called
563    when <miniexp_read_r> encounters the character <c> (in range 0 to 127.)
564    When both <p_diezechar> and <p_macroqueue> are non zero, a non zero entry
565    in <p_diezechar[c]> defines a special parsing function that is called when
566    <miniexp_read_r> encounters the character '#' followed by character <c> (in
567    range 0 to 127.)  These parsing functions return a list of <miniexp_t> that
568    function <miniexp_read_r> returns one-by-one before processing more
569    input. This list is stored in the variable pointed by <io.p_macroqueue>.
570 */
571 
572 typedef struct miniexp_io_s miniexp_io_t;
573 typedef miniexp_t (*miniexp_macrochar_t)(miniexp_io_t*);
574 
575 struct miniexp_io_s
576 {
577   int (*fputs)(miniexp_io_t*, const char*);
578   int (*fgetc)(miniexp_io_t*);
579   int (*ungetc)(miniexp_io_t*, int);
580   void *data[4];
581   int *p_flags; /* previously named p_print7bits */
582   miniexp_macrochar_t *p_macrochar;
583   miniexp_macrochar_t *p_diezechar;
584   minivar_t *p_macroqueue;
585   minivar_t *p_reserved;
586 };
587 
588 #define miniexp_io_print7bits          0x1
589 #define miniexp_io_u4escape            0x2
590 #define miniexp_io_u6escape            0x4
591 #define miniexp_io_quotemoresymbols    0x20
592 
593 /* miniexp_io_init --
594    Initialize a default <miniexp_io_t> structure
595    that reads from stdin and prints to stdout.
596    Field <data[0]> is used to hold the stdin file pointer.
597    Field <data[1]> is used to hold the stdout file pointer.
598    Fields <p_flags>, <p_macrochar>, <p_diezechar>
599    and <p_macroqueue> are set to point to zero-initialized
600    shared variables. */
601 
602 MINILISPAPI void miniexp_io_init(miniexp_io_t *io);
603 
604 /* miniexp_io_set_{input,output} --
605    Override the file descriptor used for input or output.
606    You must call <miniexp_io_init> before. */
607 
608 #if defined(stdin)
609 MINILISPAPI void miniexp_io_set_output(miniexp_io_t *io, FILE *f);
610 MINILISPAPI void miniexp_io_set_input(miniexp_io_t *io, FILE *f);
611 #endif
612 
613 /* miniexp_read_r --
614    Reads an expression by repeatedly
615    invoking <minilisp_getc> and <minilisp_ungetc>.
616    Returns <miniexp_dummy> when an error occurs. */
617 
618 MINILISPAPI miniexp_t miniexp_read_r(miniexp_io_t *io);
619 
620 /* miniexp_prin_r, miniexp_print_r --
621    Prints a minilisp expression by repeatedly invoking <minilisp_puts>.
622    Only <minilisp_print> outputs a final newline character.
623    These functions are safe to call anytime. */
624 
625 MINILISPAPI miniexp_t miniexp_prin_r(miniexp_io_t *io, miniexp_t p);
626 MINILISPAPI miniexp_t miniexp_print_r(miniexp_io_t *io, miniexp_t p);
627 
628 /* miniexp_pprin_r, miniexp_pprint_r --
629    Prints a minilisp expression with reasonably pretty line breaks.
630    Argument <width> is the intended number of columns.
631    Only <minilisp_pprint> outputs a final newline character.
632    These functions can cause a garbage collection to occur. */
633 
634 MINILISPAPI miniexp_t miniexp_pprin_r(miniexp_io_t *io, miniexp_t p, int w);
635 MINILISPAPI miniexp_t miniexp_pprint_r(miniexp_io_t *io, miniexp_t p, int w);
636 
637 /* miniexp_io, miniexp_read, miniexp_{,p}prin{,t} --
638    Variable <miniexp_io> contains the pre-initialized input/output data
639    structure that is used by the non-reentrant input/output functions. */
640 
641 extern MINILISPAPI miniexp_io_t miniexp_io;
642 MINILISPAPI miniexp_t miniexp_read(void);
643 MINILISPAPI miniexp_t miniexp_prin(miniexp_t p);
644 MINILISPAPI miniexp_t miniexp_print(miniexp_t p);
645 MINILISPAPI miniexp_t miniexp_pprin(miniexp_t p, int width);
646 MINILISPAPI miniexp_t miniexp_pprint(miniexp_t p, int width);
647 
648 
649 /* Backward compatibility (will eventually disappear) */
650 extern MINILISPAPI int (*minilisp_puts)(const char *);
651 extern MINILISPAPI int (*minilisp_getc)(void);
652 extern MINILISPAPI int (*minilisp_ungetc)(int);
653 extern MINILISPAPI miniexp_t (*minilisp_macrochar_parser[128])(void);
654 extern MINILISPAPI miniexp_t (*minilisp_diezechar_parser[128])(void);
655 extern MINILISPAPI miniexp_macrochar_t miniexp_macrochar[128];
656 extern MINILISPAPI minivar_t miniexp_macroqueue;
657 extern MINILISPAPI int minilisp_print_7bits;
658 #if defined(stdin)
659 MINILISPAPI void minilisp_set_output(FILE *f);
660 MINILISPAPI void minilisp_set_input(FILE *f);
661 #endif
662 
663 /* -------------------------------------------------- */
664 /* STUFF FOR C++ ONLY                                 */
665 /* -------------------------------------------------- */
666 
667 #ifdef __cplusplus
668 # ifndef __cplusplus
669 {
670 # endif
671 } // extern "C"
672 
673 typedef void minilisp_mark_t(miniexp_t *pp);
674 
675 /* -------- MINIVARS -------- */
676 
677 /* minivar_t --
678    A class for protected garbage collector variables. */
679 
680 class MINILISPAPI
681 minivar_t
682 {
683   miniexp_t data;
684   minivar_t *next;
685   minivar_t **pprev;
686 public:
687   minivar_t();
688   minivar_t(miniexp_t p);
689   minivar_t(const minivar_t &v);
690   operator miniexp_t&() { return data; }
691   miniexp_t* operator&() { return &data; }
692   minivar_t& operator=(miniexp_t p) { data = p; return *this; }
693   minivar_t& operator=(const minivar_t &v) { data = v.data; return *this; }
694   ~minivar_t();
695 #ifdef MINIEXP_IMPLEMENTATION
696   static minivar_t *vars;
697   static void mark(minilisp_mark_t*);
698 #endif
699 };
700 
701 
702 /* -------- MINIOBJ -------- */
703 
704 
705 /* miniobj_t --
706    The base class for c++ objects
707    represented by object expressions. */
708 
709 class MINILISPAPI
710 miniobj_t {
711  public:
712   virtual ~miniobj_t();
713 
714   /* --- stuff defined by MINIOBJ_DECLARE --- */
715   /* classname: a symbol characterizing this class. */
716   static const miniexp_t classname;
717   /* classof: class name symbol for this object. */
718   virtual miniexp_t classof() const = 0;
719   /* isa -- tests if this is an instance of <classname>. */
720   virtual bool isa(miniexp_t classname) const;
721 
722   /* --- optional stuff --- */
723   /* pname: returns a printable name for this object.
724      The caller must deallocate the result with delete[]. */
725   virtual char *pname() const;
726   /* stringp, doublep: tells whether this object should be
727      interpreted/printed as a generic string (for miniexp_strinp)
728      or a double (for miniexp_doublep). */
729   virtual bool stringp(const char* &s, size_t &l) const;
730   virtual bool doublep(double &d) const;
731   /* mark: calls action() on all member miniexps of the object,
732      for garbage collecting purposes. */
733   virtual void mark(minilisp_mark_t *action);
734   /* destroy: called by the garbage collector to
735      deallocate the object. Defaults to 'delete this'. */
736   virtual void destroy();
737 
738 };
739 
740 /* MINIOBJ_DECLARE --
741    MINIOBJ_IMPLEMENT --
742    Useful code fragments for implementing
743    the mandatory part of miniobj subclasses. */
744 
745 #define MINIOBJ_DECLARE(cls, supercls, name) \
746   public: static const miniexp_t classname; \
747           virtual miniexp_t classof() const; \
748           virtual bool isa(miniexp_t) const;
749 
750 #define MINIOBJ_IMPLEMENT(cls, supercls, name)\
751   const miniexp_t cls::classname = miniexp_symbol(name);\
752   miniexp_t cls::classof() const {\
753     return cls::classname; }\
754   bool cls::isa(miniexp_t n) const {\
755     return (cls::classname==n) || (supercls::isa(n)); }
756 
757 
758 /* miniexp_to_obj --
759    Returns a pointer to the object represented by an lisp
760    expression. Returns NULL if the expression is not an
761    object expression.
762 */
763 
miniexp_to_obj(miniexp_t p)764 static inline miniobj_t *miniexp_to_obj(miniexp_t p) {
765   if (miniexp_objectp(p))
766     return ((miniobj_t**)(((size_t)p)&~((size_t)3)))[0];
767   return 0;
768 }
769 
770 /* miniexp_object --
771    Create an object expression for a given object. */
772 
773 MINILISPAPI miniexp_t miniexp_object(miniobj_t *obj);
774 
775 
776 /* miniexp_mutate --
777    Atomically modifies a member of a garbage collected object.
778    The object implementation must call this function to change
779    the contents of a member variable <v> of object <obj>.
780    Returns <p>*/
781 
782 MINILISPAPI miniexp_t miniexp_mutate(miniexp_t obj, miniexp_t *v, miniexp_t p);
783 
784 
785 #endif /* __cplusplus */
786 
787 
788 
789 
790 
791 /* -------------------------------------------------- */
792 /* THE END                                            */
793 /* -------------------------------------------------- */
794 
795 #endif /* MINIEXP_H */
796