- Made miniswig support HSQUIRRELVM arguments (and realized it was not needed
[supertux.git] / tools / miniswig / tree.h
index 4b9485c..387012e 100644 (file)
@@ -4,10 +4,17 @@
 #include <vector>
 #include <string>
 #include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <assert.h>
+
+class Namespace;
 
 class AtomicType {
 public:
-    std::string name;
+    AtomicType()
+        : parent(0)
+    { }
     virtual ~AtomicType()
     { }
 
@@ -15,6 +22,9 @@ public:
     {
         out << name;
     }
+
+    std::string name;
+    Namespace* parent;
 };
 
 class BasicType : public AtomicType {
@@ -38,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)
@@ -56,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...
@@ -70,6 +84,28 @@ public:
     int ref;
 };
 
+class HSQUIRRELVMType : public AtomicType {
+public:
+    HSQUIRRELVMType()
+    {
+        this->name = "HSQUIRRELVM";
+        assert(_instance == 0);
+        _instance = this;
+    }
+    virtual ~HSQUIRRELVMType()
+    {
+        assert(_instance == this);
+        _instance = 0;
+    }
+
+    static HSQUIRRELVMType* instance()
+    {
+        return _instance;
+    }
+private:
+    static HSQUIRRELVMType* _instance;
+};
+
 class StringType : public AtomicType {
 public:
     StringType()
@@ -143,12 +179,10 @@ public:
 
 class Namespace {
 public:
-    std::string name;
-};
-
-class CompilationUnit {
-public:
-    ~CompilationUnit() {
+    Namespace() {
+        parent = 0;
+    }
+    virtual ~Namespace() {
         for(std::vector<Function*>::iterator i = functions.begin();
                 i != functions.end(); ++i)
             delete *i;
@@ -159,10 +193,63 @@ public:
                 i != namespaces.end(); ++i)
             delete *i;
     }
+    void add_type(AtomicType* type)
+    {
+        types.push_back(type);
+        type->parent = this;
+    }
+    void add_namespace(Namespace* ns)
+    {
+        namespaces.push_back(ns);
+        ns->parent = this;
+    }
+    AtomicType* _findType(const std::string& name, bool godown = false) {
+        for(std::vector<AtomicType*>::iterator i = types.begin();
+                i != types.end(); ++i) {
+            AtomicType* type = *i;
+            if(type->name == name)
+                return type;
+        }
+        if(godown && parent)
+            return parent->_findType(name, true);
+
+        return 0;
+    }
+
+    Namespace* _findNamespace(const std::string& name, bool godown = false) {
+        for(std::vector<Namespace*>::iterator i = namespaces.begin();
+                i != namespaces.end(); ++i) {
+            Namespace* ns = *i;
+            if(ns->name == name)
+                return ns;
+        }
+        if(godown && parent)
+            return parent->_findNamespace(name, true);
+
+        return 0;
+    }
+
+    Namespace* findNamespace(const std::string& name, bool godown = false) {
+        Namespace* ret = _findNamespace(name, godown);
+        if(!ret) {
+            std::ostringstream msg;
+            msg << "Couldn't find namespace '" << name << "'.";
+            throw std::runtime_error(msg.str());
+        }
+
+        return ret;
+    }
+                                                                             
     std::vector<Function*> functions;
     std::vector<AtomicType*> types;
     std::vector<Namespace*> namespaces;
+
+    Namespace* parent;
+    std::string name;
+};
+
+class CompilationUnit : public Namespace {
+public:
 };
 
 #endif