reworked miniswig a bit to support virtual functions and to only emit constructors...
authorMatthias Braun <matze@braunis.de>
Thu, 5 May 2005 18:58:00 +0000 (18:58 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 5 May 2005 18:58:00 +0000 (18:58 +0000)
SVN-Revision: 2411

src/scripting/Jamfile
src/scripting/scripted_object.h
src/scripting/wrapper.cpp
src/scripting/wrapper.interface.h
tools/miniswig/create_wrapper.cpp
tools/miniswig/create_wrapper.h
tools/miniswig/lexer.ll
tools/miniswig/parser.yy
tools/miniswig/tree.h

index 9def306..6214f71 100644 (file)
@@ -11,7 +11,7 @@ if $(MINISWIG)
         SEARCH on $(headerfile) = $(SOURCH_SOURCE) ;
     
         MiniSwig $(cppfile) : $(sources) ;
-        CPPFLAGS on $(cppfile) = $(CPPFLAGS) ;
+        CPPFLAGS on $(cppfile) = $(CPPFLAGS) -DSCRIPTING_API ;
         headerfile on $(cppfile) = $(headerfile) ;
         modulename on $(cppfile) = $(3) ;
         FLAGS on $(cppfile) = $(4) ;
index b22fd08..4ac8177 100644 (file)
@@ -8,20 +8,20 @@ class ScriptedObject
 {
 public:
 #ifndef SCRIPTING_API
-    ScriptedObject();
-    virtual ~ScriptedObject();
+  ScriptedObject();
+  virtual ~ScriptedObject();
 #endif
 
-    void set_animation(const std::string& animation);
-    std::string get_animation();
+  virtual void set_animation(const std::string& animation) = 0;
+  virtual std::string get_animation() = 0;
 
-    void move(float x, float y);
-    void set_pos(float x, float y);
-    float get_pos_x();
-    float get_pos_y();
-    void set_velocity(float x, float y);
-    float get_velocity_x();
-    float get_velocity_y();
+  virtual void move(float x, float y) = 0;
+  virtual void set_pos(float x, float y) = 0;
+  virtual float get_pos_x() = 0;
+  virtual float get_pos_y() = 0;
+  virtual void set_velocity(float x, float y) = 0;
+  virtual float get_velocity_x() = 0;
+  virtual float get_velocity_y() = 0;
 };
 
 }
index d8c475c..5cb15e3 100644 (file)
 
 using namespace Scripting;
 
-static int Display_release_wrapper(SQUserPointer ptr, int )
-{
-  Display* _this = reinterpret_cast<Display*> (ptr);
-  delete _this;
-  return 0;
-}
-
-static int Display_construct_wrapper(HSQUIRRELVM v)
-{
-  Display* _this = new Display();
-  sq_setinstanceup(v, 1, _this);
-  sq_setreleasehook(v, 1, Display_release_wrapper);
-
-  return 0;
-}
-
 static int Display_set_effect_wrapper(HSQUIRRELVM v)
 {
-  Display* _this;
+  Scripting::Display* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   const char* arg0;
   sq_getstring(v, 2, &arg0);
   
@@ -41,27 +24,10 @@ static int Display_set_effect_wrapper(HSQUIRRELVM v)
   return 0;
 }
 
