I would like to announce a MAJOR breakthrough in Felix: separate compilation.
There are caveats, and the tooling is not complete. However I want to show what this is about. First, here is a library: /////////////// xt.flx //////////////////////////////////////////////////////////////// export fun setup (x:int) => x+10; class A { export fun setup2 (x:int) => x+100; } export inline cfun setup3 (x:int) => x+1000; export "fred" inline cfun setup4 (x:int) => x+10000; cfun setup5 (x:int) => 100000; export cfun setup5 of (int) as "joe"; export proc p99 (x:int) { println$ "p99=" + str (x + 99); } export cproc p100 (x:int) { println$ "p100=" + str (x +100); } println$ "Done " + 22.setup.str; ///////////////////////////////////////////////////////////////////////////////////////// You can run this as a program too. There are some variations on exports shown here, for testing. Exported entities are ready for dlsym() when the code is loaded at run time, however that's not new. When Felix compiles this code, it sees that there are exports and produces a new file: ////////// xt_interface.flx ///////////////////////////////////////////////////////////////////////// class xt_interface { // FELIX FUNCTION setup // binding for export fun _i41924_f41924_setup as setup fun setup : int -> int = "setup(ptf,$1)" requires property "needs_ptf", header """ extern "C" FLX_IMPORT int setup(void *, int); """ ; // FELIX C FUNCTION setup3 // binding for export cfun _i41933_f41933_setup3 as setup3 fun setup3 : int -> int = "setup3($1)" requires header """ extern "C" FLX_IMPORT int setup3(int); """ ; // FELIX C FUNCTION fred // binding for export cfun setup4 as fred fun fred : int -> int = "fred($1)" requires header """ extern "C" FLX_IMPORT int fred(int); """ ; // FELIX C FUNCTION joe // binding for export cfun setup5 as joe fun joe : int -> int = "joe($1)" requires header """ extern "C" FLX_IMPORT int joe(int); """ ; // FELIX FUNCTION p99 // binding for export proc _i41942_p41942_p99 as p99 proc p99 : int = "p99(ptf,$1);" requires property "needs_ptf", header """ extern "C" FLX_IMPORT ::flx::rtl::con_t * p99(void *, int); """ ; // FELIX C FUNCTION p100 // binding for export cproc _i41945_p41945_p100 as p100 proc p100 : int = "p100($1);" requires header """ extern "C" FLX_IMPORT ::flx::rtl::con_t * p100(int); """ ; // FELIX FUNCTION setup2 // binding for export fun _i41929_f41929_setup2 as setup2 fun setup2 : int -> int = "setup2(ptf,$1)" requires property "needs_ptf", header """ extern "C" FLX_IMPORT int setup2(void *, int); """ ; } ///////////////////////////////////////////////// This file contains Felix bindings for the libraries extern "C" wrappers for the Felix functions which were exported. The file is currently plonked into the cache, so I copied it out manually. I'll show the script in a second. Now, to use this file we will write a little test client: ///////// xtclient.flx /////////////////////////////////////////// include "./xt_interface"; open xt_interface; println$ setup 1; println$ setup2 2; println$ setup3 3; println$ fred 4; println$ joe 5; p99(60); p100(70); /////////////////////////////////////////////////////////////////////////////// And that's it! I decided to put the interface in a class for some obscure reason so after including the interface, I opened the class (but you can use qualified names instead if you want). Here's my script: build/release/host/bin/flx --test=build/release -c --nolink -o xt.o xt cp ~/.felix/cache/text/Users/johnskaller/felix/xt_interface.flx . build/release/host/bin/flx --test=build/release xt.o xtclient 11 102 1003 10004 100000 p99=159 p100=170 Apart from tooling issues, there's a MAJOR caveat. Or three. (1) You have to use shared bindings of known C types as function arguments and returns. Note this is a dual requirement! For the C types, you will have to share them so the bindings are the same type in both library and client. The types generated for Felix anonymous data types like tuples, records and unions have distinct name in distinct compilations. So the C types names generated in the interface will be those used in the library and won't agree with the C names generated for the same Felix types in the client. So you more or less have to use Felix types which are bindings to types defined in C, and share both the bindings between the library and client, AND the C headers. Some relief may be available by exporting types (you can do that too), but type exports are just typedefs in the felix generated C++ *.hpp file. The machinery above does NOT use the generated *.hpp header file (the interface is self contained up to the Felix RTL) (2) If you export a Felix function with "fun" instead of "cfun", the wrapper requires a thread frame pointer for the library. In the the generated interface I CHEAT: fun setup2 : int -> int = "setup2(ptf,$1)" requires property "needs_ptf", header """ extern "C" FLX_IMPORT int setup2(void *, int); """ ; Here the type pass in is void * which accepts anything. That is NOT the correct type, the correct type is actually flxusr::xt::thread_frame_t * but we have no access to that. So instead, I am just passing the client's thread frame pointer "ptf". The requires property "needs_ptf" annotation ensures it exists. That thread frame agrees with all others as far as the common initial fields go, which includes the GC and program arguments (and some standard files, although at present println etc use ::std::cout instead of the ones actually passed in). I any procedure in the library you call through the interface actually tries to access any variable (read or write) in the thread frame all hell will break lose (because we cheated and passed in the wrong one). If you really wanted to create a thread frame for the library you could, but because of the cheat .. there's no way to pass it. Plugins do this. I may have to fix it so you can either cheat or not... :) :) The point of the cheat is to allow the GC to be used, even from C calls. After all the GC is just an ordinary C library itself. (C++ actually but lets not pick knits here). Note that the file xt.hpp generated is already a precise interface for the library but it contains cruft. It should be usable from C++, but there's no way you could publish it in a Debian package as a normal C library! -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language