simple c++ header files and create squirrel wrappers for them.
SVN-Revision: 2391
SubDir TOP ;
# Decend into subdirs
+SubInclude TOP tools miniswig ;
SubInclude TOP lib ;
SubInclude TOP src ;
SubInclude TOP data ;
fi
fi
+AC_PROG_LEX
+LEX_LIBS=$LEXLIB
+AC_SUBST([LEX_LIBS])
+AC_CHECK_PROGS([BISON], bison)
+AC_SUBST([BISON])
+
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
return $(object) ;
}
- RegisterFileType Flex++Rule : .ll ;
+ RegisterFileType Lex++Rule : .ll ;
if $(COMPILER_TYPE) != "GCC"
{
Includes $(headerfile:G=) : $(headerfile) ;
- Bison $(cfile) $(headerfile) : $(<) ;
+ Bison $(cfile) : $(<) ;
# work around jam warning about independent target
Includes $(cfile) : $(headerfile) ;
# here
Includes $(headerfile:G=) : $(headerfile) ;
- Bison $(cppfile) $(headerfile) : $(<) ;
- Includes $(cppfile) : $(headerfile) ;
+ Bison $(cppfile) : $(<) ;
+#Includes $(cppfile) : $(headerfile) ;
return $(object) ;
}
--- /dev/null
+SubDir TOP tools miniswig ;
+
+if $(LEX) && $(BISON) {
+ MINISWIG = [ Application miniswig : [ Wildcard *.yy *.ll *.cpp ] ] ;
+ C++Flags miniswig : -Wno-unused ;
+ IncludeDir miniswig : . ;
+ ExternalLibs miniswig : LEX ;
+}
+
--- /dev/null
+#include "tree.h"
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include "create_wrapper.h"
+#include "globals.h"
+
+void
+WrapperCreator::create_wrapper(CompilationUnit* unit)
+{
+ // hpp file
+ hppout
+ << "/**\n"
+ << " * WARNING: This file is automatically generated from '"
+ << inputfile << "' - do not change\n"
+ << " */\n"
+ << "#ifndef __" << modulename << "_WRAPPER_HPP__\n"
+ << "#define __" << modulename << "_WRAPPER_HPP__\n"
+ << "\n"
+ << "#include \"WrapperUtil.hpp\"\n"
+ << "\n"
+ << "extern WrappedFunction " << modulename << "_global_functions[];\n"
+ << "extern WrappedClass " << modulename << "_classes[];\n"
+ << "\n"
+ << "#endif\n"
+ << "\n";
+
+ // cpp header
+ out << "/**\n"
+ << " * WARNING: This file is automatically generated from '"
+ << inputfile << "' - do not change\n"
+ << " */\n"
+ << "\n"
+ << "#include <new>\n"
+ << "#include <string>\n"
+ << "#include <squirrel.h>\n"
+ << "#include \"WrapperUtil.hpp\"\n"
+ << "#include \"" << inputfile << "\"\n"
+ << "\n";
+
+ for(std::vector<AtomicType*>::iterator i = unit->types.begin();
+ i != unit->types.end(); ++i) {
+ AtomicType* type = *i;
+ Class* _class = dynamic_cast<Class*> (type);
+ if(_class != 0)
+ create_class_wrapper(_class);
+ }
+ for(std::vector<Function*>::iterator i = unit->functions.begin();
+ i != unit->functions.end(); ++i) {
+ create_function_wrapper(0, *i);
+ }
+
+ // create function list...
+ out << "WrappedFunction " << modulename << "_global_functions[] = {\n";
+ for(std::vector<Function*>::iterator i = unit->functions.begin();
+ i != unit->functions.end(); ++i) {
+ Function* function = *i;
+ out << ind << "{ \"" << function->name << "\", &"
+ << function->name << "_wrapper },\n";
+ }
+ out << ind << "{ 0, 0 }\n"
+ << "};\n"
+ << "\n";
+
+ // create class list...
+ std::ostringstream classlist;
+ classlist << "WrappedClass " << modulename << "_classes[] = {\n";
+
+ for(std::vector<AtomicType*>::iterator i = unit->types.begin();
+ i != unit->types.end(); ++i) {
+ AtomicType* type = *i;
+ Class* _class = dynamic_cast<Class*> (type);
+ if(_class == 0)
+ continue;
+
+ classlist << ind << "{ \"" << _class->name << "\", "
+ << modulename << "_" << _class->name
+ << "_methods },\n";
+
+ 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)
+ continue;
+
+ out << ind << "{ \"" << function->name << "\", &"
+ << _class->name << "_" << function->name << "_wrapper },\n";
+ }
+ classlist << ind << "{ 0, 0 }\n";
+ out << "};\n"
+ << "\n";
+ }
+ classlist << "};\n";
+ out << classlist.str();
+ out << "\n";
+}
+
+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");
+
+ out << "static int ";
+ if(_class != 0) {
+ out << _class->name << "_";
+ }
+ out << function->name << "_wrapper(HSQUIRRELVM v)\n"
+ << "{\n";
+ // avoid warning...
+ if(_class == 0 && function->parameters.empty()
+ && function->return_type.is_void()) {
+ out << ind << "(void) v;\n";
+ }
+
+ // eventually retrieve pointer to class
+ if(_class != 0) {
+ out << ind << _class->name << "* _this;\n";
+ out << ind << "sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);\n";
+ out << ind << "assert(_this != 0);\n";
+ }
+
+ // declare and retrieve arguments
+ size_t i = 0;
+ for(std::vector<Parameter>::iterator p = function->parameters.begin();
+ p != function->parameters.end(); ++p) {
+ char argname[64];
+ snprintf(argname, sizeof(argname), "arg%u", i);
+ prepare_argument(p->type, i + 2, argname);
+
+ ++i;
+ }
+ // call function
+ out << ind << "\n";
+ out << ind;
+ if(!function->return_type.is_void()) {
+ function->return_type.write_c_type(out);
+ out << " return_value = ";
+ }
+ if(_class != 0) {
+ out << "_this->";
+ }
+ out << function->name << "(";
+ for(size_t i = 0; i < function->parameters.size(); ++i) {
+ if(i != 0)
+ out << ", ";
+ out << "arg" << i;
+ }
+ out << ");\n";
+ out << ind << "\n";
+ // push return value back on stack and return
+ if(function->return_type.is_void()) {
+ out << ind << "return 0;\n";
+ } else {
+ push_to_stack(function->return_type, "return_value");
+ out << ind << "return 1;\n";
+ }
+ out << "}\n";
+ out << "\n";
+}
+
+void
+WrapperCreator::prepare_argument(const Type& type, size_t index,
+ const std::string& var)
+{
+ if(type.ref > 0 && type.atomic_type != StringType::instance())
+ throw std::runtime_error("References not handled yet");
+ if(type.pointer > 0)
+ throw std::runtime_error("Pointers not handled yet");
+ if(type.atomic_type == &BasicType::INT) {
+ out << ind << "int " << var << ";\n";
+ out << ind << "sq_getinteger(v, " << index << ", &" << var << ");\n";
+ } else if(type.atomic_type == &BasicType::FLOAT) {
+ out << ind << "float " << var << ";\n";
+ out << ind << "sq_getfloat(v, " << index << ", &" << var << ");\n";
+ } else if(type.atomic_type == &BasicType::BOOL) {
+ out << ind << "SQBool " << var << ";\n";
+ out << ind << "sq_getbool(v, " << index << ", &" << var << ");\n";
+ } else if(type.atomic_type == StringType::instance()) {
+ out << ind << "const char* " << var << ";\n";
+ out << ind << "sq_getstring(v, " << index << ", &" << var << ");\n";
+ } else {
+ std::ostringstream msg;
+ msg << "Type '" << type.atomic_type->name << "' not supported yet.";
+ throw std::runtime_error(msg.str());
+ }
+}
+
+void
+WrapperCreator::push_to_stack(const Type& type, const std::string& var)
+{
+ if(type.ref > 0 && type.atomic_type != StringType::instance())
+ throw std::runtime_error("References not handled yet");
+ if(type.pointer > 0)
+ throw std::runtime_error("Pointers not handled yet");
+ out << ind;
+ if(type.atomic_type == &BasicType::INT) {
+ out << "sq_pushinteger(v, " << var << ");\n";
+ } else if(type.atomic_type == &BasicType::FLOAT) {
+ out << "sq_pushfloat(v, " << var << ");\n";
+ } else if(type.atomic_type == &BasicType::BOOL) {
+ out << "sq_pushbool(v, " << var << ");\n";
+ } else if(type.atomic_type == StringType::instance()) {
+ out << "sq_pushstring(v, " << var << ".c_str(), "
+ << var << ".size());\n";
+ } else {
+ std::ostringstream msg;
+ msg << "Type '" << type.atomic_type->name << "' not supported yet.";
+ throw std::runtime_error(msg.str());
+ }
+}
+
+void
+WrapperCreator::create_class_wrapper(Class* _class)
+{
+ create_class_destruct_function(_class);
+ create_class_construct_function(_class);
+ 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)
+ continue;
+ // don't wrap constructors and destructors (for now...)
+ if(function->type != Function::FUNCTION)
+ 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)
+{
+ out << "static int " << _class->name << "_release_wrapper(SQUserPointer ptr, int )\n"
+ << "{\n"
+ << ind << _class->name
+ << "* _this = reinterpret_cast<" << _class->name << "*> (ptr);\n"
+ << ind << "_this->~" << _class->name << "();\n"
+ << ind << "return 0;\n"
+ << "}\n"
+ << "\n";
+}
+
--- /dev/null
+#ifndef __CREATE_WRAPPER_H__
+#define __CREATE_WRAPPER_H__
+
+#include "tree.h"
+
+class WrapperCreator
+{
+public:
+ /// this is used for indentation
+ const char* ind;
+ // output stream
+ std::ostream& out;
+ std::ostream& hppout;
+
+ WrapperCreator(std::ostream& _out = std::cout, std::ostream& _hppout = std::cout)
+ : out(_out), hppout(_hppout)
+ {
+ ind = " ";
+ }
+
+ void create_wrapper(CompilationUnit* unit);
+ void create_class_wrapper(Class* _class);
+ void create_class_construct_function(Class* _class);
+ void create_class_destruct_function(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);
+};
+
+#endif
+
--- /dev/null
+#ifndef __GLOBALS_H__
+#define __GLOBALS_H__
+
+#include "tree.h"
+#include <iostream>
+
+extern CompilationUnit* unit;
+extern std::istream* input;
+extern std::string inputfile;
+extern std::string modulename;
+
+#endif
+
--- /dev/null
+%{
+#include <math.h>
+#include <stdlib.h>
+#include "tree.h"
+#include "parser.hpp"
+#include "globals.h"
+
+#define YY_DECL int yylex YY_PROTO(( YYSTYPE* yylval ))
+
+#define YY_INPUT(buf, result, max_size) \
+{ \
+ input->read(buf, max_size); \
+ result = input->gcount(); \
+}
+
+%}
+
+%option noyywrap
+%option yylineno
+/* %option never-interactive */
+
+%%
+
+[[:space:]]+ /* eat spaces */
+\/\*.*\*\/ /* eat comment */
+\/\/[^\n]*\n /* eat comment */
+class { return T_CLASS; }
+struct { return T_STRUCT; }
+static { return T_STATIC; }
+const { return T_CONST; }
+unsigned { return T_UNSIGNED; }
+signed { return T_SIGNED; }
+void { return T_VOID; }
+bool { return T_BOOL; }
+char { return T_CHAR; }
+short { return T_SHORT; }
+int { return T_INT; }
+long { return T_LONG; }
+float { return T_FLOAT; }
+double { return T_DOUBLE; }
+public { return T_PUBLIC; }
+protected { return T_PROTECTED; }
+private { return T_PRIVATE; }
+[a-zA-Z_][a-zA-Z_0-9]* {
+ // is it a type?
+ for(std::vector<AtomicType*>::iterator i = unit->types.begin();
+ i != unit->types.end(); ++i) {
+ AtomicType* type = *i;
+ if(type->name == yytext) {
+ yylval->atomic_type = type;
+ return T_ATOMIC_TYPE;
+ }
+ }
+ // or a namespace? (hack for now...)
+ if(strcmp(yytext, "std") == 0) {
+ yylval->_namespace = unit->namespaces[0];
+ return T_NAMESPACE;
+ }
+ yylval->str = strdup(yytext);
+ 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;
+ }
+. { return yytext[0]; }
+
+%%
+
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include "tree.h"
+#include "globals.h"
+#include "create_wrapper.h"
+
+extern int yyparse();
+extern int yylex();
+
+CompilationUnit* unit = 0;
+std::istream* input = 0;
+std::string inputfile;
+std::string modulename = "wrapper";
+
+void usage()
+{
+ std::cout << "Usage: miniswig --input FILE --output-cpp FILE --output-hpp FILE [--module NAME]\n";
+ std::cout << "\n";
+}
+
+int main(int argc, char** argv)
+{
+ std::string outputcpp;
+ std::string outputhpp;
+ for(int i = 0; i < argc; ++i) {
+ if(strcmp(argv[i], "--module") == 0) {
+ if(i+1 >= argc) {
+ std::cerr << "Need to specify a module name.\n";
+ usage();
+ return 1;
+ }
+ modulename = argv[++i];
+ } else if(strcmp(argv[i], "--input") == 0) {
+ if(i+1 >= argc) {
+ std::cerr << "Need to specify input file name.\n";
+ usage();
+ return 1;
+ }
+ inputfile = argv[++i];
+ } else if(strcmp(argv[i], "--output-cpp") == 0) {
+ if(i+1 >= argc) {
+ std::cerr << "Need to specifiy output cpp name.\n";
+ usage();
+ return 1;
+ }
+ outputcpp = argv[++i];
+ } else if(strcmp(argv[i], "--output-hpp") == 0) {
+ if(i+1 >= argc) {
+ std::cerr << "Need to specify output hpp name.\n";
+ usage();
+ return 1;
+ }
+ outputhpp = argv[++i];
+ } else if(argv[i][0] == '-') {
+ std::cerr << "Unknown option '" << argv[i] << "'.\n";
+ usage();
+ return 1;
+ } else {
+ }
+ }
+ if(inputfile == "" || outputcpp == "" || outputhpp == "") {
+ std::cerr << "Not all options specified.\n";
+ usage();
+ return 1;
+ }
+
+ try {
+ input = new std::ifstream(inputfile.c_str());
+ if(!input->good()) {
+ std::cerr << "Couldn't open file '" << input << "' for reading.\n";
+ return 1;
+ }
+ unit = new CompilationUnit();
+ unit->types.push_back(new StringType());
+ Namespace* std_namespace = new Namespace();
+ std_namespace->name = "std";
+ unit->namespaces.push_back(std_namespace);
+ yyparse();
+ std::ofstream cppout(outputcpp.c_str());
+ if(!cppout.good()) {
+ std::cerr << "Couldn't open file '" << outputcpp << "' for writing.\n";
+ return 1;
+ }
+ std::ofstream hppout(outputhpp.c_str());
+ if(!hppout.good()) {
+ std::cerr << "Couldn't open file '" << outputhpp << "' for writing.\n";
+ return 1;
+ }
+ WrapperCreator creator(cppout, hppout);
+ creator.create_wrapper(unit);
+ } catch(std::exception& e) {
+ std::cerr << e.what() << "\n";
+ return 1;
+ }
+
+ return 0;
+}
+
--- /dev/null
+%{
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include "tree.h"
+#include "globals.h"
+
+%}
+
+%pure_parser
+%union {
+ char* str;
+ int ival;
+ float fval;
+ Class* _class;
+ Function* function;
+ Type* type;
+ AtomicType* atomic_type;
+ Namespace* _namespace;
+}
+
+%{
+
+extern int yylex(YYSTYPE* yylval);
+void yyerror(const char* s);
+extern int yylineno;
+
+static Class* currentClass = 0;
+static Function* currentFunction = 0;
+static Type* currentType = 0;
+static ClassMember::Visbility currentVisibility;
+
+class ParseError : public std::exception
+{
+public:
+ ParseError(const std::string& message) throw()
+ {
+ std::ostringstream msg;
+ msg << "Parse error in line " << yylineno << ": "
+ << message;
+ this->message = msg.str();
+ }
+ virtual ~ParseError() throw()
+ {}
+ const char* what() const throw()
+ {
+ return message.c_str();
+ }
+
+private:
+ std::string message;
+};
+
+%}
+
+%token <ival> T_INT
+%token <fval> T_FLOAT
+%token <str> T_STRING
+%token <str> T_ID
+%token <atomic_type> T_ATOMIC_TYPE
+%token <_namespace> T_NAMESPACE;
+%token T_CLASS
+%token T_STRUCT
+%token T_STATIC
+%token T_CONST
+%token T_UNSIGNED
+%token T_SIGNED
+%token T_VOID
+%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
+%token T_PRIVATE
+%token T_DDCOL "::"
+
+%type <_class> class_declaration
+%type <function> function_declaration
+%type <function> constructor_declaration;
+%type <function> destructor_declaration;
+%type <type> type
+%type <atomic_type> type_identifier
+
+%%
+
+input: /* empty */
+ | compilation_unit
+;
+
+compilation_unit: compilation_unit_part
+ | compilation_unit compilation_unit_part
+;
+
+compilation_unit_part: class_declaration
+ { unit->types.push_back($1); }
+ | function_declaration
+ { unit->functions.push_back($1); }
+;
+
+class_declaration: T_CLASS T_ID '{'
+ {
+ currentClass = new Class();
+ currentClass->name = $2;
+ free($2);
+ currentVisibility = ClassMember::PROTECTED;
+ }
+ class_body '}' ';'
+ {
+ $$ = currentClass;
+ }
+;
+
+class_body: /* empty */
+ | visibility_change class_body
+ | constructor_declaration
+ {
+ $1->visibility = currentVisibility;
+ currentClass->members.push_back($1);
+ }
+ class_body
+ | destructor_declaration
+ {
+ $1->visibility = currentVisibility;
+ currentClass->members.push_back($1);
+ }
+ class_body
+ | function_declaration
+ {
+ $1->visibility = currentVisibility;
+ currentClass->members.push_back($1);
+ }
+ class_body
+ | variable_declaration class_body
+;
+
+visibility_change: T_PUBLIC ':'
+ { currentVisibility = ClassMember::PUBLIC; }
+ | T_PROTECTED ':'
+ { currentVisibility = ClassMember::PROTECTED; }
+ | T_PRIVATE ':'
+ { currentVisibility = ClassMember::PRIVATE; }
+;
+
+constructor_declaration: T_ID '('
+ {
+ currentFunction = new Function();
+ currentFunction->type = Function::CONSTRUCTOR;
+ free($1);
+ }
+ param_list ')' ';'
+ {
+ $$ = currentFunction;
+ }
+;
+
+destructor_declaration: '~' T_ID '(' ')' ';'
+ {
+ currentFunction = new Function();
+ currentFunction->type = Function::DESTRUCTOR;
+ free($2);
+ $$ = currentFunction;
+ }
+;
+
+variable_declaration: type T_ID ';'
+
+function_declaration: type T_ID '('
+ {
+ currentFunction = new Function();
+ currentFunction->type = Function::FUNCTION;
+ currentFunction->return_type = *($1);
+ delete $1;
+ currentFunction->name = $2;
+ free($2);
+ }
+ param_list ')' ';'
+ {
+ $$ = currentFunction;
+ }
+;
+
+param_list: /* empty */
+ | param_list2
+;
+
+param_list2: parameter
+ | parameter ',' param_list2
+;
+
+parameter: type
+ {
+ Parameter parameter;
+ parameter.type = *($1);
+ delete $1;
+ currentFunction->parameters.push_back(parameter);
+ }
+ | type T_ID
+ {
+ Parameter parameter;
+ parameter.type = *($1);
+ delete $1;
+ parameter.name = *($2);
+ free($2);
+ currentFunction->parameters.push_back(parameter);
+ }
+;
+
+type: {
+ currentType = new Type();
+ }
+ prefix_type_modifiers atomic_type postfix_type_modifiers
+ {
+ $$ = currentType;
+ }
+;
+
+prefix_type_modifiers: /* empty */
+ | T_UNSIGNED prefix_type_modifiers
+ | T_SIGNED prefix_type_modifiers
+ | T_STATIC prefix_type_modifiers
+ | T_CONST prefix_type_modifiers
+;
+
+postfix_type_modifiers: /* empty */
+ | T_CONST postfix_type_modifiers
+ { currentType->_const = true; }
+ | '*' postfix_type_modifiers
+ { currentType->pointer++; }
+ | '&' postfix_type_modifiers
+ { currentType->ref++; }
+;
+
+atomic_type: T_VOID { currentType->atomic_type = &BasicType::VOID; }
+ | T_BOOL { currentType->atomic_type = &BasicType::BOOL; }
+ | T_CHAR { currentType->atomic_type = &BasicType::CHAR; }
+ | T_SHORT { currentType->atomic_type = &BasicType::SHORT; }
+ | T_INT { currentType->atomic_type = &BasicType::INT; }
+ | T_LONG { currentType->atomic_type = &BasicType::LONG; }
+ | T_FLOAT { currentType->atomic_type = &BasicType::FLOAT; }
+ | T_DOUBLE { currentType->atomic_type = &BasicType::DOUBLE; }
+ | type_identifier { currentType->atomic_type = $1; }
+;
+
+type_identifier: T_ATOMIC_TYPE
+ {
+ // search for type in current compilation unit...
+ $$ = $1;
+ }
+ | T_NAMESPACE "::" type_identifier
+ {
+ // hack...
+ $$ = $3;
+ }
+;
+
+%%
+
+void yyerror(const char* error)
+{
+ throw ParseError(error);
+}
+
--- /dev/null
+#include "tree.h"
+
+BasicType BasicType::VOID("void");
+BasicType BasicType::BOOL("bool");
+BasicType BasicType::CHAR("char");
+BasicType BasicType::SHORT("short");
+BasicType BasicType::INT("int");
+BasicType BasicType::LONG("long");
+BasicType BasicType::FLOAT("float");
+BasicType BasicType::DOUBLE("double");
+
+StringType* StringType::_instance = 0;
--- /dev/null
+#ifndef __TREE_H__
+#define __TREE_H__
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+class AtomicType {
+public:
+ std::string name;
+ virtual ~AtomicType()
+ { }
+
+ virtual void write_c(std::ostream& out)
+ {
+ out << name;
+ }
+};
+
+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), _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 == &BasicType::VOID && pointer == 0)
+ return true;
+ return false;
+ }
+
+ AtomicType* atomic_type;
+ bool _const;
+ bool _static;
+ // number of '*' in the type declaration...
+ int pointer;
+ // number of '&' in the type declaration...
+ int ref;
+};
+
+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:
+ enum FuncType {
+ FUNCTION,
+ CONSTRUCTOR,
+ DESTRUCTOR
+ };
+ FuncType type;
+ std::string name;
+ Type return_type;
+ std::vector<Parameter> parameters;
+};
+
+class Class : public AtomicType {
+public:
+ ~Class() {
+ for(std::vector<ClassMember*>::iterator i = members.begin();
+ i != members.end(); ++i)
+ delete *i;
+ }
+
+ std::vector<ClassMember*> members;
+};
+
+class Namespace {
+public:
+ std::string name;
+};
+
+class CompilationUnit {
+public:
+ ~CompilationUnit() {
+ for(std::vector<Function*>::iterator i = functions.begin();
+ i != functions.end(); ++i)
+ delete *i;
+ for(std::vector<AtomicType*>::iterator i = types.begin();
+ i != types.end(); ++i)
+ delete *i;
+ for(std::vector<Namespace*>::iterator i = namespaces.begin();
+ i != namespaces.end(); ++i)
+ delete *i;
+ }
+
+ std::vector<Function*> functions;
+ std::vector<AtomicType*> types;
+ std::vector<Namespace*> namespaces;
+};
+
+#endif
+