summaryrefslogtreecommitdiff
path: root/Source/Modules/chicken.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/chicken.cxx')
-rw-r--r--Source/Modules/chicken.cxx1552
1 files changed, 1552 insertions, 0 deletions
diff --git a/Source/Modules/chicken.cxx b/Source/Modules/chicken.cxx
new file mode 100644
index 0000000..3bf6602
--- /dev/null
+++ b/Source/Modules/chicken.cxx
@@ -0,0 +1,1552 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * chicken.cxx
+ *
+ * CHICKEN language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_chicken_cxx[] = "$Id: chicken.cxx 11133 2009-02-20 07:52:24Z wsfulton $";
+
+#include "swigmod.h"
+
+#include <ctype.h>
+
+static const char *chicken_usage = (char *) "\
+\
+CHICKEN Options (available with -chicken)\n\
+ -proxy - Export TinyCLOS class definitions\n\
+ -closprefix <prefix> - Prepend <prefix> to all clos identifiers\n\
+ -useclassprefix - Prepend the class name to all clos identifiers\n\
+ -unhideprimitive - Unhide the primitive: symbols\n\
+ -nounit - Do not (declare (unit ...)) in scheme file\n\
+ -noclosuses - Do not (declare (uses ...)) in scheme file\n\
+ -nocollection - Do not register pointers with chicken garbage\n\
+ collector and export destructors\n\
+\n";
+
+static char *module = 0;
+static char *chicken_path = (char *) "chicken";
+static int num_methods = 0;
+
+static File *f_begin = 0;
+static File *f_runtime = 0;
+static File *f_header = 0;
+static File *f_wrappers = 0;
+static File *f_init = 0;
+static String *chickentext = 0;
+static String *closprefix = 0;
+static String *swigtype_ptr = 0;
+
+
+static String *f_sym_size = 0;
+
+/* some options */
+static int declare_unit = 1;
+static int no_collection = 0;
+static int clos_uses = 1;
+
+/* C++ Support + Clos Classes */
+static int clos = 0;
+static String *c_class_name = 0;
+static String *class_name = 0;
+static String *short_class_name = 0;
+
+static int in_class = 0;
+static int have_constructor = 0;
+static bool exporting_destructor = false;
+static bool exporting_constructor = false;
+static String *constructor_name = 0;
+static String *member_name = 0;
+
+/* sections of the .scm code */
+static String *scm_const_defs = 0;
+static String *clos_class_defines = 0;
+static String *clos_methods = 0;
+
+/* Some clos options */
+static int useclassprefix = 0;
+static String *clossymnameprefix = 0;
+static int hide_primitive = 1;
+static Hash *primitive_names = 0;
+
+/* Used for overloading constructors */
+static int has_constructor_args = 0;
+static List *constructor_arg_types = 0;
+static String *constructor_dispatch = 0;
+
+static Hash *overload_parameter_lists = 0;
+
+class CHICKEN:public Language {
+public:
+
+ virtual void main(int argc, char *argv[]);
+ virtual int top(Node *n);
+ virtual int functionWrapper(Node *n);
+ virtual int variableWrapper(Node *n);
+ virtual int constantWrapper(Node *n);
+ virtual int classHandler(Node *n);
+ virtual int memberfunctionHandler(Node *n);
+ virtual int membervariableHandler(Node *n);
+ virtual int constructorHandler(Node *n);
+ virtual int destructorHandler(Node *n);
+ virtual int validIdentifier(String *s);
+ virtual int staticmembervariableHandler(Node *n);
+ virtual int staticmemberfunctionHandler(Node *n);
+ virtual int importDirective(Node *n);
+
+protected:
+ void addMethod(String *scheme_name, String *function);
+ /* Return true iff T is a pointer type */
+ int isPointer(SwigType *t);
+ void dispatchFunction(Node *n);
+
+ String *chickenNameMapping(String *, const_String_or_char_ptr );
+ String *chickenPrimitiveName(String *);
+
+ String *runtimeCode();
+ String *defaultExternalRuntimeFilename();
+ String *buildClosFunctionCall(List *types, const_String_or_char_ptr closname, const_String_or_char_ptr funcname);
+};
+
+/* -----------------------------------------------------------------------
+ * swig_chicken() - Instantiate module
+ * ----------------------------------------------------------------------- */
+
+static Language *new_swig_chicken() {
+ return new CHICKEN();
+}
+
+extern "C" {
+ Language *swig_chicken(void) {
+ return new_swig_chicken();
+ }
+}
+
+void CHICKEN::main(int argc, char *argv[]) {
+ int i;
+
+ SWIG_library_directory(chicken_path);
+
+ // Look for certain command line options
+ for (i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-help") == 0) {
+ fputs(chicken_usage, stdout);
+ SWIG_exit(0);
+ } else if (strcmp(argv[i], "-proxy") == 0) {
+ clos = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-closprefix") == 0) {
+ if (argv[i + 1]) {
+ clossymnameprefix = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-useclassprefix") == 0) {
+ useclassprefix = 1;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-unhideprimitive") == 0) {
+ hide_primitive = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nounit") == 0) {
+ declare_unit = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-noclosuses") == 0) {
+ clos_uses = 0;
+ Swig_mark_arg(i);
+ } else if (strcmp(argv[i], "-nocollection") == 0) {
+ no_collection = 1;
+ Swig_mark_arg(i);
+ }
+ }
+ }
+
+ if (!clos)
+ hide_primitive = 0;
+
+ // Add a symbol for this module
+ Preprocessor_define("SWIGCHICKEN 1", 0);
+
+ // Set name of typemaps
+
+ SWIG_typemap_lang("chicken");
+
+ // Read in default typemaps */
+ SWIG_config_file("chicken.swg");
+ allow_overloading();
+}
+
+int CHICKEN::top(Node *n) {
+ String *chicken_filename = NewString("");
+ File *f_scm;
+ String *scmmodule;
+
+ /* Initialize all of the output files */
+ String *outfile = Getattr(n, "outfile");
+
+ f_begin = NewFile(outfile, "w", SWIG_output_files());
+ if (!f_begin) {
+ FileErrorDisplay(outfile);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_runtime = NewString("");
+ f_init = NewString("");
+ f_header = NewString("");
+ f_wrappers = NewString("");
+ chickentext = NewString("");
+ closprefix = NewString("");
+ f_sym_size = NewString("");
+ primitive_names = NewHash();
+ overload_parameter_lists = NewHash();
+
+ /* Register file targets with the SWIG file handler */
+ Swig_register_filebyname("header", f_header);
+ Swig_register_filebyname("wrapper", f_wrappers);
+ Swig_register_filebyname("begin", f_begin);
+ Swig_register_filebyname("runtime", f_runtime);
+ Swig_register_filebyname("init", f_init);
+
+ Swig_register_filebyname("chicken", chickentext);
+ Swig_register_filebyname("closprefix", closprefix);
+
+ clos_class_defines = NewString("");
+ clos_methods = NewString("");
+ scm_const_defs = NewString("");
+
+ Swig_banner(f_begin);
+
+ Printf(f_runtime, "\n");
+ Printf(f_runtime, "#define SWIGCHICKEN\n");
+
+ if (no_collection)
+ Printf(f_runtime, "#define SWIG_CHICKEN_NO_COLLECTION 1\n");
+
+ Printf(f_runtime, "\n");
+
+ /* Set module name */
+ module = Swig_copy_string(Char(Getattr(n, "name")));
+ scmmodule = NewString(module);
+ Replaceall(scmmodule, "_", "-");
+
+ Printf(f_header, "#define SWIG_init swig_%s_init\n", module);
+ Printf(f_header, "#define SWIG_name \"%s\"\n", scmmodule);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "extern \"C\" {\n");
+ Printf(f_wrappers, "#endif\n\n");
+
+ Language::top(n);
+
+ SwigType_emit_type_table(f_runtime, f_wrappers);
+
+ Printf(f_wrappers, "#ifdef __cplusplus\n");
+ Printf(f_wrappers, "}\n");
+ Printf(f_wrappers, "#endif\n");
+
+ Printf(f_init, "C_kontinue (continuation, ret);\n");
+ Printf(f_init, "}\n\n");
+
+ Printf(f_init, "#ifdef __cplusplus\n");
+ Printf(f_init, "}\n");
+ Printf(f_init, "#endif\n");
+
+ Printf(chicken_filename, "%s%s.scm", SWIG_output_directory(), module);
+ if ((f_scm = NewFile(chicken_filename, "w", SWIG_output_files())) == 0) {
+ FileErrorDisplay(chicken_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ Swig_banner_target_lang(f_scm, ";;");
+ Printf(f_scm, "\n");
+
+ if (declare_unit)
+ Printv(f_scm, "(declare (unit ", scmmodule, "))\n\n", NIL);
+ Printv(f_scm, "(declare \n",
+ tab4, "(hide swig-init swig-init-return)\n",
+ tab4, "(foreign-declare \"C_extern void swig_", module, "_init(C_word,C_word,C_word) C_noret;\"))\n", NIL);
+ Printv(f_scm, "(define swig-init (##core#primitive \"swig_", module, "_init\"))\n", NIL);
+ Printv(f_scm, "(define swig-init-return (swig-init))\n\n", NIL);
+
+ if (clos) {
+ //Printf (f_scm, "(declare (uses tinyclos))\n");
+ //New chicken versions have tinyclos as an egg
+ Printf(f_scm, "(require-extension tinyclos)\n");
+ Replaceall(closprefix, "$module", scmmodule);
+ Printf(f_scm, "%s\n", closprefix);
+ Printf(f_scm, "%s\n", clos_class_defines);
+ Printf(f_scm, "%s\n", clos_methods);
+ } else {
+ Printf(f_scm, "%s\n", scm_const_defs);
+ }
+
+ Printf(f_scm, "%s\n", chickentext);
+
+
+ Close(f_scm);
+ Delete(f_scm);
+
+ char buftmp[20];
+ sprintf(buftmp, "%d", num_methods);
+ Replaceall(f_init, "$nummethods", buftmp);
+ Replaceall(f_init, "$symsize", f_sym_size);
+
+ if (hide_primitive)
+ Replaceall(f_init, "$veclength", buftmp);
+ else
+ Replaceall(f_init, "$veclength", "0");
+
+ Delete(chicken_filename);
+ Delete(chickentext);
+ Delete(closprefix);
+ Delete(overload_parameter_lists);
+
+ Delete(clos_class_defines);
+ Delete(clos_methods);
+ Delete(scm_const_defs);
+
+ /* Close all of the files */
+ Delete(primitive_names);
+ Delete(scmmodule);
+ Dump(f_runtime, f_begin);
+ Dump(f_header, f_begin);
+ Dump(f_wrappers, f_begin);
+ Wrapper_pretty_print(f_init, f_begin);
+ Delete(f_header);
+ Delete(f_wrappers);
+ Delete(f_sym_size);
+ Delete(f_init);
+ Close(f_begin);
+ Delete(f_runtime);
+ Delete(f_begin);
+ return SWIG_OK;
+}
+
+int CHICKEN::functionWrapper(Node *n) {
+
+ String *name = Getattr(n, "name");
+ String *iname = Getattr(n, "sym:name");
+ SwigType *d = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+
+ Parm *p;
+ int i;
+ String *wname;
+ Wrapper *f;
+ String *mangle = NewString("");
+ String *get_pointers;
+ String *cleanup;
+ String *argout;
+ String *tm;
+ String *overname = 0;
+ String *declfunc = 0;
+ String *scmname;
+ bool any_specialized_arg = false;
+ List *function_arg_types = NewList();
+
+ int num_required;
+ int num_arguments;
+ int have_argout;
+
+ Printf(mangle, "\"%s\"", SwigType_manglestr(d));
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+ wname = NewString("");
+ get_pointers = NewString("");
+ cleanup = NewString("");
+ argout = NewString("");
+ declfunc = NewString("");
+ scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ /* Local vars */
+ Wrapper_add_local(f, "resultobj", "C_word resultobj");
+
+ /* Write code to extract function parameters. */
+ emit_parameter_variables(l, f);
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ Append(wname, Swig_name_wrapper(iname));
+ if (overname) {
+ Append(wname, overname);
+ }
+ // Check for interrupts
+ Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
+
+ Printv(f->def, "static ", "void ", wname, " (C_word argc, C_word closure, C_word continuation", NIL);
+ Printv(declfunc, "void ", wname, "(C_word,C_word,C_word", NIL);
+
+ /* Generate code for argument marshalling */
+ for (i = 0, p = l; i < num_arguments; i++) {
+
+ while (checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+
+ SwigType *pt = Getattr(p, "type");
+ String *ln = Getattr(p, "lname");
+
+ Printf(f->def, ", C_word scm%d", i + 1);
+ Printf(declfunc, ",C_word");
+
+ /* Look for an input typemap */
+ if ((tm = Getattr(p, "tmap:in"))) {
+ String *parse = Getattr(p, "tmap:in:parse");
+ if (!parse) {
+ String *source = NewStringf("scm%d", i + 1);
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$target", ln);
+ Replaceall(tm, "$input", source);
+ Setattr(p, "emit:input", source); /* Save the location of
+ the object */
+
+ if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
+ Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
+ } else {
+ Replaceall(tm, "$disown", "0");
+ }
+
+ if (i >= num_required)
+ Printf(get_pointers, "if (argc-2>%i && (%s)) {\n", i, source);
+ Printv(get_pointers, tm, "\n", NIL);
+ if (i >= num_required)
+ Printv(get_pointers, "}\n", NIL);
+
+ if (clos) {
+ if (i < num_required) {
+ if (strcmp("void", Char(pt)) != 0) {
+ Node *class_node = 0;
+ String *clos_code = Getattr(p, "tmap:in:closcode");
+ class_node = classLookup(pt);
+ if (clos_code && class_node) {
+ String *class_name = NewStringf("<%s>", Getattr(class_node, "sym:name"));
+ Replaceall(class_name, "_", "-");
+ Append(function_arg_types, class_name);
+ Append(function_arg_types, Copy(clos_code));
+ any_specialized_arg = true;
+ Delete(class_name);
+ } else {
+ Append(function_arg_types, "<top>");
+ Append(function_arg_types, "$input");
+ }
+ }
+ }
+ }
+ Delete(source);
+ }
+
+ p = Getattr(p, "tmap:in:next");
+ continue;
+ } else {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+ break;
+ }
+ }
+
+ /* finish argument marshalling */
+
+ Printf(f->def, ") {");
+ Printf(declfunc, ")");
+
+ if (num_required != num_arguments) {
+ Append(function_arg_types, "^^##optional$$");
+ }
+
+ /* First check the number of arguments is correct */
+ if (num_arguments != num_required)
+ Printf(f->code, "if (argc-2<%i || argc-2>%i) C_bad_argc(argc,%i);\n", num_required, num_arguments, num_required + 2);
+ else
+ Printf(f->code, "if (argc!=%i) C_bad_argc(argc,%i);\n", num_arguments + 2, num_arguments + 2);
+
+ /* Now piece together the first part of the wrapper function */
+ Printv(f->code, get_pointers, NIL);
+
+ /* Insert constraint checking code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:check"))) {
+ Replaceall(tm, "$target", Getattr(p, "lname"));
+ Printv(f->code, tm, "\n", NIL);
+ p = Getattr(p, "tmap:check:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert cleanup code */
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:freearg"))) {
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Printv(cleanup, tm, "\n", NIL);
+ p = Getattr(p, "tmap:freearg:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ /* Insert argument output code */
+ have_argout = 0;
+ for (p = l; p;) {
+ if ((tm = Getattr(p, "tmap:argout"))) {
+
+ if (!have_argout) {
+ have_argout = 1;
+ // Print initial argument output code
+ Printf(argout, "SWIG_Chicken_SetupArgout\n");
+ }
+
+ Replaceall(tm, "$source", Getattr(p, "lname"));
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$arg", Getattr(p, "emit:input"));
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printf(argout, "%s", tm);
+ p = Getattr(p, "tmap:argout:next");
+ } else {
+ p = nextSibling(p);
+ }
+ }
+
+ Setattr(n, "wrap:name", wname);
+
+ /* Emit the function call */
+ String *actioncode = emit_action(n);
+
+ /* Return the function value */
+ if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
+ Replaceall(tm, "$source", "result");
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "1");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+
+ Printf(f->code, "%s", tm);
+
+ if (have_argout)
+ Printf(f->code, "\nSWIG_APPEND_VALUE(resultobj);\n");
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
+ }
+ emit_return_variable(n, d, f);
+
+ /* Insert the argumetn output code */
+ Printv(f->code, argout, NIL);
+
+ /* Output cleanup code */
+ Printv(f->code, cleanup, NIL);
+
+ /* Look to see if there is any newfree cleanup code */
+ if (GetFlag(n, "feature:new")) {
+ if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+ }
+
+ /* See if there is any return cleanup code */
+ if ((tm = Swig_typemap_lookup("ret", n, "result", 0))) {
+ Replaceall(tm, "$source", "result");
+ Printf(f->code, "%s\n", tm);
+ }
+
+
+ if (have_argout) {
+ Printf(f->code, "C_kontinue(continuation,C_SCHEME_END_OF_LIST);\n");
+ } else {
+ if (exporting_constructor && clos && hide_primitive) {
+ /* Don't return a proxy, the wrapped CLOS class is the proxy */
+ Printf(f->code, "C_kontinue(continuation,resultobj);\n");
+ } else {
+ // make the continuation the proxy creation function, if one exists
+ Printv(f->code, "{\n",
+ "C_word func;\n",
+ "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
+ "if (C_swig_is_closurep(func))\n",
+ " ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
+ "else\n", " C_kontinue(continuation, resultobj);\n", "}\n", NIL);
+ }
+ }
+
+ /* Error handling code */
+#ifdef USE_FAIL
+ Printf(f->code, "fail:\n");
+ Printv(f->code, cleanup, NIL);
+ Printf(f->code, "swig_panic (\"failure in " "'$symname' SWIG function wrapper\");\n");
+#endif
+ Printf(f->code, "}\n");
+
+ /* Substitute the cleanup code */
+ Replaceall(f->code, "$cleanup", cleanup);
+
+ /* Substitute the function name */
+ Replaceall(f->code, "$symname", iname);
+ Replaceall(f->code, "$result", "resultobj");
+
+ /* Dump the function out */
+ Printv(f_wrappers, "static ", declfunc, " C_noret;\n", NIL);
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the function with the interpreter. */
+ if (!Getattr(n, "sym:overloaded")) {
+ if (exporting_destructor && !no_collection) {
+ Printf(f_init, "((swig_chicken_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (swig_chicken_destructor) %s;\n", swigtype_ptr, wname);
+ } else {
+ addMethod(scmname, wname);
+ }
+
+ /* Only export if we are not in a class, or if in a class memberfunction */
+ if (!in_class || member_name) {
+ String *method_def;
+ String *clos_name;
+ if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+
+ if (!any_specialized_arg) {
+ method_def = NewString("");
+ Printv(method_def, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")", NIL);
+ } else {
+ method_def = buildClosFunctionCall(function_arg_types, clos_name, chickenPrimitiveName(scmname));
+ }
+ Printv(clos_methods, method_def, "\n", NIL);
+ Delete(clos_name);
+ Delete(method_def);
+ }
+
+ if (have_constructor && !has_constructor_args && any_specialized_arg) {
+ has_constructor_args = 1;
+ constructor_arg_types = Copy(function_arg_types);
+ }
+ } else {
+ /* add function_arg_types to overload hash */
+ List *flist = Getattr(overload_parameter_lists, scmname);
+ if (!flist) {
+ flist = NewList();
+ Setattr(overload_parameter_lists, scmname, flist);
+ }
+
+ Append(flist, Copy(function_arg_types));
+
+ if (!Getattr(n, "sym:nextSibling")) {
+ dispatchFunction(n);
+ }
+ }
+
+
+ Delete(wname);
+ Delete(get_pointers);
+ Delete(cleanup);
+ Delete(declfunc);
+ Delete(mangle);
+ Delete(function_arg_types);
+ DelWrapper(f);
+ return SWIG_OK;
+}
+
+int CHICKEN::variableWrapper(Node *n) {
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+
+ String *wname = NewString("");
+ String *mangle = NewString("");
+ String *tm;
+ String *tm2 = NewString("");;
+ String *argnum = NewString("0");
+ String *arg = NewString("argv[0]");
+ Wrapper *f;
+ String *overname = 0;
+ String *scmname;
+
+ int num_required;
+ int num_arguments;
+
+ scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ Printf(mangle, "\"%s\"", SwigType_manglestr(t));
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ f = NewWrapper();
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ // evaluation function names
+ Append(wname, Swig_name_wrapper(iname));
+ if (overname) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ // Check for interrupts
+ Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
+
+ if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
+
+ Printv(f->def, "static ", "void ", wname, "(C_word, C_word, C_word, C_word) C_noret;\n", NIL);
+ Printv(f->def, "static " "void ", wname, "(C_word argc, C_word closure, " "C_word continuation, C_word value) {\n", NIL);
+
+ Wrapper_add_local(f, "resultobj", "C_word resultobj");
+
+ Printf(f->code, "if (argc!=2 && argc!=3) C_bad_argc(argc,2);\n");
+
+ /* Check for a setting of the variable value */
+ if (!GetFlag(n, "feature:immutable")) {
+ Printf(f->code, "if (argc > 2) {\n");
+ if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
+ Replaceall(tm, "$source", "value");
+ Replaceall(tm, "$target", name);
+ Replaceall(tm, "$input", "value");
+ /* Printv(f->code, tm, "\n",NIL); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
+ }
+ Printf(f->code, "}\n");
+ }
+
+ String *varname;
+ if (SwigType_istemplate((char *) name)) {
+ varname = SwigType_namestr((char *) name);
+ } else {
+ varname = name;
+ }
+
+ // Now return the value of the variable - regardless
+ // of evaluating or setting.
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+ Replaceall(tm, "$source", varname);
+ Replaceall(tm, "$varname", varname);
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ /* Printf(f->code, "%s\n", tm); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+
+ Printv(f->code, "{\n",
+ "C_word func;\n",
+ "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
+ "if (C_swig_is_closurep(func))\n",
+ " ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
+ "else\n", " C_kontinue(continuation, resultobj);\n", "}\n", NIL);
+
+ /* Error handling code */
+#ifdef USE_FAIL
+ Printf(f->code, "fail:\n");
+ Printf(f->code, "swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name);
+#endif
+ Printf(f->code, "}\n");
+
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the variable with the interpreter. */
+ addMethod(scmname, wname);
+
+ if (!in_class || member_name) {
+ String *clos_name;
+ if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+
+ Node *class_node = classLookup(t);
+ String *clos_code = Getattr(n, "tmap:varin:closcode");
+ if (class_node && clos_code && !GetFlag(n, "feature:immutable")) {
+ Replaceall(clos_code, "$input", "(car lst)");
+ Printv(clos_methods, "(define (", clos_name, " . lst) (if (null? lst) (", chickenPrimitiveName(scmname), ") (",
+ chickenPrimitiveName(scmname), " ", clos_code, ")))\n", NIL);
+ } else {
+ /* Simply re-export the procedure */
+ if (GetFlag(n, "feature:immutable") && GetFlag(n, "feature:constasvar")) {
+ Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
+ Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
+ } else {
+ Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
+ }
+ }
+ Delete(clos_name);
+ }
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
+ }
+
+ Delete(wname);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ Delete(mangle);
+ DelWrapper(f);
+ return SWIG_OK;
+}
+
+/* ------------------------------------------------------------
+ * constantWrapper()
+ * ------------------------------------------------------------ */
+
+int CHICKEN::constantWrapper(Node *n) {
+
+ char *name = GetChar(n, "name");
+ char *iname = GetChar(n, "sym:name");
+ SwigType *t = Getattr(n, "type");
+ ParmList *l = Getattr(n, "parms");
+ String *value = Getattr(n, "value");
+
+ String *proc_name = NewString("");
+ String *wname = NewString("");
+ String *mangle = NewString("");
+ String *tm;
+ String *tm2 = NewString("");
+ String *source = NewString("");
+ String *argnum = NewString("0");
+ String *arg = NewString("argv[0]");
+ Wrapper *f;
+ String *overname = 0;
+ String *scmname;
+ String *rvalue;
+ SwigType *nctype;
+
+ int num_required;
+ int num_arguments;
+
+ scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ Printf(source, "swig_const_%s", iname);
+ Replaceall(source, "::", "__");
+
+ Printf(mangle, "\"%s\"", SwigType_manglestr(t));
+
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else {
+ if (!addSymbol(iname, n))
+ return SWIG_ERROR;
+ }
+
+ Append(wname, Swig_name_wrapper(iname));
+ if (overname) {
+ Append(wname, overname);
+ }
+
+ nctype = NewString(t);
+ if (SwigType_isconst(nctype)) {
+ Delete(SwigType_pop(nctype));
+ }
+
+ if (SwigType_type(nctype) == T_STRING) {
+ rvalue = NewStringf("\"%s\"", value);
+ } else if (SwigType_type(nctype) == T_CHAR) {
+ rvalue = NewStringf("\'%s\'", value);
+ } else {
+ rvalue = NewString(value);
+ }
+
+ /* Special hook for member pointer */
+ if (SwigType_type(t) == T_MPOINTER) {
+ Printf(f_header, "static %s = %s;\n", SwigType_str(t, source), rvalue);
+ } else {
+ if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
+ Replaceall(tm, "$source", rvalue);
+ Replaceall(tm, "$target", source);
+ Replaceall(tm, "$result", source);
+ Replaceall(tm, "$value", rvalue);
+ Printf(f_header, "%s\n", tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
+ return SWIG_NOWRAP;
+ }
+ }
+
+ f = NewWrapper();
+
+ /* Attach the standard typemaps */
+ emit_attach_parmmaps(l, f);
+ Setattr(n, "wrap:parms", l);
+
+ /* Get number of required and total arguments */
+ num_arguments = emit_num_arguments(l);
+ num_required = emit_num_required(l);
+
+ // evaluation function names
+
+ // Check for interrupts
+ Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
+
+ if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
+
+ Setattr(n, "wrap:name", wname);
+ Printv(f->def, "static ", "void ", wname, "(C_word, C_word, C_word) C_noret;\n", NIL);
+
+ Printv(f->def, "static ", "void ", wname, "(C_word argc, C_word closure, " "C_word continuation) {\n", NIL);
+
+ Wrapper_add_local(f, "resultobj", "C_word resultobj");
+
+ Printf(f->code, "if (argc!=2) C_bad_argc(argc,2);\n");
+
+ // Return the value of the variable
+ if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
+
+ Replaceall(tm, "$source", source);
+ Replaceall(tm, "$varname", source);
+ Replaceall(tm, "$target", "resultobj");
+ Replaceall(tm, "$result", "resultobj");
+ /* Printf(f->code, "%s\n", tm); */
+ emit_action_code(n, f->code, tm);
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
+ }
+
+ Printv(f->code, "{\n",
+ "C_word func;\n",
+ "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
+ "if (C_swig_is_closurep(func))\n",
+ " ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
+ "else\n", " C_kontinue(continuation, resultobj);\n", "}\n", NIL);
+
+ /* Error handling code */
+#ifdef USE_FAIL
+ Printf(f->code, "fail:\n");
+ Printf(f->code, "swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name);
+#endif
+ Printf(f->code, "}\n");
+
+ Wrapper_print(f, f_wrappers);
+
+ /* Now register the variable with the interpreter. */
+ addMethod(scmname, wname);
+
+ if (!in_class || member_name) {
+ String *clos_name;
+ if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+ if (GetFlag(n, "feature:constasvar")) {
+ Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
+ Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
+ } else {
+ Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
+ }
+ Delete(clos_name);
+ }
+
+ } else {
+ Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
+ }
+
+ Delete(wname);
+ Delete(nctype);
+ Delete(proc_name);
+ Delete(argnum);
+ Delete(arg);
+ Delete(tm2);
+ Delete(mangle);
+ Delete(source);
+ Delete(rvalue);
+ DelWrapper(f);
+ return SWIG_OK;
+}
+
+int CHICKEN::classHandler(Node *n) {
+ /* Create new strings for building up a wrapper function */
+ have_constructor = 0;
+ constructor_dispatch = 0;
+ constructor_name = 0;
+
+ c_class_name = NewString(Getattr(n, "sym:name"));
+ class_name = NewString("");
+ short_class_name = NewString("");
+ Printv(class_name, "<", c_class_name, ">", NIL);
+ Printv(short_class_name, c_class_name, NIL);
+ Replaceall(class_name, "_", "-");
+ Replaceall(short_class_name, "_", "-");
+
+ if (!addSymbol(class_name, n))
+ return SWIG_ERROR;
+
+ /* Handle inheritance */
+ String *base_class = NewString("");
+ List *baselist = Getattr(n, "bases");
+ if (baselist && Len(baselist)) {
+ Iterator base = First(baselist);
+ while (base.item) {
+ if (!Getattr(base.item, "feature:ignore"))
+ Printv(base_class, "<", Getattr(base.item, "sym:name"), "> ", NIL);
+ base = Next(base);
+ }
+ }
+
+ Replaceall(base_class, "_", "-");
+
+ String *scmmod = NewString(module);
+ Replaceall(scmmod, "_", "-");
+
+ Printv(clos_class_defines, "(define ", class_name, "\n", " (make <swig-metaclass-", scmmod, "> 'name \"", short_class_name, "\"\n", NIL);
+ Delete(scmmod);
+
+ if (Len(base_class)) {
+ Printv(clos_class_defines, " 'direct-supers (list ", base_class, ")\n", NIL);
+ } else {
+ Printv(clos_class_defines, " 'direct-supers (list <object>)\n", NIL);
+ }
+
+ Printf(clos_class_defines, " 'direct-slots (list 'swig-this\n");
+
+ String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
+
+ SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
+ swigtype_ptr = SwigType_manglestr(ct);
+
+ Printf(f_runtime, "static swig_chicken_clientdata _swig_chicken_clientdata%s = { 0 };\n", mangled_classname);
+ Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_chicken_clientdata", mangled_classname, ");\n", NIL);
+ SwigType_remember(ct);
+
+ /* Emit all of the members */
+
+ in_class = 1;
+ Language::classHandler(n);
+ in_class = 0;
+
+ Printf(clos_class_defines, ")))\n\n");
+
+ if (have_constructor) {
+ Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n", " (swig-initialize obj initargs ", NIL);
+ if (constructor_arg_types) {
+ String *initfunc_name = NewStringf("%s@@SWIG@initmethod", class_name);
+ String *func_call = buildClosFunctionCall(constructor_arg_types, initfunc_name, chickenPrimitiveName(constructor_name));
+ Printf(clos_methods, "%s)\n)\n", initfunc_name);
+ Printf(clos_methods, "(declare (hide %s))\n", initfunc_name);
+ Printf(clos_methods, "%s\n", func_call);
+ Delete(func_call);
+ Delete(initfunc_name);
+ Delete(constructor_arg_types);
+ constructor_arg_types = 0;
+ } else if (constructor_dispatch) {
+ Printf(clos_methods, "%s)\n)\n", constructor_dispatch);
+ Delete(constructor_dispatch);
+ constructor_dispatch = 0;
+ } else {
+ Printf(clos_methods, "%s)\n)\n", chickenPrimitiveName(constructor_name));
+ }
+ Delete(constructor_name);
+ constructor_name = 0;
+ } else {
+ Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n", " (swig-initialize obj initargs (lambda x #f)))\n", NIL);
+ }
+
+ /* export class initialization function */
+ if (clos) {
+ String *funcname = NewString(mangled_classname);
+ Printf(funcname, "_swig_chicken_setclosclass");
+ String *closfuncname = NewString(funcname);
+ Replaceall(closfuncname, "_", "-");
+
+ Printv(f_wrappers, "static void ", funcname, "(C_word,C_word,C_word,C_word) C_noret;\n",
+ "static void ", funcname, "(C_word argc, C_word closure, C_word continuation, C_word cl) {\n",
+ " C_trace(\"", funcname, "\");\n",
+ " if (argc!=3) C_bad_argc(argc,3);\n",
+ " swig_chicken_clientdata *cdata = (swig_chicken_clientdata *) SWIGTYPE", swigtype_ptr, "->clientdata;\n",
+ " cdata->gc_proxy_create = CHICKEN_new_gc_root();\n",
+ " CHICKEN_gc_root_set(cdata->gc_proxy_create, cl);\n", " C_kontinue(continuation, C_SCHEME_UNDEFINED);\n", "}\n", NIL);
+ addMethod(closfuncname, funcname);
+
+ Printv(clos_methods, "(", chickenPrimitiveName(closfuncname), " (lambda (x lst) (if lst ",
+ "(cons (make ", class_name, " 'swig-this x) lst) ", "(make ", class_name, " 'swig-this x))))\n\n", NIL);
+ Delete(closfuncname);
+ Delete(funcname);
+ }
+
+ Delete(mangled_classname);
+ Delete(swigtype_ptr);
+ swigtype_ptr = 0;
+
+ Delete(class_name);
+ Delete(short_class_name);
+ Delete(c_class_name);
+ class_name = 0;
+ short_class_name = 0;
+ c_class_name = 0;
+
+ return SWIG_OK;
+}
+
+int CHICKEN::memberfunctionHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ member_name = chickenNameMapping(proc, short_class_name);
+ Language::memberfunctionHandler(n);
+ Delete(member_name);
+ member_name = NULL;
+ Delete(proc);
+
+ return SWIG_OK;
+}
+
+int CHICKEN::staticmemberfunctionHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ member_name = NewStringf("%s-%s", short_class_name, proc);
+ Language::staticmemberfunctionHandler(n);
+ Delete(member_name);
+ member_name = NULL;
+ Delete(proc);
+
+ return SWIG_OK;
+}
+
+int CHICKEN::membervariableHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ //String *pb = SwigType_typedef_resolve_all(SwigType_base(Getattr(n, "type")));
+
+ Language::membervariableHandler(n);
+
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ //Node *class_node = Swig_symbol_clookup(pb, Getattr(n, "sym:symtab"));
+ Node *class_node = classLookup(Getattr(n, "type"));
+
+ //String *getfunc = NewStringf("%s-%s-get", short_class_name, proc);
+ //String *setfunc = NewStringf("%s-%s-set", short_class_name, proc);
+ String *getfunc = Swig_name_get(Swig_name_member(c_class_name, iname));
+ Replaceall(getfunc, "_", "-");
+ String *setfunc = Swig_name_set(Swig_name_member(c_class_name, iname));
+ Replaceall(setfunc, "_", "-");
+
+ Printv(clos_class_defines, " (list '", proc, " ':swig-virtual ':swig-get ", chickenPrimitiveName(getfunc), NIL);
+
+ if (!GetFlag(n, "feature:immutable")) {
+ if (class_node) {
+ Printv(clos_class_defines, " ':swig-set (lambda (x y) (", chickenPrimitiveName(setfunc), " x (slot-ref y 'swig-this))))\n", NIL);
+ } else {
+ Printv(clos_class_defines, " ':swig-set ", chickenPrimitiveName(setfunc), ")\n", NIL);
+ }
+ } else {
+ Printf(clos_class_defines, ")\n");
+ }
+
+ Delete(proc);
+ Delete(setfunc);
+ Delete(getfunc);
+ return SWIG_OK;
+}
+
+int CHICKEN::staticmembervariableHandler(Node *n) {
+ String *iname = Getattr(n, "sym:name");
+ String *proc = NewString(iname);
+ Replaceall(proc, "_", "-");
+
+ member_name = NewStringf("%s-%s", short_class_name, proc);
+ Language::staticmembervariableHandler(n);
+ Delete(member_name);
+ member_name = NULL;
+ Delete(proc);
+
+ return SWIG_OK;
+}
+
+int CHICKEN::constructorHandler(Node *n) {
+ have_constructor = 1;
+ has_constructor_args = 0;
+
+
+ exporting_constructor = true;
+ Language::constructorHandler(n);
+ exporting_constructor = false;
+
+ has_constructor_args = 1;
+
+ String *iname = Getattr(n, "sym:name");
+ constructor_name = Swig_name_construct(iname);
+ Replaceall(constructor_name, "_", "-");
+ return SWIG_OK;
+}
+
+int CHICKEN::destructorHandler(Node *n) {
+
+ if (no_collection)
+ member_name = NewStringf("delete-%s", short_class_name);
+
+ exporting_destructor = true;
+ Language::destructorHandler(n);
+ exporting_destructor = false;
+
+ if (no_collection) {
+ Delete(member_name);
+ member_name = NULL;
+ }
+
+ return SWIG_OK;
+}
+
+int CHICKEN::importDirective(Node *n) {
+ String *modname = Getattr(n, "module");
+ if (modname && clos_uses) {
+
+ // Find the module node for this imported module. It should be the
+ // first child but search just in case.
+ Node *mod = firstChild(n);
+ while (mod && Strcmp(nodeType(mod), "module") != 0)
+ mod = nextSibling(mod);
+
+ if (mod) {
+ String *name = Getattr(mod, "name");
+ if (name) {
+ Printf(closprefix, "(declare (uses %s))\n", name);
+ }
+ }
+ }
+
+ return Language::importDirective(n);
+}
+
+String *CHICKEN::buildClosFunctionCall(List *types, const_String_or_char_ptr closname, const_String_or_char_ptr funcname) {
+ String *method_signature = NewString("");
+ String *func_args = NewString("");
+ String *func_call = NewString("");
+
+ Iterator arg_type;
+ int arg_count = 0;
+ int optional_arguments = 0;
+
+ for (arg_type = First(types); arg_type.item; arg_type = Next(arg_type)) {
+ if (Strcmp(arg_type.item, "^^##optional$$") == 0) {
+ optional_arguments = 1;
+ } else {
+ Printf(method_signature, " (arg%i %s)", arg_count, arg_type.item);
+ arg_type = Next(arg_type);
+ if (!arg_type.item)
+ break;
+
+ String *arg = NewStringf("arg%i", arg_count);
+ String *access_arg = Copy(arg_type.item);
+
+ Replaceall(access_arg, "$input", arg);
+ Printf(func_args, " %s", access_arg);
+
+ Delete(arg);
+ Delete(access_arg);
+ }
+ arg_count++;
+ }
+
+ if (optional_arguments) {
+ Printf(func_call, "(define-method (%s %s . args) (apply %s %s args))", closname, method_signature, funcname, func_args);
+ } else {
+ Printf(func_call, "(define-method (%s %s) (%s %s))", closname, method_signature, funcname, func_args);
+ }
+
+ Delete(method_signature);
+ Delete(func_args);
+
+ return func_call;
+}
+
+extern "C" {
+
+ /* compares based on non-primitive names */
+ static int compareTypeListsHelper(const DOH *a, const DOH *b, int opt_equal) {
+ List *la = (List *) a;
+ List *lb = (List *) b;
+
+ Iterator ia = First(la);
+ Iterator ib = First(lb);
+
+ while (ia.item && ib.item) {
+ int ret = Strcmp(ia.item, ib.item);
+ if (ret)
+ return ret;
+ ia = Next(Next(ia));
+ ib = Next(Next(ib));
+ } if (opt_equal && ia.item && Strcmp(ia.item, "^^##optional$$") == 0)
+ return 0;
+ if (ia.item)
+ return -1;
+ if (opt_equal && ib.item && Strcmp(ib.item, "^^##optional$$") == 0)
+ return 0;
+ if (ib.item)
+ return 1;
+
+ return 0;
+ }
+
+ static int compareTypeLists(const DOH *a, const DOH *b) {
+ return compareTypeListsHelper(a, b, 0);
+ }
+}
+
+void CHICKEN::dispatchFunction(Node *n) {
+ /* Last node in overloaded chain */
+
+ int maxargs;
+ String *tmp = NewString("");
+ String *dispatch = Swig_overload_dispatch(n, "%s (2+$numargs,closure," "continuation$commaargs);", &maxargs);
+
+ /* Generate a dispatch wrapper for all overloaded functions */
+
+ Wrapper *f = NewWrapper();
+ String *iname = Getattr(n, "sym:name");
+ String *wname = NewString("");
+ String *scmname = NewString(iname);
+ Replaceall(scmname, "_", "-");
+
+ Append(wname, Swig_name_wrapper(iname));
+
+ Printv(f->def, "static void real_", wname, "(C_word, C_word, C_word, C_word) C_noret;\n", NIL);
+
+ Printv(f->def, "static void real_", wname, "(C_word oldargc, C_word closure, C_word continuation, C_word args) {", NIL);
+
+ Wrapper_add_local(f, "argc", "int argc");
+ Printf(tmp, "C_word argv[%d]", maxargs + 1);
+ Wrapper_add_local(f, "argv", tmp);
+ Wrapper_add_local(f, "ii", "int ii");
+ Wrapper_add_local(f, "t", "C_word t = args");
+ Printf(f->code, "if (!C_swig_is_list (args)) {\n");
+ Printf(f->code, " swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, " "\"Argument #1 must be a list of overloaded arguments\");\n");
+ Printf(f->code, "}\n");
+ Printf(f->code, "argc = C_unfix (C_i_length (args));\n");
+ Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++, t = C_block_item (t, 1)) {\n", maxargs);
+ Printf(f->code, "argv[ii] = C_block_item (t, 0);\n");
+ Printf(f->code, "}\n");
+
+ Printv(f->code, dispatch, "\n", NIL);
+ Printf(f->code, "swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE," "\"No matching function for overloaded '%s'\");\n", iname);
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+ addMethod(scmname, wname);
+
+ DelWrapper(f);
+ f = NewWrapper();
+
+ /* varargs */
+ Printv(f->def, "void ", wname, "(C_word, C_word, C_word, ...) C_noret;\n", NIL);
+ Printv(f->def, "void ", wname, "(C_word c, C_word t0, C_word t1, ...) {", NIL);
+ Printv(f->code,
+ "C_word t2;\n",
+ "va_list v;\n",
+ "C_word *a, c2 = c;\n",
+ "C_save_rest (t1, c2, 2);\n", "a = C_alloc((c-2)*3);\n", "t2 = C_restore_rest (a, C_rest_count (0));\n", "real_", wname, " (3, t0, t1, t2);\n", NIL);
+ Printv(f->code, "}\n", NIL);
+ Wrapper_print(f, f_wrappers);
+
+ /* Now deal with overloaded function when exporting clos */
+ if (clos) {
+ List *flist = Getattr(overload_parameter_lists, scmname);
+ if (flist) {
+ Delattr(overload_parameter_lists, scmname);
+
+ SortList(flist, compareTypeLists);
+
+ String *clos_name;
+ int construct = 0;
+ if (have_constructor && !has_constructor_args) {
+ has_constructor_args = 1;
+ constructor_dispatch = NewStringf("%s@SWIG@new@dispatch", short_class_name);
+ clos_name = Copy(constructor_dispatch);
+ construct = 1;
+ Printf(clos_methods, "(declare (hide %s))\n", clos_name);
+ } else if (in_class)
+ clos_name = NewString(member_name);
+ else
+ clos_name = chickenNameMapping(scmname, (char *) "");
+
+ Iterator f;
+ List *prev = 0;
+ int all_primitive = 1;
+
+ /* first check for duplicates and an empty call */
+ String *newlist = NewList();
+ for (f = First(flist); f.item; f = Next(f)) {
+ /* check if cur is a duplicate of prev */
+ if (prev && compareTypeListsHelper(f.item, prev, 1) == 0) {
+ Delete(f.item);
+ } else {
+ Append(newlist, f.item);
+ prev = f.item;
+ Iterator j;
+ for (j = First(f.item); j.item; j = Next(j)) {
+ if (Strcmp(j.item, "^^##optional$$") != 0 && Strcmp(j.item, "<top>") != 0)
+ all_primitive = 0;
+ }
+ }
+ }
+ Delete(flist);
+ flist = newlist;
+
+ if (all_primitive) {
+ Printf(clos_methods, "(define %s %s)\n", clos_name, chickenPrimitiveName(scmname));
+ } else {
+ for (f = First(flist); f.item; f = Next(f)) {
+ /* now export clos code for argument */
+ String *func_call = buildClosFunctionCall(f.item, clos_name, chickenPrimitiveName(scmname));
+ Printf(clos_methods, "%s\n", func_call);
+ Delete(f.item);
+ Delete(func_call);
+ }
+ }
+
+ Delete(clos_name);
+ Delete(flist);
+ }
+ }
+
+ DelWrapper(f);
+ Delete(dispatch);
+ Delete(tmp);
+ Delete(wname);
+}
+
+int CHICKEN::isPointer(SwigType *t) {
+ return SwigType_ispointer(SwigType_typedef_resolve_all(t));
+}
+
+void CHICKEN::addMethod(String *scheme_name, String *function) {
+ String *sym = NewString("");
+ if (clos) {
+ Append(sym, "primitive:");
+ }
+ Append(sym, scheme_name);
+
+ /* add symbol to Chicken internal symbol table */
+ if (hide_primitive) {
+ Printv(f_init, "{\n",
+ " C_word *p0 = a;\n", " *(a++)=C_CLOSURE_TYPE|1;\n", " *(a++)=(C_word)", function, ";\n", " C_mutate(return_vec++, (C_word)p0);\n", "}\n", NIL);
+ } else {
+ Printf(f_sym_size, "+C_SIZEOF_INTERNED_SYMBOL(%d)", Len(sym));
+ Printf(f_init, "sym = C_intern (&a, %d, \"%s\");\n", Len(sym), sym);
+ Printv(f_init, "C_mutate ((C_word*)sym+1, (*a=C_CLOSURE_TYPE|1, a[1]=(C_word)", function, ", tmp=(C_word)a, a+=2, tmp));\n", NIL);
+ }
+
+ if (hide_primitive) {
+ Setattr(primitive_names, scheme_name, NewStringf("(vector-ref swig-init-return %i)", num_methods));
+ } else {
+ Setattr(primitive_names, scheme_name, Copy(sym));
+ }
+
+ num_methods++;
+
+ Delete(sym);
+}
+
+String *CHICKEN::chickenPrimitiveName(String *name) {
+ String *value = Getattr(primitive_names, name);
+ if (value)
+ return value;
+ else {
+ Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existant primitive name %s\n", name);
+ return NewString("#f");
+ }
+}
+
+int CHICKEN::validIdentifier(String *s) {
+ char *c = Char(s);
+ /* Check whether we have an R5RS identifier. */
+ /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
+ /* <initial> --> <letter> | <special initial> */
+ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~'))) {
+ /* <peculiar identifier> --> + | - | ... */
+ if ((strcmp(c, "+") == 0)
+ || strcmp(c, "-") == 0 || strcmp(c, "...") == 0)
+ return 1;
+ else
+ return 0;
+ }
+ /* <subsequent> --> <initial> | <digit> | <special subsequent> */
+ while (*c) {
+ if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
+ || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
+ || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
+ || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
+ || (*c == '-') || (*c == '.') || (*c == '@')))
+ return 0;
+ c++;
+ }
+ return 1;
+}
+
+ /* ------------------------------------------------------------
+ * closNameMapping()
+ * Maps the identifier from C++ to the CLOS based on command
+ * line parameters and such.
+ * If class_name = "" that means the mapping is for a function or
+ * variable not attached to any class.
+ * ------------------------------------------------------------ */
+String *CHICKEN::chickenNameMapping(String *name, const_String_or_char_ptr class_name) {
+ String *n = NewString("");
+
+ if (Strcmp(class_name, "") == 0) {
+ // not part of a class, so no class name to prefix
+ if (clossymnameprefix) {
+ Printf(n, "%s%s", clossymnameprefix, name);
+ } else {
+ Printf(n, "%s", name);
+ }
+ } else {
+ if (useclassprefix) {
+ Printf(n, "%s-%s", class_name, name);
+ } else {
+ if (clossymnameprefix) {
+ Printf(n, "%s%s", clossymnameprefix, name);
+ } else {
+ Printf(n, "%s", name);
+ }
+ }
+ }
+ return n;
+}
+
+String *CHICKEN::runtimeCode() {
+ String *s = Swig_include_sys("chickenrun.swg");
+ if (!s) {
+ Printf(stderr, "*** Unable to open 'chickenrun.swg'\n");
+ s = NewString("");
+ }
+ return s;
+}
+
+String *CHICKEN::defaultExternalRuntimeFilename() {
+ return NewString("swigchickenrun.h");
+}