changeset 153:775a941b036c

repl: Implement basic REPL.
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 03 Sep 2019 14:06:42 +0200
parents 88fec15abdbc
children aa6847f62505
files src/CMakeLists.txt src/repl.c
diffstat 2 files changed, 66 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/CMakeLists.txt	Tue Sep 03 14:06:29 2019 +0200
+++ b/src/CMakeLists.txt	Tue Sep 03 14:06:42 2019 +0200
@@ -68,3 +68,8 @@
 TARGET_LINK_LIBRARIES(value_test core)
 YADD_TEST(value_test)
 
+##
+
+# REPL
+ADD_EXECUTABLE(repl repl.c)
+TARGET_LINK_LIBRARIES(repl core frontend)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/repl.c	Tue Sep 03 14:06:42 2019 +0200
@@ -0,0 +1,61 @@
+#include <stdio.h>
+
+#include "eval.h"
+#include "parse.h"
+#include "preprocess.h"
+
+int repl(void) {
+#define bufsize 512
+    char buf[bufsize];
+
+    yeval_state_t state;
+    state.call_stack = YVEC_NEW(NULL, 16, yexpr_t);
+
+    while (1) {
+        ystr_t input = ystr_new(NULL), output = ystr_new(NULL),
+               error = ystr_new(NULL);
+        yexpr_t stmt = yexpr_new(), result;
+
+        fprintf(stdout, "() >> ");
+
+        if (NULL == fgets(buf, bufsize, stdin)) break;
+        input = ystr_new(buf);
+        if (0 == ystr_cmp_str(&input, "quit\n")) {
+            return 0;
+        }
+        if (!yparse_str(&input, &stmt, &error)) {
+            fprintf(stderr, "parse error: %s\n", ystr_str(&input));
+            goto cleanup_continue;
+        }
+        if (YEXPR_LIST != stmt.typ) {
+            fprintf(stderr, "bug: expression should be list!\n");
+            goto cleanup_continue;
+        }
+        ypreprocess(&stmt);
+        result = yeval_list_return_last(&state, &stmt.value.list, 0);
+
+        if (result.typ != YEXPR_UNDEF) {
+            output = yexpr_debug_str(&result);
+            fprintf(stdout, "%s\n", ystr_str(&output));
+        } else {
+            fputc('\n', stdout);
+        }
+
+    cleanup_continue:
+        ystr_destroy(&input);
+        ystr_destroy(&error);
+        ystr_destroy(&output);
+        yexpr_destroy(&result);
+        // stmt is not destroyed, values in it may be used later
+    }
+
+    yvec_destroy(&state.call_stack);
+
+    return 0;
+#undef bufsize
+}
+
+int main(void) {
+    repl();
+    return 0;
+}