5 #include "create_wrapper.h"
9 WrapperCreator::create_wrapper(CompilationUnit* unit)
14 << " * WARNING: This file is automatically generated from '"
15 << inputfile << "' - do not change\n"
17 << "#ifndef __" << modulename << "_WRAPPER_HPP__\n"
18 << "#define __" << modulename << "_WRAPPER_HPP__\n"
20 << "#include \"WrapperUtil.hpp\"\n"
22 << "extern WrappedFunction " << modulename << "_global_functions[];\n"
23 << "extern WrappedClass " << modulename << "_classes[];\n"
30 << " * WARNING: This file is automatically generated from '"
31 << inputfile << "' - do not change\n"
35 << "#include <string>\n"
36 << "#include <squirrel.h>\n"
37 << "#include \"WrapperUtil.hpp\"\n"
38 << "#include \"" << inputfile << "\"\n"
41 for(std::vector<AtomicType*>::iterator i = unit->types.begin();
42 i != unit->types.end(); ++i) {
43 AtomicType* type = *i;
44 Class* _class = dynamic_cast<Class*> (type);
46 create_class_wrapper(_class);
48 for(std::vector<Function*>::iterator i = unit->functions.begin();
49 i != unit->functions.end(); ++i) {
50 create_function_wrapper(0, *i);
53 // create function list...
54 out << "WrappedFunction " << modulename << "_global_functions[] = {\n";
55 for(std::vector<Function*>::iterator i = unit->functions.begin();
56 i != unit->functions.end(); ++i) {
57 Function* function = *i;
58 out << ind << "{ \"" << function->name << "\", &"
59 << function->name << "_wrapper },\n";
61 out << ind << "{ 0, 0 }\n"
65 // create class list...
66 std::ostringstream classlist;
67 classlist << "WrappedClass " << modulename << "_classes[] = {\n";
69 for(std::vector<AtomicType*>::iterator i = unit->types.begin();
70 i != unit->types.end(); ++i) {
71 AtomicType* type = *i;
72 Class* _class = dynamic_cast<Class*> (type);
76 classlist << ind << "{ \"" << _class->name << "\", "
77 << modulename << "_" << _class->name
80 out << "static WrappedFunction " << modulename << "_"
81 << _class->name << "_methods[] = {\n";
82 out << ind << "{ \"constructor\", &"
83 << _class->name << "_" << "construct_wrapper },\n";
84 for(std::vector<ClassMember*>::iterator i = _class->members.begin();
85 i != _class->members.end(); ++i) {
86 ClassMember* member = *i;
87 if(member->visibility != ClassMember::PUBLIC)
89 Function* function = dynamic_cast<Function*> (member);
90 if(!function || function->type != Function::FUNCTION)
93 out << ind << "{ \"" << function->name << "\", &"
94 << _class->name << "_" << function->name << "_wrapper },\n";
96 classlist << ind << "{ 0, 0 }\n";
101 out << classlist.str();
106 WrapperCreator::create_function_wrapper(Class* _class, Function* function)
108 if(function->type == Function::CONSTRUCTOR)
109 throw std::runtime_error("Constructors not supported yet");
110 if(function->type == Function::DESTRUCTOR)
111 throw std::runtime_error("Destructors not supported yet");
113 out << "static int ";
115 out << _class->name << "_";
117 out << function->name << "_wrapper(HSQUIRRELVM v)\n"
120 if(_class == 0 && function->parameters.empty()
121 && function->return_type.is_void()) {
122 out << ind << "(void) v;\n";
125 // eventually retrieve pointer to class
127 out << ind << _class->name << "* _this;\n";
128 out << ind << "sq_getinstanceup(v, 1, (SQUserPointer*) &_this, 0);\n";
129 out << ind << "assert(_this != 0);\n";
132 // declare and retrieve arguments
134 for(std::vector<Parameter>::iterator p = function->parameters.begin();
135 p != function->parameters.end(); ++p) {
137 snprintf(argname, sizeof(argname), "arg%u", i);
138 prepare_argument(p->type, i + 2, argname);
145 if(!function->return_type.is_void()) {
146 function->return_type.write_c_type(out);
147 out << " return_value = ";
152 out << function->name << "(";
153 for(size_t i = 0; i < function->parameters.size(); ++i) {
160 // push return value back on stack and return
161 if(function->return_type.is_void()) {
162 out << ind << "return 0;\n";
164 push_to_stack(function->return_type, "return_value");
165 out << ind << "return 1;\n";
172 WrapperCreator::prepare_argument(const Type& type, size_t index,
173 const std::string& var)
175 if(type.ref > 0 && type.atomic_type != StringType::instance())
176 throw std::runtime_error("References not handled yet");
178 throw std::runtime_error("Pointers not handled yet");
179 if(type.atomic_type == &BasicType::INT) {
180 out << ind << "int " << var << ";\n";
181 out << ind << "sq_getinteger(v, " << index << ", &" << var << ");\n";
182 } else if(type.atomic_type == &BasicType::FLOAT) {
183 out << ind << "float " << var << ";\n";
184 out << ind << "sq_getfloat(v, " << index << ", &" << var << ");\n";
185 } else if(type.atomic_type == &BasicType::BOOL) {
186 out << ind << "SQBool " << var << ";\n";
187 out << ind << "sq_getbool(v, " << index << ", &" << var << ");\n";
188 } else if(type.atomic_type == StringType::instance()) {
189 out << ind << "const char* " << var << ";\n";
190 out << ind << "sq_getstring(v, " << index << ", &" << var << ");\n";
192 std::ostringstream msg;
193 msg << "Type '" << type.atomic_type->name << "' not supported yet.";
194 throw std::runtime_error(msg.str());
199 WrapperCreator::push_to_stack(const Type& type, const std::string& var)
201 if(type.ref > 0 && type.atomic_type != StringType::instance())
202 throw std::runtime_error("References not handled yet");
204 throw std::runtime_error("Pointers not handled yet");
206 if(type.atomic_type == &BasicType::INT) {
207 out << "sq_pushinteger(v, " << var << ");\n";
208 } else if(type.atomic_type == &BasicType::FLOAT) {
209 out << "sq_pushfloat(v, " << var << ");\n";
210 } else if(type.atomic_type == &BasicType::BOOL) {
211 out << "sq_pushbool(v, " << var << ");\n";
212 } else if(type.atomic_type == StringType::instance()) {
213 out << "sq_pushstring(v, " << var << ".c_str(), "
214 << var << ".size());\n";
216 std::ostringstream msg;
217 msg << "Type '" << type.atomic_type->name << "' not supported yet.";
218 throw std::runtime_error(msg.str());
223 WrapperCreator::create_class_wrapper(Class* _class)
225 create_class_destruct_function(_class);
226 create_class_construct_function(_class);
227 for(std::vector<ClassMember*>::iterator i = _class->members.begin();
228 i != _class->members.end(); ++i) {
229 ClassMember* member = *i;
230 if(member->visibility != ClassMember::PUBLIC)
232 Function* function = dynamic_cast<Function*> (member);
235 // don't wrap constructors and destructors (for now...)
236 if(function->type != Function::FUNCTION)
238 create_function_wrapper(_class, function);
243 WrapperCreator::create_class_construct_function(Class* _class)
245 out << "static int " << _class->name << "_construct_wrapper(HSQUIRRELVM v)\n";
247 out << ind << _class->name << "* _this = new "
248 << _class->name << "();\n";
249 out << ind << "sq_setinstanceup(v, 1, _this);\n";
250 out << ind << "sq_setreleasehook(v, 1, "
251 << _class->name << "_release_wrapper);\n";
253 out << ind << "return 0;\n";
259 WrapperCreator::create_class_destruct_function(Class* _class)
261 out << "static int " << _class->name << "_release_wrapper(SQUserPointer ptr, int )\n"
263 << ind << _class->name
264 << "* _this = reinterpret_cast<" << _class->name << "*> (ptr);\n"
265 << ind << "_this->~" << _class->name << "();\n"
266 << ind << "return 0;\n"