[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.
Yup.
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).
Ok.
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.
cheers,
felix