-#include "tree.h"
+#include "tree.hpp"
#include <iostream>
#include <sstream>
#include <stdexcept>
-#include "create_wrapper.h"
-#include "globals.h"
+#include "create_wrapper.hpp"
+#include "globals.hpp"
void
WrapperCreator::create_wrapper(Namespace* ns)
{
+ std::string fromfile = original_file != "" ? original_file : inputfile;
+
// hpp file
hppout
<< "/**\n"
- << " * WARNING: This file is automatically generated from '"
- << inputfile << "' - do not change\n"
+ << " * WARNING: This file is automatically generated from:\n"
+ << " * '" << fromfile << "'\n"
+ << " * DO NOT CHANGE\n"
<< " */\n"
<< "#ifndef __" << modulename << "_WRAPPER_H__\n"
<< "#define __" << modulename << "_WRAPPER_H__\n"
<< "\n"
- << "#include \"wrapper_util.h\"\n"
+ << "#include \"wrapper_util.hpp\"\n"
<< "\n"
<< "extern WrappedFunction " << modulename << "_global_functions[];\n"
<< "extern WrappedClass " << modulename << "_classes[];\n"
+ << "extern WrappedConstant<int> "
+ << modulename << "_int_constants[];\n"
+ << "extern WrappedConstant<float> "
+ << modulename << "_float_constants[];\n"
+ << "extern WrappedConstant<const char*> "
+ << modulename << "_string_constants[];\n"
+ << "\n"
+ << "static inline void register_"
+ << modulename << "_wrapper(HSQUIRRELVM v)\n"
+ << "{\n"
+ << " register_functions(v, "
+ << modulename << "_global_functions);\n"
+ << " register_classes(v, " << modulename << "_classes);\n"
+ << " register_constants(v, " << modulename << "_int_constants);\n"
+ << " register_constants(v, " << modulename << "_float_constants);\n"
+ << " register_constants(v, "<< modulename << "_string_constants);\n"
+ << "}\n"
<< "\n"
<< "#endif\n"
<< "\n";
// cpp header
out << "/**\n"
- << " * WARNING: This file is automatically generated from '"
- << inputfile << "' - do not change\n"
+ << " * WARNING: This file is automatically generated from:\n"
+ << " * '" << fromfile << "'\n"
+ << " * DO NOT CHANGE\n"
<< " */\n"
+ << "#include <config.h>\n"
<< "\n"
<< "#include <new>\n"
+ << "#include <assert.h>\n"
<< "#include <string>\n"
<< "#include <squirrel.h>\n"
- << "#include \"wrapper_util.h\"\n"
- << "#include \"wrapper.interface.h\"\n"
+ << "#include \"wrapper_util.hpp\"\n"
+ << "#include \"wrapper.interface.hpp\"\n"
<< "\n";
if(selected_namespace != "") {
out << "using namespace " << selected_namespace << ";\n";
}
// create function list...
- out << "WrappedFunction " << modulename << "_global_functions[] = {\n";
- for(std::vector<Function*>::iterator i = ns->functions.begin();
- i != ns->functions.end(); ++i) {
- Function* function = *i;
- out << ind << "{ \"" << function->name << "\", &"
- << function->name << "_wrapper },\n";
- }
- out << ind << "{ 0, 0 }\n"
- << "};\n"
- << "\n";
+ create_function_list(ns);
+ create_const_lists(ns);
// create class list...
std::ostringstream classlist;
continue;
classlist << ind << "{ \"" << _class->name << "\", "
- << modulename << "_" << _class->name
- << "_methods },\n";
-
+ << modulename << "_" << _class->name << "_methods, "
+ << modulename << "_" << _class->name << "_int_consts, "
+ << modulename << "_" << _class->name << "_float_consts, "
+ << modulename << "_" << _class->name << "_string_consts "
+ << "},\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)
+ if(!function || function->type == Function::DESTRUCTOR)
continue;
out << ind << "{ \"" << function->name << "\", &"
}
out << "};\n"
<< "\n";
+ create_class_const_lists(_class);
}
- classlist << ind << "{ 0, 0 }\n";
+ classlist << ind << "{ 0, 0, 0, 0, 0 }\n";
classlist << "};\n";
out << classlist.str();
out << "\n";
}
void
+WrapperCreator::create_function_list(Namespace* ns)
+{
+ out << "WrappedFunction " << modulename << "_global_functions[] = {\n";
+ for(std::vector<Function*>::iterator i = ns->functions.begin();
+ i != ns->functions.end(); ++i) {
+ Function* function = *i;
+ out << ind << "{ \"" << function->name << "\", &"
+ << function->name << "_wrapper },\n";
+ }
+ out << ind << "{ 0, 0 }\n"
+ << "};\n"
+ << "\n";
+}
+
+void
+WrapperCreator::create_const_lists(Namespace* ns)
+{
+ out << "WrappedConstant<int> " << modulename << "_int_constants[] = {\n";
+ for(std::vector<Field*>::iterator i = ns->fields.begin();
+ i != ns->fields.end(); ++i) {
+ Field* field = *i;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::INT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_int_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<float> "
+ << modulename << "_float_constants[] = {\n";
+ for(std::vector<Field*>::iterator i = ns->fields.begin();
+ i != ns->fields.end(); ++i) {
+ Field* field = *i;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::FLOAT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<const char*> "
+ << modulename << "_string_constants[] = {\n";
+ for(std::vector<Field*>::iterator i = ns->fields.begin();
+ i != ns->fields.end(); ++i) {
+ Field* field = *i;
+ if(!field->has_const_value
+ || field->type->atomic_type != StringType::instance())
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+}
+
+void
+WrapperCreator::create_class_const_lists(Class* _class)
+{
+ out << "static WrappedConstant<int> "
+ << modulename << "_" << _class->name << "_int_consts[] = {\n";
+ for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+ i != _class->members.end(); ++i) {
+ ClassMember* member = *i;
+ if(member->visibility != ClassMember::PUBLIC)
+ continue;
+ Field* field = dynamic_cast<Field*> (member);
+ if(!field)
+ continue;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::INT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_int_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<float> "
+ << modulename << "_" << _class->name << "_float_consts[] = {\n";
+ for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+ i != _class->members.end(); ++i) {
+ ClassMember* member = *i;
+ if(member->visibility != ClassMember::PUBLIC)
+ continue;
+ Field* field = dynamic_cast<Field*> (member);
+ if(!field)
+ continue;
+ if(!field->has_const_value
+ || field->type->atomic_type != &BasicType::FLOAT)
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ out << "\n";
+
+ out << "WrappedConstant<const char*> "
+ << modulename << "_" << _class->name << "_string_consts[] = {\n";
+ for(std::vector<ClassMember*>::iterator i = _class->members.begin();
+ i != _class->members.end(); ++i) {
+ ClassMember* member = *i;
+ if(member->visibility != ClassMember::PUBLIC)
+ continue;
+ Field* field = dynamic_cast<Field*> (member);
+ if(!field)
+ continue;
+ if(!field->has_const_value
+ || field->type->atomic_type != StringType::instance())
+ continue;
+ out << ind << "{ \"" << field->name << "\", "
+ << field->const_float_value << "},\n";
+ }
+ out << ind << "{ 0, 0}\n";
+ out << "};\n";
+ 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");
-
+ 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 << "_";
<< "{\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
- size_t i = 0;
+ int i = 0;
+ int arg_offset = 2;
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);
-
+ if(i == 0 && p->type.atomic_type == HSQUIRRELVMType::instance()) {
+ out << ind << "HSQUIRRELVM arg0 = v;\n";
+ arg_offset--;
+ } else {
+ char argname[64];
+ snprintf(argname, sizeof(argname), "arg%d", i);
+ prepare_argument(p->type, i + arg_offset, argname);
+ }
++i;
}
+
// call function
out << ind << "\n";
out << ind;
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()) {
- out << ind << "return 0;\n";
+ if(function->docu_comment.find("@SUSPEND@") != std::string::npos) {
+ out << ind << "return sq_suspendvm(v);\n";
+ } else {
+ out << ind << "return 0;\n";
+ }
} else {
push_to_stack(function->return_type, "return_value");
out << ind << "return 1;\n";
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;
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"