This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

G-Translate 0.1


Hi again, Guile folks:

Since some people are looking for a way to automatically generate
Guile wrapper functions directly from function declarations, I have
hacked together a very simple minded tool allowing G-Wrap to do this.
It is not incredibly sophisticated, but I have converted my own
libraries to use it and it has worked well for me.  Simply putting the
proper comment before the ANSI declaration in a source or header file
triggers the generation of the wrapper function.
e.g. Scanning the following text in a header file:

  /*[EXPORT]
   *  Calculates eigenvectors Z and eigenvalues w of real symmetric matrix A,
   *  using Lapack.
   */
  void eig_dsyev(MAT *A, MAT *Z, VEC* w);

is equivalent to putting 

  (new-function 'eig-dsyev
	        'void "eig_dsyev" ((MAT A) (MAT Z) (VEC w))
   "Calculates eigenvectors Z and eigenvalues w of real symmetric matrix A,
  using Lapack.")

in your g-wrap declarations file.

This is assuming you have prepared for using VEC and MAT with the
lines such as the following in the g-wrap description file:
  
  (set! type-translations
	(append '((VEC* VEC) (MAT* MAT)) type-translations))
  (new-type 'VEC  "VEC"  "VEC_print"  "v_free"  "VEC_eq")
  (new-type 'MAT  "MAT"  "MAT_print"  "m_free"  "MAT_eq")


The README file follows.  Feel free to criticize this first attempt
(or to rewrite it yourself the "right" way and tell me about it so I
can use it myself :)

 -Chris

============================== README ===================================

G-Translate        Copyright (C) 1997 Christopher Lee
**********************************************************************

G-Translate is available from the g-wrap page: 
http://www.cs.cmu.edu/~chrislee/g-wrap

***** INSTALL *****

To install, edit the Makefile and type 'make install'.

***** INTRODUCTION *****

G-Translate is an experimental extension to G-Wrap, consisting of a program
'g-scan' and a Guile module (g-wrap g-translate) which scan source code
for functions to export.

Instead of manually writing g-wrap descriptions of functions you want
to export, you can load the g-translate module in your description
file with
	(use-modules (g-wrap g-translate))
and scan automatically for functions to export using this command:
	(gwrap-c-scan-source-file "g-scan.c")

This command, gwrap-c-scan-source-file, looks through "g-scan.c" for
ANSI function declarations that are preceded by comments starting
with "\n/*[EXPORT" and does some simplistic parsing to find out enough
about a function to write a wrapper function to export it to the
Scheme interpreter.

For example, since g-scan.c includes the following text:

	/*[EXPORT (name my-string-append)]
	 * Returns the result of appending strings st1 and str2.
	 */
	char * string_append(char* str1, char *str2)
	{
	  char *ret = get_string(strlen(str1)+strlen(str2));
	  strcpy(ret,str1);
	  strcat(ret,str2);
	  return ret;
	}

a G-Wrap wrapper for the function would be created so that calling 

	(my-string-append "g-" "wrap")

in the interpreter should return the string "g-wrap".

To export a function, simply add the following comment before an ANSI
function declaration:
/*[EXPORT <flags>]
 <Description>
 */
Where <description> is a short description of what the function does,
and <flags> (usually left empty) can indicate that g-translate should
override its default assumptions about return type, parameter types,
or function name.

If <flags> contains:
	(name <new-name>)
		-- the function is exported as <new-name>
	(types ((<n> <new-type>) ...))
		-- the type of the <n>-th parameter (the first
		   parameter is 0) is assumed to be <new-type>
	(ret-type <new-type>)
		-- the return type of the function is assumed to be
		   <new-type>

Up to three characters of each line of <description> are ignored if
they are space or '*' characters.

***** NOTES *****

I have tested this on some large libraries I use for my work and it is
very convenient.  However, there are many open issues:
	1) The inclusion of a (uses-modules ...) clause in the
	   description file is wrong, and it should be done in the
	   file 'g-wrap-guile' from g-wrap instead.
	2) Parsing and error handling are extremely simplistic.
	3) C-preprocessing is not supported, since the trigger text
	   for exporting a function is in the comments.
	4) K&R C is not supported
	5) The <flags> are read as C-text and then written inside of
	   parentheses to be parsed by Scheme.  If unparsable text or
	   unbalanced parentheses are part of the <flags>
	   specification, then the Scheme read will fail.

***** G-SCAN *****

G-Translate uses a (brain-dead?) parser program written in C called
g-scan to scan through sources and header files for functions to
export.

G-Scan reads through a file for comments starting with [newline] and
then "/*[EXPORT".  After seeing this, it stores all text until the
next "]" character as a 'flags' string, then stores all text until the
next "*/" as a description string.  Next, it expects to see an ANSI C
function declaration, which must look "normal" and have its return
type specified.  g-scan then outputs a Scheme list of the form

  (<scheme-fn-name> <flags> <arg-lst> <ret-type> <c-fn-name> <doc-string>)

where <scheme-fn-name> is the name of the functions with all
underscores '_' translated to dashes '-', and <arg-list> is a list of
(<type> <param-name>) lists.

Running "g-scan g-scan.c" results in:

	(string-append
	 ((name my-string-append))
	 char* "string_append" ((char* str1) (char* str2) )
	"Returns the result of appending strings st1 and str2.
	")