On 18/11/2010, at 3:24 AM, john skaller wrote:

> I am now paying for them. Argg. The binding routine packs away so much state, 
> it will
> be very hard to unravel ;( Particularly to provide a "functional" routine, 
> yet keep all
> the existing code working...


Here's the main problem: it's an old trick come back to bite me I think:


type lookup_state_t = {
  syms: Flx_mtypes2.sym_state_t;
  sym_table: Flx_sym_table.t;
  env_cache: (Flx_types.bid_t, Flx_mtypes2.env_t) Hashtbl.t;
}

First, that "syms" thing is a huge global variable containing various
caches, compiler options, just about everything I got tired of passing around
individually.

but worse, is the sym_table:

type elt = {
  sym: Flx_sym.t;                 (** The symbol. *)
  parent: Flx_types.bid_t option; (** The parent of the symbol. *)
}

(** The type of the symbol table. *)
type t = (Flx_types.bid_t, elt) Hashtbl.t

In "theory" this simply cannot work. The symbol table has no name_maps, so no 
lookups can occur. There two possible solutions:

a) Lets look at the sym_state_t:


type sym_state_t =
{
  counter : bid_t ref;
  varmap : typevarmap_t;
  ticache : (bid_t, Flx_btype.t) Hashtbl.t;
  env_cache : (bid_t, env_t) Hashtbl.t;
  registry : type_registry_t;
  compiler_options : felix_compiler_options_t;
  instances : instance_registry_t;
  include_files : string list ref;
  roots : BidSet.t ref;
  quick_names : (string, (bid_t * Flx_btype.t list)) Hashtbl.t;
  mutable bifaces : Flx_btype.biface_t list;
  mutable reductions : reduction_t list;
  mutable axioms: axiom_t list;
  variant_map: (Flx_btype.t * Flx_btype.t, bid_t) Hashtbl.t;
  typeclass_to_instance: (bid_t, (bvs_t * Flx_btype.t * Flx_btype.t list * 
bid_t) list) Hashtbl.t;
  instances_of_typeclass: (bid_t, (bid_t * (bvs_t * Flx_btype.t * Flx_btype.t 
list)) list) Hashtbl.t;
  transient_specialisation_cache: (bid_t * Flx_btype.t list, bid_t * 
Flx_btype.t list) Hashtbl.t;
}

As you can see this contains a set of global registries and caches.
I have no idea what quick_names is :)

Now: the top level of a symbol table only really needs a single name map,
because there's no "external" code or declarations to look "in" to the
top level (except the initialisation code which is a bit weird).

Still, where is it? The answer is: I used a trick. When making the symbol tables
everything gets wrapped in a dummy module. The result is that the top
level is a single module entry. Since it just got made for fun, no one can
look into it, so there's no need to keep its name map. The name map
OF the inside of the module is then the global namespace, and that is kept
in the entry of the module in the symbol table itself. So all we need to be able
to do is find that entry and bind what is inside it against that name map.

Indeed, doing this trick also wraps up all the initialisation code into
an _init_ function for that module, so the top level initialisation is
just a call to that function, all we need to do is find it: inspection of
the compiler shows the hackery to get it, all based on a particular
invariant on the top level symbol table.

Binding then works, binding the whole table against its own contained
"root" module.

The problem is, I now want to bind *parts* of the system, namely sublibraries,
against some subsets of the symbol table, namely, the parts they depend on.
For example the standard library is a leaf. We may have several leaves and
then some libraries that use them.

The bound incremental symbol tables can be formed, for each library,
so in the end we just concatenate the required ones together with the
main program code and then throw all of that at the optimiser: the point
being each libraries bound tables can be stored on disk, so we basically
don't have to do any parsing or lookups for any libraries more than once.

I now have to make a key decision: whether to support relocation
(all closed bound tables start at offset 0 and on loading get relocated
to a free address) or somehow fix the addresses (eg by hashing,
or just do everything in some sequence and if there's a clash throw
it all out and rebuild from scratch).

Or just give up and do checkpoint caching: save everything every now and
then, to restart we try the lastest checkpoint, if that's inconsistent we 
backtrack
to the one before etc, until we find a consistent point, possibly an empty 
state.
Grr :)



--
john skaller
skal...@users.sourceforge.net





------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to