change some LAYER_GUI to LAYER_HUD, update tinygettext, fix a warning in miniswig
[supertux.git] / tools / miniswig / parser.yy
index 852892e..e609476 100644 (file)
@@ -1,10 +1,11 @@
 %{
+#include <config.h>
 
 #include <iostream>
 #include <sstream>
 #include <stdexcept>
-#include "tree.h"
-#include "globals.h"
+#include "tree.hpp"
+#include "globals.hpp"
 
 %}
 
@@ -15,6 +16,7 @@
     float       fval;
     Class*      _class;
     Function*   function;
+    Field*      field;
     Type*       type;
     AtomicType* atomic_type;
     Namespace*  _namespace;
@@ -30,14 +32,16 @@ bool search_down = true;
 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 ClassMember::Visbility current_visibility;
+static Field* current_field = 0;
+static ClassMember::Visibility current_visibility;
 
 class ParseError : public std::exception
 {
 public:
-    ParseError(const std::string& message) throw()
+    ParseError(const std::string& message) throw() :
+         message()
     {
         std::ostringstream msg;
         msg << "Parse error in '" << current_file
@@ -67,7 +71,8 @@ private:
 %token T_CLASS
 %token T_STRUCT
 %token T_STATIC
-%token T_VIRTUAL
+%token T_SUSPEND
+%token T_CUSTOM
 %token T_CONST
 %token T_UNSIGNED
 %token T_SIGNED
@@ -75,9 +80,7 @@ private:
 %token T_BOOL
 %token T_CHAR
 %token T_SHORT
-%token T_INT
 %token T_LONG
-%token T_FLOAT
 %token T_DOUBLE
 %token T_PUBLIC
 %token T_PROTECTED
@@ -89,6 +92,7 @@ private:
 %type <function> function_declaration
 %type <function> constructor_declaration;
 %type <function> destructor_declaration;
+%type <field> field_declaration;
 %type <type>   type
 %type <atomic_type> type_identifier
 
@@ -134,10 +138,12 @@ namespace_member:
     | function_declaration
         { current_namespace->functions.push_back($1); }
     | namespace_declaration
+    | field_declaration
+        { current_namespace->fields.push_back($1); }
 ;  
 
 class_declaration:
-    T_CLASS T_ID '{' 
+    T_CLASS T_ID 
         {
             current_class = new Class();
             current_class->name = $2;
@@ -146,12 +152,39 @@ class_declaration:
             last_docucomment = "";
             current_visibility = ClassMember::PROTECTED;
         }
-    class_body '}' ';'
+    superclass_list '{' class_body '}' ';'
         {
             $$ = current_class;
         }
 ;
 
+superclass_list:
+    /* empty */
+    | ':' superclasses
+;
+
+superclasses:
+      superclass
+    | superclasses ',' superclass
+;
+
+superclass:
+    superclass_visibility type_identifier
+        {
+            Class* superclass = dynamic_cast<Class*> ($2);
+            if(superclass == 0)
+                throw ParseError("SuperClass is not a Class type");
+            current_class->super_classes.push_back(superclass);
+            superclass->sub_classes.push_back(current_class);
+        }
+;
+
+superclass_visibility:
+    T_PUBLIC
+    | T_PROTECTED
+    | T_PRIVATE
+;
+
 class_body: /* empty */
         | class_body class_body_element
 ;
@@ -173,7 +206,11 @@ class_body_element:
                 $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:
@@ -188,57 +225,101 @@ 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
+field_declaration:
+    type T_ID 
+        {
+            current_field = new Field();
+            current_field->type = $1;
+            current_field->docu_comment = last_docucomment;
+            last_docucomment = "";
+            current_field->name = $2;
+            free($2);
+        }
+    maybe_const_initialisation ';'
+        {
+            $$ = current_field;
+        }
 ;
 
-variable_declaration:
-    type T_ID ';'
-;
+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);
-            delete $2;
-            currentFunction->name = $3;
-            free($3);
-            currentFunction->docu_comment = 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 ';'
+    parameter_list ')' function_attributes abstract_declaration ';'
         {
-            $$ = currentFunction;
+            $$ = current_function;
         }
 ;
 
+function_attributes:
+    /* empty */
+    | T_CONST function_attributes
+    | T_CUSTOM '(' T_STRING ')' function_attributes
+      {
+        current_function->parameter_spec = $3;
+        current_function->custom = true;
+      }
+    | T_SUSPEND function_attributes
+      {
+        current_function->suspend = true;
+      }
+;
+
 abstract_declaration:
     /* empty */
     | '=' T_INT
@@ -260,16 +341,16 @@ parameter:
             Parameter parameter;
             parameter.type = *($1);
             delete $1;
-            currentFunction->parameters.push_back(parameter);
+            current_function->parameters.push_back(parameter);
         }
     | type T_ID
         {
             Parameter parameter;
             parameter.type = *($1);
             delete $1;
-            parameter.name = *($2);
+            parameter.name = $2;
             free($2);
-            currentFunction->parameters.push_back(parameter);
+            current_function->parameters.push_back(parameter);
         }
 ;
 
@@ -337,7 +418,6 @@ atomic_type:
 type_identifier:
     T_ATOMIC_TYPE
         {
-            // search for type in current compilation unit...
             $$ = $1;
         }
     | namespace_refs "::" T_ATOMIC_TYPE
@@ -362,6 +442,7 @@ namespace_refs:
 
 %%
 
+__attribute__((noreturn))
 void yyerror(const char* error)
 {
     throw ParseError(error);