Exemplo n.º 1
0
int main(int argc, char ** argv) {
    lean::save_stack_info();
    lean::register_modules();
    bool export_objects  = false;
    unsigned trust_lvl   = 0;
    bool quiet           = false;
    bool interactive     = false;
    bool only_deps       = false;
    bool flycheck        = false;
    bool flyinfo         = false;
    lean_mode mode       = lean_mode::Standard;
    unsigned num_threads = 1;
    std::string output;
    std::string cpp_output;
    std::string cache_name;
    std::string index_name;
    input_kind default_k = input_kind::Lean; // default
    while (true) {
        int c = getopt_long(argc, argv, g_opt_str, g_long_options, NULL);
        if (c == -1)
            break; // end of command line
        switch (c) {
        case 'j':
            num_threads = atoi(optarg);
            break;
        case 'S':
            server = true;
            break;
        case 'v':
            display_header(std::cout);
            return 0;
        case 'g':
            std::cout << g_githash << "\n";
            return 0;
        case 'h':
            display_help(std::cout);
            return 0;
        case 'l':
            default_k = input_kind::Lean;
            break;
        case 'u':
            default_k = input_kind::Lua;
            break;
        case 'R':
            default_k = input_kind::Trace;
            break;
        case 'k':
            script_state::set_check_interrupt_freq(atoi(optarg));
            break;
        case 'p':
            std::cout << lean::get_lean_path() << "\n";
            return 0;
        case 's':
            lean::set_thread_stack_size(atoi(optarg)*1024);
            break;
        case 'o':
            output         = optarg;
            export_objects = true;
            break;
        case 'C':
            cpp_output = optarg;
            export_cpp = true;
            break;
        case 'c':
            cache_name = optarg;
            use_cache  = true;
            break;
        case 'i':
            index_name = optarg;
            gen_index  = true;
        case 't':
            trust_lvl = atoi(optarg);
            break;
        case 'T':
            tmode = keep_theorem_mode::DiscardImported;
            break;
        case 'X':
            tmode = keep_theorem_mode::DiscardAll;
            break;
        case 'q':
            opts = opts.update("verbose", false);
            break;
        case 'd':
            only_deps = true;
            break;
        case 'D':
            try {
                opts = set_config_option(opts, optarg);
            } catch (lean::exception & ex) {
                std::cerr << ex.what() << std::endl;
                return 1;
            }
            break;
        case 'F':
            flycheck = true;
            break;
        case 'I':
            flyinfo = true;
            break;
        default:
            std::cerr << "Unknown command line option\n";
            display_help(std::cerr);
            return 1;
        }
    }

    environment env = mode == lean_mode::Standard ? mk_environment(trust_lvl) : mk_hott_environment(trust_lvl);
    io_state ios(lean::mk_pretty_formatter_factory());
    if (quiet)
        ios.set_option("verbose", false);
    if (flycheck)
        ios.set_option("flycheck", true);
    if (flyinfo)
        ios.set_option("flyinfo", true);
    script_state S = lean::get_thread_script_state();
    set_environment set1(S, env);
    set_io_state    set2(S, ios);
    definition_cache   cache;
    definition_cache * cache_ptr = nullptr;
    if (use_cache) {
        cache_ptr = &cache;
        std::ifstream in(cache_name, std::ifstream::binary);
        if (!in.bad() && !in.fail())
            cache.load(in);
    }
    declaration_index index;
    declaration_index * index_ptr = nullptr;
    if (gen_index)
        index_ptr = &index;

    try {
        bool ok = true;
        for (int i = optind; i < argc; i++) {
            try {
                char const * ext = get_file_extension(argv[i]);
                input_kind k     = default_k;
                if (ext) {
                    if (strcmp(ext, "lean") == 0) {
                        k = input_kind::Lean;
                    } else if (strcmp(ext, "lua") == 0) {
                        k = input_kind::Lua;
                    }
                }
                switch (k) {
                case input_kind::Lean:
                    if (only_deps) {
                        if (!display_deps(env, std::cout, std::cerr, argv[i]))
                            ok = false;
                    } else if (!parse_commands(env, ios, argv[i], false, num_threads,
                                               cache_ptr, index_ptr, tmode)) {
                        ok = false;
                    }
                    break;
                case input_kind::Lua:
                    lean::system_import(argv[i]);
                    break;
                case input_kind::Trace:
                    ok = lean::parse_server_trace(env, ios, argv[i]);
                    break;
                default:
                    lean_unreachable();
                    break;
                }
            } catch (lean::exception & ex) {
                simple_pos_info_provider pp(argv[i]);
                ok = false;
                lean::display_error(diagnostic(env, ios), &pp, ex);
            }
        }
        if (ok && server && default_k == input_kind::Lean) {
            signal(SIGINT, on_ctrl_c);
            ios.set_option(lean::name("pp", "beta"), true);
            lean::server Sv(env, ios, num_threads);
            if (!Sv(std::cin))
                ok = false;
        }
        if (use_cache) {
            std::ofstream out(cache_name, std::ofstream::binary);
            cache.save(out);
        }
        if (gen_index) {
            std::shared_ptr<lean::file_output_channel> out(new lean::file_output_channel(index_name.c_str()));
            ios.set_regular_channel(out);
            index.save(regular(env, ios));
        }
        if (export_objects && ok) {
            std::ofstream out(output, std::ofstream::binary);
            export_module(out, env);
        }
        if (export_cpp && ok) {
            export_as_cpp_file(cpp_output, "olean_lib", env);
        }
        return ok ? 0 : 1;
    } catch (lean::exception & ex) {
        lean::display_error(diagnostic(env, ios), nullptr, ex);
    }
    return 1;
}
Exemplo n.º 2
0
 virtual pos_info get_some_pos() const { return pos_info(-1, -1); }
