Tweaks.
[supertux.git] / lib / utils / lispreader.h
1 /* $Id$ */
2 /*
3  * lispreader.h
4  *
5  * Copyright (C) 1998-2000 Mark Probst
6  * Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifndef SUPERTUX_LISPREADER_H
25 #define SUPERTUX_LISPREADER_H
26
27 #include <cstdio>
28 #include <string>
29 #include <vector>
30 #include <exception>
31
32 #include <zlib.h>
33
34 #include "../utils/exceptions.h"
35
36 namespace SuperTux {
37
38 #define LISP_STREAM_FILE       1
39 #define LISP_STREAM_STRING     2
40 #define LISP_STREAM_ANY        3
41
42 #define LISP_TYPE_INTERNAL      -3
43 #define LISP_TYPE_PARSE_ERROR   -2
44 #define LISP_TYPE_EOF           -1
45 #define LISP_TYPE_NIL           0
46 #define LISP_TYPE_SYMBOL        1
47 #define LISP_TYPE_INTEGER       2
48 #define LISP_TYPE_STRING        3
49 #define LISP_TYPE_REAL          4
50 #define LISP_TYPE_CONS          5
51 #define LISP_TYPE_PATTERN_CONS  6
52 #define LISP_TYPE_BOOLEAN       7
53 #define LISP_TYPE_PATTERN_VAR   8
54
55 #define LISP_PATTERN_ANY        1
56 #define LISP_PATTERN_SYMBOL     2
57 #define LISP_PATTERN_STRING     3
58 #define LISP_PATTERN_INTEGER    4
59 #define LISP_PATTERN_REAL       5
60 #define LISP_PATTERN_BOOLEAN    6
61 #define LISP_PATTERN_LIST       7
62 #define LISP_PATTERN_OR         8
63
64 // Exception
65 class LispReaderException : public SuperTuxException
66 {
67   public:
68     LispReaderException(const char* _message = "lispreader error", const char* _file = "", const unsigned int _line = 0)
69       : SuperTuxException(_message, _file, _line) { };
70 };
71
72 typedef struct
73   {
74     int type;
75
76     union
77       {
78         FILE *file;
79         struct
80           {
81             char *buf;
82             int pos;
83           }
84         string;
85         struct
86           {
87             void *data;
88             int (*next_char) (void *data);
89             void (*unget_char) (char c, void *data);
90           }
91         any;
92       } v;
93   }
94 lisp_stream_t;
95
96 typedef struct _lisp_object_t lisp_object_t;
97 struct _lisp_object_t
98   {
99     int type;
100
101     union
102       {
103         struct
104           {
105             struct _lisp_object_t *car;
106             struct _lisp_object_t *cdr;
107           }
108         cons;
109
110         char *string;
111         int integer;
112         float real;
113
114         struct
115           {
116             int type;
117             int index;
118             struct _lisp_object_t *sub;
119           }
120         pattern;
121       } v;
122   };
123
124 lisp_stream_t* lisp_stream_init_file (lisp_stream_t *stream, FILE *file);
125 lisp_stream_t* lisp_stream_init_string (lisp_stream_t *stream, char *buf);
126 lisp_stream_t* lisp_stream_init_any (lisp_stream_t *stream, void *data,
127                                      int (*next_char) (void *data),
128                                      void (*unget_char) (char c, void *data));
129
130 lisp_object_t* lisp_read (lisp_stream_t *in);
131 lisp_object_t* lisp_read_from_file(const std::string& filename);
132 void lisp_free (lisp_object_t *obj);
133
134 lisp_object_t* lisp_read_from_string (const char *buf);
135
136 int lisp_compile_pattern (lisp_object_t **obj, int *num_subs);
137 int lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars, int num_subs);
138 int lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t **vars);
139
140 int lisp_type (lisp_object_t *obj);
141 int lisp_integer (lisp_object_t *obj);
142 float lisp_real (lisp_object_t *obj);
143 char* lisp_symbol (lisp_object_t *obj);
144 char* lisp_string (lisp_object_t *obj);
145 int lisp_boolean (lisp_object_t *obj);
146 lisp_object_t* lisp_car (lisp_object_t *obj);
147 lisp_object_t* lisp_cdr (lisp_object_t *obj);
148
149 lisp_object_t* lisp_cxr (lisp_object_t *obj, const char *x);
150
151 lisp_object_t* lisp_make_integer (int value);
152 lisp_object_t* lisp_make_real (float value);
153 lisp_object_t* lisp_make_symbol (const char *value);
154 lisp_object_t* lisp_make_string (const char *value);
155 lisp_object_t* lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr);
156 lisp_object_t* lisp_make_boolean (int value);
157
158 int lisp_list_length (lisp_object_t *obj);
159 lisp_object_t* lisp_list_nth_cdr (lisp_object_t *obj, int index);
160 lisp_object_t* lisp_list_nth (lisp_object_t *obj, int index);
161
162 void lisp_dump (lisp_object_t *obj, FILE *out);
163
164 #define lisp_nil()           ((lisp_object_t*)0)
165
166 #define lisp_nil_p(obj)      (obj == 0)
167 #define lisp_integer_p(obj)  (lisp_type((obj)) == LISP_TYPE_INTEGER)
168 #define lisp_real_p(obj)     (lisp_type((obj)) == LISP_TYPE_REAL)
169 #define lisp_symbol_p(obj)   (lisp_type((obj)) == LISP_TYPE_SYMBOL)
170 #define lisp_string_p(obj)   (lisp_type((obj)) == LISP_TYPE_STRING)
171 #define lisp_cons_p(obj)     (lisp_type((obj)) == LISP_TYPE_CONS)
172 #define lisp_boolean_p(obj)  (lisp_type((obj)) == LISP_TYPE_BOOLEAN)
173
174 /** */
175 class LispReader
176 {
177 private:
178   lisp_object_t* owner;
179   lisp_object_t* lst;
180
181   lisp_object_t* search_for(const char* name);
182   
183 public:
184   /** cur == ((pos 1 2 3) (id 12 3 4)...) */
185   LispReader(lisp_object_t* l);
186   ~LispReader();
187
188   bool read_int_vector(const char* name, std::vector<int>& vec);
189   bool read_int_vector(const char* name, std::vector<unsigned int>& vec);
190   bool read_char_vector(const char* name, std::vector<char>& vec);
191   bool read_string_vector(const char* name, std::vector<std::string>& vec);
192   bool read_string(const char* name, std::string& str, bool translatable = false);
193   bool read_int(const char* name, int& i);
194   bool read_float(const char* name, float& f);
195   bool read_bool(const char* name, bool& b);
196   bool read_lisp(const char* name, lisp_object_t*& b);
197   lisp_object_t* read_lisp(const char* name);
198
199   static LispReader* load(const std::string& filename,
200       const std::string& toplevellist);
201
202   lisp_object_t* get_lisp();
203 };
204
205 } //namespace SuperTux
206
207 #endif /*SUPERTUX_LISPREADER_H*/
208