X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Fexpr.c;h=bf25ba17f8d2cb5340f655f51cc9d714154cb0f9;hb=ee8ad0f1bb728915a8a7496d269cd70d78484a0d;hp=b97351ccf55496d32b9e773030aa98e374ffc504;hpb=278c49c1014fcd6f0b69fe20091bb1234e2db6b5;p=nothing.git diff --git a/src/script/expr.c b/src/script/expr.c index b97351cc..bf25ba17 100644 --- a/src/script/expr.c +++ b/src/script/expr.c @@ -38,62 +38,62 @@ struct Expr void_expr(void) return expr; } -void print_atom_as_sexpr(struct Atom *atom) +void print_atom_as_sexpr(FILE *stream, struct Atom *atom) { assert(atom); switch (atom->type) { case ATOM_SYMBOL: - printf("%s", atom->sym); + fprintf(stream, "%s", atom->sym); break; case ATOM_NUMBER: - printf("%ld", atom->num); + fprintf(stream, "%ld", atom->num); break; case ATOM_STRING: - printf("\"%s\"", atom->str); + fprintf(stream, "\"%s\"", atom->str); break; case ATOM_NATIVE: - printf(""); + fprintf(stream, ""); break; } } -void print_cons_as_sexpr(struct Cons *head) +void print_cons_as_sexpr(FILE *stream, struct Cons *head) { assert(head); struct Cons *cons = head; - printf("("); - print_expr_as_sexpr(cons->car); + fprintf(stream, "("); + print_expr_as_sexpr(stream, cons->car); while (cons->cdr.type == EXPR_CONS) { cons = cons->cdr.cons; - printf(" "); - print_expr_as_sexpr(cons->car); + fprintf(stream, " "); + print_expr_as_sexpr(stream, cons->car); } if (cons->cdr.atom->type != ATOM_SYMBOL || strcmp("nil", cons->cdr.atom->sym) != 0) { - printf(" . "); - print_expr_as_sexpr(cons->cdr); + fprintf(stream, " . "); + print_expr_as_sexpr(stream, cons->cdr); } - printf(")"); + fprintf(stream, ")"); } -void print_expr_as_sexpr(struct Expr expr) +void print_expr_as_sexpr(FILE *stream, struct Expr expr) { switch (expr.type) { case EXPR_ATOM: - print_atom_as_sexpr(expr.atom); + print_atom_as_sexpr(stream, expr.atom); break; case EXPR_CONS: - print_cons_as_sexpr(expr.cons); + print_cons_as_sexpr(stream, expr.cons); break; case EXPR_VOID: @@ -286,15 +286,17 @@ static int atom_as_sexpr(struct Atom *atom, char *output, size_t n) return 0; } -static int cons_as_sexpr(struct Cons *cons, char *output, size_t n) +static int cons_as_sexpr(struct Cons *head, char *output, size_t n) { - assert(cons); + assert(head); assert(output); /* TODO(#378): cons_as_sexpr does not handle encoding errors of snprintf */ - /* TODO(#379): cons_as_sexpr does not support lists */ + + struct Cons *cons = head; int m = (int) n; + int c = snprintf(output, n, "("); if (m - c <= c) { return c; @@ -305,14 +307,32 @@ static int cons_as_sexpr(struct Cons *cons, char *output, size_t n) return c; } - c += snprintf(output + c, (size_t) (m - c), " . "); - if (m - c <= 0) { - return c; + while (cons->cdr.type == EXPR_CONS) { + cons = cons->cdr.cons; + + c += snprintf(output + c, (size_t) (m - c), " "); + if (m - c <= 0) { + return c; + } + + c += expr_as_sexpr(cons->car, output + c, (size_t) (m - c)); + if (m - c <= 0) { + return c; + } } - c += expr_as_sexpr(cons->cdr, output + c, (size_t) (m - c)); - if (m - c <= 0) { - return c; + if (cons->cdr.atom->type != ATOM_SYMBOL || + strcmp("nil", cons->cdr.atom->sym) != 0) { + + c += snprintf(output + c, (size_t) (m - c), " . "); + if (m - c <= 0) { + return c; + } + + c += expr_as_sexpr(cons->cdr, output + c, (size_t) (m - c)); + if (m - c <= 0) { + return c; + } } c += snprintf(output + c, (size_t) (m - c), ")");