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) |
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 |