main.cpp 2.34 KB
Newer Older
lyz's avatar
lyz committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
#include "ast.hpp"

#include <filesystem>
#include <iostream>
#include <string>

using std::string;
using std::operator""s;

struct Config
{
    string exe_name; // compiler exe name
    std::filesystem::path input_file;
    std::filesystem::path output_file;

    bool emitast{false};

    Config(int argc, char **argv) : argc(argc), argv(argv)
    {
        parse_cmd_line();
        check();
    }

private:
    int argc{-1};
    char **argv{nullptr};

    void parse_cmd_line();
    void check();
    // print helper infomation and exit
    void print_help() const;
    void print_err(const string &msg) const;
};

int main(int argc, char **argv)
{
    Config config(argc, argv);
    auto syntax_tree = parse(config.input_file.c_str());
    auto ast = AST(syntax_tree);
    ASTPrinter printer;
    ast.run_visitor(printer);

    return 0;
}

void Config::parse_cmd_line()
{
    exe_name = argv[0];
    for (int i = 1; i < argc; ++i)
    {
        if (argv[i] == "-h"s || argv[i] == "--help"s)
        {
            print_help();
        }
        else if (argv[i] == "-o"s)
        {
            if (output_file.empty() && i + 1 < argc)
            {
                output_file = argv[i + 1];
                i += 1;
            }
            else
            {
                print_err("bad output file");
            }
        }
        else if (argv[i] == "-emit-ast"s)
        {
            emitast = true;
        }
        else
        {
            if (input_file.empty())
            {
                input_file = argv[i];
            }
            else
            {
                string err =
                    "unrecognized command-line option \'"s + argv[i] + "\'"s;
                print_err(err);
            }
        }
    }
}

void Config::check()
{
    if (input_file.empty())
    {
        print_err("no input file");
    }
    if (input_file.extension() != ".cminus")
    {
        print_err("file format not recognized");
    }
    if (output_file.empty())
    {
        output_file = input_file.stem();
    }
}

void Config::print_help() const
{
    std::cout << "Usage: " << exe_name
              << " [-h|--help] [-o <target-file>] [-mem2reg] [-emit-llvm] [-S] "
                 "<input-file>"
              << std::endl;
    exit(0);
}

void Config::print_err(const string &msg) const
{
    std::cout << exe_name << ": " << msg << std::endl;
    exit(-1);
}