view dang/compiler.d @ 211:9e9f3e7e342b default tip

Added dang folder and Module in ast.
author Anders Johnsen <skabet@gmail.com>
date Tue, 12 Aug 2008 20:07:35 +0200
parents
children
line wrap: on
line source

module dang.compiler;

import tango.io.Stdout,
       tango.core.Signal,
       tango.core.Memory,
       tango.sys.Process,
       tango.time.StopWatch,
       tango.text.Util,
       tango.io.FileConduit,
       tango.io.FilePath;

import lexer.Lexer,
       parser.Action,
       parser.Parser;

import basic.SourceManager;

import basic.Message;

import ast.Module;

import tango.stdc.posix.unistd;
import tango.stdc.stdlib;

import Opt = dang.OptParse;
            
class NullAction : Action 
{
}

void checkFiles(char[][] *files)
{
//    GC.disable();
    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 ~= path.toString();
    }

    *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!(Module[], SourceManager) postParse;
    Signal!(Module[], SourceManager) postSema;

    preStart.attach(&checkFiles);

    auto argParse = new Opt.OptionParser(`Dang "D" compiler v0.1`);

    bool optimize = false;
    bool inline = false;


    SourceManager src_mgr = new SourceManager;
    MessageHandler messages = new MessageHandler(src_mgr);

    argParse.addOption(["-h", "--help"], Opt.Action.Help)
        .help("Show this help message");

    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;
    StopWatch total;
    total.start;

    Module[] modules;

    StopWatch watch;
    watch.start;
    foreach (file; filesToHandle)
    {
        preLex(file);

        auto start = src_mgr.addFile(file);
        auto lexer = new Lexer(start, src_mgr, messages);
        postLex(lexer);

        preParse(lexer);

        auto parser = new Parser(messages);
        auto action = new NullAction;
        modules ~= cast(Module)parser.parse(src_mgr, lexer, action);
        timings ~= Measurement("Lex + Parse of '"~file~"'", watch.stop);
        messages.checkErrors(ExitLevel.Parser);
/*
        StopWatch watch2;
        watch.start;
        watch2.start;
        Module[] mods = (new LoadModule).visit(m, src_mgr, messages);
        (new ScopeBuilder).visit(m);
        auto scope_builder = watch2.stop;
        watch2.start;
        (new ScopeCheck).visit(m);
        auto scope_check = watch2.stop;
        watch2.start;
        (new TypeCheck).visit(m);
        auto type_check = watch2.stop;
        watch2.start;

        foreach (decl; m.decls)
            decl.simplify();
        auto simplify = watch2.stop;
        auto extra_stuff = watch.stop;
        timings ~= Measurement("Extra stuff", watch.stop);
        timings ~= Measurement("  - Building scopes", scope_builder);
        timings ~= Measurement("  - Checking scopes", scope_check);
        timings ~= Measurement("  - Checking types", type_check);

        postParse(m, src_mgr);*/
    }
/*
    (new LiteralInterpreter(messages)).visit(modules);
    messages.checkErrors;
    postParse(modules, src_mgr);

    class ModuleLoader : Visitor!(void)
    {
        Module[] visit(Module[] modules, MessageHandler messages, SourceManager src_mgr)
        {
            this.modules = modules;
            this.messages = messages;
            this.src_mgr = src_mgr;
            super.visit(modules);
            return this.modules;
        }

        override void visitImportDecl(ImportDecl decl)
        {
            char[] path = replace!(char)(decl.get,'.','/')~".d";

            auto start = src_mgr.addFile(path);
            auto lexer = new Lexer(start, src_mgr, messages);

            auto parser = new Parser(messages);
            auto action = new AstAction(src_mgr);

            Module m = cast(Module)parser.parse(src_mgr, lexer, action);
            modules ~= m;
            m.outputModule = false;
    //        decl.env.mHandle.add(m);
            messages.checkErrors(ExitLevel.Parser);
        }

        Module[] modules;
        SourceManager src_mgr;
        MessageHandler messages;
    }

    modules = (new ModuleLoader()).visit(modules, messages, src_mgr);
    messages.checkErrors;

    (new BuildScopes).visit(modules);
    (new BuildSymbols).visit(modules);
    StopWatch watch2;
    watch.start;
    watch2.start;

    (new BuildTypes(messages)).visit(modules);

    (new CheckScopes(messages)).visit(modules);
    messages.checkErrors;
    auto scope_check = watch2.stop;

    watch2.start;
    (new CheckTypes(messages)).visit(modules);
    messages.checkErrors;
    auto type_check = watch2.stop;

    watch2.start;
    (new ObjectOriented(messages)).visit(modules);
    messages.checkErrors;
    auto object_check = watch2.stop;

    watch2.start;
    auto vc = new VC;
    vc.msg = messages;
    foreach (m; modules)
        m.verify(vc);
    messages.checkErrors;
    auto ast_verify = watch2.stop;

    foreach (m; modules)
        foreach (decl; m.decls)
            decl.simplify();

    timings ~= Measurement("Total", total.stop);
    postSema(modules, src_mgr);

    if (options.flag("time"))
        foreach (m; timings)
            Stderr.formatln("{,-45} {}ms", m.label, m.time*1e3);
    */
}