[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] Chicken and SWIG

From: felix
Subject: Re: [Chicken-users] Chicken and SWIG
Date: Tue, 04 May 2004 08:59:04 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

John Lenz wrote:

What would be cool is for the chicken compiler to automaticly generate this call to modname_swig_init, and include it in the current module. That way we would not need to generate the above file in SWIG (chicken would pass an argument flag like -nounit or something telling SWIG not to generate this file). Thus we would not need an extra run of chicken to compile the above trivial code.

That's no problem. #>(swig) ... <# would expand into
(declare (swig-declare ...)), and the compiler can handle this
specifically by inserting extra code.

So what would happen is that swig would run and produce a modname_wrap. cxx file. This would include a function called modname_swig_init which would need to get called. modname_swig_init just does some basic setup and then registers all the wrapped functions. The chicken compiler would automaticly generate this call in the top level environment, and thus the rest of that chicken source file would be able to make calls to the wrapped functions. Secondly, if a user wanted to create a unit, they could just declare the unit in the file that includes the #>(swig) <# stuff.


SWIG will generate a file called modname_wrap.c or modname_wrap.cxx depending on if SWIG was called with the -c++ command line argument. This can also be changed by the "-o filename" flag to SWIG. (Note I just thought of this, but you will also need some way to pick between c and c++... something like #>(swig-c)...<# and #>(swig-c++) .. #< perhaps?)

csc already accepts he -c++ option, so we can use that. As a matter
of fact any swig-specific options and compiler-invocation stff should
be handled by csc anyway.

Ok, now a little more complicated :)
SWIG also by default generates a modname-clos.scm file (unless the - noclos flag is passed), which includes a bunch of (define-class ..) and (define-method ..) and whatnot. Right now, we would just run chicken again on this file.

But what would be cool is for chicken to read this file after running SWIG. So then these definitions would also be included directly into the "scope" of the chicken input file.

Well, csc would run swig and could add additional code to the
user program which uses the swig wrapper.

Ok, how about this? When SWIG is called with say a -chicken -usestdio flag, SWIG accepts the .i file on standard input, produces the modname_wrap.cxx file, and then writes all the .scm files to standard output? chicken wouldn't even need to worry about calling the modname_swig_init function, because the (foreign-declare ..) and such would be right at the top of the standard output from SWIG. chicken would then compile whatever comes from swig standard out. (which would include the call to modname_swig_init)

SWIG would remove the first line involving (declare unit) when exporting to stdout, but otherwise we would just write the .scm files to stdout. This way we don't generate any temporary files. The only file SWIG generates will be the c or c++ file. Chicken should probably pass the -o name option, and name the output file the same name as the file chicken is generating, with say "_swig_wrap" appended or something.

I think temporary files aren't really a problem. csc can handle all
that... On the other hand... Yes, it's probably preferable to pipe
the stuff via stdio.

Ok, for options, I think chicken should allow the user to select the following 1) choose between c and c++ (this coorisponds to the -c++ flag to SWIG. No -c++ option means c).

See above (-c++ for csc).

2) optinally allow the user to select the -prefix or -noprefix
3) Allow the user to select -noclos or -nogeneric. Possibly invert the defaults... i.e have chicken default to -noclos and -nogeneric, and optionally turn those on.

So maybe something like this?
#>(swig,c,clos,coolprefix) ... #<
would mean swig in c mode, with only the -nogeneric option, and a - prefix coolprefix option.

#>(swig,c++) ... #< would mean pass -c++ -nogeneric -noclos -noprefix

Yes, that's good. It would probably be #>(swig OPTION ...) ... <#, though.

This way, chicken should just add a "%module whatever" to swig stdin. Because chicken would always pass the -prefix or -noprefix option, the module name will never appear anywhere visable to the user. It will only appear in the _wrap.cxx file. The modname is prepended to generated functions, so that we don't clutter up the global symbol table.

Ok. What happens if the .i file already contains a %module directive?

How does this impact chicken? Well, it would be nice to support this as well from the chicken called swig. Thus we might want to add another option that the user can select.
#>(swig,c,clos,coolprefix1,runtime) ... <#
#>(swig,c,clos,coolprefix2,noruntime) ... <#
and chicken would just pass -runtime or -noruntime to swig. (If neither is given, not pass either).


The problem is, SWIG needs the %import directive, because it needs to know about the base classes. Since the code that normally would be in the file %import would read, and that code is from some other chicken file, the file we would import wouldn't exist. To solve this, chicken would also have to have a similar %import directive. All this would do would be to parse the chicken file looking for the #<(swig...) <# directive, (add the SAME %module <modname> that would be added when parsing that file normally), and pass that code to swig somehow. That code would either need to be written to a temporary file, or included in the swig input file in say a
%import %{
code here
NOTE: we can't just include the code directly in the file, because SWIG needs to know if it should be generating wrapper functions for it or not. When we import a file, we don't generate any code, just use it for type purposes. Thus SWIG knows that code in the %import %{ it should just be reading for type purposes.

#>(swig,c,coolmod,noruntime,import=mod1.scm,import=mod3.scm)... #<

Note as well, if we allow multiple #>(swig,...) ... <# in the same chicken file, and the user wants to have type dependence between them, chicken would need some way to do that inclusion as well... This implies that we would need to optionally name each swig block, so that the second swig block can reference the first one.
somethine like
#>(swig,...,importblock=otherBlock) <#.
In this case, chicken would do the same thing.. it would include the code from then otherBlock in an %import %{ ... %} when calling SWIG for this block. I was thinking we could use the prefix for this naming of the blocks, but we run into trouble if no prefix is given i.e. - noprefix. Also would need a way to determine which #>(swig) <# block in the included file. Although, it seems kinda wierd to have multiple #>(swig..) blocks in the same file... probably just restrict it to one per file!

Couldn't we just generate a corresponding .i file for the .scm file
we are currently compiling (which contains the #>(swig ...) ... <# stuff?
Then those could be %imported.

So, here my proposal (probably not well thought out - I'm not sure
whether I have understood all the implications you point out above):

Say we have use-example.scm (containing the swig code) then we could do

$ csc use-example.scm [-c++]

which would optionally switch to C++ mode and generate use-example.i,
which would be fed to swig (perhaps with the -c++ option). swig would
then generate use-example_wrap.c[xx], which would be added to list of
files to be compiled by csc. csc automatically passes a -prelude
option to chicken when compiling use-example.scm that runs the init-procedure.
Since the .i file will be generated (perhaps optionally with the -k
option to csc?) it can be used by %imports when compiling other modules
containing swig code. the #>(swig ...) <# should accept options for
customizing the invocation of swig, like

#>(swig -no-runtime -prefix coolmod)   ; either strings or symbols

All the unit stuff should be left to the use-example.scm code. All
that's left from the usual .scm file swig generates is the call to the
init proc, which will be handed to chicken by csc.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]