Add prompt when in interactive mode. Fix Show Environment [num]

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-08-21 18:24:26 -07:00
parent 0ffa76aa5e
commit 59e63c0421
4 changed files with 29 additions and 11 deletions

View file

@ -44,11 +44,13 @@ public:
struct regular { struct regular {
state const & m_state; state const & m_state;
regular(state const & s):m_state(s) {} regular(state const & s):m_state(s) {}
void flush() { m_state.get_regular_channel().get_stream().flush(); }
}; };
struct diagnostic { struct diagnostic {
state const & m_state; state const & m_state;
diagnostic(state const & s):m_state(s) {} diagnostic(state const & s):m_state(s) {}
void flush() { m_state.get_diagnostic_channel().get_stream().flush(); }
}; };
// hack for using std::endl with channels // hack for using std::endl with channels

View file

@ -89,6 +89,7 @@ class parser_fn {
scanner m_scanner; scanner m_scanner;
scanner::token m_curr; scanner::token m_curr;
bool m_use_exceptions; bool m_use_exceptions;
bool m_interactive;
bool m_found_errors; bool m_found_errors;
local_decls m_local_decls; local_decls m_local_decls;
unsigned m_num_local_decls; unsigned m_num_local_decls;
@ -873,11 +874,14 @@ class parser_fn {
if (opt_id == g_env_kwd) { if (opt_id == g_env_kwd) {
if (curr_is_int()) { if (curr_is_int()) {
unsigned i = parse_unsigned("invalid argument, value does not fit in a machine integer"); unsigned i = parse_unsigned("invalid argument, value does not fit in a machine integer");
auto it = m_frontend.end_objects(); auto end = m_frontend.end_objects();
auto beg = m_frontend.begin_objects(); auto beg = m_frontend.begin_objects();
auto it = end;
while (it != beg && i != 0) { while (it != beg && i != 0) {
--i; --i;
--it; --it;
}
for (; it != end; ++it) {
regular(m_frontend) << *it << endl; regular(m_frontend) << *it << endl;
} }
} else { } else {
@ -1016,7 +1020,7 @@ class parser_fn {
std::ifstream in(fname); std::ifstream in(fname);
if (!in.is_open()) if (!in.is_open())
throw parser_error("invalid import command, failed to open file"); throw parser_error("invalid import command, failed to open file");
::lean::parse_commands(m_frontend, in, m_use_exceptions); ::lean::parse_commands(m_frontend, in, m_use_exceptions, false);
} }
void parse_help() { void parse_help() {
@ -1092,10 +1096,11 @@ class parser_fn {
} }
public: public:
parser_fn(frontend & fe, std::istream & in, bool use_exceptions): parser_fn(frontend & fe, std::istream & in, bool use_exceptions, bool interactive):
m_frontend(fe), m_frontend(fe),
m_scanner(in), m_scanner(in),
m_use_exceptions(use_exceptions) { m_use_exceptions(use_exceptions),
m_interactive(interactive) {
m_found_errors = false; m_found_errors = false;
m_num_local_decls = 0; m_num_local_decls = 0;
m_scanner.set_command_keywords(g_command_keywords); m_scanner.set_command_keywords(g_command_keywords);
@ -1103,13 +1108,24 @@ public:
scan(); scan();
} }
static void show_prompt(bool interactive, frontend const & fe) {
if (interactive) {
regular(fe) << "# ";
regular(fe).flush();
}
}
void show_prompt() {
show_prompt(m_interactive, m_frontend);
}
/** \brief Parse a sequence of commands. This method also perform error management. */ /** \brief Parse a sequence of commands. This method also perform error management. */
bool parse_commands() { bool parse_commands() {
while (true) { while (true) {
try { try {
switch (curr()) { switch (curr()) {
case scanner::token::CommandId: parse_command(); break; case scanner::token::CommandId: parse_command(); break;
case scanner::token::Period: next(); break; case scanner::token::Period: show_prompt(); next(); break;
case scanner::token::Eof: return !m_found_errors; case scanner::token::Eof: return !m_found_errors;
default: default:
throw parser_error("Command expected"); throw parser_error("Command expected");
@ -1142,10 +1158,11 @@ public:
} }
}; };
bool parse_commands(frontend & fe, std::istream & in, bool use_exceptions) { bool parse_commands(frontend & fe, std::istream & in, bool use_exceptions, bool interactive) {
return parser_fn(fe, in, use_exceptions).parse_commands(); parser_fn::show_prompt(interactive, fe);
return parser_fn(fe, in, use_exceptions, interactive).parse_commands();
} }
expr parse_expr(frontend const & fe, std::istream & in) { expr parse_expr(frontend const & fe, std::istream & in) {
return parser_fn(const_cast<frontend&>(fe), in, true).parse_expr_main(); return parser_fn(const_cast<frontend&>(fe), in, true, false).parse_expr_main();
} }
} }

View file

@ -9,6 +9,6 @@ Author: Leonardo de Moura
#include "lean_frontend.h" #include "lean_frontend.h"
namespace lean { namespace lean {
bool parse_commands(frontend & fe, std::istream & in, bool use_exceptions = false); bool parse_commands(frontend & fe, std::istream & in, bool use_exceptions = true, bool interactive = false);
expr parse_expr(frontend const & fe, std::istream & in); expr parse_expr(frontend const & fe, std::istream & in);
} }

View file

@ -5,13 +5,12 @@
#include "lean_parser.h" #include "lean_parser.h"
using namespace lean; using namespace lean;
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
std::cout << "Lean (version " << LEAN_VERSION_MAJOR << "." << LEAN_VERSION_MINOR << ")\n"; std::cout << "Lean (version " << LEAN_VERSION_MAJOR << "." << LEAN_VERSION_MINOR << ")\n";
std::cout << "Type Ctrl-D to exit or 'Help.' for help."<< std::endl; std::cout << "Type Ctrl-D to exit or 'Help.' for help."<< std::endl;
frontend f; frontend f;
if (argc == 1) { if (argc == 1) {
return parse_commands(f, std::cin) ? 0 : 1; return parse_commands(f, std::cin, false, true) ? 0 : 1;
} else { } else {
bool ok = true; bool ok = true;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {