staload "error.sats"
staload "types.sats"
staload "absyn.sats"
staload "parser.sats"
staload "tychecker.sats"
staload INT0 = "interp0.sats"
staload TL = "templab.sats"
staload TR = "irtree.sats"
staload F = "frame.sats"
staload TRAN = "translate.sats"
staload CA = "canonical.sats"
staload INT1 = "interp1.sats"
staload "assem.sats"
staload "codegen.sats"
staload "fgraph.sats"
staload "igraph.sats"
staload "regalloc.sats"
staload _ = "prelude/DATS/list.dats"
staload _ = "prelude/DATS/list_vt.dats"
dynload "error.dats"
dynload "stamp.dats"
dynload "symbol.dats"
dynload "types.dats"
dynload "absyn.dats"
dynload "fixity.dats"
dynload "parser.dats"
dynload "PARCOMB/posloc.dats"
dynload "PARCOMB/tokenize.dats"
dynload "PARCOMB/parcomb.dats"
dynload "tychecker.dats"
dynload "interp0.dats"
dynload "templab.dats"
dynload "irtree.dats"
dynload "frame.dats"
dynload "translate.dats"
dynload "canonical.dats"
dynload "interp1.dats"
dynload "assem.dats"
dynload "codegen.dats"
dynload "fgnode.dats"
dynload "tempset.dats"
dynload "fgraph.dats"
dynload "igraph.dats"
dynload "liveness.dats"
dynload "regalloc.dats"
fn compusage (cmd: string) = begin
printf ("%s --help: print out usage\n", @(cmd));
printf ("%s <file>: compile the given <file>\n", @(cmd));
printf ("%s : compile the program read from the stdin\n", @(cmd));
end
fun fprint_stmlst (out: FILEref, ss: $TR.stmlst): void =
case+ ss of
| list_cons (s, ss) => begin
$TR.fprint_stm (out, s); fprint_newline (out); fprint_stmlst (out, ss)
end | list_nil () => fprint_newline (out)
fn print_stmlst (ss: $TR.stmlst): void = fprint_stmlst (stdout_ref, ss)
#include "params.hats"
fn emit_proc (
knd: int, frm: $F.frame_t, inss: instrlst
) : void = () where {
val frmsz = $F.frame_size_get (frm)
val lab_frm = $F.frame_name_get (frm)
val nam_frm = $TL.label_name_get (lab_frm)
val () = print ("\t.text\n")
val () = if knd > 0 then printf (".globl %s\n", @(nam_frm))
#if MARCH == "x86_32" #then
val () = printf ("\t.type\t%s, @function\n", @(nam_frm))
#endif val () = printf ("%s:\n", @(nam_frm))
#if MARCH == "x86_32" #then
val () = printf ("\t.set\t.%s_framesize, %i\n", @(nam_frm, frmsz))
#endif val () = $F.procEntryExit1_entr_emit (stdout_ref, frm)
fun loop (inss: instrlst): void = case+ inss of
| list_cons (ins, inss) => let
val () = case+ ins of
| INSTRoper (asm, _, _, _)
when string_is_empty asm => ()
| INSTRoper _ => let
val asm = regalloc_insfmt (ins) in printf ("\t%s\n", @(asm))
end | INSTRlabel (asm, _) => printf ("%s\n", @(asm))
| INSTRmove (_, src, dst) => let
val src = regassgn_find src and dst = regassgn_find dst in
if $TL.eq_temp_temp (src, dst) then () else let
val asm = regalloc_insfmt (ins) in printf ("\t%s\n", @(asm))
end end
in
loop inss
end | list_nil () => ()
val () = loop (inss)
#if (MARCH == "x86_32") #then
val () = printf ("\t.size\t%s, .-%s\n", @(nam_frm, nam_frm))
#endif }
fn emit_char (c: char): void =
case+ 0 of
| _ when char_isprint c => print_char c
| _ when (c = '\n') => print_string "\\n"
| _ when (c = '\t') => print_string "\\t"
| _ => let
val _0 = int_of_char '0'
val d = uint_of_char c
val d2 = int_of_uint (d mod 8U)
val c2 = char_of_int (_0 + d2)
val d = d / 8U
val d1 = int_of_uint (d mod 8U)
val c1 = char_of_int (_0 + d1)
val d = d / 8U
val d0 = int_of (d)
val c0 = char_of_int (_0 + d0)
in
print_char '\\'; print_char c0; print_char c1; print_char c2
end
fn emit_string_def
(def: string): void = () where {
val () = print_char '"'
val () = loop (def, 0) where {
val def = string1_of_string def
fun loop {n,i:nat | i <= n}
(str: string n, i: size_t i): void =
if string_isnot_at_end (str, i)
then (emit_char str[i]; loop (str, i+1))
} val () = print_char '"'
}
#if (MARCH == "SPIM") #then
fn emit_string
(lab: $TL.label_t, def: string): void = () where {
val () = print ("\t.data\n")
val () = $TL.print_label (lab)
val () = print ":\n"
val () = print "\t.asciiz\t"
val () = emit_string_def (def)
val () = print "\n"
} #endif
#if (MARCH == "x86_32") #then
fn emit_string
(lab: $TL.label_t, def: string): void = () where {
val () = print "."
val () = $TL.print_label (lab)
val () = print ":\n"
val () = print "\t.string\t"
val () = emit_string_def (def)
val () = print "\n"
} #endif
implement main (argc, argv) = let
val () = case+ argc of
| _ when argc >= 2 => begin case+ argv.[1] of
| "--help" => (
compusage (argv.[0]); exit {void} (0)
)
| _ => () end | _ => ()
val prog_exp = case+ argc of
| 1 => parse_from_stdin ()
| _ =>> parse_from_file (argv.[1])
val prog_ty = transProg (prog_exp)
val prog_e1xp = $TRAN.transProg1 (prog_exp)
val prog_stm = $TRAN.unNx (prog_e1xp)
val theFraglst = list_reverse ($F.frame_theFraglst_get ())
datatype f1rag =
| F1RAGproc of ($F.frame_t, $TR.stmlst) | F1RAGstring of ($TL.label_t, string)
viewtypedef f1raglst_vt = List_vt f1rag
val theF1raglst = loop (theFraglst, list_vt_nil) where {
fun loop (xs: $F.fraglst_vt, res: f1raglst_vt): f1raglst_vt = case+ xs of
| ~list_vt_cons (x, xs) => let
val f1rag = case+ x of
| $F.FRAGproc (frm, stm) => let
val stms = $CA.linearize stm
val (lab_done, blks) = $CA.blocklst_gen (stms)
val stms = $CA.trace_schedule (lab_done, blks)
val lab_frm = $F.frame_name_get (frm)
in
F1RAGproc (frm, stms)
end | $F.FRAGstring (lab, str) => let
in
F1RAGstring (lab, str)
end in
loop (xs, list_vt_cons (f1rag, res))
end | ~list_vt_nil () => list_vt_reverse res
}
val prog_stms = $CA.linearize prog_stm
val (lab_done, prog_blks) = $CA.blocklst_gen (prog_stms)
val prog_stms = $CA.trace_schedule (lab_done, prog_blks)
val () = loop (theF1raglst) where {
fun loop (xs: f1raglst_vt): void = case+ xs of
| ~list_vt_cons (x, xs) => let
val () = case+ x of
| F1RAGproc (frm, stms) => let
val inss = codegen_proc (frm, stms)
val inss = instrlst_regalloc (frm, inss)
val () = emit_proc (0, frm, inss)
in
end | F1RAGstring (label, str) => emit_string (label, str)
in
loop (xs)
end | ~list_vt_nil () => ()
} val prog_frm = $F.theTopFrame
val prog_inss = codegen_proc (prog_frm, prog_stms)
val prog_inss = instrlst_regalloc (prog_frm, prog_inss)
val () = emit_proc (1, prog_frm, prog_inss)
in
end