changeset 163:2448ebe4a586

built-ins: Allow setting separate output stream.
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 03 Sep 2019 17:16:49 +0200
parents f6c1d15232ee
children f91caf9fe066
files src/built-ins.c src/built-ins.h
diffstat 2 files changed, 22 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/built-ins.c	Tue Sep 03 17:16:05 2019 +0200
+++ b/src/built-ins.c	Tue Sep 03 17:16:49 2019 +0200
@@ -6,6 +6,10 @@
 
 // TODO: Write standard library!
 
+static FILE* output_handle = NULL;
+
+void ybuiltin_set_output(FILE* out) { output_handle = out; }
+
 /**
  * @brief Type of a built-in function called during execution.
  *
@@ -31,7 +35,7 @@
 };
 
 static const char* YBUILTIN_ENUM_STR[] = {
-   "BUILTIN:UNDEF", "BUILTIN:FOR", "BUILTIN:LET",  "BUILTIN:DEFN",
+    "BUILTIN:UNDEF", "BUILTIN:FOR", "BUILTIN:LET",  "BUILTIN:DEFN",
     "BUILTIN:+",     "BUILTIN:-",   "BUILTIN:*",    "BUILTIN:/",
     "BUILTIN:IF",    "BUILTIN:SEQ", "BUILTIN:EQ",   "BUILTIN:LT",
     "BUILTIN:CAR",   "BUILTIN:CDR", "BUILTIN:PUSH",
@@ -98,7 +102,7 @@
         yexpr_t exc = ybuiltin_type_error(                            \
             YBUILTIN_##BUILTINTYPE,                                   \
             ystr_new("type mismatch for " #BUILTINTYPE "; want " want \
-                     " received something else"),                      \
+                     " received something else"),                     \
             &invalid_expr);                                           \
         return exc;                                                   \
     }
@@ -335,16 +339,18 @@
 yexpr_t ybuiltin_fn_print(yeval_state_t* state) {
 #define _pattern "(print expr [expr...])"
     yexpr_t print;
+    FILE* out = output_handle == NULL ? stdout : output_handle;
 
     if (!yvec_pop(&state->call_stack, &print)) NOTENOUGHFAIL(PRINT);
     if (print.typ != YEXPR_LIST) BADEXPRFAIL(PRINT, print);
     if (print.value.list.len < 1) BADEXPRFAIL(PRINT, print);
 
     for (size_t i = 1; i < print.value.list.len; i++) {
-        yexpr_t evald = yeval(state, YVEC_AT(&print.value.list, i, yexpr_t), false);
+        yexpr_t evald =
+            yeval(state, YVEC_AT(&print.value.list, i, yexpr_t), false);
         ystr_t repr = yexpr_debug_str(&evald);
-        fputs(ystr_str(&repr), stdout);
-        fputc(' ', stdout);
+        fputs(ystr_str(&repr), out);
+        if (i != print.value.list.len - (size_t)1) fputc(' ', out);
         yexpr_destroy(&evald);
         ystr_destroy(&repr);
     }
@@ -383,12 +389,10 @@
  *
  * TODO: write built-ins.
  */
-static const ybuiltin_fn YBUILTIN_FNS[] = {ybuiltin_fn_undef, ybuiltin_fn_for,
-                                           ybuiltin_fn_let,   NULL,
-                                           ybuiltin_fn_plus,  ybuiltin_fn_minus,
-                                           ybuiltin_fn_times, NULL,
-                                           ybuiltin_fn_if,    ybuiltin_fn_print,
-                                           ybuiltin_fn_eq};
+static const ybuiltin_fn YBUILTIN_FNS[] = {
+    ybuiltin_fn_undef, ybuiltin_fn_for,   ybuiltin_fn_let,   NULL,
+    ybuiltin_fn_plus,  ybuiltin_fn_minus, ybuiltin_fn_times, NULL,
+    ybuiltin_fn_if,    ybuiltin_fn_print, ybuiltin_fn_eq};
 
 const char* ybuiltin_name(YBUILTIN_TYPE t) {
     assert(t * sizeof(const char*) < sizeof(YBUILTIN_ENUM_STR));
--- a/src/built-ins.h	Tue Sep 03 17:16:05 2019 +0200
+++ b/src/built-ins.h	Tue Sep 03 17:16:49 2019 +0200
@@ -29,6 +29,13 @@
 yexpr_t ybuiltin_run(YBUILTIN_TYPE t, yeval_state_t* state);
 
 /**
+ * @brief Set standard output for output built-ins.
+ *
+ * TODO: Figure out a more general way for I/O.
+ */
+void ybuiltin_set_output(FILE* out);
+
+/**
  * @}
  */