src/Pure/Tools/codegen_thingol.ML
changeset 21082 82460fa3340d
parent 21012 f08574148b7a
child 21123 9f7c430cf9ac
equal deleted inserted replaced
21081:837b535137a9 21082:82460fa3340d
    59       Bot
    59       Bot
    60     | Fun of (iterm list * iterm) list * typscheme
    60     | Fun of (iterm list * iterm) list * typscheme
    61     | Datatype of (vname * sort) list * (string * itype list) list
    61     | Datatype of (vname * sort) list * (string * itype list) list
    62     | Datatypecons of string
    62     | Datatypecons of string
    63     | Class of class list * (vname * (string * itype) list)
    63     | Class of class list * (vname * (string * itype) list)
    64     | Classmember of class
    64     | Classop of class
    65     | Classinst of (class * (string * (vname * sort) list))
    65     | Classinst of (class * (string * (vname * sort) list))
    66           * ((class * (string * inst list list)) list
    66           * ((class * (string * inst list list)) list
    67         * (string * iterm) list);
    67         * (string * iterm) list);
    68   type code = def Graph.T;
    68   type code = def Graph.T;
    69   type transact;
    69   type transact;
    72   val merge_code: code * code -> code;
    72   val merge_code: code * code -> code;
    73   val project_code: string list (*hidden*) -> string list option (*selected*)
    73   val project_code: string list (*hidden*) -> string list option (*selected*)
    74     -> code -> code;
    74     -> code -> code;
    75   val add_eval_def: string (*shallow name space*) * iterm -> code -> string * code;
    75   val add_eval_def: string (*shallow name space*) * iterm -> code -> string * code;
    76 
    76 
    77 
       
    78   val ensure_def: (transact -> def * code) -> bool -> string
    77   val ensure_def: (transact -> def * code) -> bool -> string
    79     -> string -> transact -> transact;
    78     -> string -> transact -> transact;
    80   val succeed: 'a -> transact -> 'a * code;
    79   val succeed: 'a -> transact -> 'a * code;
    81   val fail: string -> transact -> 'a * code;
    80   val fail: string -> transact -> 'a * code;
    82   val message: string -> (transact -> 'a) -> transact -> 'a;
    81   val message: string -> (transact -> 'a) -> transact -> 'a;
    83   val start_transact: string option -> (transact -> 'a * transact) -> code -> 'a * code;
    82   val start_transact: string option -> (transact -> 'a * transact) -> code -> 'a * code;
       
    83 
       
    84   type var_ctxt;
       
    85   val make_vars: string list -> var_ctxt;
       
    86   val intro_vars: string list -> var_ctxt -> var_ctxt;
       
    87   val lookup_var: var_ctxt -> string -> string;
    84 
    88 
    85   val trace: bool ref;
    89   val trace: bool ref;
    86   val tracing: ('a -> string) -> 'a -> 'a;
    90   val tracing: ('a -> string) -> 'a -> 'a;
    87 end;
    91 end;
    88 
    92 
   250     Bot
   254     Bot
   251   | Fun of (iterm list * iterm) list * typscheme
   255   | Fun of (iterm list * iterm) list * typscheme
   252   | Datatype of (vname * sort) list * (string * itype list) list
   256   | Datatype of (vname * sort) list * (string * itype list) list
   253   | Datatypecons of string
   257   | Datatypecons of string
   254   | Class of class list * (vname * (string * itype) list)
   258   | Class of class list * (vname * (string * itype) list)
   255   | Classmember of class
   259   | Classop of class
   256   | Classinst of (class * (string * (vname * sort) list))
   260   | Classinst of (class * (string * (vname * sort) list))
   257         * ((class * (string * inst list list)) list
   261         * ((class * (string * inst list list)) list
   258       * (string * iterm) list);
   262       * (string * iterm) list);
   259 val eq_def = (op =) : def * def -> bool;
   263 val eq_def = (op =) : def * def -> bool;
   260 
   264 
   329       | SOME l' => if l = l' then SOME l
   333       | SOME l' => if l = l' then SOME l
   330           else error "Function definition with different number of arguments"
   334           else error "Function definition with different number of arguments"
   331     end
   335     end
   332   ) eqs NONE; eqs);
   336   ) eqs NONE; eqs);
   333 
   337 
   334 fun check_prep_def modl Bot =
   338 fun check_prep_def code Bot =
   335       Bot
   339       Bot
   336   | check_prep_def modl (Fun (eqs, d)) =
   340   | check_prep_def code (Fun (eqs, d)) =
   337       Fun (check_funeqs eqs, d)
   341       Fun (check_funeqs eqs, d)
   338   | check_prep_def modl (d as Datatype _) =
   342   | check_prep_def code (d as Datatype _) =
   339       d
   343       d
   340   | check_prep_def modl (Datatypecons dtco) =
   344   | check_prep_def code (Datatypecons dtco) =
   341       error "Attempted to add bare datatype constructor"
   345       error "Attempted to add bare datatype constructor"
   342   | check_prep_def modl (d as Class _) =
   346   | check_prep_def code (d as Class _) =
   343       d
   347       d
   344   | check_prep_def modl (Classmember _) =
   348   | check_prep_def code (Classop _) =
   345       error "Attempted to add bare class member"
   349       error "Attempted to add bare class member"
   346   | check_prep_def modl (d as Classinst ((class, (tyco, arity)), (_, memdefs))) =
   350   | check_prep_def code (d as Classinst ((class, (tyco, arity)), (_, memdefs))) =
   347       let
   351       let
   348         val Class (_, (v, membrs)) = get_def modl class;
   352         val Class (_, (v, membrs)) = get_def code class;
   349         val _ = if length memdefs > length memdefs
   353         val _ = if length memdefs > length memdefs
   350           then error "Too many member definitions given"
   354           then error "Too many member definitions given"
   351           else ();
   355           else ();
   352         fun check_memdef (m, _) =
   356         fun check_memdef (m, _) =
   353           if AList.defined (op =) memdefs m
   357           if AList.defined (op =) memdefs m
   354           then () else error ("Missing definition for member " ^ quote m);
   358           then () else error ("Missing definition for member " ^ quote m);
   355         val _ = map check_memdef memdefs;
   359         val _ = map check_memdef memdefs;
   356       in d end
   360       in d end
   357   | check_prep_def modl Classinstmember =
   361   | check_prep_def code Classinstmember =
   358       error "Attempted to add bare class instance member";
   362       error "Attempted to add bare class instance member";
   359 
   363 
   360 fun postprocess_def (name, Datatype (_, constrs)) =
   364 fun postprocess_def (name, Datatype (_, constrs)) =
   361       (check_samemodule (name :: map fst constrs);
   365       (check_samemodule (name :: map fst constrs);
   362       fold (fn (co, _) =>
   366       fold (fn (co, _) =>
   366       ) constrs
   370       ) constrs
   367       )
   371       )
   368   | postprocess_def (name, Class (_, (_, membrs))) =
   372   | postprocess_def (name, Class (_, (_, membrs))) =
   369       (check_samemodule (name :: map fst membrs);
   373       (check_samemodule (name :: map fst membrs);
   370       fold (fn (m, _) =>
   374       fold (fn (m, _) =>
   371         add_def_incr true (m, Classmember name)
   375         add_def_incr true (m, Classop name)
   372         #> add_dep (m, name)
   376         #> add_dep (m, name)
   373         #> add_dep (name, m)
   377         #> add_dep (name, m)
   374       ) membrs
   378       ) membrs
   375       )
   379       )
   376   | postprocess_def _ =
   380   | postprocess_def _ =
   377       I;
   381       I;
   378 
   382 
   379 
   383 
   380 (* transaction protocol *)
   384 (* transaction protocol *)
   381 
   385 
   382 fun ensure_def defgen strict msg name (dep, modl) =
   386 fun ensure_def defgen strict msg name (dep, code) =
   383   let
   387   let
   384     (*FIXME represent dependencies as tuple (name, name -> string), for better error msgs*)
   388     (*FIXME represent dependencies as tuple (name, name -> string), for better error msgs*)
   385     val msg' = (case dep
   389     val msg' = (case dep
   386      of NONE => msg
   390      of NONE => msg
   387       | SOME dep => msg ^ ", required for " ^ quote dep)
   391       | SOME dep => msg ^ ", required for " ^ quote dep)
   388       ^ (if strict then " (strict)" else " (non-strict)");
   392       ^ (if strict then " (strict)" else " (non-strict)");
   389     fun add_dp NONE = I
   393     fun add_dp NONE = I
   390       | add_dp (SOME dep) =
   394       | add_dp (SOME dep) =
   391           tracing (fn _ => "adding dependency " ^ quote dep ^ " -> " ^ quote name)
   395           tracing (fn _ => "adding dependency " ^ quote dep ^ " -> " ^ quote name)
   392           #> add_dep (dep, name);
   396           #> add_dep (dep, name);
   393     fun prep_def def modl =
   397     fun prep_def def code =
   394       (check_prep_def modl def, modl);
   398       (check_prep_def code def, code);
   395     fun invoke_generator name defgen modl =
   399     fun invoke_generator name defgen code =
   396       defgen (SOME name, modl)
   400       defgen (SOME name, code)
   397         handle FAIL msgs =>
   401         handle FAIL msgs =>
   398           if strict then raise FAIL (msg' :: msgs)
   402           if strict then raise FAIL (msg' :: msgs)
   399           else (Bot, modl);
   403           else (Bot, code);
   400   in
   404   in
   401     modl
   405     code
   402     |> (if can (get_def modl) name
   406     |> (if can (get_def code) name
   403         then
   407         then
   404           tracing (fn _ => "asserting node " ^ quote name)
   408           tracing (fn _ => "asserting node " ^ quote name)
   405           #> add_dp dep
   409           #> add_dp dep
   406         else
   410         else
   407           tracing (fn _ => "allocating node " ^ quote name ^ (if strict then " (strict)" else " (non-strict)"))
   411           tracing (fn _ => "allocating node " ^ quote name ^ (if strict then " (strict)" else " (non-strict)"))
   418           #> tracing (fn _ => "adding done")
   422           #> tracing (fn _ => "adding done")
   419        ))
   423        ))
   420     |> pair dep
   424     |> pair dep
   421   end;
   425   end;
   422 
   426 
   423 fun succeed some (_, modl) = (some, modl);
   427 fun succeed some (_, code) = (some, code);
   424 
   428 
   425 fun fail msg (_, modl) = raise FAIL [msg];
   429 fun fail msg (_, code) = raise FAIL [msg];
   426 
   430 
   427 fun message msg f trns =
   431 fun message msg f trns =
   428   f trns handle FAIL msgs =>
   432   f trns handle FAIL msgs =>
   429     raise FAIL (msg :: msgs);
   433     raise FAIL (msg :: msgs);
   430 
   434 
   431 fun start_transact init f modl =
   435 fun start_transact init f code =
   432   let
   436   let
   433     fun handle_fail f x =
   437     fun handle_fail f x =
   434       (f x
   438       (f x
   435       handle FAIL msgs =>
   439       handle FAIL msgs =>
   436         (error o cat_lines) ("Code generation failed, while:" :: msgs))
   440         (error o cat_lines) ("Code generation failed, while:" :: msgs))
   437   in
   441   in
   438     modl
   442     code
   439     |> (if is_some init then ensure_bot (the init) else I)
   443     |> (if is_some init then ensure_bot (the init) else I)
   440     |> pair init
   444     |> pair init
   441     |> handle_fail f
   445     |> handle_fail f
   442     |-> (fn x => fn (_, modl) => (x, modl))
   446     |-> (fn x => fn (_, code) => (x, code))
   443   end;
   447   end;
   444 
   448 
   445 fun add_eval_def (shallow, e) code =
   449 fun add_eval_def (shallow, e) code =
   446   let
   450   let
   447     val name = "VALUE";
   451     val name = "VALUE";
   451     |> Graph.new_node (sname, Fun ([([], e)], ([("_", [])], ITyVar "_")))
   455     |> Graph.new_node (sname, Fun ([([], e)], ([("_", [])], ITyVar "_")))
   452     |> fold (curry Graph.add_edge sname) (Graph.keys code) (*FIXME*)
   456     |> fold (curry Graph.add_edge sname) (Graph.keys code) (*FIXME*)
   453     |> pair name
   457     |> pair name
   454   end;
   458   end;
   455 
   459 
       
   460 
       
   461 (** variable name contexts **)
       
   462 
       
   463 type var_ctxt = string Symtab.table * Name.context;
       
   464 
       
   465 fun make_vars names = (fold (fn name => Symtab.update_new (name, name)) names Symtab.empty,
       
   466   Name.make_context names);
       
   467 
       
   468 fun intro_vars names (namemap, namectxt) =
       
   469   let
       
   470     val (names', namectxt') = Name.variants names namectxt;
       
   471     val namemap' = fold2 (curry Symtab.update) names names' namemap;
       
   472   in (namemap', namectxt') end;
       
   473 
       
   474 fun lookup_var (namemap, _) name = case Symtab.lookup namemap name
       
   475  of SOME name' => name'
       
   476   | NONE => error ("invalid name in context: " ^ quote name);
       
   477 
   456 end; (*struct*)
   478 end; (*struct*)
   457 
   479 
   458 
   480 
   459 structure BasicCodegenThingol: BASIC_CODEGEN_THINGOL = CodegenThingol;
   481 structure BasicCodegenThingol: BASIC_CODEGEN_THINGOL = CodegenThingol;