Add --interactive

This commit is contained in:
augustin64 2024-01-12 22:11:47 +01:00
parent 1b078176b3
commit 1b749a0091
3 changed files with 65 additions and 20 deletions

View File

@ -21,6 +21,7 @@ make -j
```bash ```bash
build/main build/main
``` ```
Ceci ouvre une repl. Une entrée doit se terminer par `;;` pour être exécutée.
### Arguments ### Arguments
@ -28,11 +29,12 @@ La commande `build/main -h` pourrait être plus à jour que ce fichier
``` ```
Usage: build/main [OPTIONS] Usage: build/main [OPTIONS]
--help | -h Afficher cette aide --help | -h Afficher cette aide
--tokens | -t Afficher les tokens lus --interactive | -i [FILENAME] Ouvre une repl après interprétation d'un fichier
--ast | -a Afficher l'AST créé --tokens | -t Afficher les tokens lus
--type-memory | -T Afficher le contenu de la mémoire de types avant exécution --ast | -a Afficher l'AST créé
--memory | -m Afficher le contenu de la mémoire après exécution --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 ### Tests

View File

@ -64,21 +64,21 @@ void print_error_position(vector<string> history, CodePosition pos) {
if (pos.column == -1 || pos.line == -1) if (pos.column == -1 || pos.line == -1)
return; return;
cout << endl << BOLD cerr << endl << BOLD
<< setw(4) << setfill(' ') << setw(4) << setfill(' ')
<< pos.line+1 << " " RESET << pos.line+1 << " " RESET
<< history[pos.line] << endl; << history[pos.line] << endl;
for (int i=0; i < pos.column + 5; i++) 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<string> history, const RuntimeError& error) { void print_error_stack_trace(vector<string> 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) { 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) << to_string(get<1>(e).line+1) + ":" + to_string(get<1>(e).column+1)
<< RESET BLUE << RESET BLUE
<< setw(16) << setfill(' ') << setw(16) << setfill(' ')
@ -86,5 +86,5 @@ void print_error_stack_trace(vector<string> history, const RuntimeError& error)
<< trim(history[get<1>(e).line]) << endl; << 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;
} }

View File

@ -1,4 +1,5 @@
#include <cstring> #include <cstring>
#include <fstream>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@ -10,15 +11,16 @@ using namespace std;
void show_help(char* prog_name) { void show_help(char* prog_name) {
printf("Usage: %s [OPTIONS]\n\n", prog_name); printf("Usage: %s [OPTIONS]\n\n", prog_name);
printf("\t--help | -h\tAfficher cette aide\n"); printf("\t--help | -h\t\tAfficher cette aide\n");
printf("\t--tokens | -t\tAfficher les tokens lus\n"); printf("\t--interactive | -i [FILENAME]\tOuvre une repl après interprétation d'un fichier\n");
printf("\t--ast | -a\tAfficher l'AST créé\n"); printf("\t--tokens | -t\t\tAfficher les tokens lus\n");
printf("\t--type-memory | -T\tAfficher le contenu de la mémoire de types avant exécution\n"); printf("\t--ast | -a\t\tAfficher l'AST créé\n");
printf("\t--memory | -m\tAfficher le contenu de la mémoire après exécution\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; int i=1;
while (i < argc) { while (i < argc) {
char* cur = argv[i]; char* cur = argv[i];
@ -29,6 +31,13 @@ void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &prin
case 'h': case 'h':
help = true; help = true;
break; break;
case 'i':
if (++i >= argc) {
cerr << "Argument manquant pour -i" << endl;
exit(1);
}
interactive = argv[i];
break;
case 't': case 't':
print_tokens = true; print_tokens = true;
break; break;
@ -42,11 +51,17 @@ void parse_main_arguments(int argc, char* argv[], bool &print_tokens, bool &prin
dump_mem = true; dump_mem = true;
break; break;
default: default:
cerr << "Unknow argument: -" << cur[j] << endl; cerr << "Argument inconnu: -" << cur[j] << endl;
} }
} }
} else if (!strcmp(cur, "--help")) { } else if (!strcmp(cur, "--help")) {
help = true; 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")) { } else if (!strcmp(cur, "--tokens")) {
print_tokens = true; print_tokens = true;
} else if (!strcmp(cur, "--ast")) { } 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")) { } else if (!strcmp(cur, "--memory")) {
dump_mem = true; dump_mem = true;
} else { } else {
cerr << "Unknow argument: " << cur << endl; cerr << "Argument inconnu: " << cur << endl;
} }
i++; i++;
} }
} }
vector<string> 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<std::string> lines;
while (getline(file, line))
lines.push_back(line);
return lines;
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
bool print_tokens = false; bool print_tokens = false;
bool print_ast = false; bool print_ast = false;
bool dump_type_mem = false; bool dump_type_mem = false;
bool dump_mem = false; bool dump_mem = false;
bool help = 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) { if (help) {
show_help(argv[0]); show_help(argv[0]);
@ -83,6 +117,12 @@ int main(int argc, char* argv[]) {
while (!received_eof) { while (!received_eof) {
try { try {
if (interactive != "" && input.size() == 0) {
input = get_history(interactive);
execute(input, memory, 0, {});
continue;
}
int initial_line = input.size(); int initial_line = input.size();
input = get_input(input, received_eof); input = get_input(input, received_eof);
@ -108,6 +148,9 @@ int main(int argc, char* argv[]) {
} }
} catch (const SyntaxError& e) { } catch (const SyntaxError& e) {
if (e.type == ErrorType::EmptyInput)
continue;
print_error_position(input, e.pos); print_error_position(input, e.pos);
cout << BOLD RED "Syntax Error: " RESET << e.get_message() << endl << endl; cout << BOLD RED "Syntax Error: " RESET << e.get_message() << endl << endl;