-static int Camera_release_wrapper(SQUserPointer ptr, int )
-{
-  Camera* _this = reinterpret_cast<Camera*> (ptr);
-  delete _this;
-  return 0;
-}
-
-static int Camera_construct_wrapper(HSQUIRRELVM v)
-{
-  Camera* _this = new Camera();
-  sq_setinstanceup(v, 1, _this);
-  sq_setreleasehook(v, 1, Camera_release_wrapper);
-
-  return 0;
-}
-
 static int Camera_shake_wrapper(HSQUIRRELVM v)
 {
-  Camera* _this;
+  Scripting::Camera* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   float arg0;
   sq_getfloat(v, 2, &arg0);
   float arg1;
@@ -76,9 +42,8 @@ static int Camera_shake_wrapper(HSQUIRRELVM v)
 
 static int Camera_set_pos_wrapper(HSQUIRRELVM v)
 {
-  Camera* _this;
+  Scripting::Camera* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   float arg0;
   sq_getfloat(v, 2, &arg0);
   float arg1;
@@ -91,9 +56,8 @@ static int Camera_set_pos_wrapper(HSQUIRRELVM v)
 
 static int Camera_set_mode_wrapper(HSQUIRRELVM v)
 {
-  Camera* _this;
+  Scripting::Camera* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   const char* arg0;
   sq_getstring(v, 2, &arg0);
   
@@ -102,27 +66,10 @@ static int Camera_set_mode_wrapper(HSQUIRRELVM v)
   return 0;
 }
 
-static int Level_release_wrapper(SQUserPointer ptr, int )
-{
-  Level* _this = reinterpret_cast<Level*> (ptr);
-  delete _this;
-  return 0;
-}
-
-static int Level_construct_wrapper(HSQUIRRELVM v)
-{
-  Level* _this = new Level();
-  sq_setinstanceup(v, 1, _this);
-  sq_setreleasehook(v, 1, Level_release_wrapper);
-
-  return 0;
-}
-
 static int Level_finish_wrapper(HSQUIRRELVM v)
 {
-  Level* _this;
+  Scripting::Level* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   
   _this->finish();
   
@@ -131,9 +78,8 @@ static int Level_finish_wrapper(HSQUIRRELVM v)
 
 static int Level_spawn_wrapper(HSQUIRRELVM v)
 {
-  Level* _this;
+  Scripting::Level* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   const char* arg0;
   sq_getstring(v, 2, &arg0);
   const char* arg1;
@@ -144,27 +90,10 @@ static int Level_spawn_wrapper(HSQUIRRELVM v)
   return 0;
 }
 
-static int ScriptedObject_release_wrapper(SQUserPointer ptr, int )
-{
-  ScriptedObject* _this = reinterpret_cast<ScriptedObject*> (ptr);
-  delete _this;
-  return 0;
-}
-
-static int ScriptedObject_construct_wrapper(HSQUIRRELVM v)
-{
-  ScriptedObject* _this = new ScriptedObject();
-  sq_setinstanceup(v, 1, _this);
-  sq_setreleasehook(v, 1, ScriptedObject_release_wrapper);
-
-  return 0;
-}
-
 static int ScriptedObject_set_animation_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   const char* arg0;
   sq_getstring(v, 2, &arg0);
   
@@ -175,9 +104,8 @@ static int ScriptedObject_set_animation_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_get_animation_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   
   std::string return_value = _this->get_animation();
   
@@ -187,9 +115,8 @@ static int ScriptedObject_get_animation_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_move_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   float arg0;
   sq_getfloat(v, 2, &arg0);
   float arg1;
@@ -202,9 +129,8 @@ static int ScriptedObject_move_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_set_pos_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   float arg0;
   sq_getfloat(v, 2, &arg0);
   float arg1;
@@ -217,9 +143,8 @@ static int ScriptedObject_set_pos_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   
   float return_value = _this->get_pos_x();
   
@@ -229,9 +154,8 @@ static int ScriptedObject_get_pos_x_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   
   float return_value = _this->get_pos_y();
   
@@ -241,9 +165,8 @@ static int ScriptedObject_get_pos_y_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_set_velocity_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   float arg0;
   sq_getfloat(v, 2, &arg0);
   float arg1;
@@ -256,9 +179,8 @@ static int ScriptedObject_set_velocity_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   
   float return_value = _this->get_velocity_x();
   
@@ -268,9 +190,8 @@ static int ScriptedObject_get_velocity_x_wrapper(HSQUIRRELVM v)
 
 static int ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM v)
 {
-  ScriptedObject* _this;
+  Scripting::ScriptedObject* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   
   float return_value = _this->get_velocity_y();
   
@@ -278,27 +199,10 @@ static int ScriptedObject_get_velocity_y_wrapper(HSQUIRRELVM v)
   return 1;
 }
 
-static int Sound_release_wrapper(SQUserPointer ptr, int )
-{
-  Sound* _this = reinterpret_cast<Sound*> (ptr);
-  delete _this;
-  return 0;
-}
-
-static int Sound_construct_wrapper(HSQUIRRELVM v)
-{
-  Sound* _this = new Sound();
-  sq_setinstanceup(v, 1, _this);
-  sq_setreleasehook(v, 1, Sound_release_wrapper);
-
-  return 0;
-}
-
 static int Sound_play_music_wrapper(HSQUIRRELVM v)
 {
-  Sound* _this;
+  Scripting::Sound* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   const char* arg0;
   sq_getstring(v, 2, &arg0);
   
@@ -309,9 +213,8 @@ static int Sound_play_music_wrapper(HSQUIRRELVM v)
 
 static int Sound_play_sound_wrapper(HSQUIRRELVM v)
 {
-  Sound* _this;
+  Scripting::Sound* _this;
   sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);
-  assert(_this != 0);
   const char* arg0;
   sq_getstring(v, 2, &arg0);
   
@@ -336,25 +239,21 @@ WrappedFunction supertux_global_functions[] = {
 };
 
 static WrappedFunction supertux_Display_methods[] = {
-  { "constructor", &Display_construct_wrapper },
   { "set_effect", &Display_set_effect_wrapper },
 };
 
 static WrappedFunction supertux_Camera_methods[] = {
-  { "constructor", &Camera_construct_wrapper },
   { "shake", &Camera_shake_wrapper },
   { "set_pos", &Camera_set_pos_wrapper },
   { "set_mode", &Camera_set_mode_wrapper },
 };
 
 static WrappedFunction supertux_Level_methods[] = {
-  { "constructor", &Level_construct_wrapper },
   { "finish", &Level_finish_wrapper },
   { "spawn", &Level_spawn_wrapper },
 };
 
 static WrappedFunction supertux_ScriptedObject_methods[] = {
-  { "constructor", &ScriptedObject_construct_wrapper },
   { "set_animation", &ScriptedObject_set_animation_wrapper },
   { "get_animation", &ScriptedObject_get_animation_wrapper },
   { "move", &ScriptedObject_move_wrapper },
@@ -367,7 +266,6 @@ static WrappedFunction supertux_ScriptedObject_methods[] = {
 };
 
 static WrappedFunction supertux_Sound_methods[] = {
-  { "constructor", &Sound_construct_wrapper },
   { "play_music", &Sound_play_music_wrapper },
   { "play_sound", &Sound_play_sound_wrapper },
 };
index 0b4513d..fe729d6 100644 (file)
@@ -1,9 +1,8 @@
 /** This file is processes by miniswig to produce the scripting API */
-#define SCRIPTING_API
-
 #include "display.h"
 #include "camera.h"
 #include "level.h"
 #include "scripted_object.h"
 #include "sound.h"
 #include "functions.h"
+
index f5ebbfe..b3223bb 100644 (file)
@@ -85,15 +85,13 @@ WrapperCreator::create_wrapper(Namespace* ns)
             
         out << "static WrappedFunction " << modulename << "_"
             << _class->name << "_methods[] = {\n";
-        out << ind << "{ \"constructor\", &"
-            << _class->name << "_" << "construct_wrapper },\n";
         for(std::vector<ClassMember*>::iterator i = _class->members.begin();
                 i != _class->members.end(); ++i) {
             ClassMember* member = *i;
             if(member->visibility != ClassMember::PUBLIC)
                 continue;
             Function* function = dynamic_cast<Function*> (member);
-            if(!function || function->type != Function::FUNCTION)
+            if(!function || function->type == Function::DESTRUCTOR)
                 continue;
 
             out << ind << "{ \"" << function->name << "\", &"
@@ -111,11 +109,15 @@ WrapperCreator::create_wrapper(Namespace* ns)
 void
 WrapperCreator::create_function_wrapper(Class* _class, Function* function)
 {
-    if(function->type == Function::CONSTRUCTOR)
-        throw std::runtime_error("Constructors not supported yet");
     if(function->type == Function::DESTRUCTOR)
-        throw std::runtime_error("Destructors not supported yet");
-    
+        assert(false);
+
+    std::string ns_prefix;
+    if(selected_namespace != "")
+        ns_prefix = selected_namespace + "::";
+    if(function->type == Function::CONSTRUCTOR)
+        function->name = "constructor";
+
     out << "static int ";
     if(_class != 0) {
         out << _class->name << "_";
@@ -124,15 +126,15 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
         << "{\n";
     // avoid warning...
     if(_class == 0 && function->parameters.empty() 
-            && function->return_type.is_void()) {
+            && function->return_type.is_void()
+            && function->type != Function::CONSTRUCTOR) {
         out << ind << "(void) v;\n";
     }
     
-    // eventually retrieve pointer to class
-    if(_class != 0) {
-        out << ind << _class->name << "* _this;\n";
+    // eventually retrieve pointer to class instance
+    if(_class != 0 && function->type != Function::CONSTRUCTOR) {
+        out << ind << ns_prefix <<  _class->name << "* _this;\n";
         out << ind << "sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);\n";
-        out << ind << "assert(_this != 0);\n";
     }
     
     // declare and retrieve arguments
@@ -145,6 +147,7 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
  
         ++i;
     }
+    
     // call function
     out << ind << "\n";
     out << ind;
@@ -153,17 +156,30 @@ WrapperCreator::create_function_wrapper(Class* _class, Function* function)
         out << " return_value = ";
     }
     if(_class != 0) {
-        out << "_this->";
-    } else if(selected_namespace != "") {
-        out << selected_namespace << "::";
+        if(function->type == Function::CONSTRUCTOR) {
+            out << ns_prefix << _class->name << "* _this = new " << ns_prefix;
+        } else {
+            out << "_this->";
+        }
+    } else {
+        out << ns_prefix;
+    }
+    if(function->type == Function::CONSTRUCTOR) {
+        out << _class->name << "(";
+    } else {
+        out << function->name << "(";
     }
-    out << function->name << "(";
     for(size_t i = 0; i < function->parameters.size(); ++i) {
         if(i != 0)
             out << ", ";
         out << "arg" << i;
     }
     out << ");\n";
+    if(function->type == Function::CONSTRUCTOR) {
+        out << ind << "sq_setinstanceup(v, 1, _this);\n";
+        out << ind << "sq_setreleasehook(v, 1, " 
+            << _class->name << "_release_hook);\n";
+    }
     out << ind << "\n";
     // push return value back on stack and return
     if(function->return_type.is_void()) {
@@ -230,8 +246,7 @@ WrapperCreator::push_to_stack(const Type& type, const std::string& var)
 void
 WrapperCreator::create_class_wrapper(Class* _class)
 {
-    create_class_destruct_function(_class);
-    create_class_construct_function(_class);
+    bool release_hook_created = false;
     for(std::vector<ClassMember*>::iterator i = _class->members.begin();
             i != _class->members.end(); ++i) {
         ClassMember* member = *i;
@@ -240,33 +255,22 @@ WrapperCreator::create_class_wrapper(Class* _class)
         Function* function = dynamic_cast<Function*> (member);
         if(!function)
             continue;
-        // don't wrap constructors and destructors (for now...)
-        if(function->type != Function::FUNCTION)
+        if(function->type == Function::CONSTRUCTOR
+            && !release_hook_created) {
+          create_class_release_hook(_class);
+          release_hook_created = true;
+        }
+        // don't wrap destructors
+        if(function->type == Function::DESTRUCTOR)
             continue;
         create_function_wrapper(_class, function);
     }
 }
 
 void
-WrapperCreator::create_class_construct_function(Class* _class)
-{
-    out << "static int " << _class->name << "_construct_wrapper(HSQUIRRELVM v)\n";
-    out << "{\n";
-    out << ind << _class->name << "* _this = new "
-        << _class->name << "();\n";
-    out << ind << "sq_setinstanceup(v, 1, _this);\n";
-    out << ind << "sq_setreleasehook(v, 1, " 
-        << _class->name << "_release_wrapper);\n";
-    out << "\n";
-    out << ind << "return 0;\n";
-    out << "}\n";
-    out << "\n";
-}
-
-void
-WrapperCreator::create_class_destruct_function(Class* _class)
+WrapperCreator::create_class_release_hook(Class* _class)
 {
-    out << "static int " << _class->name << "_release_wrapper(SQUserPointer ptr, int )\n"
+    out << "static int " << _class->name << "_release_hook(SQUserPointer ptr, int )\n"
         << "{\n"
         << ind << _class->name 
         << "* _this = reinterpret_cast<" << _class->name << "*> (ptr);\n"
index 0b546eb..359c1ed 100644 (file)
@@ -20,8 +20,7 @@ public:
 
     void create_wrapper(Namespace* ns);
     void create_class_wrapper(Class* _class);
-    void create_class_construct_function(Class* _class);
-    void create_class_destruct_function(Class* _class);
+    void create_class_release_hook(Class* _class);
     void create_function_wrapper(Class* _class, Function* function);
     void prepare_argument(const Type& type, size_t idx, const std::string& var);
     void push_to_stack(const Type& type, const std::string& var);
index 3285ec4..0e6229c 100644 (file)
@@ -28,6 +28,7 @@
 class                                   { return T_CLASS; }
 struct                                  { return T_STRUCT; }
 static                                  { return T_STATIC; }
+virtual                                 { return T_VIRTUAL; }
 const                                   { return T_CONST; }
 unsigned                                { return T_UNSIGNED; }
 signed                                  { return T_SIGNED; }
index e66b58c..6c25c9e 100644 (file)
@@ -66,6 +66,7 @@ private:
 %token T_CLASS
 %token T_STRUCT
 %token T_STATIC
+%token T_VIRTUAL
 %token T_CONST
 %token T_UNSIGNED
 %token T_SIGNED
@@ -195,35 +196,45 @@ constructor_declaration:
 ;
 
 destructor_declaration:
-    '~' T_ID '(' ')' ';'
+    maybe_virtual '~' T_ID '(' ')' abstract_declaration ';'
         {
             currentFunction = new Function();
             currentFunction->type = Function::DESTRUCTOR;
-            free($2);
+            free($3);
             $$ = currentFunction;
         }
 ;
 
+maybe_virtual:
+    /* empty */
+    | T_VIRTUAL
+;
+
 variable_declaration:
     type T_ID ';'
 ;
 
 function_declaration:
-    type T_ID '(' 
+    maybe_virtual type T_ID '(' 
         {
             currentFunction = new Function();
             currentFunction->type = Function::FUNCTION;
-            currentFunction->return_type = *($1);
-            delete $1;
-            currentFunction->name = $2;
-            free($2);
+            currentFunction->return_type = *($2);
+            delete $2;
+            currentFunction->name = $3;
+            free($3);
         }                           
-    parameter_list ')' ';'
+    parameter_list ')' abstract_declaration ';'
         {
             $$ = currentFunction;
         }
 ;
 
+abstract_declaration:
+    /* empty */
+    | '=' T_INT
+;
+
 parameter_list:
     /* empty */
     | parameters
@@ -270,9 +281,13 @@ prefix_type_modifiers:
 
 prefix_type_modifier:
     T_UNSIGNED
+        { current_type->_unsigned = true; }
     | T_SIGNED
+        { current_type->_unsigned = false; }
     | T_STATIC
+        { current_type->_static = true; }
     | T_CONST
+        { current_type->_const = true; }
 ;
 
 postfix_type_modifiers:
index 181a9fe..b6f8554 100644 (file)
@@ -48,7 +48,8 @@ private:
 class Type {
 public:
     Type() 
-        : atomic_type(0), _const(false), _static(false), pointer(0), ref(0)
+        : atomic_type(0), _unsigned(false), _const(false), _static(false),
+        pointer(0), ref(0)
     { }
 
     void write_c_type(std::ostream& out)
@@ -66,12 +67,15 @@ public:
 
     bool is_void() const
     {
+        if(atomic_type == 0)
+            return true;
         if(atomic_type == &BasicType::VOID && pointer == 0)
             return true;
         return false;
     }
 
     AtomicType* atomic_type;
+    bool _unsigned;
     bool _const;
     bool _static;
     // number of '*' in the type declaration...