X-Git-Url: http://git.joshuawise.com/snipe.git/blobdiff_plain/12aa4087bee3e70f170d7457794921de4e385227..0a24e44d4e9f82f8d3d83de8e58c83c8cf2868b6:/top/top.sml diff --git a/top/top.sml b/top/top.sml index cb409bf..35e03a6 100644 --- a/top/top.sml +++ b/top/top.sml @@ -30,87 +30,93 @@ struct (* see flag explanations below *) val flag_verbose = Flag.flag "verbose" + val flag_liveness = Flag.flag "liveness" val flag_ast = Flag.flag "ast" val flag_ir = Flag.flag "ir" val flag_assem = Flag.flag "assem" fun reset_flags () = List.app Flag.unset [flag_verbose, flag_ast, - flag_ir, flag_assem]; + flag_ir, flag_assem, flag_liveness]; val options = [{short = "v", long=["verbose"], - desc=G.NoArg (fn () => Flag.set flag_verbose), - help="verbose messages"}, - {short = "", long=["dump-ast"], - desc=G.NoArg (fn () => Flag.set flag_ast), - help="pretty print the AST"}, - {short = "", long=["dump-ir"], - desc=G.NoArg (fn () => Flag.set flag_ir), - help="pretty print the IR"}, - {short = "", long=["dump-assem"], - desc=G.NoArg (fn () => Flag.set flag_assem), - help="pretty print the assembly before register allocaction"} - ] + desc=G.NoArg (fn () => Flag.set flag_verbose), + help="verbose messages"}, + {short = "a", long=["dump-ast"], + desc=G.NoArg (fn () => Flag.set flag_ast), + help="pretty print the AST"}, + {short = "i", long=["dump-ir"], + desc=G.NoArg (fn () => Flag.set flag_ir), + help="pretty print the IR"}, + {short = "l", long=["dump-liveness"], + desc=G.NoArg (fn () => Flag.set flag_liveness), + help="pretty print the liveness results"}, + {short = "s", long=["dump-assem"], + desc=G.NoArg (fn () => Flag.set flag_assem), + help="pretty print the assembly before register allocaction"} + ] fun stem s = let - val (prefix, suffix) = - Substring.splitr (fn c => c <> #".") (Substring.full s) + val (prefix, suffix) = + Substring.splitr (fn c => c <> #".") (Substring.full s) in - if Substring.isEmpty prefix (* no "." in string s *) - then s (* return whole string *) - else Substring.string (Substring.trimr 1 prefix) + if Substring.isEmpty prefix (* no "." in string s *) + then s (* return whole string *) + else Substring.string (Substring.trimr 1 prefix) end fun main (name, args) = let - val header = "Usage: compile [OPTION...] SOURCEFILE\nwhere OPTION is" - val usageinfo = G.usageInfo {header = header, options = options} - fun errfn msg = (say (msg ^ "\n" ^ usageinfo) ; raise EXIT) - - val _ = Temp.reset (); (* reset temp variable counter *) - val _ = reset_flags (); (* return all flags to default value *) - - val _ = if List.length args = 0 then - (say usageinfo; raise EXIT) - else () - - val (opts, files) = - G.getOpt {argOrder = G.Permute, - options = options, - errFn = errfn} - args - - val source = - case files - of [] => errfn "Error: no input file" - | [filename] => filename - | _ => errfn "Error: more than one input file" - - val _ = Flag.guard flag_verbose say ("Parsing... " ^ source) - val ast = Parse.parse source - val _ = Flag.guard flag_ast - (fn () => say (Ast.Print.pp_program ast)) () - - val _ = Flag.guard flag_verbose say "Checking..." - val _ = TypeChecker.typecheck ast - - val _ = Flag.guard flag_verbose say "Translating..." - val ir = Trans.translate ast - val _ = Flag.guard flag_ir (fn () => say (Tree.Print.pp_program ir)) () - - val _ = Flag.guard flag_verbose say "Generating proto-x86_64 code..." - val assem = Codegen.codegen ir - val _ = Flag.guard flag_assem - (fn () => List.app (TextIO.print o x86.prettyprint) assem) () + val header = "Usage: compile [OPTION...] SOURCEFILE\nwhere OPTION is" + val usageinfo = G.usageInfo {header = header, options = options} + fun errfn msg = (say (msg ^ "\n" ^ usageinfo) ; raise EXIT) + + val _ = Temp.reset (); (* reset temp variable counter *) + val _ = reset_flags (); (* return all flags to default value *) + + val _ = if List.length args = 0 then + (say usageinfo; raise EXIT) + else () + + val (opts, files) = + G.getOpt {argOrder = G.Permute, + options = options, + errFn = errfn} + args + + val source = + case files + of [] => errfn "Error: no input file" + | [filename] => filename + | _ => errfn "Error: more than one input file" + + val _ = Flag.guard flag_verbose say ("Parsing... " ^ source) + val ast = Parse.parse source + val _ = Flag.guard flag_ast + (fn () => say (Ast.Print.pp_program ast)) () + + val _ = Flag.guard flag_verbose say "Checking..." + val ast = TypeChecker.typecheck ast + + val _ = Flag.guard flag_verbose say "Translating..." + val ir = Trans.translate ast + val _ = Flag.guard flag_ir (fn () => say (Tree.Print.pp_program ir)) () + + val _ = Flag.guard flag_verbose say "Generating proto-x86_64 code..." + val assem = Codegen.codegen ir + val _ = Flag.guard flag_assem + (fn () => List.app (TextIO.print o x86.prettyprint) assem) () val _ = Flag.guard flag_verbose say "Analyzing liveness..." val liveness = Liveness.liveness assem; - + val _ = Flag.guard flag_liveness + (fn () => List.app (TextIO.print o Liveness.prettyprint) liveness) () + val _ = Flag.guard flag_verbose say "Graphing..." val igraph = Igraph.gengraph liveness; - + val _ = Flag.guard flag_verbose say "Ordering..." val order = ColorOrder.colororder igraph; @@ -122,25 +128,25 @@ struct val _ = Flag.guard flag_verbose say "Peepholing..." val x86p = Peephole.peephole x86; - + val _ = Flag.guard flag_verbose say "Stringifying..." - val x86d = [x86.DIRECTIVE(".file\t\"" ^ source ^ "\""), - x86.DIRECTIVE(".globl _l1_main"), - x86.DIRECTIVE("_l1_main:")] - @ x86p - @ [x86.DIRECTIVE ".ident\t\"15-411 L1 compiler v2 by czl@ and jwise@\""] - val code = Stringify.stringify x86d - - val afname = stem source ^ ".s" - val _ = Flag.guard flag_verbose say ("Writing assembly to " ^ afname ^ " ...") - val _ = SafeIO.withOpenOut afname (fn afstream => - TextIO.output (afstream, code)) + val x86d = [x86.DIRECTIVE(".file\t\"" ^ source ^ "\""), + x86.DIRECTIVE(".globl _l2_main"), + x86.DIRECTIVE("_l2_main:")] + @ x86p + @ [x86.DIRECTIVE ".ident\t\"15-411 L2 compiler by czl@ and jwise@\""] + val code = Stringify.stringify x86d + + val afname = stem source ^ ".s" + val _ = Flag.guard flag_verbose say ("Writing assembly to " ^ afname ^ " ...") + val _ = SafeIO.withOpenOut afname (fn afstream => + TextIO.output (afstream, code)) in - OS.Process.success + OS.Process.success end handle ErrorMsg.Error => ( say "Compilation failed" ; OS.Process.failure ) - | EXIT => OS.Process.failure - | ErrorMsg.InternalError s => ( say ("Internal compiler error: "^s^"\n"); OS.Process.failure) + | EXIT => OS.Process.failure + | ErrorMsg.InternalError s => ( say ("Internal compiler error: "^s^"\n"); OS.Process.failure) | e => (say ("Unrecognized exception " ^ exnMessage e); OS.Process.failure) fun test s = main ("", String.tokens Char.isSpace s)