Mercurial > projects > dang
view dang/compiler.d @ 87:9a35a973175a new_gen
Some improvements to the compiler program
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 04 May 2008 12:58:02 +0200 |
parents | 381975d76baf |
children | eb5b2c719a39 |
line wrap: on
line source
module dang.compiler; import tango.io.Stdout, tango.core.Signal, tango.time.StopWatch, tango.io.FilePath; import lexer.Lexer, parser.Parser; import misc.DataSource; import ast.Decl; import tools.AstPrinter, tools.DotPrinter; import gen.CodeGen; import sema.Visitor, sema.AstAction, sema.SymbolTableBuilder, sema.ImplicitCast, sema.Declarations; import Opt = dang.OptParse; void checkFiles(char[][] *files) { bool non_existant_files = false; bool duplicate_files = false; char[][] validFiles; foreach (file; *files) { scope path = new FilePath(file); if (!path.exists) { Stderr.formatln("'{}' does not exist", file).newline; non_existant_files = true; continue; } bool fileInStack = false; foreach (vFile; validFiles) if (vFile == file) { fileInStack = true; duplicate_files = true; } if (fileInStack) continue; validFiles ~= file; } *files = validFiles; if (non_existant_files) throw new Exception("All files given must exist"); if (duplicate_files) Stderr("warning: duplicate files ignored").newline; } void main(char[][] args) { char[][] filesToHandle; Signal!(char[][]*) preStart; Signal!(char[]) preLex; Signal!(Lexer) postLex; Signal!(Lexer) preParse; Signal!(Decl[], DataSource) postParse; preStart.attach(&checkFiles); auto argParse = new Opt.OptionParser(`Dang "D" compiler v0.0`); bool optimize = false; bool inline = false; argParse.addOption(["-h", "--help"], Opt.Action.Help) .help("Show this help message"); argParse.addOption(["--ast-dump-dot"], "what-to-do", Opt.Action.StoreConst, "dot") .help("Output the AST in the dot format"); argParse.addOption(["--ast-dump-code"], "what-to-do", Opt.Action.StoreConst, "code") .help("Output the AST as code"); argParse.addOption(["--gen-llvm"], "what-to-do", Opt.Action.StoreConst, "gen-llvm") .help("Compile to LLVM code (default)"); argParse.addOption( ["-O","--optimize"], { optimize = true; } ).help("Tell LLVM to do its standard optimizations"); argParse.addOption( ["--inline"], { inline = true; } ).help("Tell LLVM that its allowed to inline functions"); argParse .addOption(["--time"], Opt.Action.SetTrue, "time") .help("Time the various operations performed."); auto options = argParse.parse(args); filesToHandle ~= options.args; // Will throw exception if some files don't exist preStart(&filesToHandle); struct Measurement { char[] label; double time; } Measurement[] timings; auto what = options["what-to-do"]; if (what == "" || what == "gen-llvm") postParse.attach( (Decl[] decls, DataSource src) { StopWatch w; w.start; auto llvmGen = new CodeGen(); llvmGen.gen(decls, optimize, inline); timings ~= Measurement("Generating LLVM bytecode", w.stop); }); else if (what == "dot") postParse.attach( (Decl[] decls, DataSource src) { StopWatch w; w.start; auto print = new DotPrinter(); print.print(decls); timings ~= Measurement("Generating dot output", w.stop); }); else if (what == "code") postParse.attach( (Decl[] decls, DataSource src) { StopWatch w; w.start; auto print = new AstPrinter(src); print.print(decls); timings ~= Measurement("Converting AST to text", w.stop); }); StopWatch total; total.start; foreach(file ; filesToHandle) { preLex(file); auto src = DataSource(file); auto lexer = new Lexer(src); postLex(lexer); preParse(lexer); StopWatch watch; watch.start; auto parser = new Parser; auto decls = cast(Decl[])parser.parse(lexer, new AstAction); timings ~= Measurement("Lex + Parse", watch.stop); StopWatch watch2; watch.start; watch2.start; (new SymbolTableBuilder).visit(decls); auto symbol_table = watch2.stop; watch2.start; (new Declarations).visit(decls); auto declarations = watch2.stop; watch2.start; (new ImplicitCast).visit(decls); auto implicit_casts = watch2.stop; watch2.start; foreach (decl; decls) decl.simplify(); auto simplify = watch2.stop; auto extra_stuff = watch.stop; timings ~= Measurement("Extra stuff", watch.stop); timings ~= Measurement(" - Building scopes", symbol_table); timings ~= Measurement(" - Extracting declarations", declarations); timings ~= Measurement(" - Making casts explicit", implicit_casts); postParse(decls, src); } timings ~= Measurement("Total", total.stop); if (options.flag("time")) foreach (m; timings) Stderr.formatln("{,-45} {}ms", m.label, m.time*1e3); }