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;
}