From: rexim Date: Sun, 16 Dec 2018 17:47:22 +0000 (+0700) Subject: (#542) Implement format_list X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=427aecf272d941fb59444bbbd2564bf1f1973563;p=nothing.git (#542) Implement format_list --- diff --git a/src/ebisp/interpreter.c b/src/ebisp/interpreter.c index a1dce0f3..8b7964c1 100644 --- a/src/ebisp/interpreter.c +++ b/src/ebisp/interpreter.c @@ -518,4 +518,54 @@ match_list(struct Gc *gc, const char *format, struct Expr xs, ...) return eval_success(NIL(gc)); } -/* TODO(#542): format_list(). Similar to match_list() but for constructing list */ +static struct Expr +format_list_rec(Gc *gc, const char *format, va_list args) +{ + assert(gc); + assert(format); + + if (*format == 0) { + return NIL(gc); + } + + switch (*format) { + case 'd': { + long int p = va_arg(args, long int); + return CONS(gc, NUMBER(gc, p), + format_list_rec(gc, format + 1, args)); + } + + case 's': { + const char* p = va_arg(args, const char*); + return CONS(gc, STRING(gc, p), + format_list_rec(gc, format + 1, args)); + } + + case 'q': { + const char* p = va_arg(args, const char*); + return CONS(gc, SYMBOL(gc, p), + format_list_rec(gc, format + 1, args)); + } + + case 'e': { + struct Expr p = va_arg(args, struct Expr); + return CONS(gc, p, format_list_rec(gc, format + 1, args)); + } + + default: { + fprintf(stderr, "Wrong format parameter: %c\n", *format); + assert(0); + } + } +} + +struct Expr +format_list(Gc *gc, const char *format, ...) +{ + va_list args; + va_start(args, format); + struct Expr result = format_list_rec(gc, format, args); + va_end(args); + + return result; +} diff --git a/src/ebisp/interpreter.h b/src/ebisp/interpreter.h index fb3153ec..67572bb1 100644 --- a/src/ebisp/interpreter.h +++ b/src/ebisp/interpreter.h @@ -29,4 +29,7 @@ void load_std_library(Gc *gc, struct Scope *scope); struct EvalResult match_list(struct Gc *gc, const char *format, struct Expr args, ...); +struct Expr +format_list(Gc *gc, const char *format, ...); + #endif // INTERPRETER_H_