#ifndef __TREE_H__ #define __TREE_H__ #include #include #include #include #include #include class Namespace; class AtomicType { public: AtomicType() : parent(0) { } virtual ~AtomicType() { } virtual void write_c(std::ostream& out) { out << name; } std::string name; Namespace* parent; }; class BasicType : public AtomicType { public: static BasicType VOID; static BasicType BOOL; static BasicType CHAR; static BasicType SHORT; static BasicType INT; static BasicType LONG; static BasicType FLOAT; static BasicType DOUBLE; private: BasicType(const std::string& name) { this->name = name; } }; class Type { public: Type() : atomic_type(0), _unsigned(false), _const(false), _static(false), pointer(0), ref(0) { } void write_c_type(std::ostream& out) { if(_static) out << "static "; if(_const) out << "const "; atomic_type->write_c(out); for(int i = 0; i < pointer; ++i) out << "*"; for(int i = 0; i < ref; ++i) out << "&"; } 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... int pointer; // number of '&' in the type declaration... int ref; }; class SQIntegerType : public AtomicType { public: SQIntegerType() { this->name = "SQInteger"; assert(_instance == 0); _instance = this; } virtual ~SQIntegerType() { assert(_instance == this); _instance = NULL; } static SQIntegerType* instance() { return _instance; } private: static SQIntegerType* _instance; }; class HSQUIRRELVMType : public AtomicType { public: HSQUIRRELVMType() { this->name = "HSQUIRRELVM"; assert(_instance == 0); _instance = this; } virtual ~HSQUIRRELVMType() { assert(_instance == this); _instance = NULL; } static HSQUIRRELVMType* instance() { return _instance; } private: static HSQUIRRELVMType* _instance; }; class StringType : public AtomicType { public: StringType() { this->name = "string"; assert(_instance == 0); _instance = this; } virtual ~StringType() { assert(_instance == this); _instance = 0; } static StringType* instance() { return _instance; } virtual void write_c(std::ostream& out) { out << "std::string"; } private: static StringType* _instance; }; class Parameter { public: std::string name; Type type; }; class ClassMember { public: virtual ~ClassMember() { } enum Visbility { PUBLIC, PROTECTED, PRIVATE }; Visbility visibility; }; class Function : public ClassMember { public: Function() { type = FUNCTION; suspend = false; custom = false; } enum FuncType { FUNCTION, CONSTRUCTOR, DESTRUCTOR }; FuncType type; /// function should suspend squirrel VM after execution bool suspend; /// a custom wrapper (just pass along HSQUIRRELVM) bool custom; std::string docu_comment; std::string name; Type return_type; std::vector 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() { for(std::vector::iterator i = members.begin(); i != members.end(); ++i) delete *i; } std::vector members; std::vector super_classes; std::vector sub_classes; std::string docu_comment; }; class Namespace { public: Namespace() { parent = 0; } virtual ~Namespace() { for(std::vector::iterator i = functions.begin(); i != functions.end(); ++i) delete *i; for(std::vector::iterator i = types.begin(); i != types.end(); ++i) delete *i; for(std::vector::iterator i = namespaces.begin(); 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::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::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 functions; std::vector fields; std::vector types; std::vector namespaces; Namespace* parent; std::string name; }; class CompilationUnit : public Namespace { public: }; #endif