Exemplo n.º 3
0
 emscripten_shell() : trust_lvl(10000), num_threads(1), opts("flycheck", true),
     env(mk_environment(trust_lvl)), ios(opts, lean::mk_pretty_formatter_factory()),
     S(lean::get_thread_script_state()), set1(S, env), set2(S, ios) {
 }
Exemplo n.º 4
0
int main(int argc, char ** argv) {
    lean::initializer init;
    bool export_objects     = false;
    unsigned trust_lvl      = LEAN_BELIEVER_TRUST_LEVEL+1;
    bool server             = false;
    bool only_deps          = false;
    unsigned num_threads    = 1;
    bool use_cache          = false;
    bool gen_index          = false;
    keep_theorem_mode tmode = keep_theorem_mode::All;
    options opts;
    std::string output;
    std::string cache_name;
    std::string index_name;
    optional<unsigned> line;
    optional<unsigned> column;
    optional<std::string> export_txt;
    bool show_goal = false;
    input_kind default_k = input_kind::Unspecified;
    while (true) {
        int c = getopt_long(argc, argv, g_opt_str, g_long_options, NULL);
        if (c == -1)
            break; // end of command line
        switch (c) {
        case 'j':
            num_threads = atoi(optarg);
            break;
        case 'S':
            server = true;
            break;
        case 'v':
            display_header(std::cout);
            return 0;
        case 'g':
            std::cout << g_githash << "\n";
            return 0;
        case 'h':
            display_help(std::cout);
            return 0;
        case 'l':
            default_k = input_kind::Lean;
            break;
        case 'H':
            default_k = input_kind::HLean;
            break;
        case 'u':
            default_k = input_kind::Lua;
            break;
        case 'R':
            default_k = input_kind::Trace;
            break;
        case 'k':
            script_state::set_check_interrupt_freq(atoi(optarg));
            break;
        case 'p':
            if (default_k == input_kind::HLean)
                lean::initialize_lean_path(true);
            std::cout << lean::get_lean_path() << "\n";
            return 0;
        case 's':
            lean::set_thread_stack_size(atoi(optarg)*1024);
            break;
        case 'o':
            output         = optarg;
            export_objects = true;
            break;
        case 'c':
            cache_name = optarg;
            use_cache  = true;
            break;
        case 'i':
            index_name = optarg;
            gen_index  = true;
            break;
        case 'M':
            lean::set_max_memory_megabyte(atoi(optarg));
            opts = opts.update(lean::get_max_memory_opt_name(), atoi(optarg));
            break;
        case 't':
            trust_lvl = atoi(optarg);
            break;
        case 'r':
            tmode = keep_theorem_mode::DiscardImported;
            break;
        case 'X':
            tmode = keep_theorem_mode::DiscardAll;
            break;
        case 'q':
            opts = opts.update(lean::get_verbose_opt_name(), false);
            break;
        case 'd':
            only_deps = true;
            break;
        case 'D':
            try {
                opts = set_config_option(opts, optarg);
            } catch (lean::exception & ex) {
                std::cerr << ex.what() << std::endl;
                return 1;
            }
            break;
        case 'F':
            opts = opts.update("flycheck", true);
            break;
        case 'P':
            opts = opts.update("profile", true);
            break;
        case 'L':
            line = atoi(optarg);
            break;
        case 'O':
            column = atoi(optarg);
            break;
        case 'G':
            show_goal = true;
            break;
        case 'E':
            export_txt = std::string(optarg);
            break;
        default:
            std::cerr << "Unknown command line option\n";
            display_help(std::cerr);
            return 1;
        }
    }

    if (show_goal) {
        std::cout << "SHOW GOAL @ " << *line << " : " << *column << "\n";
        exit(0);
    }

    #if !defined(LEAN_MULTI_THREAD)
    lean_assert(!server);
    lean_assert(num_threads == 1);
    #endif

    bool has_lean  = (default_k == input_kind::Lean);
    bool has_hlean = (default_k == input_kind::HLean);
    for (int i = optind; i < argc; i++) {
        char const * ext = get_file_extension(argv[i]);
        if (ext && strcmp(ext, "lean") == 0) {
            has_lean = true;
            if (has_hlean) {
                std::cerr << ".hlean file cannot be mixed with .lean files\n";
                return 1;
            }
            if (default_k == input_kind::Unspecified)
                default_k = input_kind::Lean;
        } else if (ext && strcmp(ext, "hlean") == 0) {
            has_hlean = true;
            if (has_lean) {
                std::cerr << ".lean file cannot be mixed with .hlean files\n";
                return 1;
            }
            if (default_k == input_kind::Unspecified)
                default_k = input_kind::HLean;
        }
    }
    if (default_k == input_kind::Unspecified)
        default_k = input_kind::Lean;

    if (has_hlean)
        lean::initialize_lean_path(true);

    environment env = has_hlean ? mk_hott_environment(trust_lvl) : mk_environment(trust_lvl);
    io_state ios(opts, lean::mk_pretty_formatter_factory());
    script_state S = lean::get_thread_script_state();
    set_environment set1(S, env);
    set_io_state    set2(S, ios);
    definition_cache   cache;
    definition_cache * cache_ptr = nullptr;
    if (use_cache) {
        try {
            cache_ptr = &cache;
            std::ifstream in(cache_name, std::ifstream::binary);
            if (!in.bad() && !in.fail())
                cache.load(in);
        } catch (lean::throwable & ex) {
            cache_ptr = nullptr;
            auto out = regular(env, ios);
            // I'm using flycheck_error instead off flycheck_warning because
            // the :error-patterns at lean-flycheck.el do not work after
            // I add a rule for FLYCHECK_WARNING.
            // Same for display_error_pos vs display_warning_pos.
            lean::flycheck_error warn(out);
            if (optind < argc)
                display_error_pos(out, argv[optind], 1, 0);
            out << "failed to load cache file '" << cache_name << "', "
                << ex.what() << ". cache is going to be ignored\n";
        }
    }
    declaration_index index;
    declaration_index * index_ptr = nullptr;
    if (gen_index)
        index_ptr = &index;

    try {
        bool ok = true;
        for (int i = optind; i < argc; i++) {
            try {
                char const * ext = get_file_extension(argv[i]);
                input_kind k     = default_k;
                if (ext) {
                    if (strcmp(ext, "lean") == 0) {
                        k = input_kind::Lean;
                    } else if (strcmp(ext, "hlean") == 0) {
                        k = input_kind::HLean;
                    } else if (strcmp(ext, "lua") == 0) {
                        k = input_kind::Lua;
                    }
                }
                switch (k) {
                case input_kind::Lean:
                case input_kind::HLean:
                    if (only_deps) {
                        if (!display_deps(env, std::cout, std::cerr, argv[i]))
                            ok = false;
                    } else if (!parse_commands(env, ios, argv[i], false, num_threads,
                                               cache_ptr, index_ptr, tmode)) {
                        ok = false;
                    }
                    break;
                case input_kind::Lua:
                    lean::system_import(argv[i]);
                    break;
                case input_kind::Trace:
                    ok = lean::parse_server_trace(env, ios, argv[i]);
                    break;
                default:
                    lean_unreachable();
                    break;
                }
            } catch (lean::exception & ex) {
                simple_pos_info_provider pp(argv[i]);
                ok = false;
                lean::display_error(diagnostic(env, ios), &pp, ex);
            }
        }
        if (ok && server && (default_k == input_kind::Lean || default_k == input_kind::HLean)) {
            signal(SIGINT, on_ctrl_c);
            ios.set_option(lean::name("pp", "beta"), true);
            lean::server Sv(env, ios, num_threads);
            if (!Sv(std::cin))
                ok = false;
        }
        if (use_cache) {
            std::ofstream out(cache_name, std::ofstream::binary);
            cache.save(out);
        }
        if (gen_index) {
            std::shared_ptr<lean::file_output_channel> out(new lean::file_output_channel(index_name.c_str()));
            ios.set_regular_channel(out);
            index.save(regular(env, ios));
        }
        if (export_objects && ok) {
            std::ofstream out(output, std::ofstream::binary);
            export_module(out, env);
        }
        if (export_txt) {
            std::ofstream out(*export_txt);
            export_module_as_lowtext(out, env);
        }
        return ok ? 0 : 1;
    } catch (lean::throwable & ex) {
        lean::display_error(diagnostic(env, ios), nullptr, ex);
    } catch (std::bad_alloc & ex) {
        std::cerr << "out of memory" << std::endl;
        return 1;
    }
    return 1;
}