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