Re: [Seed7-users] Compiled code question
Interpreter and compiler for the Seed7 programming language.
Brought to you by:
thomas_mertes
From: Conrad S. <con...@gm...> - 2008-09-28 22:08:51
|
Hi Thomas Thanks for your very detailed answer. I'll intersperse replies to your questions below: On Sun, 2008-09-28 at 22:20 +0200, Thomas Mertes wrote: > "Conrad Steenberg" <con...@ca...> wrote: > > Hi Thomas et al. :-) > > > > I've been playing with seed7 for a while and like the fact that it has > > both an interpreter to create portable or fast native code. > > > > My apologies if this is a FAQ: > > Is it possible to call C code in a different library from compiled s7 > > code? > > Currently there is no easy way to do this (call C code in a > different library). In the future an easier and simpler foreign > function interface will be introduced. > > Because Seed7 programs and the Seed7 interpreter and compiler should > achieve maximum portability the calling of foreign functions is > not a priority. But I see also the advantages of an foreign function > interface. That is a very good goal, yes. FWIW Python ctypes can probably be adapted for this purpose - it uses libffi to provide cross-platform portability (see http://sourceware.org/libffi/ and http://en.wikipedia.org/wiki/Libffi). > What functions from which library you want to call? My specific interest is in numerical analysis, so I'm thinking of things like LAPACK and BLAS, both of which are very portable. I also tinker around with "service-based" RPCs where having code mobility to different platforms, along with strict type checking are great assets. > Maybe it is possible to write a portable interface to this library. Yes, that would be the way to do it. I'm thinking of the way that Numerical Python works. > > The current way to call functions from external libraries is as > follows: > Functions of external libraries are introduced as primitive actions > to the hi interpreter. The primitive actions are described here: > http://seed7.sourceforge.net/manual/actions.htm > > The primitive action which describes the addition of two integers > is INT_ADD. The Seed7 interface to the INT_ADD action is defined > in the file seed7_05.s7i with: > > const func integer: (in integer param) + (in integer param) is action "INT_ADD"; > > To use a primitive action it is necessary to define it in the hi > interpreter. In the hi interpreter every primitive action is > described with a function which describes it. The function for the > INT_ADD action is int_add(). The int_add() function is defined in > the file intlib.c with; > > #ifdef ANSI_C > > objecttype int_add (listtype arguments) > #else > > objecttype int_add (arguments) > listtype arguments; > #endif > > { /* int_add */ > isit_int(arg_1(arguments)); > isit_int(arg_3(arguments)); > return(bld_int_temp( > take_int(arg_1(arguments)) + > take_int(arg_3(arguments)))); > } /* int_add */ > > Note that ansi C prototypes and K&R function headers are used. The > int_add() function adds the first and the third argument (the second > argument contains the + symbol. Several macros and helper functions > are used in this functions. > > - The macros 'arg_1', 'arg_2', 'arg_3', etc. can be used to get an > individual argument (E.g.: 'arg_3(arguments)' ). > - The macros 'isit_int', 'isit_stri', 'isit_file', etc. can be > used to check for the correct category of an argument > (E.g.: 'isit_int(arg_1(arguments))' ). > - The macros 'take_char', 'take_float', 'take_bigint', etc. can be > used to get the corresponding value of an argument > (E.g.: 'take_int(arg_1(arguments))' ). > - The functions 'bld_int_temp', 'bld_array_temp', 'bld_win_temp', > etc. can be used to create the (objecttype) result of a primitiv > action (E.g.: 'return(bld_int_temp(0))' ). > > The file intlib.h contains the prototype for the int_add function: > > objecttype int_add (listtype); > > and also a definition for the K&R C language: > > objecttype int_add (); > > Additionally every primitive action is registered in the file > primitive.c, The line which registrates INT_ADD is: > > { "INT_ADD", int_add, }, > > Note that all primitive action entries in the file primitive.c are > sorted alphabetically. With this definitions the hi interpreter > understands a primitive action. OK, this makes perfect sense. > > To allow an primitive function in a compiled Seed7 program the Seed7 > compiler (comp.sd7) needs to know the action also. The compiler > function which creates code for the INT_ADD action is: > > const proc: process_int_add (in ref_list: params, inout expr_type: c_expr) is func > > begin > c_expr.expr &:= "("; > process_expr(params[1], c_expr); > c_expr.expr &:= ") + ("; > process_expr(params[3], c_expr); > c_expr.expr &:= ")"; > end func; > > This function is called from the function process_action with the > line: > > elsif action_name = "INT_ADD" then > process_int_add(params, c_expr); > > Some primitive actions are more complicated and inline code would > not be the best solution for it. In this case an additional helper > function is used. The INT_STR function is such a function. The > definition of the int_str function in the file intlib.c is: > > #ifdef ANSI_C > > objecttype int_str (listtype arguments) > #else > > objecttype int_str (arguments) > listtype arguments; > #endif > > { /* int_str */ > isit_int(arg_1(arguments)); > return(bld_stri_temp(intStr( > take_int(arg_1(arguments))))); > } /* int_str */ > > The main work for the INT_STR primitive action is done in the helper > function intStr(). The helper function intStr() can be found in the > file int_rtl.c; > > #ifdef ANSI_C > > stritype intStr (inttype number) > #else > > stritype intStr (number) > inttype number; > #endif > > { > uinttype unsigned_number; > booltype sign; > strelemtype buffer_1[50]; > strelemtype *buffer; > memsizetype len; > stritype result; > > /* intStr */ > if ((sign = (number < 0))) { > unsigned_number = -number; > } else { > unsigned_number = number; > } /* if */ > buffer = &buffer_1[50]; > do { > *(--buffer) = (strelemtype) (unsigned_number % 10 + '0'); > } while ((unsigned_number /= 10) != 0); > if (sign) { > *(--buffer) = (strelemtype) '-'; > } /* if */ > len = &buffer_1[50] - buffer; > if (!ALLOC_STRI(result, len)) { > raise_error(MEMORY_ERROR); > return(NULL); > } else { > result->size = len; > memcpy(result->mem, buffer, (SIZE_TYPE) (len * sizeof(strelemtype))); > return(result); > } /* if */ > } /* intStr */ > > The file int_rtl.h contains a prototype definition for the intStr() > helper function: > > stritype intStr (inttype number); > > and also a definition for the K&R C language: > > stritype intStr (); > > The helper functions are also used in the code generated by the > Seed7 compiler: > > const proc: process_int_str (in ref_list: params, inout expr_type: c_expr) is func > > begin > prepare_stri_result(c_expr); > c_expr.result_expr &:= "intStr("; > getStdParamToResultExpr(params[1], c_expr); > c_expr.result_expr &:= ")"; > end func; > > As I said I normaly prefer a portable solution to provide > functionality. This means that the helper functions should be > written in a portable manner and use only portable libraries. > If this is not possible the helper functions should be written > as drivers. To support graphics under linux (with X11) and > windows (with gdi) there are two driver libraries: > drw_x11.c and drw_win.c . Such driver libraries should provide > the same functionality under different operating systems. > The headers for the drawing helper functions is defined in the > file drw_drv.h . The drawing actions are defined in the file > drwlib.c . > > I hope that this explanation helps. > If you need more information, just tell. Thanks, that helps a lot! Since I'm still learning the language I'll implement a few algorithms and see how it goes. Regards, Conrad > > Greetings Thomas Mertes > > Seed7 Homepage: http://seed7.sourceforge.net > Seed7 - The extensible programming language: User defined statements > and operators, abstract data types, templates without special > syntax, OO with interfaces and multiple dispatch, statically typed, > interpreted or compiled, portable, runs under linux/unix/windows. > -- ----------------------------------------------------------------------------- Conrad D. Steenberg Ph.D. con...@ca... Scientific Software Engineer http://www.nupack.org Pierce Bio-Engineering Lab Mail Code 114-96 California Institute of Technology Pasadena, CA, 91125 |