void update();
private:
- //static const size_t STREAMBUFFERSIZE = 1024 * 500;
- static const size_t STREAMBUFFERSIZE = 1024 * 20;
+ static const size_t STREAMBUFFERSIZE = 1024 * 500;
static const size_t STREAMFRAGMENTS = 5;
static const size_t STREAMFRAGMENTSIZE
= STREAMBUFFERSIZE / STREAMFRAGMENTS;
#include <cstdlib>
#include <string>
#include <stdexcept>
-#include <sstream>
-#include <fstream>
#include "lisp/parser.hpp"
#include "lisp/lisp.hpp"
#include <string>
-class Config {
+class Config
+{
public:
Config();
~Config();
{ 0, 0 }
};
+WrappedConstant<int> supertux_int_constants[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_float_constants[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_string_constants[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_DisplayEffect_methods[] = {
{ "fade_out", &DisplayEffect_fade_out_wrapper },
{ "fade_in", &DisplayEffect_fade_in_wrapper },
{ "is_black", &DisplayEffect_is_black_wrapper },
};
+static WrappedConstant<int> supertux_DisplayEffect_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_DisplayEffect_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_DisplayEffect_string_consts[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_Camera_methods[] = {
{ "shake", &Camera_shake_wrapper },
{ "set_pos", &Camera_set_pos_wrapper },
{ "set_mode", &Camera_set_mode_wrapper },
};
+static WrappedConstant<int> supertux_Camera_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_Camera_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_Camera_string_consts[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_Level_methods[] = {
{ "finish", &Level_finish_wrapper },
{ "spawn", &Level_spawn_wrapper },
{ "flip_vertically", &Level_flip_vertically_wrapper },
};
+static WrappedConstant<int> supertux_Level_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_Level_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_Level_string_consts[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_ScriptedObject_methods[] = {
{ "set_animation", &ScriptedObject_set_animation_wrapper },
{ "get_animation", &ScriptedObject_get_animation_wrapper },
{ "get_name", &ScriptedObject_get_name_wrapper },
};
+static WrappedConstant<int> supertux_ScriptedObject_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_ScriptedObject_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_ScriptedObject_string_consts[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_Sound_methods[] = {
{ "play_music", &Sound_play_music_wrapper },
{ "play", &Sound_play_wrapper },
};
+static WrappedConstant<int> supertux_Sound_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_Sound_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_Sound_string_consts[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_Text_methods[] = {
{ "set_text", &Text_set_text_wrapper },
{ "set_font", &Text_set_font_wrapper },
{ "set_visible", &Text_set_visible_wrapper },
};
+static WrappedConstant<int> supertux_Text_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_Text_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_Text_string_consts[] = {
+ { 0, 0}
+};
+
static WrappedFunction supertux_Player_methods[] = {
{ "set_bonus", &Player_set_bonus_wrapper },
{ "make_invincible", &Player_make_invincible_wrapper },
{ "add_coins", &Player_add_coins_wrapper },
};
+static WrappedConstant<int> supertux_Player_int_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<float> supertux_Player_float_consts[] = {
+ { 0, 0}
+};
+
+WrappedConstant<const char*> supertux_Player_string_consts[] = {
+ { 0, 0}
+};
+
WrappedClass supertux_classes[] = {
- { "DisplayEffect", supertux_DisplayEffect_methods },
- { "Camera", supertux_Camera_methods },
- { "Level", supertux_Level_methods },
- { "ScriptedObject", supertux_ScriptedObject_methods },
- { "Sound", supertux_Sound_methods },
- { "Text", supertux_Text_methods },
- { "Player", supertux_Player_methods },
- { 0, 0 }
+ { "DisplayEffect", supertux_DisplayEffect_methods, supertux_DisplayEffect_int_consts, supertux_DisplayEffect_float_consts, supertux_DisplayEffect_string_consts },
+ { "Camera", supertux_Camera_methods, supertux_Camera_int_consts, supertux_Camera_float_consts, supertux_Camera_string_consts },
+ { "Level", supertux_Level_methods, supertux_Level_int_consts, supertux_Level_float_consts, supertux_Level_string_consts },
+ { "ScriptedObject", supertux_ScriptedObject_methods, supertux_ScriptedObject_int_consts, supertux_ScriptedObject_float_consts, supertux_ScriptedObject_string_consts },
+ { "Sound", supertux_Sound_methods, supertux_Sound_int_consts, supertux_Sound_float_consts, supertux_Sound_string_consts },
+ { "Text", supertux_Text_methods, supertux_Text_int_consts, supertux_Text_float_consts, supertux_Text_string_consts },
+ { "Player", supertux_Player_methods, supertux_Player_int_consts, supertux_Player_float_consts, supertux_Player_string_consts },
+ { 0, 0, 0, 0, 0 }
};
extern WrappedFunction supertux_global_functions[];
extern WrappedClass supertux_classes[];
+extern WrappedConstant<int> supertux_int_constants[];
+extern WrappedConstant<float> supertux_float_constants[];
+extern WrappedConstant<const char*> supertux_string_constants[];
+
+static inline void register_supertux_wrapper(HSQUIRRELVM v)
+{
+ register_functions(v, supertux_global_functions);
+ register_classes(v, supertux_classes);
+ register_constants(v, supertux_int_constants);
+ register_constants(v, supertux_float_constants);
+ register_constants(v, supertux_string_constants);
+}
#endif
{
sq_pushstring(v, name, -1);
sq_newclosure(v, func, 0); //create a new function
- sq_createslot(v, -3);
+ if(sq_createslot(v, -3) < 0) {
+ std::stringstream msg;
+ msg << "Couldn't register function '" << name << "'";
+ throw SquirrelError(v, msg.str());
+ }
}
static void register_class(HSQUIRRELVM v, WrappedClass* wclass)
{
sq_pushstring(v, wclass->name, -1);
sq_newclass(v, false);
- for(WrappedFunction* func = wclass->functions; func->name != 0; ++func) {
- register_function(v, func->f, func->name);
+ register_functions(v, wclass->functions);
+ register_constants(v, wclass->int_consts);
+ register_constants(v, wclass->float_consts);
+ register_constants(v, wclass->string_consts);
+
+ if(sq_createslot(v, -3) < 0) {
+ std::stringstream msg;
+ msg << "Couldn't register function '" << wclass->name << "'";
+ throw SquirrelError(v, msg.str());
}
- sq_createslot(v, -3);
}
void register_functions(HSQUIRRELVM v, WrappedFunction* functions)
sq_pop(v, 1);
}
+
void print_squirrel_stack(HSQUIRRELVM v)
{
printf("--------------------------------------------------------------\n");
case OT_USERPOINTER:
printf("userpointer");
break;
+ case OT_THREAD:
+ printf("thread");
+ break;
case OT_CLASS:
printf("class");
break;
msg << "SQuirrel error: " << message << " (";
const char* lasterr;
sq_getlasterror(v);
- sq_getstring(v, -1, &lasterr);
+ if(sq_gettype(v, -1) != OT_STRING) {
+ lasterr = "no error info";
+ } else {
+ sq_getstring(v, -1, &lasterr);
+ }
sq_pop(v, 1);
msg << lasterr << ")";
this->message = msg.str();
#include <squirrel.h>
#include <exception>
+#include <sstream>
#include <string>
struct WrappedFunction {
const char* name;
SQFUNCTION f;
};
+
+template<typename T>
+struct WrappedConstant {
+ const char* name;
+ T value;
+};
+
struct WrappedClass {
const char* name;
WrappedFunction* functions;
+ WrappedConstant<int>* int_consts;
+ WrappedConstant<float>* float_consts;
+ WrappedConstant<const char*>* string_consts;
};
class SquirrelError : public std::exception
void register_functions(HSQUIRRELVM v, WrappedFunction* functions);
void register_classes(HSQUIRRELVM v, WrappedClass* classes);
+static inline void push_value(HSQUIRRELVM v, int val)
+{
+ sq_pushinteger(v, val);
+}
+
+static inline void push_value(HSQUIRRELVM v, float val)
+{
+ sq_pushfloat(v, val);
+}
+
+static inline void push_value(HSQUIRRELVM v, const char* str)
+{
+ sq_pushstring(v, str, -1);
+}
+
+template<typename T>
+void register_constants(HSQUIRRELVM v, WrappedConstant<T>* constants)
+{
+ sq_pushroottable(v);
+ for(WrappedConstant<T>* c = constants; *constants->name != 0; ++c) {
+ sq_pushstring(v, c->name, -1);
+ push_value(v, c->value);
+ if(sq_createslot(v, -3) < 0) {
+ std::stringstream msg;
+ msg << "Couldn't register int constant '" << c->name << "'";
+ throw SquirrelError(v, msg.str());
+ }
+ }
+ sq_pop(v, 1);
+}
+
void print_squirrel_stack(HSQUIRRELVM v);
#endif
<< "\n"
<< "extern WrappedFunction " << modulename << "_global_functions[];\n"
<< "extern WrappedClass " << modulename << "_classes[];\n"
+ << "extern WrappedConstant<int> "
+ << modulename << "_int_constants[];\n"
+ << "extern WrappedConstant<float> "
+ << modulename << "_float_constants[];\n"
+ << "extern WrappedConstant<const char*> "
+ << modulename << "_string_constants[];\n"
+ << "\n"
+ << "static inline void register_"
+ << modulename << "_wrapper(HSQUIRRELVM v)\n"
+ << "{\n"
+ << " register_functions(v, "
+ << modulename << "_global_functions);\n"
+ << " register_classes(v, " << modulename << "_classes);\n"
+ << " register_constants(v, " << modulename << "_int_constants);\n"
+ << " register_constants(v, " << modulename << "_float_constants);\n"
+ << " register_constants(v, "<< modulename << "_string_constants);\n"
+ << "}\n"
<< "\n"
<< "#endif\n"
<< "\n";
}
// create function list...
- out << "WrappedFunction " << modulename << "_global_functions[] = {\n";
- for(std::vector<Function*>::iterator i = ns->functions.begin();
- i != ns->functions.end(); ++i) {
- Function* function = *i;
- out << ind << "{ \"" << function->name << "\", &"
- << function->name << "_wrapper },\n";
- }
- out << ind << "{ 0, 0 }\n"
- << "};\n"
- << "\n";
+ create_function_list(ns);
+ create_const_lists(ns);
// create class list...
std::ostringstream classlist;
continue;
classlist << ind << "{ \"" << _class->name << "\", "
- << modulename << "_" << _class->name
- << "_methods },\n";
-
+ << modulename << "_" << _class->name << "_methods, "
+ << modulename << "_" << _class->name << "_int_consts, "
+ << modulename << "_" << _class->name << "_float_consts, "
+ << modulename << "_" << _class->name << "_string_consts "
+ << "},\n";
+
out << "static WrappedFunction " << modulename << "_"
<< _class->name << "_methods[] = {\n";
for(std::vector<ClassMember*>::iterator i = _class->members.begin();
}
out << "};\n"
<< "\n";
+ create_class_const_lists(_class);
}
- classlist << ind << "{ 0, 0 }\n";
+ classlist << ind << "{ 0, 0, 0, 0, 0 }\n";
classlist << "};\n";
out << classlist.str();
out << "\n";
}
void
+WrapperCreator::create_function_list(Namespace* ns)
+{
+ out << "WrappedFunction " << modulename << "_global_functions[] = {\n";
+ for(std::vector<Function*>::iterator i = ns->functions.begin();
+ i != ns->functions.end(); ++i) {
+ Function* function = *i;
+ out << ind << "{ \"" << function->name << "\", &"
+ << function->name << "_wrapper },\n";
+ }
+ out << ind << "{ 0, 0 }\n"
+ << "};\n"
+ << "\n";
+}
+
+void
+WrapperCreator::create_const_lists(Namespace* ns)
+{
+ out << "WrappedConstant<int> " << modulename << "_int_constants[] = {\n";
+ for(std::vector<Field*>::iterator i = ns->fields.begin();
+ i != ns->fields.end(); ++i) {
+ Field* field = *i;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::INT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_int_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<float> "
+ << modulename << "_float_constants[] = {\n";
+ for(std::vector<Field*>::iterator i = ns->fields.begin();
+ i != ns->fields.end(); ++i) {
+ Field* field = *i;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::FLOAT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<const char*> "
+ << modulename << "_string_constants[] = {\n";
+ for(std::vector<Field*>::iterator i = ns->fields.begin();
+ i != ns->fields.end(); ++i) {
+ Field* field = *i;
+ if(!field->has_const_value
+ || field->type->atomic_type != StringType::instance())
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+}
+
+void
+WrapperCreator::create_class_const_lists(Class* _class)
+{
+ out << "static WrappedConstant<int> "
+ << modulename << "_" << _class->name << "_int_consts[] = {\n";
+ for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+ i != _class->members.end(); ++i) {
+ ClassMember* member = *i;
+ if(member->visibility != ClassMember::PUBLIC)
+ continue;
+ Field* field = dynamic_cast<Field*> (member);
+ if(!field)
+ continue;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::INT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_int_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<float> "
+ << modulename << "_" << _class->name << "_float_consts[] = {\n";
+ for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+ i != _class->members.end(); ++i) {
+ ClassMember* member = *i;
+ if(member->visibility != ClassMember::PUBLIC)
+ continue;
+ Field* field = dynamic_cast<Field*> (member);
+ if(!field)
+ continue;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::FLOAT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<const char*> "
+ << modulename << "_" << _class->name << "_string_consts[] = {\n";
+ for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+ i != _class->members.end(); ++i) {
+ ClassMember* member = *i;
+ if(member->visibility != ClassMember::PUBLIC)
+ continue;
+ Field* field = dynamic_cast<Field*> (member);
+ if(!field)
+ continue;
+ if(!field->has_const_value
+ || field->type->atomic_type != StringType::instance())
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+}
+
+void
WrapperCreator::create_function_wrapper(Class* _class, Function* function)
{
if(function->type == Function::DESTRUCTOR)
}
void create_wrapper(Namespace* ns);
+
+private:
+ void create_function_list(Namespace* ns);
+ void create_const_lists(Namespace* ns);
+ void create_class_const_lists(Class* _class);
void create_class_wrapper(Class* _class);
void create_class_release_hook(Class* _class);
void create_function_wrapper(Class* _class, Function* function);
class { return T_CLASS; }
struct { return T_STRUCT; }
static { return T_STATIC; }
-virtual { return T_VIRTUAL; }
+virtual { }
const { return T_CONST; }
unsigned { return T_UNSIGNED; }
signed { return T_SIGNED; }
return T_ID;
}
\:\: { return T_DDCOL; }
-[0-9]+ {
- yylval->ival = atoi(yytext);
- return T_INT;
- }
-[0-9]*\.[0-9]+(e[0-9]+)? {
- yylval->fval = atof(yytext);
- return T_FLOAT;
- }
-\".*\" {
- yylval->str = strdup(yytext);
- return T_STRING;
- }
+(0x)?[0-9]+ {
+ sscanf(yytext, "%i", &(yylval->ival));
+ return T_INT;
+}
+[0-9]*\.[0-9]+(e[0-9]+)? {
+ sscanf(yytext, "%f", &(yylval->fval));
+ return T_FLOAT;
+}
+\".*\" {
+ yylval->str = strdup(yytext);
+ return T_STRING;
+}
. { return yytext[0]; }
%%
float fval;
Class* _class;
Function* function;
+ Field* field;
Type* type;
AtomicType* atomic_type;
Namespace* _namespace;
Namespace* search_namespace = 0;
Namespace* current_namespace = 0;
static Class* current_class = 0;
-static Function* currentFunction = 0;
+static Function* current_function = 0;
static Type* current_type = 0;
+static Field* current_field = 0;
static ClassMember::Visbility current_visibility;
class ParseError : public std::exception
%token T_CLASS
%token T_STRUCT
%token T_STATIC
-%token T_VIRTUAL
%token T_CONST
%token T_UNSIGNED
%token T_SIGNED
%type <function> function_declaration
%type <function> constructor_declaration;
%type <function> destructor_declaration;
+%type <field> field_declaration;
%type <type> type
%type <atomic_type> type_identifier
| function_declaration
{ current_namespace->functions.push_back($1); }
| namespace_declaration
+ | field_declaration
+ { current_namespace->fields.push_back($1); }
;
class_declaration:
$1->visibility = current_visibility;
current_class->members.push_back($1);
}
- | variable_declaration
+ | field_declaration
+ {
+ $1->visibility = current_visibility;
+ current_class->members.push_back($1);
+ }
;
visibility_change:
constructor_declaration:
T_ID '('
{
- currentFunction = new Function();
- currentFunction->type = Function::CONSTRUCTOR;
- currentFunction->docu_comment = last_docucomment;
+ current_function = new Function();
+ current_function->type = Function::CONSTRUCTOR;
+ current_function->docu_comment = last_docucomment;
last_docucomment = "";
free($1);
}
parameter_list ')' ';'
{
- $$ = currentFunction;
+ $$ = current_function;
}
;
destructor_declaration:
- maybe_virtual '~' T_ID '(' ')' abstract_declaration ';'
+ '~' T_ID '(' ')' abstract_declaration ';'
{
- currentFunction = new Function();
- currentFunction->type = Function::DESTRUCTOR;
- currentFunction->docu_comment = last_docucomment;
+ current_function = new Function();
+ current_function->type = Function::DESTRUCTOR;
+ current_function->docu_comment = last_docucomment;
last_docucomment = "";
- free($3);
- $$ = currentFunction;
+ free($2);
+ $$ = current_function;
}
;
-maybe_virtual:
- /* empty */
- | T_VIRTUAL
-;
-
-variable_declaration:
- type T_ID ';'
+field_declaration:
+ type T_ID
{
- delete $1;
+ current_field = new Field();
+ current_field->type = $1;
+ current_field->name = $2;
free($2);
}
+ maybe_const_initialisation ';'
+ {
+ $$ = current_field;
+ }
;
+maybe_const_initialisation:
+ /* empty */
+ | '=' T_INT
+ {
+ if(current_field->type->atomic_type == &BasicType::FLOAT) {
+ current_field->const_float_value = (float) $2;
+ } else {
+ current_field->const_int_value = $2;
+ }
+ current_field->has_const_value = true;
+ }
+ | '=' T_FLOAT
+ {
+ current_field->const_float_value = $2;
+ current_field->has_const_value = true;
+ }
+ | '=' T_STRING
+ {
+ current_field->const_string_value = $2;
+ current_field->has_const_value = true;
+ }
+;
+
function_declaration:
- maybe_virtual type T_ID '('
+ type T_ID '('
{
- currentFunction = new Function();
- currentFunction->type = Function::FUNCTION;
- currentFunction->return_type = *($2);
+ /*
+ current_function = new Function();
+ current_function->type = Function::FUNCTION;
+ current_function->return_type = *($2);
delete $2;
- currentFunction->name = $3;
+ current_function->name = $3;
free($3);
- currentFunction->docu_comment = last_docucomment;
+ current_function->docu_comment = last_docucomment;
+ last_docucomment = "";
+ */
+
+ current_function = new Function();
+ current_function->type = Function::FUNCTION;
+ current_function->return_type = *($1);
+ delete $1;
+ current_function->name = $2;
+ free($2);
+ current_function->docu_comment = last_docucomment;
last_docucomment = "";
}
parameter_list ')' abstract_declaration ';'
{
- $$ = currentFunction;
+ $$ = current_function;
}
;
Parameter parameter;
parameter.type = *($1);
delete $1;
- currentFunction->parameters.push_back(parameter);
+ current_function->parameters.push_back(parameter);
}
| type T_ID
{
delete $1;
parameter.name = $2;
free($2);
- currentFunction->parameters.push_back(parameter);
+ current_function->parameters.push_back(parameter);
}
;
std::vector<Parameter> parameters;
};
+class Field : public ClassMember {
+public:
+ Field()
+ {
+ has_const_value = false;
+ }
+
+ Type* type;
+ std::string docu_comment;
+ std::string name;
+ bool has_const_value;
+
+ union {
+ float const_float_value;
+ int const_int_value;
+ };
+ std::string const_string_value;
+};
+
class Class : public AtomicType {
public:
~Class() {
}
std::vector<Function*> functions;
+ std::vector<Field*> fields;
std::vector<AtomicType*> types;
std::vector<Namespace*> namespaces;