I have modified Felix so now each file is parsed and desugared, then the assembly produced concatenated. Previously the algorithm was this: let asms = (do actual desugaring state) in let include_files = from the state in
let asms = List.fold_left begin fun asms file -> let curpath, stmts = Flx_colns.include_file state.syms curpath file in desugar_stmts state curpath stmts :: asms end [asms] include_files in List.concat asms so basically, this is a recursive descent, pushing the root first, then down the left side of the tree. My new code generates this: //PROCEDURE <5998:> _init_: Resume method con_t *_init_::resume(){ FLX_START_SWITCH PTF _i3390_v3390_sep = PTF sep; PTF sep = (_a2728t_22326)("/"); _i5836_p5836__init_(FLX_FPAR_PASS_ONLY); PTF INSTALL_ROOT_TOPDIR = PTF _i5808_v5808_INSTALL_ROOT_TOPDIR; PTF INSTALL_ROOT = PTF _i5809_v5809_INSTALL_ROOT; which you can see is bugged (we copy sep before initialising it). Sep is the filename separator. There's also a call to a module initialisation routine which is plat/config. The code is for "flx" so this is kind of important :) Here's the order of the packed code: Processed file std/version output len=2 Processed file std/lexer output len=5 Processed file std/avl output len=2 Processed file std/darray output len=4 Processed file std/varray output len=5 Processed file std/array output len=3 Processed file std/list output len=6 Processed file std/string output len=18 Processed file std/carray output len=3 Processed file std/slice output len=1 Processed file std/option output len=2 Processed file std/pointer output len=3 Processed file std/filename output len=2 <**** FIRST Processed file std/stdout output len=3 Processed file std/textio output len=2 Processed file std/cstdio output len=3 Processed file std/categ output len=3 Processed file std/control output len=3 Processed file std/cstdlib output len=3 Processed file plat/filename output len=2 <**** SECOND Processed file std/env output len=2 Processed file std/dynlink output len=2 Processed file std/system output len=2 Processed file std/typing output len=3 Processed file std/c_hack output len=2 Processed file std/debug output len=3 Processed file std/arith_casts output len=3 Processed file std/float_math output len=22 Processed file std/float_format output len=6 Processed file std/mixedint output len=2 Processed file std/char output len=14 Processed file std/number output len=4 Processed file std/real output len=1 Processed file std/int output len=87 Processed file std/bool output len=6 Processed file std/address output len=7 Processed file std/flx_tclass output len=38 Processed file std/__init__ output len=0 Processed file plat/float output len=9 Processed file plat/arithmax output len=1 Processed file std/ctypesets output len=17 Processed file plat/ctypedefs output len=44 Processed file plat/flx_ctypes output len=12 Processed file std output len=20 Processed file plat/config output len=2 Processed file build/release-optimized/src/flx/flx output len=1044 The global code in each file will be initialised in the above order. Each module has an _init_ procedure and a call to it is generated. Some inlining occurs so in the mainline you may see the actual text of the initialisation. The problem is here in std/filename: include "plat/filename.flx"; module Filename { val sep = Plat_Filename::sep; .... and plat/filename.flx: // GENERATED DURING CONFIGURATION module Plat_Filename { val sep = "/"; } which are done in that order (see above). My new algorithm is: while List.length (!unprocessed) > 0 do let candidate = List.hd (!unprocessed) in let candidate = strip_extension candidate in unprocessed := List.tl (!unprocessed); if not (List.mem candidate (!processed)) then begin processed := candidate :: !processed; let stmts = parse_file state candidate in let desugar_state = Flx_desugar.make_desugar_state module_name state.syms in let include_files, asms = Flx_desugar.desugar_stmts desugar_state (Filename.dirname candidate ) stmts in List.iter (fun s -> if not (List.mem s (!processed)) && not (List.mem s (!unprocessed)) then begin print_endline ("Add Include file: " ^ s); unprocessed := s :: (!unprocessed) end ) include_files ; outputs := (candidate,asms) :: (!outputs) end done; Now the thing is: NEITHER algorithm is right. The both ensure that if A uses B and B hasn't been handled yet, B is done before A. But then if C comes along and needs B, it is too late. Recursive descent on a tree is a topological sort, on a DAG it isn't. The question is: what to do: the old code only worked by a fluke. It used to be the "sep" was a MACRO to prevent this problem, because the real problem is that you cannot assume an ordering of initialisation, except within a single file. In theory, you can't even assume library files are initialised before your program (What happens if you make P an include file? .. then all bets are off). So I actually broke the rules myself here. I.e. I thought my new algorithm was broke cause it wasn't a topological sort but the real problem is the library is broke :) [Of course a top sort would fix this one .. :] -- john skaller skal...@users.sourceforge.net ------------------------------------------------------------------------------ Centralized Desktop Delivery: Dell and VMware Reference Architecture Simplifying enterprise desktop deployment and management using Dell EqualLogic storage and VMware View: A highly scalable, end-to-end client virtualization framework. Read more! http://p.sf.net/sfu/dell-eql-dev2dev _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language