Mercurial > lbo > hg > ylisp
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; +}