From 11864191841cc1d5f8bf10c21d1c45a5b5380cf0 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Wed, 26 Sep 2018 12:47:43 -0400 Subject: [PATCH] Added a shell when no arguments are given to sloth. Now has a new dependencies on editline library. --- .gitignore | 1 + Makefile | 8 +++--- src/main.c | 21 +++++++++++---- src/shell.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/shell.h | 7 +++++ 5 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 src/shell.c create mode 100644 src/shell.h diff --git a/.gitignore b/.gitignore index b604e04..a557fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o +src/shell.o sloth vgcore* .vscode diff --git a/Makefile b/Makefile index dc5ea91..0b948a7 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -sloth: src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o - gcc src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o -o sloth +sloth: src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o + gcc src/main.c src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o -ledit -o sloth src/parser/lex.yy.o: src/parser/lex.yy.c src/parser/parser.tab.h gcc -c src/parser/lex.yy.c -o src/parser/lex.yy.o src/parser/parser.tab.o: src/parser/parser.tab.c @@ -20,5 +20,7 @@ src/operations/operators.o: src/operations/operators.h src/operations/operators gcc -c src/operations/operators.c -o src/operations/operators.o src/operations/node.o: src/operations/node.h src/operations/node.c gcc -c src/operations/node.c -o src/operations/node.o +src/shell.o: src/shell.h src/shell.c + gcc -c src/shell.c -o src/shell.o clean: - rm src/parser/lex.yy.c src/parser/parser.tab.c src/parser/parser.tab.h src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o sloth + rm src/parser/lex.yy.c src/parser/parser.tab.c src/parser/parser.tab.h src/parser/lex.yy.o src/parser/parser.tab.o src/variables/environment.o src/variables/variable.o src/variables/value.o src/operations/node.o src/operations/operators.o src/shell.o sloth diff --git a/src/main.c b/src/main.c index 50b8f5d..20eda67 100644 --- a/src/main.c +++ b/src/main.c @@ -1,19 +1,31 @@ #include #include #include "sloth.h" +#include "shell.h" + +void interpret_file(char* fileName); /* the result variable */ struct Node* result; int main(int argc, char* argv[]) { - if (argc != 2) { - printf("Incorrect number of arguments passed. Expected %d, got %d.\n", 1, argc - 1); + if (argc == 1) { + start_shell(); + } else if (argc == 2) { + interpret_file(argv[1]); + } else { + printf("Incorrect number of arguments passed. Expected %d or %d, got %d.\n", 0, 1, argc - 1); printf("Usage: lexer [program_name].sl\n"); exit(-1); } + +} + + +void interpret_file(char* fileName) { /* save stdin */ FILE* orig_stdin = stdin; - stdin = fopen(argv[1], "r"); + stdin = fopen(fileName, "r"); yyparse( ); @@ -27,5 +39,4 @@ int main(int argc, char* argv[]) { eval_statement(result, env); delete_environment(env); delete_tree(result); - return 0; -} +} \ No newline at end of file diff --git a/src/shell.c b/src/shell.c new file mode 100644 index 0000000..775c7d8 --- /dev/null +++ b/src/shell.c @@ -0,0 +1,75 @@ +#include +#include +#include "shell.h" +#include "variables/environment.h" +#include "operations/node.h" + + +// For keeping track of command history +#ifdef _WIN32 // If we're compiling on windows +#include +static char buffer[2048]; +// Fake readline function +char* readline(char* prompt) { + fputs(prompt, stdout); + fgets(buffer, 2048, stdin); + char* cpy = malloc(strlen(buffer) + 1); + strcpy(cpy, buffer); + cpy[strlen(cpy) - 1] = '\0'; + return cpy; +} +void add_history(char* unused) {} + +#else // Otherwise we'll just use the handy readline library +#include +#endif + + +struct Node* result; + +FILE* stringToFile(char* str) { // Creates a temporary file with the given string as its contents + int i = 0; + + FILE* tmp = tmpfile(); + if (tmp == NULL) { + fprintf(stderr, "Unable to create temp file"); + return NULL; + } + + while (str[i] != '\0') { + fputc(str[i], tmp); i++; + } + + // Set the file pointer to the beginning + rewind(tmp); + return tmp; +} + +void start_shell() { + printf("Welcome to SLOTH Version 0.0.1\n"); + printf("Press CTRL+C to Exit\n"); + + struct Environment* env = create_environment(); + while (1) { + // Read line from user and input it into the history + char* input = readline("sloth> "); + add_history(input); + // If user enters "exit" quit the loop + if (strcmp(input, "exit") == 0) { break; } + FILE* inputAsFile = stringToFile(input); + /* save stdin */ + FILE* orig_stdin = stdin; + stdin = inputAsFile; + + yyparse( ); + + /* restore stdin */ + fclose(stdin); + stdin = orig_stdin; + + eval_statement(result, env); + } + + delete_environment(env); + delete_tree(result); +} \ No newline at end of file diff --git a/src/shell.h b/src/shell.h new file mode 100644 index 0000000..9a51151 --- /dev/null +++ b/src/shell.h @@ -0,0 +1,7 @@ +#ifndef SHELL_H +#define SHELL_H + +FILE* stringToFile(char* str); +void start_shell(); + +#endif