]> git.lizzy.rs Git - nothing.git/commitdiff
(#395) Make region print eval errors on stdout
authorrexim <reximkut@gmail.com>
Sat, 13 Oct 2018 20:51:44 +0000 (03:51 +0700)
committerrexim <reximkut@gmail.com>
Sat, 13 Oct 2018 20:51:44 +0000 (03:51 +0700)
src/game/level/region.c
src/script/expr.c
src/script/expr.h
src/script/repl.c
src/ui/console.c

index a941d277028a9e3bc1a2692260b8092fde4f5265..993b55c7fdf8c98b2745f5eb351fc7b1f616f39b 100644 (file)
@@ -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);
         }
 
index 1ecec674efccfc9a362b050dee8a5d4fd1ba1d82..bf25ba17f8d2cb5340f655f51cc9d714154cb0f9 100644 (file)
@@ -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("<native>");
+        fprintf(stream, "<native>");
         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:
index 3f24c72b6fa02123c1252e7aaef315665fae1291..25e03a5fc1d6f14b74d83ab1125b9969e2045072 100644 (file)
@@ -1,8 +1,9 @@
 #ifndef EXPR_H_
 #define EXPR_H_
 
-#include <stdlib.h>
 #include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 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_
index 9c3460ec308f3dbb385aff9b65d805ac443d15a0..5f5e19cf303ce629ddca9224a257bd20952a92c3 100644 (file)
@@ -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;
     }
index 8faa10482b815a93e3cd61601a3dcc0e37a0f639..c98ee8032c4ecf723e2600154527ca6a9796d4c6 100644 (file)
@@ -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) {