projects
/
supertux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fixed MN_STRINGSELECT menu item
[supertux.git]
/
src
/
lisp
/
parser.cpp
diff --git
a/src/lisp/parser.cpp
b/src/lisp/parser.cpp
index
65f163a
..
a558adc
100644
(file)
--- a/
src/lisp/parser.cpp
+++ b/
src/lisp/parser.cpp
@@
-1,8
+1,7
@@
// $Id$
//
// $Id$
//
-// TuxKart - a fun racing game with go-kart
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
+// SuperTux
+// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@@
-25,10
+24,13
@@
#include <cassert>
#include <iostream>
#include <cassert>
#include <iostream>
-#include "tinygettext/tinygettext.h"
-#include "parser.h"
-#include "lisp.h"
-#include "file_system.h"
+#include "tinygettext/tinygettext.hpp"
+#include "physfs/physfs_stream.hpp"
+#include "parser.hpp"
+#include "lisp.hpp"
+#include "obstack/obstackpp.hpp"
+
+#include "gameconfig.hpp"
namespace lisp
{
namespace lisp
{
@@
-38,19
+40,35
@@
Parser::Parser(bool translate)
{
if(translate) {
dictionary_manager = new TinyGetText::DictionaryManager();
{
if(translate) {
dictionary_manager = new TinyGetText::DictionaryManager();
+ dictionary_manager->set_charset("UTF-8");
+ if (config && (config->locale != "")) dictionary_manager->set_language(config->locale);
}
}
+
+ obstack_init(&obst);
}
Parser::~Parser()
{
}
Parser::~Parser()
{
+ obstack_free(&obst, NULL);
delete lexer;
delete dictionary_manager;
}
delete lexer;
delete dictionary_manager;
}
-Lisp*
+static std::string dirname(const std::string& filename)
+{
+ std::string::size_type p = filename.find_last_of('/');
+ if(p == std::string::npos)
+ return "";
+
+ return filename.substr(0, p+1);
+}
+
+const Lisp*
Parser::parse(const std::string& filename)
{
Parser::parse(const std::string& filename)
{
- std::ifstream in(filename.c_str());
+ IFileStreambuf ins(filename);
+ std::istream in(&ins);
+
if(!in.good()) {
std::stringstream msg;
msg << "Parser problem: Couldn't open file '" << filename << "'.";
if(!in.good()) {
std::stringstream msg;
msg << "Parser problem: Couldn't open file '" << filename << "'.";
@@
-58,50
+76,55
@@
Parser::parse(const std::string& filename)
}
if(dictionary_manager) {
}
if(dictionary_manager) {
- dictionary_manager->add_directory(
FileSystem::
dirname(filename));
+ dictionary_manager->add_directory(dirname(filename));
dictionary = & (dictionary_manager->get_dictionary());
}
dictionary = & (dictionary_manager->get_dictionary());
}
-
- return parse(in);
+
+ return parse(in
, filename
);
}
}
-Lisp*
-Parser::parse(std::istream& stream)
+
const
Lisp*
+Parser::parse(std::istream& stream
, const std::string& sourcename
)
{
delete lexer;
lexer = new Lexer(stream);
{
delete lexer;
lexer = new Lexer(stream);
+ this->filename = sourcename;
token = lexer->getNextToken();
token = lexer->getNextToken();
- Lisp* result = new Lisp(Lisp::TYPE_CONS);
+
+ Lisp* result = new(obst) Lisp(Lisp::TYPE_CONS);
result->v.cons.car = read();
result->v.cons.cdr = 0;
result->v.cons.car = read();
result->v.cons.cdr = 0;
-
+
delete lexer;
lexer = 0;
delete lexer;
lexer = 0;
- return result;
+ return result;
+}
+
+void
+Parser::parse_error(const char* msg) const
+{
+ std::stringstream emsg;
+ emsg << "Parse Error at '" << filename << "' line " << lexer->getLineNumber()
+ << ": " << msg;
+ throw std::runtime_error(emsg.str());
}
}
-Lisp*
+
const
Lisp*
Parser::read()
{
Lisp* result;
switch(token) {
case Lexer::TOKEN_EOF: {
Parser::read()
{
Lisp* result;
switch(token) {
case Lexer::TOKEN_EOF: {
- std::stringstream msg;
- msg << "Parse Error at line " << lexer->getLineNumber() << ": "
- << "Unexpected EOF.";
- throw std::runtime_error(msg.str());
+ parse_error("Unexpected EOF.");
}
case Lexer::TOKEN_CLOSE_PAREN: {
}
case Lexer::TOKEN_CLOSE_PAREN: {
- std::stringstream msg;
- msg << "Parse Error at line " << lexer->getLineNumber() << ": "
- << "Unexpected ')'.";
- throw std::runtime_error(msg.str());
+ parse_error("Unexpected ')'.");
}
case Lexer::TOKEN_OPEN_PAREN: {
}
case Lexer::TOKEN_OPEN_PAREN: {
- result = new Lisp(Lisp::TYPE_CONS);
-
+ result = new
(obst)
Lisp(Lisp::TYPE_CONS);
+
token = lexer->getNextToken();
if(token == Lexer::TOKEN_CLOSE_PAREN) {
result->v.cons.car = 0;
token = lexer->getNextToken();
if(token == Lexer::TOKEN_CLOSE_PAREN) {
result->v.cons.car = 0;
@@
-114,21
+137,21
@@
Parser::read()
// evaluate translation function (_ str) in place here
token = lexer->getNextToken();
if(token != Lexer::TOKEN_STRING)
// evaluate translation function (_ str) in place here
token = lexer->getNextToken();
if(token != Lexer::TOKEN_STRING)
-
throw new std::runtim
e_error("Expected string after '(_'");
-
- result = new Lisp(Lisp::TYPE_STRING);
+
pars
e_error("Expected string after '(_'");
+
+ result = new
(obst)
Lisp(Lisp::TYPE_STRING);
if(dictionary) {
std::string translation = dictionary->translate(lexer->getString());
if(dictionary) {
std::string translation = dictionary->translate(lexer->getString());
- result->v.string = new char[translation.size()+1];
+ result->v.string = new
(obst)
char[translation.size()+1];
memcpy(result->v.string, translation.c_str(), translation.size()+1);
} else {
memcpy(result->v.string, translation.c_str(), translation.size()+1);
} else {
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new char[len];
+ size_t len = strlen(lexer->getString()) + 1;
+ result->v.string = new
(obst)
char[len];
memcpy(result->v.string, lexer->getString(), len);
}
token = lexer->getNextToken();
if(token != Lexer::TOKEN_CLOSE_PAREN)
memcpy(result->v.string, lexer->getString(), len);
}
token = lexer->getNextToken();
if(token != Lexer::TOKEN_CLOSE_PAREN)
-
throw new std::runtim
e_error("Expected ')' after '(_ string'");
+
pars
e_error("Expected ')' after '(_ string'");
break;
}
break;
}
@@
-139,40
+162,41
@@
Parser::read()
cur->v.cons.cdr = 0;
break;
}
cur->v.cons.cdr = 0;
break;
}
- cur->v.cons.cdr = new Lisp(Lisp::TYPE_CONS);
- cur = cur->v.cons.cdr;
+ Lisp *newcur = new(obst) Lisp(Lisp::TYPE_CONS);
+ cur->v.cons.cdr = newcur;
+ cur = newcur;
} while(1);
break;
}
case Lexer::TOKEN_SYMBOL: {
} while(1);
break;
}
case Lexer::TOKEN_SYMBOL: {
- result = new Lisp(Lisp::TYPE_SYMBOL);
+ result = new
(obst)
Lisp(Lisp::TYPE_SYMBOL);
size_t len = strlen(lexer->getString()) + 1;
size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new char[len];
+ result->v.string = new
(obst)
char[len];
memcpy(result->v.string, lexer->getString(), len);
break;
}
case Lexer::TOKEN_STRING: {
memcpy(result->v.string, lexer->getString(), len);
break;
}
case Lexer::TOKEN_STRING: {
- result = new Lisp(Lisp::TYPE_STRING);
+ result = new
(obst)
Lisp(Lisp::TYPE_STRING);
size_t len = strlen(lexer->getString()) + 1;
size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new char[len];
+ result->v.string = new
(obst)
char[len];
memcpy(result->v.string, lexer->getString(), len);
break;
}
case Lexer::TOKEN_INTEGER:
memcpy(result->v.string, lexer->getString(), len);
break;
}
case Lexer::TOKEN_INTEGER:
- result = new Lisp(Lisp::TYPE_INTEGER);
+ result = new
(obst)
Lisp(Lisp::TYPE_INTEGER);
sscanf(lexer->getString(), "%d", &result->v.integer);
break;
case Lexer::TOKEN_REAL:
sscanf(lexer->getString(), "%d", &result->v.integer);
break;
case Lexer::TOKEN_REAL:
- result = new Lisp(Lisp::TYPE_REAL);
+ result = new
(obst)
Lisp(Lisp::TYPE_REAL);
sscanf(lexer->getString(), "%f", &result->v.real);
break;
case Lexer::TOKEN_TRUE:
sscanf(lexer->getString(), "%f", &result->v.real);
break;
case Lexer::TOKEN_TRUE:
- result = new Lisp(Lisp::TYPE_BOOLEAN);
+ result = new
(obst)
Lisp(Lisp::TYPE_BOOLEAN);
result->v.boolean = true;
break;
case Lexer::TOKEN_FALSE:
result->v.boolean = true;
break;
case Lexer::TOKEN_FALSE:
- result = new Lisp(Lisp::TYPE_BOOLEAN);
+ result = new
(obst)
Lisp(Lisp::TYPE_BOOLEAN);
result->v.boolean = false;
break;
result->v.boolean = false;
break;