--- gforth/libcc.fs 2006/12/28 20:53:04 1.5 +++ gforth/libcc.fs 2007/02/10 15:30:15 1.7 @@ -21,9 +21,8 @@ \ What this implementation does is this: if it sees a declaration like -\ \ something that tells it to include \ \ something that tells it that the current library is libc - +\ \c #include \ c-function dlseek lseek n d n -- d \ it genererates C code similar to the following: @@ -46,6 +45,29 @@ \ the function pointer of gforth_c_lseek_ndn_d on the stack and \ calls CALL-C. +\ ToDo: + +\ Batching, caching and lazy evaluation: + +\ Batching: + +\ New words are deferred, and the corresponding C functions are +\ collected in one file, until the first word is EXECUTEd; then the +\ file is compiled and linked into the system, and the word is +\ resolved. + +\ Caching: + +\ Instead of compiling all this stuff anew for every execution, we +\ keep the files around and have an index file containing the function +\ names and their corresponding .so files. If the needed wrapper name +\ is already present, it is just linked instead of generating the +\ wrapper again. This is all done by loading the index file(s?), +\ which define words for the wrappers in a separate wordlist. + +\ The files are built in .../lib/gforth/$VERSION/libcc/ or +\ ~/.gforth/libcc/$HOST/. + \ other things to do: \ c-variable forth-name c-name @@ -67,13 +89,64 @@ : const+ ( n1 "name" -- n2 ) dup constant 1+ ; -\ dlerror +\ linked list stuff (should go elsewhere) + +hex + +require struct.fs + +struct + cell% field list-next + 1 0 field list-payload +end-struct list% + +: list-insert { node list -- } + list list-next @ node list-next ! + node list list-next ! ; -\ require lib.fs +: list-append { node endlistp -- } + \ insert node at place pointed to by endlistp + node endlistp @ list-insert + node list-next endlistp ! ; -\ library libc libc.so.6 -\ libc sleep int (int) sleep -\ libc dlerror (ptr) dlerror +: list-map ( ... list xt -- ... ) + \ xt ( ... node -- ... ) + { xt } begin { node } + node while + node xt execute + node list-next @ + repeat ; + +\ C prefix lines + +\ linked list of longcstrings: [ link | count-cell | characters ] + +list% + cell% field c-prefix-count + 1 0 field c-prefix-chars +end-struct c-prefix% + +variable c-prefix-lines 0 c-prefix-lines ! +variable c-prefix-lines-end c-prefix-lines c-prefix-lines-end ! + +: save-c-prefix-line ( c-addr u -- ) + align here 0 , c-prefix-lines-end list-append ( c-addr u ) + longstring, ; + +: \c ( "rest-of-line" -- ) + -1 parse save-c-prefix-line ; + +: print-c-prefix-line ( node -- ) + dup c-prefix-chars swap c-prefix-count @ type cr ; + +: print-c-prefix-lines ( -- ) + c-prefix-lines @ ['] print-c-prefix-line list-map ; + +\c #include "engine/libcc.h" + +print-c-prefix-lines + +\ Types (for parsing) wordlist constant libcc-types @@ -218,7 +291,7 @@ create gen-wrapped-types : gen-wrapper-function ( addr -- ) \ addr points to the return type index of a c-function descriptor c@+ { ret } count 2dup { d: pars } chars + count { d: c-name } - .\" #include \"engine/libcc.h\"\n" + print-c-prefix-lines ." void gforth_c_" c-name type ." _" pars bounds u+do i c@ type-letter emit @@ -295,6 +368,8 @@ s" Library not found" exception constant \ c-function func test5 -- func \ c-function void test6 -- void +\c #include + c-function strlen strlen a -- n cr s\" fooo\0" 2dup dump drop .s strlen cr .s cr