Re: [Seed7-users] Compiled code question
Interpreter and compiler for the Seed7 programming language.
Brought to you by:
thomas_mertes
From: Thomas M. <tho...@gm...> - 2008-09-28 20:20:42
|
"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. What functions from which library you want to call? Maybe it is possible to write a portable interface to this library. 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. 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. 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. -- GMX startet ShortView.de. Hier findest Du Leute mit Deinen Interessen! Jetzt dabei sein: http://www.shortview.de/wasistshortview.php?mc=sv_ext_mf@gmx |