From ee8ad0f1bb728915a8a7496d269cd70d78484a0d Mon Sep 17 00:00:00 2001 From: rexim Date: Sun, 14 Oct 2018 03:51:44 +0700 Subject: [PATCH] (#395) Make region print eval errors on stdout --- src/game/level/region.c | 3 +-- src/script/expr.c | 32 ++++++++++++++++---------------- src/script/expr.h | 9 +++++---- src/script/repl.c | 12 ++++++++---- src/ui/console.c | 4 +++- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/game/level/region.c b/src/game/level/region.c index a941d277..993b55c7 100644 --- a/src/game/level/region.c +++ b/src/game/level/region.c @@ -55,8 +55,7 @@ Region *create_region(Rect rect, const char *script_src) parse_result.expr); if (eval_result.is_error) { fprintf(stderr, "Evaluation error: "); - /* TODO(#395): eval error is not printed on stderr */ - print_expr_as_sexpr(eval_result.expr); + print_expr_as_sexpr(stderr, eval_result.expr); RETURN_LT(lt, NULL); } diff --git a/src/script/expr.c b/src/script/expr.c index 1ecec674..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: diff --git a/src/script/expr.h b/src/script/expr.h index 3f24c72b..25e03a5f 100644 --- a/src/script/expr.h +++ b/src/script/expr.h @@ -1,8 +1,9 @@ #ifndef EXPR_H_ #define EXPR_H_ -#include #include +#include +#include typedef struct Gc Gc; typedef struct Scope Scope; @@ -41,7 +42,7 @@ struct Expr cons_as_expr(struct Cons *cons); struct Expr void_expr(void); void destroy_expr(struct Expr expr); -void print_expr_as_sexpr(struct Expr expr); +void print_expr_as_sexpr(FILE *stream, struct Expr expr); int expr_as_sexpr(struct Expr expr, char *output, size_t n); // TODO(#337): EvalResult does not belong to expr unit @@ -86,7 +87,7 @@ struct Atom *create_string_atom(Gc *gc, const char *str, const char *str_end); struct Atom *create_symbol_atom(Gc *gc, const char *sym, const char *sym_end); struct Atom *create_native_atom(Gc *gc, NativeFunction fun, void *param); void destroy_atom(struct Atom *atom); -void print_atom_as_sexpr(struct Atom *atom); +void print_atom_as_sexpr(FILE *stream, struct Atom *atom); struct Cons { @@ -96,6 +97,6 @@ struct Cons struct Cons *create_cons(Gc *gc, struct Expr car, struct Expr cdr); void destroy_cons(struct Cons *cons); -void print_cons_as_sexpr(struct Cons *cons); +void print_cons_as_sexpr(FILE *stream, struct Cons *cons); #endif // EXPR_H_ diff --git a/src/script/repl.c b/src/script/repl.c index 9c3460ec..5f5e19cf 100644 --- a/src/script/repl.c +++ b/src/script/repl.c @@ -21,6 +21,7 @@ static struct EvalResult quit(void *param, Gc *gc, struct Scope *scope, struct E static void eval_line(Gc *gc, Scope *scope, const char *line) { + /* TODO: there is no way to disable REPL debug output */ const char *read_iter = line; while (*read_iter != 0) { printf("Before parse:\t"); @@ -43,15 +44,18 @@ static void eval_line(Gc *gc, Scope *scope, const char *line) gc_inspect(gc); printf("Scope:\t"); - print_expr_as_sexpr(scope->expr); + print_expr_as_sexpr(stdout, scope->expr); printf("\n"); if (eval_result.is_error) { - printf("Error:\t"); + fprintf(stderr, "Error:\t"); + print_expr_as_sexpr(stderr, eval_result.expr); + fprintf(stderr, "\n"); + continue; } - print_expr_as_sexpr(eval_result.expr); - printf("\n"); + print_expr_as_sexpr(stderr, eval_result.expr); + fprintf(stdout, "\n"); read_iter = next_token(parse_result.end).begin; } diff --git a/src/ui/console.c b/src/ui/console.c index 8faa1048..c98ee803 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -58,13 +58,15 @@ static struct EvalResult rect_apply_force(void *param, Gc *gc, struct Scope *sco assert(scope); assert(param); + /* TODO: rect_apply_force doesn't sanitize it's input */ + Level *level = (Level*) param; const char *rect_id = CAR(args).atom->str; struct Expr vector_force_expr = CAR(CDR(args)); const float force_x = (float) CAR(vector_force_expr).atom->num; const float force_y = (float) CDR(vector_force_expr).atom->num; - print_expr_as_sexpr(args); printf("\n"); + print_expr_as_sexpr(stdout, args); printf("\n"); Rigid_rect *rigid_rect = level_rigid_rect(level, rect_id); if (rigid_rect != NULL) { -- 2.44.0