src/Tools/nbe.ML
changeset 82453 f9e6cbc6bf22
parent 82447 741f6f6df144
child 82454 ba1f9fb23b8d
equal deleted inserted replaced
82452:8b575e1fef3b 82453:f9e6cbc6bf22
   212 (** assembling and compiling ML code from terms **)
   212 (** assembling and compiling ML code from terms **)
   213 
   213 
   214 (* abstract ML syntax *)
   214 (* abstract ML syntax *)
   215 
   215 
   216 infix 9 `$` `$$`;
   216 infix 9 `$` `$$`;
   217 fun e1 `$` e2 = "(" ^ e1 ^ " " ^ e2 ^ ")";
   217 infix 8 `*`;
       
   218 fun e1 `$` e2 = enclose "(" ")" (e1 ^ " " ^ e2);
   218 fun e `$$` [] = e
   219 fun e `$$` [] = e
   219   | e `$$` es = "(" ^ e ^ " " ^ implode_space es ^ ")";
   220   | e `$$` es = enclose "(" ")" (e ^ " " ^ implode_space es);
   220 fun ml_abs v e = "(fn " ^ v ^ " => " ^ e ^ ")";
   221 fun ml_abs v e = enclose "(" ")" ("fn " ^ v ^ " => " ^ e);
   221 
   222 
   222 fun ml_cases t cs =
   223 fun ml_cases e cs = enclose "(" ")"
   223   "(case " ^ t ^ " of " ^ space_implode " | " (map (fn (p, t) => p ^ " => " ^ t) cs) ^ ")";
   224   ("case " ^ e ^ " of " ^ space_implode " | " (map (fn (p, e) => p ^ " => " ^ e) cs));
   224 fun ml_Let d e = "let\n" ^ d ^ " in " ^ e ^ " end";
   225 fun ml_Let d e = "let\n" ^ d ^ " in " ^ e ^ " end";
   225 fun ml_as v t = "(" ^ v ^ " as " ^ t ^ ")";
   226 fun ml_as v t = enclose "(" ")" (v ^ " as " ^ t);
   226 
   227 
   227 fun ml_and [] = "true"
   228 fun ml_and [] = "true"
   228   | ml_and [x] = x
   229   | ml_and [e] = e
   229   | ml_and xs = "(" ^ space_implode " andalso " xs ^ ")";
   230   | ml_and es = enclose "(" ")" (space_implode " andalso " es);
   230 fun ml_if b x y = "(if " ^ b ^ " then " ^ x ^ " else " ^ y ^ ")";
   231 fun ml_if b e1 e2 = enclose "(" ")" ("if" ^ b ^ " then " ^ e1 ^ " else " ^ e2);
   231 
   232 
   232 fun ml_list es = "[" ^ commas es ^ "]";
   233 fun e1 `*` e2 = enclose "(" ")" (e1 ^ ", " ^ e2);
       
   234 fun ml_list es = enclose "[" "]" (commas es);
   233 
   235 
   234 fun ml_fundefs ([(name, [([], e)])]) =
   236 fun ml_fundefs ([(name, [([], e)])]) =
   235       "val " ^ name ^ " = " ^ e ^ "\n"
   237       "val " ^ name ^ " = " ^ e ^ "\n"
   236   | ml_fundefs (eqs :: eqss) =
   238   | ml_fundefs (eqs :: eqss) =
   237       let
   239       let
   267   val name_same = prefix ^ "same";
   269   val name_same = prefix ^ "same";
   268 in
   270 in
   269 
   271 
   270 val univs_cookie = (get_result, put_result, name_put);
   272 val univs_cookie = (get_result, put_result, name_put);
   271 
   273 
   272 fun nbe_type n ts = name_type `$` ("(" ^ quote n ^ ", " ^ ml_list ts ^ ")")
       
   273 fun nbe_tparam v = "t_" ^ v;
   274 fun nbe_tparam v = "t_" ^ v;
   274 fun nbe_dict v n = "d_" ^ v ^ "_" ^ string_of_int n;
   275 fun nbe_dict v n = "d_" ^ v ^ "_" ^ string_of_int n;
   275 fun nbe_bound v = "v_" ^ v;
   276 fun nbe_bound v = "v_" ^ v;
   276 fun nbe_bound_optional NONE = "_"
   277 fun nbe_bound_optional NONE = "_"
   277   | nbe_bound_optional (SOME v) = nbe_bound v;
   278   | nbe_bound_optional (SOME v) = nbe_bound v;
   278 fun nbe_default v = "w_" ^ v;
   279 fun nbe_default v = "w_" ^ v;
       
   280 fun nbe_type n ts = name_type `$` (quote n `*` ml_list ts);
       
   281 fun nbe_fun c tys = c `$` ml_list tys;
   279 
   282 
   280 (*note: these three are the "turning spots" where proper argument order is established!*)
   283 (*note: these three are the "turning spots" where proper argument order is established!*)
   281 fun nbe_apps t [] = t
   284 fun nbe_apps t [] = t
   282   | nbe_apps t ts = name_apps `$$` [t, ml_list (rev ts)];
   285   | nbe_apps t ts = name_apps `$$` [t, ml_list (rev ts)];
   283 fun nbe_apps_local c tys ts = c `$` ml_list tys `$` ml_list (rev ts);
   286 fun nbe_apps_fun c tys ts = nbe_fun c tys `$` ml_list (rev ts);
   284 fun nbe_apps_constr c tys ts = name_const `$` ("((" ^ c ^ ", " ^ ml_list tys ^ "), " ^ ml_list (rev ts) ^ ")");
   287 fun nbe_apps_constr c tys ts = name_const `$` ((c `*` ml_list tys) `*` ml_list (rev ts));
   285 fun nbe_apps_constmatch c ts = name_const `$` ("((" ^ c ^ ", _), " ^ ml_list (rev ts) ^ ")");
   288 fun nbe_apps_constmatch c ts = name_const `$` ((c `*` "_") `*` ml_list (rev ts));
   286 
   289 
   287 fun nbe_abss 0 f = f `$` ml_list []
   290 fun nbe_abss 0 f = f `$` ml_list []
   288   | nbe_abss n f = name_abss `$$` [string_of_int n, f];
   291   | nbe_abss n f = name_abss `$$` [string_of_int n, f];
   289 
   292 
   290 fun nbe_same (v1, v2) = "(" ^ name_same ^ " (" ^ nbe_bound v1 ^ ", " ^ nbe_bound v2 ^ "))";
   293 fun nbe_same (v1, v2) = enclose "(" ")" (name_same `$` (nbe_bound v1 `*` nbe_bound v2));
   291 
   294 
   292 end;
   295 end;
   293 
   296 
   294 open Basic_Code_Symbol;
   297 open Basic_Code_Symbol;
   295 open Basic_Code_Thingol;
   298 open Basic_Code_Thingol;
   333 fun assemble_preprocessed_eqnss ctxt idx_of_const deps eqnss =
   336 fun assemble_preprocessed_eqnss ctxt idx_of_const deps eqnss =
   334   let
   337   let
   335     fun fun_ident 0 (Code_Symbol.Constant "") = "nbe_value" 
   338     fun fun_ident 0 (Code_Symbol.Constant "") = "nbe_value" 
   336       | fun_ident i sym = "c_" ^ string_of_int (idx_of_const sym)
   339       | fun_ident i sym = "c_" ^ string_of_int (idx_of_const sym)
   337           ^ "_" ^ Code_Symbol.default_base sym ^ "_" ^ string_of_int i;
   340           ^ "_" ^ Code_Symbol.default_base sym ^ "_" ^ string_of_int i;
   338     fun constr_fun_ident c =
   341     fun constr_ident c =
   339       if Config.get ctxt trace
   342       if Config.get ctxt trace
   340       then string_of_int (idx_of_const c) ^ " (*" ^ Code_Symbol.default_base c ^ "*)"
   343       then string_of_int (idx_of_const c) ^ " (*" ^ Code_Symbol.default_base c ^ "*)"
   341       else string_of_int (idx_of_const c);
   344       else string_of_int (idx_of_const c);
   342 
   345 
   343     fun apply_local i sym = nbe_apps_local (fun_ident i sym);
   346     fun assemble_fun i sym = nbe_fun (fun_ident i sym);
   344     fun apply_constr sym = nbe_apps_constr (constr_fun_ident sym);
   347     fun assemble_app_fun i sym = nbe_apps_fun (fun_ident i sym);
   345     fun apply_constmatch sym = nbe_apps_constmatch (constr_fun_ident sym);
   348     fun assemble_app_constr sym = nbe_apps_constr (constr_ident sym);
       
   349     fun assemble_app_constmatch sym = nbe_apps_constmatch (constr_ident sym);
   346 
   350 
   347     fun assemble_constapp sym tys dictss ts =
   351     fun assemble_constapp sym tys dictss ts =
   348       let
   352       let
   349         val s_tys = map (assemble_type) tys;
   353         val s_tys = map (assemble_type) tys;
   350         val ts' = (maps o map) assemble_dict (map2 (fn ty => map (fn dict => (ty, dict))) tys dictss) @ ts;
   354         val ts' = (maps o map) assemble_dict (map2 (fn ty => map (fn dict => (ty, dict))) tys dictss) @ ts;
   351       in case AList.lookup (op =) eqnss sym
   355       in case AList.lookup (op =) eqnss sym
   352        of SOME (num_args, _) => if num_args <= length ts'
   356        of SOME (num_args, _) => if num_args <= length ts'
   353             then let val (ts1, ts2) = chop num_args ts'
   357             then let val (ts1, ts2) = chop num_args ts'
   354             in nbe_apps (apply_local 0 sym s_tys ts1) ts2
   358             in nbe_apps (assemble_app_fun 0 sym s_tys ts1) ts2
   355             end else nbe_apps (nbe_abss num_args (fun_ident 0 sym `$` ml_list s_tys)) ts'
   359             end else nbe_apps (nbe_abss num_args (assemble_fun 0 sym s_tys)) ts'
   356         | NONE => if member (op =) deps sym
   360         | NONE => if member (op =) deps sym
   357             then nbe_apps (fun_ident 0 sym `$` ml_list s_tys) ts'
   361             then nbe_apps (assemble_fun 0 sym s_tys) ts'
   358             else apply_constr sym s_tys ts'
   362             else assemble_app_constr sym s_tys ts'
   359       end
   363       end
   360     and assemble_classrels classrels =
   364     and assemble_classrels classrels =
   361       fold_rev (fn classrel => assemble_constapp (Class_Relation classrel) [] [] o single) classrels
   365       fold_rev (fn classrel => assemble_constapp (Class_Relation classrel) [] [] o single) classrels
   362     and assemble_dict (ty, Dict (classrels, x)) =
   366     and assemble_dict (ty, Dict (classrels, x)) =
   363           assemble_classrels classrels (assemble_plain_dict ty x)
   367           assemble_classrels classrels (assemble_plain_dict ty x)
   365           assemble_constapp (Class_Instance inst) tys (map snd dictss) []
   369           assemble_constapp (Class_Instance inst) tys (map snd dictss) []
   366       | assemble_plain_dict _ (Dict_Var { var, index, ... }) =
   370       | assemble_plain_dict _ (Dict_Var { var, index, ... }) =
   367           nbe_dict var index
   371           nbe_dict var index
   368 
   372 
   369     fun assemble_constmatch sym _ dictss ts =
   373     fun assemble_constmatch sym _ dictss ts =
   370       apply_constmatch sym ((maps o map) (K "_") dictss @ ts);
   374       assemble_app_constmatch sym ((maps o map) (K "_") dictss @ ts);
   371 
   375 
   372     fun assemble_iterm constapp =
   376     fun assemble_iterm constapp =
   373       let
   377       let
   374         fun of_iterm match_continuation t =
   378         fun of_iterm match_continuation t =
   375           let
   379           let
   388     val assemble_args = map (assemble_iterm assemble_constmatch NONE);
   392     val assemble_args = map (assemble_iterm assemble_constmatch NONE);
   389     val assemble_rhs = assemble_iterm assemble_constapp;
   393     val assemble_rhs = assemble_iterm assemble_constapp;
   390 
   394 
   391     fun assemble_eqn sym s_tparams dict_params default_params (i, ((samepairs, args), rhs)) =
   395     fun assemble_eqn sym s_tparams dict_params default_params (i, ((samepairs, args), rhs)) =
   392       let
   396       let
   393         val default_rhs = apply_local (i + 1) sym s_tparams (dict_params @ default_params);
   397         val default_rhs = assemble_app_fun (i + 1) sym s_tparams (dict_params @ default_params);
   394         val s_args = assemble_args args;
   398         val s_args = assemble_args args;
   395         val s_rhs = if null samepairs then assemble_rhs (SOME default_rhs) rhs
   399         val s_rhs = if null samepairs then assemble_rhs (SOME default_rhs) rhs
   396           else ml_if (ml_and (map nbe_same samepairs))
   400           else ml_if (ml_and (map nbe_same samepairs))
   397             (assemble_rhs (SOME default_rhs) rhs) default_rhs;
   401             (assemble_rhs (SOME default_rhs) rhs) default_rhs;
   398         val eqns = [([ml_list s_tparams, ml_list (rev (dict_params @ map2 ml_as default_params s_args))], s_rhs),
   402         val eqns = [([ml_list s_tparams, ml_list (rev (dict_params @ map2 ml_as default_params s_args))], s_rhs),
   399           ([ml_list s_tparams, ml_list (rev (dict_params @ default_params))], default_rhs)]
   403           ([ml_list s_tparams, ml_list (rev (dict_params @ default_params))], default_rhs)]
   400       in (fun_ident i sym, eqns) end;
   404       in (fun_ident i sym, eqns) end;
   401 
   405 
   402     fun assemble_default_eqn sym s_tparams dict_params default_params i =
   406     fun assemble_default_eqn sym s_tparams dict_params default_params i =
   403       (fun_ident i sym,
   407       (fun_ident i sym,
   404         [([ml_list s_tparams, ml_list (rev (dict_params @ default_params))], apply_constr sym s_tparams (dict_params @ default_params))])
   408         [([ml_list s_tparams, ml_list (rev (dict_params @ default_params))], assemble_app_constr sym s_tparams (dict_params @ default_params))])
   405 
   409 
   406     fun assemble_value_eqn sym s_tparams dict_params (([], args), rhs) =
   410     fun assemble_value_eqn sym s_tparams dict_params (([], args), rhs) =
   407       (fun_ident 0 sym,
   411       (fun_ident 0 sym,
   408         [([ml_list s_tparams, ml_list (rev (dict_params @ assemble_args args))], assemble_rhs NONE rhs)]);
   412         [([ml_list s_tparams, ml_list (rev (dict_params @ assemble_args args))], assemble_rhs NONE rhs)]);
   409 
   413 
   410     fun assemble_eqns (sym, (num_args, (s_tparams, dict_params, eqns, default_params))) =
   414     fun assemble_eqns (sym, (num_args, (s_tparams, dict_params, eqns, default_params))) =
   411       (if Code_Symbol.is_value sym then [assemble_value_eqn sym s_tparams dict_params (the_single eqns)]
   415       (if Code_Symbol.is_value sym then [assemble_value_eqn sym s_tparams dict_params (the_single eqns)]
   412       else map_index (assemble_eqn sym s_tparams dict_params default_params) eqns
   416       else map_index (assemble_eqn sym s_tparams dict_params default_params) eqns
   413         @ [assemble_default_eqn sym s_tparams dict_params default_params (length eqns)],
   417         @ [assemble_default_eqn sym s_tparams dict_params default_params (length eqns)],
   414       ml_abs (ml_list s_tparams) (nbe_abss num_args (fun_ident 0 sym `$` ml_list s_tparams)));
   418       ml_abs (ml_list s_tparams) (nbe_abss num_args (assemble_fun 0 sym s_tparams)));
   415 
   419 
   416     val (fun_vars, fun_vals) = map_split assemble_eqns eqnss;
   420     val (fun_vars, fun_vals) = map_split assemble_eqns eqnss;
   417     val deps_vars = ml_list (map (fun_ident 0) deps);
   421     val deps_vars = ml_list (map (fun_ident 0) deps);
   418   in ml_abs deps_vars (ml_Let (ml_fundefs (flat fun_vars)) (ml_list fun_vals)) end;
   422   in ml_abs deps_vars (ml_Let (ml_fundefs (flat fun_vars)) (ml_list fun_vals)) end;
   419 
   423