From: Matthias Braun Date: Mon, 29 Nov 2004 00:15:46 +0000 (+0000) Subject: old files X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=6e9df9a8235a9fdf093e52cbb438334ccc43ea6e;p=supertux.git old files SVN-Revision: 2219 --- diff --git a/lib/utils/lispreader.cpp b/lib/utils/lispreader.cpp deleted file mode 100644 index 6076b16fe..000000000 --- a/lib/utils/lispreader.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -/* $Id$ */ -/* - * lispreader.c - * - * Copyright (C) 1998-2000 Mark Probst - * Copyright (C) 2002 Ingo Ruhnke - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "app/globals.h" -#include "app/setup.h" -#include "lispreader.h" - -using namespace SuperTux; - -#define TOKEN_ERROR -1 -#define TOKEN_EOF 0 -#define TOKEN_OPEN_PAREN 1 -#define TOKEN_CLOSE_PAREN 2 -#define TOKEN_SYMBOL 3 -#define TOKEN_STRING 4 -#define TOKEN_INTEGER 5 -#define TOKEN_REAL 6 -#define TOKEN_PATTERN_OPEN_PAREN 7 -#define TOKEN_DOT 8 -#define TOKEN_TRUE 9 -#define TOKEN_FALSE 10 - - -#define MAX_TOKEN_LENGTH 4096 - -static char token_string[MAX_TOKEN_LENGTH + 1] = ""; -static int token_length = 0; - -static lisp_object_t end_marker = { LISP_TYPE_EOF, {{0, 0}} }; -static lisp_object_t error_object = { LISP_TYPE_PARSE_ERROR , {{0,0}} }; -static lisp_object_t close_paren_marker = { LISP_TYPE_PARSE_ERROR , {{0,0}} }; -static lisp_object_t dot_marker = { LISP_TYPE_PARSE_ERROR , {{0,0}} }; - -static void -_token_clear (void) -{ - token_string[0] = '\0'; - token_length = 0; -} - -static void -_token_append (char c) -{ - if (token_length >= MAX_TOKEN_LENGTH) - throw std::runtime_error("token too long."); - - token_string[token_length++] = c; - token_string[token_length] = '\0'; -} - -static int -_next_char (lisp_stream_t *stream) -{ - switch (stream->type) - { - case LISP_STREAM_FILE : - return getc(stream->v.file); - - case LISP_STREAM_STRING : - { - char c = stream->v.string.buf[stream->v.string.pos]; - - if (c == 0) - return EOF; - - ++stream->v.string.pos; - - return c; - } - - case LISP_STREAM_ANY: - return stream->v.any.next_char(stream->v.any.data); - } - - assert(false); - return EOF; -} - -static void -_unget_char (char c, lisp_stream_t *stream) -{ - switch (stream->type) - { - case LISP_STREAM_FILE : - ungetc(c, stream->v.file); - break; - - case LISP_STREAM_STRING : - --stream->v.string.pos; - break; - - case LISP_STREAM_ANY: - stream->v.any.unget_char(c, stream->v.any.data); - break; - - default : - assert(false); - } -} - -static int -_scan (lisp_stream_t *stream) -{ - static char *delims = "\"();"; - - int c; - - _token_clear(); - - do - { - c = _next_char(stream); - if (c == EOF) - return TOKEN_EOF; - else if (c == ';') /* comment start */ - while (1) - { - c = _next_char(stream); - if (c == EOF) - return TOKEN_EOF; - else if (c == '\n') - break; - } - } - while (isspace(c)); - - switch (c) - { - case '(' : - return TOKEN_OPEN_PAREN; - - case ')' : - return TOKEN_CLOSE_PAREN; - - case '"' : - while (1) - { - c = _next_char(stream); - if (c == EOF) - return TOKEN_ERROR; - if (c == '"') - break; - if (c == '\\') - { - c = _next_char(stream); - - switch (c) - { - case EOF : - return TOKEN_ERROR; - - case 'n' : - c = '\n'; - break; - - case 't' : - c = '\t'; - break; - } - } - - _token_append(c); - } - return TOKEN_STRING; - - case '#' : - c = _next_char(stream); - if (c == EOF) - return TOKEN_ERROR; - - switch (c) - { - case 't' : - return TOKEN_TRUE; - - case 'f' : - return TOKEN_FALSE; - - case '?' : - c = _next_char(stream); - if (c == EOF) - return TOKEN_ERROR; - - if (c == '(') - return TOKEN_PATTERN_OPEN_PAREN; - else - return TOKEN_ERROR; - } - return TOKEN_ERROR; - - default : - if (isdigit(c) || c == '-') - { - int have_nondigits = 0; - int have_digits = 0; - int have_floating_point = 0; - - do - { - if (isdigit(c)) - have_digits = 1; - else if (c == '.') - have_floating_point++; - _token_append(c); - - c = _next_char(stream); - - if (c != EOF && !isdigit(c) && !isspace(c) && c != '.' && !strchr(delims, c)) - have_nondigits = 1; - } - while (c != EOF && !isspace(c) && !strchr(delims, c)); - - if (c != EOF) - _unget_char(c, stream); - - if (have_nondigits || !have_digits || have_floating_point > 1) - return TOKEN_SYMBOL; - else if (have_floating_point == 1) - return TOKEN_REAL; - else - return TOKEN_INTEGER; - } - else - { - if (c == '.') - { - c = _next_char(stream); - if (c != EOF && !isspace(c) && !strchr(delims, c)) - _token_append('.'); - else - { - _unget_char(c, stream); - return TOKEN_DOT; - } - } - do - { - _token_append(c); - c = _next_char(stream); - } - while (c != EOF && !isspace(c) && !strchr(delims, c)); - if (c != EOF) - _unget_char(c, stream); - - return TOKEN_SYMBOL; - } - } - - throw std::runtime_error("invalid token in lisp file"); - return TOKEN_ERROR; -} - -static lisp_object_t* -lisp_object_alloc (int type) -{ - lisp_object_t *obj = (lisp_object_t*)malloc(sizeof(lisp_object_t)); - - obj->type = type; - - return obj; -} - -lisp_stream_t* -SuperTux::lisp_stream_init_file (lisp_stream_t *stream, FILE *file) -{ - stream->type = LISP_STREAM_FILE; - stream->v.file = file; - - return stream; -} - -lisp_stream_t* -SuperTux::lisp_stream_init_string (lisp_stream_t *stream, char *buf) -{ - stream->type = LISP_STREAM_STRING; - stream->v.string.buf = buf; - stream->v.string.pos = 0; - - return stream; -} - -lisp_stream_t* -SuperTux::lisp_stream_init_any (lisp_stream_t *stream, void *data, - int (*next_char) (void *data), - void (*unget_char) (char c, void *data)) -{ - if (next_char == 0 || unget_char == 0) - throw std::runtime_error("no data"); - - stream->type = LISP_STREAM_ANY; - stream->v.any.data = data; - stream->v.any.next_char= next_char; - stream->v.any.unget_char = unget_char; - - return stream; -} - -lisp_object_t* -SuperTux::lisp_make_integer (int value) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_INTEGER); - - obj->v.integer = value; - - return obj; -} - -lisp_object_t* -SuperTux::lisp_make_real (float value) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_REAL); - - obj->v.real = value; - - return obj; -} - -lisp_object_t* -SuperTux::lisp_make_symbol (const char *value) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_SYMBOL); - - obj->v.string = strdup(value); - - return obj; -} - -lisp_object_t* -SuperTux::lisp_make_string (const char *value) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_STRING); - - obj->v.string = strdup(value); - - return obj; -} - -lisp_object_t* -SuperTux::lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_CONS); - - obj->v.cons.car = car; - obj->v.cons.cdr = cdr; - - return obj; -} - -lisp_object_t* -SuperTux::lisp_make_boolean (int value) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_BOOLEAN); - - obj->v.integer = value ? 1 : 0; - - return obj; -} - -static lisp_object_t* -lisp_make_pattern_cons (lisp_object_t *car, lisp_object_t *cdr) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_PATTERN_CONS); - - obj->v.cons.car = car; - obj->v.cons.cdr = cdr; - - return obj; -} - -static lisp_object_t* -lisp_make_pattern_var (int type, int index, lisp_object_t *sub) -{ - lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_PATTERN_VAR); - - obj->v.pattern.type = type; - obj->v.pattern.index = index; - obj->v.pattern.sub = sub; - - return obj; -} - -lisp_object_t* -SuperTux::lisp_read (lisp_stream_t *in) -{ - int token = _scan(in); - lisp_object_t *obj = lisp_nil(); - - if (token == TOKEN_EOF) - return &end_marker; - - switch (token) - { - case TOKEN_ERROR : - return &error_object; - - case TOKEN_EOF : - return &end_marker; - - case TOKEN_OPEN_PAREN : - case TOKEN_PATTERN_OPEN_PAREN : - { - lisp_object_t *last = lisp_nil(), *car; - - do - { - car = lisp_read(in); - if (car == &error_object || car == &end_marker) - { - lisp_free(obj); - return &error_object; - } - else if (car == &dot_marker) - { - if (lisp_nil_p(last)) - { - lisp_free(obj); - return &error_object; - } - - car = lisp_read(in); - if (car == &error_object || car == &end_marker) - { - lisp_free(obj); - return car; - } - else - { - last->v.cons.cdr = car; - - if (_scan(in) != TOKEN_CLOSE_PAREN) - { - lisp_free(obj); - return &error_object; - } - - car = &close_paren_marker; - } - } - else if (car != &close_paren_marker) - { - if (lisp_nil_p(last)) - obj = last = (token == TOKEN_OPEN_PAREN ? lisp_make_cons(car, lisp_nil()) : lisp_make_pattern_cons(car, lisp_nil())); - else - last = last->v.cons.cdr = lisp_make_cons(car, lisp_nil()); - } - } - while (car != &close_paren_marker); - } - return obj; - - case TOKEN_CLOSE_PAREN : - return &close_paren_marker; - - case TOKEN_SYMBOL : - return lisp_make_symbol(token_string); - - case TOKEN_STRING : - return lisp_make_string(token_string); - - case TOKEN_INTEGER : - return lisp_make_integer(atoi(token_string)); - - case TOKEN_REAL : - return lisp_make_real((float)atof(token_string)); - - case TOKEN_DOT : - return &dot_marker; - - case TOKEN_TRUE : - return lisp_make_boolean(1); - - case TOKEN_FALSE : - return lisp_make_boolean(0); - } - - throw std::runtime_error("syntax error in lisp file"); - return &error_object; -} - -void -SuperTux::lisp_free (lisp_object_t *obj) -{ - if (obj == 0) - return; - - /** We have to use this iterative code, because the recursive function - * produces a stack overflow and crashs on OSX 10.2 - */ - std::vector objs; - objs.push_back(obj); - - while(!objs.empty()) { - lisp_object_t* obj = objs.back(); - objs.pop_back(); - - switch (obj->type) { - case LISP_TYPE_INTERNAL : - case LISP_TYPE_PARSE_ERROR : - case LISP_TYPE_EOF : - return; - - case LISP_TYPE_SYMBOL : - case LISP_TYPE_STRING : - free(obj->v.string); - break; - - case LISP_TYPE_CONS : - case LISP_TYPE_PATTERN_CONS : - if(obj->v.cons.car) - objs.push_back(obj->v.cons.car); - if(obj->v.cons.cdr) - objs.push_back(obj->v.cons.cdr); - break; - - case LISP_TYPE_PATTERN_VAR : - if(obj->v.pattern.sub) - objs.push_back(obj->v.pattern.sub); - break; - } - - free(obj); - } -} - -lisp_object_t* -SuperTux::lisp_read_from_string (const char *buf) -{ - lisp_stream_t stream; - - lisp_stream_init_string(&stream, (char*)buf); - return lisp_read(&stream); -} - -static int -_compile_pattern (lisp_object_t **obj, int *index) -{ - if (*obj == 0) - return 1; - - switch (lisp_type(*obj)) - { - case LISP_TYPE_PATTERN_CONS : - { - struct - { - char *name; - int type; - } - types[] = - { - { "any", LISP_PATTERN_ANY }, - { "symbol", LISP_PATTERN_SYMBOL }, - { "string", LISP_PATTERN_STRING }, - { "integer", LISP_PATTERN_INTEGER }, - { "real", LISP_PATTERN_REAL }, - { "boolean", LISP_PATTERN_BOOLEAN }, - { "list", LISP_PATTERN_LIST }, - { "or", LISP_PATTERN_OR }, - { 0, 0 } - }; - char *type_name; - int type; - int i; - lisp_object_t *pattern; - type = -1; - - if (lisp_type(lisp_car(*obj)) != LISP_TYPE_SYMBOL) - return 0; - - type_name = lisp_symbol(lisp_car(*obj)); - for (i = 0; types[i].name != 0; ++i) - { - if (strcmp(types[i].name, type_name) == 0) - { - type = types[i].type; - break; - } - } - - if (types[i].name == 0) - return 0; - - if (type != LISP_PATTERN_OR && lisp_cdr(*obj) != 0) - return 0; - - pattern = lisp_make_pattern_var(type, (*index)++, lisp_nil()); - - if (type == LISP_PATTERN_OR) - { - lisp_object_t *cdr = lisp_cdr(*obj); - - if (!_compile_pattern(&cdr, index)) - { - lisp_free(pattern); - return 0; - } - - pattern->v.pattern.sub = cdr; - - (*obj)->v.cons.cdr = lisp_nil(); - } - - lisp_free(*obj); - - *obj = pattern; - } - break; - - case LISP_TYPE_CONS : - if (!_compile_pattern(&(*obj)->v.cons.car, index)) - return 0; - if (!_compile_pattern(&(*obj)->v.cons.cdr, index)) - return 0; - break; - } - - return 1; -} - -int -SuperTux::lisp_compile_pattern (lisp_object_t **obj, int *num_subs) -{ - int index = 0; - int result; - - result = _compile_pattern(obj, &index); - - if (result && num_subs != 0) - *num_subs = index; - - return result; -} - -static int _match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars); - -static int -_match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars) -{ - if (lisp_type(pattern) != LISP_TYPE_PATTERN_VAR) - throw std::runtime_error("type is not a var"); - - switch (pattern->v.pattern.type) - { - case LISP_PATTERN_ANY : - break; - - case LISP_PATTERN_SYMBOL : - if (obj == 0 || lisp_type(obj) != LISP_TYPE_SYMBOL) - return 0; - break; - - case LISP_PATTERN_STRING : - if (obj == 0 || lisp_type(obj) != LISP_TYPE_STRING) - return 0; - break; - - case LISP_PATTERN_INTEGER : - if (obj == 0 || lisp_type(obj) != LISP_TYPE_INTEGER) - return 0; - break; - - case LISP_PATTERN_REAL : - if (obj == 0 || lisp_type(obj) != LISP_TYPE_REAL) - return 0; - break; - - case LISP_PATTERN_BOOLEAN : - if (obj == 0 || lisp_type(obj) != LISP_TYPE_BOOLEAN) - return 0; - break; - - case LISP_PATTERN_LIST : - if (obj == 0 || lisp_type(obj) != LISP_TYPE_CONS) - return 0; - break; - - case LISP_PATTERN_OR : - { - lisp_object_t *sub; - int matched = 0; - - for (sub = pattern->v.pattern.sub; sub != 0; sub = lisp_cdr(sub)) - { - if (lisp_type(sub) != LISP_TYPE_CONS) - throw std::runtime_error("type isn't a car/cons"); - - if (_match_pattern(lisp_car(sub), obj, vars)) - matched = 1; - } - - if (!matched) - return 0; - } - break; - - default : - assert(false); - } - - if (vars != 0) - vars[pattern->v.pattern.index] = obj; - - return 1; -} - -static int -_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars) -{ - if (pattern == 0) - return obj == 0; - - if (obj == 0) - return 0; - - if (lisp_type(pattern) == LISP_TYPE_PATTERN_VAR) - return _match_pattern_var(pattern, obj, vars); - - if (lisp_type(pattern) != lisp_type(obj)) - return 0; - - switch (lisp_type(pattern)) - { - case LISP_TYPE_SYMBOL : - return strcmp(lisp_symbol(pattern), lisp_symbol(obj)) == 0; - - case LISP_TYPE_STRING : - return strcmp(lisp_string(pattern), lisp_string(obj)) == 0; - - case LISP_TYPE_INTEGER : - return lisp_integer(pattern) == lisp_integer(obj); - - case LISP_TYPE_REAL : - return lisp_real(pattern) == lisp_real(obj); - - case LISP_TYPE_CONS : - { - int result1, result2; - - result1 = _match_pattern(lisp_car(pattern), lisp_car(obj), vars); - result2 = _match_pattern(lisp_cdr(pattern), lisp_cdr(obj), vars); - - return result1 && result2; - } - break; - - default : - assert(false); - } - - return 0; -} - -int -SuperTux::lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars, int num_subs) -{ - int i; - - if (vars != 0) - for (i = 0; i < num_subs; ++i) - vars[i] = &error_object; - - return _match_pattern(pattern, obj, vars); -} - -int -SuperTux::lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t **vars) -{ - lisp_object_t *pattern; - int result; - int num_subs; - - pattern = lisp_read_from_string(pattern_string); - - if (pattern != 0 && (lisp_type(pattern) == LISP_TYPE_EOF - || lisp_type(pattern) == LISP_TYPE_PARSE_ERROR)) - return 0; - - if (!lisp_compile_pattern(&pattern, &num_subs)) - { - lisp_free(pattern); - return 0; - } - - result = lisp_match_pattern(pattern, obj, vars, num_subs); - - lisp_free(pattern); - - return result; -} - -int -SuperTux::lisp_type (lisp_object_t *obj) -{ - if (obj == 0) - return LISP_TYPE_NIL; - return obj->type; -} - -int -SuperTux::lisp_integer (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_INTEGER) - throw std::runtime_error("expected integer"); - - return obj->v.integer; -} - -char* -SuperTux::lisp_symbol (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_SYMBOL) - throw std::runtime_error("expected symbol"); - - return obj->v.string; -} - -char* -SuperTux::lisp_string (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_STRING) - throw std::runtime_error("expected string"); - - return obj->v.string; -} - -int -SuperTux::lisp_boolean (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_BOOLEAN) - throw std::runtime_error("expected boolean"); - - return obj->v.integer; -} - -float -SuperTux::lisp_real (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_REAL && obj->type != LISP_TYPE_INTEGER) - throw std::runtime_error("expected real"); - - if (obj->type == LISP_TYPE_INTEGER) - return obj->v.integer; - return obj->v.real; -} - -lisp_object_t* -SuperTux::lisp_car (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw std::runtime_error("expected car"); - - return obj->v.cons.car; -} - -lisp_object_t* -SuperTux::lisp_cdr (lisp_object_t *obj) -{ - if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw std::runtime_error("expected cons"); - - return obj->v.cons.cdr; -} - -lisp_object_t* -SuperTux::lisp_cxr (lisp_object_t *obj, const char *x) -{ - int i; - - for (i = strlen(x) - 1; i >= 0; --i) - if (x[i] == 'a') - obj = lisp_car(obj); - else if (x[i] == 'd') - obj = lisp_cdr(obj); - else - throw std::runtime_error("couldn't parse cxr"); - - return obj; -} - -int -SuperTux::lisp_list_length (lisp_object_t *obj) -{ - int length = 0; - - while (obj != 0) - { - if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw std::runtime_error("expected cons"); - - ++length; - obj = obj->v.cons.cdr; - } - - return length; -} - -lisp_object_t* -SuperTux::lisp_list_nth_cdr (lisp_object_t *obj, int index) -{ - while (index > 0) - { - if (obj == 0) - throw std::runtime_error("list too short"); - if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw std::runtime_error("expected cons"); - - --index; - obj = obj->v.cons.cdr; - } - - return obj; -} - -lisp_object_t* -SuperTux::lisp_list_nth (lisp_object_t *obj, int index) -{ - obj = lisp_list_nth_cdr(obj, index); - - if (obj == 0) - throw std::runtime_error("list too short"); - - return obj->v.cons.car; -} - -void -SuperTux::lisp_dump (lisp_object_t *obj, FILE *out) -{ - if (obj == 0) - { - fprintf(out, "()"); - return; - } - - switch (lisp_type(obj)) - { - case LISP_TYPE_EOF : - fputs("#", out); - break; - - case LISP_TYPE_PARSE_ERROR : - fputs("#", out); - break; - - case LISP_TYPE_INTEGER : - fprintf(out, "%d", lisp_integer(obj)); - break; - - case LISP_TYPE_REAL : - fprintf(out, "%f", lisp_real(obj)); - break; - - case LISP_TYPE_SYMBOL : - fputs(lisp_symbol(obj), out); - break; - - case LISP_TYPE_STRING : - { - char *p; - - fputc('"', out); - for (p = lisp_string(obj); *p != 0; ++p) - { - if (*p == '"' || *p == '\\') - fputc('\\', out); - fputc(*p, out); - } - fputc('"', out); - } - break; - - case LISP_TYPE_CONS : - case LISP_TYPE_PATTERN_CONS : - fputs(lisp_type(obj) == LISP_TYPE_CONS ? "(" : "#?(", out); - while (obj != 0) - { - lisp_dump(lisp_car(obj), out); - obj = lisp_cdr(obj); - if (obj != 0) - { - if (lisp_type(obj) != LISP_TYPE_CONS - && lisp_type(obj) != LISP_TYPE_PATTERN_CONS) - { - fputs(" . ", out); - lisp_dump(obj, out); - break; - } - else - fputc(' ', out); - } - } - fputc(')', out); - break; - - case LISP_TYPE_BOOLEAN : - if (lisp_boolean(obj)) - fputs("#t", out); - else - fputs("#f", out); - break; - - default : - throw std::runtime_error("unknown list type"); - } -} - -using namespace std; - -LispReader::LispReader (lisp_object_t* l) - : owner(0), lst (l) -{ -} - -LispReader::~LispReader() -{ - if(owner) - lisp_free(owner); -} - -LispReader* -LispReader::load(const std::string& filename, const std::string& toplevellist) -{ - lisp_object_t* obj = lisp_read_from_file(filename); - - if(obj->type == LISP_TYPE_EOF || obj->type == LISP_TYPE_PARSE_ERROR) { - lisp_free(obj); - throw std::runtime_error("Error while parsing lispfile"); - } - - if(toplevellist != lisp_symbol(lisp_car(obj))) { - lisp_car(obj); - throw std::runtime_error("Worng toplevel symbol in lisp file"); - } - - LispReader* reader = new LispReader(lisp_cdr(obj)); - reader->owner = obj; - - return reader; -} - -lisp_object_t* -LispReader::search_for(const char* name) -{ - //std::cout << "LispReader::search_for(" << name << ")" << std::endl; - lisp_object_t* cursor = lst; - - while(!lisp_nil_p(cursor)) - { - lisp_object_t* cur = lisp_car(cursor); - - if (!lisp_cons_p(cur) || !lisp_symbol_p (lisp_car(cur))) - { - lisp_dump(cur, stdout); - printf("LispReader: Read error in search\n"); - } - else - { - if (strcmp(lisp_symbol(lisp_car(cur)), name) == 0) - { - return lisp_cdr(cur); - } - } - - cursor = lisp_cdr (cursor); - } - return 0; -} - -bool -LispReader::read_int (const char* name, int& i) -{ - lisp_object_t* obj = search_for (name); - if(!obj) - return false; - - if (!lisp_integer_p(lisp_car(obj))) - return false; - - i = lisp_integer(lisp_car(obj)); - return true; -} - -bool -LispReader::read_uint (const char* name, unsigned int& i) -{ - lisp_object_t* obj = search_for (name); - if(!obj) - return false; - - if (!lisp_integer_p(lisp_car(obj))) - return false; - - i = (unsigned int) lisp_integer(lisp_car(obj)); - return true; -} - -bool -LispReader::read_lisp(const char* name, lisp_object_t*& b) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - b = obj; - return true; -} - -lisp_object_t* -LispReader::read_lisp(const char* name) -{ - return search_for(name); -} - -bool -LispReader::read_float (const char* name, float& f) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - if (!lisp_real_p(lisp_car(obj)) && !lisp_integer_p(lisp_car(obj))) - Termination::abort("LispReader expected type real at token: ", name); - - f = lisp_real(lisp_car(obj)); - return true; -} - -bool -LispReader::read_string_vector (const char* name, std::vector& vec) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - vec.clear(); - while(!lisp_nil_p(obj)) - { - if (!lisp_string_p(lisp_car(obj))) - Termination::abort("LispReader expected type string at token: ", name); - vec.push_back(lisp_string(lisp_car(obj))); - obj = lisp_cdr(obj); - } - return true; -} - -bool -LispReader::read_int_vector (const char* name, std::vector& vec) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - vec.clear(); - while(!lisp_nil_p(obj)) - { - if (!lisp_integer_p(lisp_car(obj))) - Termination::abort("LispReader expected type integer at token: ", name); - vec.push_back(lisp_integer(lisp_car(obj))); - obj = lisp_cdr(obj); - } - return true; -} - -bool -LispReader::read_int_vector (const char* name, std::vector& vec) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - vec.clear(); - while(!lisp_nil_p(obj)) - { - if (!lisp_integer_p(lisp_car(obj))) - Termination::abort("LispReader expected type integer at token: ", name); - vec.push_back(lisp_integer(lisp_car(obj))); - obj = lisp_cdr(obj); - } - return true; -} - -bool -LispReader::read_char_vector (const char* name, std::vector& vec) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - vec.clear(); - while(!lisp_nil_p(obj)) - { - vec.push_back(*lisp_string(lisp_car(obj))); - obj = lisp_cdr(obj); - } - return true; -} - -bool -LispReader::read_string (const char* name, std::string& str, bool translatable) -{ - lisp_object_t* obj; - if(translatable) - { - /* Internationalization support: check for the suffix: str + "-" + $LANG variable. - If not found, use the regular string. - So, translating a string in a Lisp file would result in something like: - (text "Hello World!") - (text-fr "Bonjour Monde!") - being fr the value of LANG (echo $LANG) for the language we want to translate to */ - - char* lang = getenv("LANG"); - - char str_[1024]; // check, for instance, for (title-fr_FR "Bonjour") - sprintf(str_, "%s-%s", name, lang); - - obj = search_for (str_); - - if(!obj) // check, for instance, for (title-fr "Bonjour") - { - if(lang != NULL && strlen(lang) >= 2) - { - char lang_[3]; - strncpy(lang_, lang, 2); - lang_[2] = '\0'; - sprintf(str_, "%s-%s", name, lang_); - - obj = search_for (str_); - } - else - obj = 0; - } - - if(!obj) // check, for instance, for (title "Hello") - obj = search_for (name); - } - else - obj = search_for (name); - - if (!obj) - return false; - - if (!lisp_string_p(lisp_car(obj))) - Termination::abort("LispReader expected type string at token: ", name); - str = lisp_string(lisp_car(obj)); - return true; -} - -bool -LispReader::read_bool (const char* name, bool& b) -{ - lisp_object_t* obj = search_for (name); - if (!obj) - return false; - - if (!lisp_boolean_p(lisp_car(obj))) - Termination::abort("LispReader expected type bool at token: ", name); - b = lisp_boolean(lisp_car(obj)); - return true; -} - -lisp_object_t* -LispReader::get_lisp() -{ - return lst; -} - -lisp_object_t* SuperTux::lisp_read_from_file(const std::string& filename) -{ - FILE* in = fopen(filename.c_str(), "r"); - - if(!in) - return 0; - - lisp_stream_t stream; - lisp_stream_init_file(&stream, in); - lisp_object_t* obj = lisp_read(&stream); - fclose(in); - - return obj; -} diff --git a/lib/utils/lispreader.h b/lib/utils/lispreader.h deleted file mode 100644 index ad8ed16f2..000000000 --- a/lib/utils/lispreader.h +++ /dev/null @@ -1,201 +0,0 @@ -/* $Id$ */ -/* - * lispreader.h - * - * Copyright (C) 1998-2000 Mark Probst - * Copyright (C) 2002 Ingo Ruhnke - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef SUPERTUX_LISPREADER_H -#define SUPERTUX_LISPREADER_H - -#include -#include -#include -#include - -#include - -#include "utils/exceptions.h" - -namespace SuperTux { - -#define LISP_STREAM_FILE 1 -#define LISP_STREAM_STRING 2 -#define LISP_STREAM_ANY 3 - -#define LISP_TYPE_INTERNAL -3 -#define LISP_TYPE_PARSE_ERROR -2 -#define LISP_TYPE_EOF -1 -#define LISP_TYPE_NIL 0 -#define LISP_TYPE_SYMBOL 1 -#define LISP_TYPE_INTEGER 2 -#define LISP_TYPE_STRING 3 -#define LISP_TYPE_REAL 4 -#define LISP_TYPE_CONS 5 -#define LISP_TYPE_PATTERN_CONS 6 -#define LISP_TYPE_BOOLEAN 7 -#define LISP_TYPE_PATTERN_VAR 8 - -#define LISP_PATTERN_ANY 1 -#define LISP_PATTERN_SYMBOL 2 -#define LISP_PATTERN_STRING 3 -#define LISP_PATTERN_INTEGER 4 -#define LISP_PATTERN_REAL 5 -#define LISP_PATTERN_BOOLEAN 6 -#define LISP_PATTERN_LIST 7 -#define LISP_PATTERN_OR 8 - -typedef struct - { - int type; - - union - { - FILE *file; - struct - { - char *buf; - int pos; - } - string; - struct - { - void *data; - int (*next_char) (void *data); - void (*unget_char) (char c, void *data); - } - any; - } v; - } -lisp_stream_t; - -typedef struct _lisp_object_t lisp_object_t; -struct _lisp_object_t - { - int type; - - union - { - struct - { - struct _lisp_object_t *car; - struct _lisp_object_t *cdr; - } - cons; - - char *string; - int integer; - float real; - - struct - { - int type; - int index; - struct _lisp_object_t *sub; - } - pattern; - } v; - }; - -lisp_stream_t* lisp_stream_init_file (lisp_stream_t *stream, FILE *file); -lisp_stream_t* lisp_stream_init_string (lisp_stream_t *stream, char *buf); -lisp_stream_t* lisp_stream_init_any (lisp_stream_t *stream, void *data, - int (*next_char) (void *data), - void (*unget_char) (char c, void *data)); - -lisp_object_t* lisp_read (lisp_stream_t *in); -lisp_object_t* lisp_read_from_file(const std::string& filename); -void lisp_free (lisp_object_t *obj); - -lisp_object_t* lisp_read_from_string (const char *buf); - -int lisp_compile_pattern (lisp_object_t **obj, int *num_subs); -int lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars, int num_subs); -int lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t **vars); - -int lisp_type (lisp_object_t *obj); -int lisp_integer (lisp_object_t *obj); -float lisp_real (lisp_object_t *obj); -char* lisp_symbol (lisp_object_t *obj); -char* lisp_string (lisp_object_t *obj); -int lisp_boolean (lisp_object_t *obj); -lisp_object_t* lisp_car (lisp_object_t *obj); -lisp_object_t* lisp_cdr (lisp_object_t *obj); - -lisp_object_t* lisp_cxr (lisp_object_t *obj, const char *x); - -lisp_object_t* lisp_make_integer (int value); -lisp_object_t* lisp_make_real (float value); -lisp_object_t* lisp_make_symbol (const char *value); -lisp_object_t* lisp_make_string (const char *value); -lisp_object_t* lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr); -lisp_object_t* lisp_make_boolean (int value); - -int lisp_list_length (lisp_object_t *obj); -lisp_object_t* lisp_list_nth_cdr (lisp_object_t *obj, int index); -lisp_object_t* lisp_list_nth (lisp_object_t *obj, int index); - -void lisp_dump (lisp_object_t *obj, FILE *out); - -#define lisp_nil() ((lisp_object_t*)0) - -#define lisp_nil_p(obj) (obj == 0) -#define lisp_integer_p(obj) (lisp_type((obj)) == LISP_TYPE_INTEGER) -#define lisp_real_p(obj) (lisp_type((obj)) == LISP_TYPE_REAL) -#define lisp_symbol_p(obj) (lisp_type((obj)) == LISP_TYPE_SYMBOL) -#define lisp_string_p(obj) (lisp_type((obj)) == LISP_TYPE_STRING) -#define lisp_cons_p(obj) (lisp_type((obj)) == LISP_TYPE_CONS) -#define lisp_boolean_p(obj) (lisp_type((obj)) == LISP_TYPE_BOOLEAN) - -/** */ -class LispReader -{ -private: - lisp_object_t* owner; - lisp_object_t* lst; - - lisp_object_t* search_for(const char* name); - -public: - /** cur == ((pos 1 2 3) (id 12 3 4)...) */ - LispReader(lisp_object_t* l); - ~LispReader(); - - bool read_int_vector(const char* name, std::vector& vec); - bool read_int_vector(const char* name, std::vector& vec); - bool read_char_vector(const char* name, std::vector& vec); - bool read_string_vector(const char* name, std::vector& vec); - bool read_string(const char* name, std::string& str, bool translatable = false); - bool read_int(const char* name, int& i); - bool read_uint(const char* name, unsigned int& i); - bool read_float(const char* name, float& f); - bool read_bool(const char* name, bool& b); - bool read_lisp(const char* name, lisp_object_t*& b); - lisp_object_t* read_lisp(const char* name); - - static LispReader* load(const std::string& filename, - const std::string& toplevellist); - - lisp_object_t* get_lisp(); -}; - -} //namespace SuperTux - -#endif /*SUPERTUX_LISPREADER_H*/ - diff --git a/lib/utils/lispwriter.cpp b/lib/utils/lispwriter.cpp deleted file mode 100644 index 383927cb7..000000000 --- a/lib/utils/lispwriter.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// $Id$ -// -// SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun - -#include - -#include "lispwriter.h" - -using namespace SuperTux; - -LispWriter::LispWriter(std::ostream& newout) - : out(newout), indent_depth(0) -{ -} - -LispWriter::~LispWriter() -{ - if(lists.size() > 0) { - std::cerr << "Warning: Not all sections closed in lispwriter!\n"; - } -} - -void -LispWriter::write_comment(const std::string& comment) -{ - out << "; " << comment << "\n"; -} - -void -LispWriter::start_list(const std::string& listname) -{ - indent(); - out << '(' << listname << '\n'; - indent_depth += 2; - - lists.push_back(listname); -} - -void -LispWriter::end_list(const std::string& listname) -{ - if(lists.size() == 0) { - std::cerr << "Trying to close list '" << listname - << "', which is not open.\n"; - return; - } - if(lists.back() != listname) { - std::cerr << "Warning: trying to close list '" << listname - << "' while list '" << lists.back() << "' is open.\n"; - return; - } - lists.pop_back(); - - indent_depth -= 2; - indent(); - out << ")\n"; -} - -void -LispWriter::write_int(const std::string& name, int value) -{ - indent(); - out << '(' << name << ' ' << value << ")\n"; -} - -void -LispWriter::write_float(const std::string& name, float value) -{ - indent(); - out << '(' << name << ' ' << value << ")\n"; -} - -void -LispWriter::write_string(const std::string& name, const std::string& value) -{ - indent(); - out << '(' << name << " \"" << value << "\")\n"; -} - -void -LispWriter::write_bool(const std::string& name, bool value) -{ - indent(); - out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n"; -} - -void -LispWriter::write_int_vector(const std::string& name, - const std::vector& value) -{ - indent(); - out << '(' << name; - for(std::vector::const_iterator i = value.begin(); i != value.end(); ++i) - out << " " << *i; - out << ")\n"; -} - -void -LispWriter::write_int_vector(const std::string& name, - const std::vector& value) -{ - indent(); - out << '(' << name; - for(std::vector::const_iterator i = value.begin(); i != value.end(); ++i) - out << " " << *i; - out << ")\n"; -} - -void -LispWriter::indent() -{ - for(int i = 0; i -#include -#include - -namespace SuperTux - { - - class LispWriter - { - public: - LispWriter(std::ostream& out); - ~LispWriter(); - - void write_comment(const std::string& comment); - - void start_list(const std::string& listname); - - void write_int(const std::string& name, int value); - void write_float(const std::string& name, float value); - void write_string(const std::string& name, const std::string& value); - void write_bool(const std::string& name, bool value); - void write_int_vector(const std::string& name, const std::vector& value); - void write_int_vector(const std::string& name, const std::vector& value); - // add more write-functions when needed... - - void end_list(const std::string& listname); - - private: - void indent(); - - std::ostream& out; - int indent_depth; - std::vector lists; - }; - -} //namespace SuperTux - -#endif //SUPERTUX_LISPWRITER_H -