diff --git a/README.md b/README.md index 788d82c..ab1c750 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ make -j ```bash build/main ``` +Ceci ouvre une repl. Une entrée doit se terminer par `;;` pour être exécutée. ### Arguments @@ -28,11 +29,12 @@ La commande `build/main -h` pourrait être plus à jour que ce fichier ``` Usage: build/main [OPTIONS] - --help | -h Afficher cette aide - --tokens | -t Afficher les tokens lus - --ast | -a Afficher l'AST créé - --type-memory | -T Afficher le contenu de la mémoire de types avant exécution - --memory | -m Afficher le contenu de la mémoire après exécution + --help | -h Afficher cette aide + --interactive | -i [FILENAME] Ouvre une repl après interprétation d'un fichier + --tokens | -t Afficher les tokens lus + --ast | -a Afficher l'AST créé + --type-memory | -T Afficher le contenu de la mémoire de types avant exécution + --memory | -m Afficher le contenu de la mémoire après exécution ``` ### Tests diff --git a/src/errors.cpp b/src/errors.cpp index be96e10..fcbb85e 100644 --- a/src/errors.cpp +++ b/src/errors.cpp @@ -64,21 +64,21 @@ void print_error_position(vector history, CodePosition pos) { if (pos.column == -1 || pos.line == -1) return; - cout << endl << BOLD + cerr << endl << BOLD << setw(4) << setfill(' ') << pos.line+1 << " " RESET << history[pos.line] << endl; for (int i=0; i < pos.column + 5; i++) - cout << " "; + cerr << " "; - cout << BOLD RED "^--" RESET << endl; + cerr << BOLD RED "^--" RESET << endl; } void print_error_stack_trace(vector history, const RuntimeError& error) { - cout << endl << BOLD "Traceback" RESET " (most recent call last)" << endl; + cerr << endl << BOLD "Traceback" RESET " (most recent call last)" << endl; for (StackTraceEntry e : error.trace) { - cout << BOLD << setw(8) << setfill(' ') + cerr << BOLD << setw(8) << setfill(' ') << to_string(get<1>(e).line+1) + ":" + to_string(get<1>(e).column+1) << RESET BLUE << setw(16) << setfill(' ') @@ -86,5 +86,5 @@ void print_error_stack_trace(vector history, const RuntimeError& error) << trim(history[get<1>(e).line]) << endl; } - cout << BOLD RED "Runtime Error: " RESET << error.get_message() << endl; + cerr << BOLD RED "Runtime Error: " RESET << error.get_message() << endl; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index cdb6163..b9c2a19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include using namespace std; @@ -10,15 +11,16 @@ using namespace std; void show_help(char* prog_name) { printf("Usage: %s [OPTIONS]\n\n", prog_name); - printf("\t--help | -h\tAfficher cette aide\n"); - printf("\t--tokens | -t\tAfficher les tokens lus\n"); - printf("\t--ast | -a\tAfficher l'AST créé\n"); - printf("\t--type-memory | -T\tAfficher le contenu de la mémoire de types avant exécution\n"); - printf("\t--memory | -m\tAfficher le contenu de la mémoire après exécution\n"); + printf("\t--help | -h\t\tAfficher cette aide\n"); + printf("\t--interactive | -i [FILENAME]\tOuvre une repl après interprétation d'un fichier\n"); + printf("\t--tokens | -t\t\tAfficher les tokens lus\n"); + printf("\t--ast | -a\t\tAfficher l'AST créé\n"); + printf("\t--type-memory | -T\t\tAfficher le contenu de la mémoire de types avant exécution\n"); + printf("\t--memory | -m\t\tAfficher le contenu de la mémoire après exécution\n"); } -void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &print_ast, bool &dump_type_mem, bool &dump_mem, bool &help) { +void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &print_ast, bool &dump_type_mem, bool &dump_mem, bool &help, string &interactive) { int i=1; while (i < argc) { char* cur = argv[i]; @@ -29,6 +31,13 @@ void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &prin case 'h': help = true; break; + case 'i': + if (++i >= argc) { + cerr << "Argument manquant pour -i" << endl; + exit(1); + } + interactive = argv[i]; + break; case 't': print_tokens = true; break; @@ -42,11 +51,17 @@ void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &prin dump_mem = true; break; default: - cerr << "Unknow argument: -" << cur[j] << endl; + cerr << "Argument inconnu: -" << cur[j] << endl; } } } else if (!strcmp(cur, "--help")) { help = true; + } else if (!strcmp(cur, "--interactive")) { + if (++i >= argc) { + cerr << "Argument manquant pour --interactive" << endl; + exit(1); + } + interactive = argv[i]; } else if (!strcmp(cur, "--tokens")) { print_tokens = true; } else if (!strcmp(cur, "--ast")) { @@ -56,21 +71,40 @@ void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &prin } else if (!strcmp(cur, "--memory")) { dump_mem = true; } else { - cerr << "Unknow argument: " << cur << endl; + cerr << "Argument inconnu: " << cur << endl; } i++; } } +vector get_history(string filename) { + ifstream file(filename); + + if (!file.good()) { // Check if file exists + cerr << "Le fichier '" << filename << "' n'existe pas ou n'est pas accessible" << endl; + exit(1); + } + + string line; + vector lines; + + while (getline(file, line)) + lines.push_back(line); + + return lines; +} + + int main(int argc, char* argv[]) { bool print_tokens = false; bool print_ast = false; bool dump_type_mem = false; bool dump_mem = false; bool help = false; + string interactive = ""; - parse_main_arguments(argc, argv, print_tokens, print_ast, dump_type_mem, dump_mem, help); + parse_main_arguments(argc, argv, print_tokens, print_ast, dump_type_mem, dump_mem, help, interactive); if (help) { show_help(argv[0]); @@ -83,6 +117,12 @@ int main(int argc, char* argv[]) { while (!received_eof) { try { + if (interactive != "" && input.size() == 0) { + input = get_history(interactive); + execute(input, memory, 0, {}); + continue; + } + int initial_line = input.size(); input = get_input(input, received_eof); @@ -108,6 +148,9 @@ int main(int argc, char* argv[]) { } } catch (const SyntaxError& e) { + if (e.type == ErrorType::EmptyInput) + continue; + print_error_position(input, e.pos); cout << BOLD RED "Syntax Error: " RESET << e.get_message() << endl << endl;