Mercurial > lbo > hg > ylisp
view src/repl.c @ 153:775a941b036c
repl: Implement basic REPL.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 03 Sep 2019 14:06:42 +0200 |
parents | |
children | cfe8ddaa770c |
line wrap: on
line source
#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; }