klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit dfc183e18788e04d2e9b0a34988badb4e8d087f2
parent b63dc958796904765e512a928e06ff0282e4f401
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 18 Nov 2011 16:38:35 -0300

Some refactoring in kwrite in preparation for mem ports.

Diffstat:
Msrc/kgports.c | 6+-----
Msrc/kread.c | 7+------
Msrc/kstate.c | 2--
Msrc/kstate.h | 4+---
Msrc/kwrite.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msrc/kwrite.h | 1+
6 files changed, 73 insertions(+), 57 deletions(-)

diff --git a/src/kgports.c b/src/kgports.c @@ -801,11 +801,7 @@ void flush(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) return; } - if (ttisfport(port)) { /* only necessary for file ports */ - FILE *file = kfport_file(port); - klisp_assert(file); - UNUSED(fflush(file)); /* TEMP for now don't signal errors on flush */ - } + kwrite_flush_port(K, port); kapply_cc(K, KINERT); } diff --git a/src/kread.c b/src/kread.c @@ -548,7 +548,7 @@ TValue kread(klisp_State *K) TValue obj; klisp_assert(ttisnil(K->shared_dict)); - /* TEMP: workaround repl problem with eofs */ + /* WORKAROUND: for repl problem with eofs */ K->ktok_seen_eof = false; obj = kread_fsm(K); @@ -563,7 +563,6 @@ TValue kread(klisp_State *K) TValue kread_from_port(klisp_State *K, TValue port, bool mut) { K->curr_port = port; - K->curr_in = kfport_file(port); K->read_mconsp = mut; ktok_set_source_info(K, kport_filename(port), @@ -583,7 +582,6 @@ TValue kread_peek_char_from_port(klisp_State *K, TValue port, bool peek) K->ktok_seen_eof = false; K->curr_port = port; - K->curr_in = kfport_file(port); int ch; if (peek) { ch = ktok_peekc(K); @@ -602,9 +600,7 @@ TValue kread_peek_u8_from_port(klisp_State *K, TValue port, bool peek) /* Reset the EOF flag in the tokenizer. The flag is shared, by operations on all ports. */ K->ktok_seen_eof = false; - K->curr_port = port; - K->curr_in = kfport_file(port); int32_t u8; if (peek) { u8 = ktok_peekc(K); @@ -626,7 +622,6 @@ void kread_ignore_whitespace_and_comments_from_port(klisp_State *K, TValue port) { K->curr_port = port; - K->curr_in = kfport_file(port); /* source code info isn't important because it will be reset later */ ktok_ignore_whitespace_and_comments(K); } diff --git a/src/kstate.c b/src/kstate.c @@ -85,8 +85,6 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { K->ud = ud; /* current input and output */ - K->curr_in = NULL; /* set on each call to read */ - K->curr_out = NULL; /* set on each call to write */ K->curr_port = KINERT; /* set on each call to read/write */ /* input / output for dynamic keys */ diff --git a/src/kstate.h b/src/kstate.h @@ -99,10 +99,8 @@ struct klisp_State { /* TEMP: error handling */ jmp_buf error_jb; - /* input and output files in use (for read & write) */ + /* input/output port in use (for read & write) */ TValue curr_port; /* save the port to update source info on errors */ - FILE *curr_in; - FILE *curr_out; /* for current-input-port, current-output-port, current-error-port */ TValue kd_in_port_key; diff --git a/src/kwrite.c b/src/kwrite.c @@ -6,6 +6,7 @@ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <assert.h> #include <inttypes.h> #include <string.h> @@ -34,27 +35,39 @@ #define get_data(ks_) (ks_sget(ks_)) #define data_is_empty(ks_) (ks_sisempty(ks_)) -/* macro for printing */ -#define kw_printf(ks_, ...) \ - if (fprintf((ks_)->curr_out, __VA_ARGS__) < 0) { \ - clearerr((ks_)->curr_out); /* clear error for next time */ \ - kwrite_error(ks_, "error writing"); \ - } - -#define kw_flush(ks_) \ - if (fflush((ks_)->curr_out) == EOF) { \ - clearerr((ks_)->curr_out); /* clear error for next time */ \ - kwrite_error(ks_, "error writing"); \ - } - void kwrite_error(klisp_State *K, char *msg) { /* all cleaning is done in throw (stacks, shared_dict, rooted objs) */ - klispE_throw_simple(K, msg); } +void kw_printf(klisp_State *K, const char *format, ...) +{ + va_list argp; + TValue port = K->curr_port; + + if (ttisfport(port)) { + FILE *file = kfport_file(port); + va_start(argp, format); + int ret = vfprintf(file, format, argp); + va_end(argp); + + if (ret < 0) { + clearerr(file); /* clear error for next time */ + kwrite_error(K, "error writing"); + return; + } + } else { + /* vsnprintf(buf, size, format, argp); */ + kwrite_error(K, "mem ports not yet supported"); + return; + } +} + +void kw_flush(klisp_State *K) { kwrite_flush_port(K, K->curr_port); } + + /* TODO: check for return codes and throw error if necessary */ #define KDEFAULT_NUMBER_RADIX 10 void kw_print_bigint(klisp_State *K, TValue bigint) @@ -578,12 +591,6 @@ void kwrite(klisp_State *K, TValue obj) krooted_tvs_pop(K); } -void kwrite_newline(klisp_State *K) -{ - kw_printf(K, "\n"); - kw_flush(K); -} - /* ** Interface */ @@ -591,42 +598,63 @@ void kwrite_display_to_port(klisp_State *K, TValue port, TValue obj, bool displayp) { K->curr_port = port; - K->curr_out = kfport_file(port); K->write_displayp = displayp; kwrite(K, obj); } void kwrite_newline_to_port(klisp_State *K, TValue port) { + K->curr_port = port; /* this isn't needed but all other + i/o functions set it */ kwrite_char_to_port(K, port, ch2tv('\n')); } void kwrite_char_to_port(klisp_State *K, TValue port, TValue ch) { - K->curr_port = port; - K->curr_out = kfport_file(port); - int res = fputc(chvalue(ch), K->curr_out); - /* implicit flush, MAYBE add flush call */ - if (res != EOF) - res = fflush(K->curr_out); - - if (res == EOF) { - clearerr(K->curr_out); /* clear error for next time */ - kwrite_error(K, "error writing char"); + K->curr_port = port; /* this isn't needed but all other + i/o functions set it */ + if (ttisfport(port)) { + FILE *file = kfport_file(port); + int res = fputc(chvalue(ch), file); + + if (res == EOF) { + clearerr(file); /* clear error for next time */ + kwrite_error(K, "error writing char"); + } + } else { + kwrite_error(K, "mem ports not yet supported"); + return; } } void kwrite_u8_to_port(klisp_State *K, TValue port, TValue u8) { - K->curr_port = port; - K->curr_out = kfport_file(port); - int res = fputc(ivalue(u8), K->curr_out); - /* implicit flush, MAYBE add flush call */ - if (res != EOF) - res = fflush(K->curr_out); - - if (res == EOF) { - clearerr(K->curr_out); /* clear error for next time */ - kwrite_error(K, "error writing u8"); + K->curr_port = port; /* this isn't needed but all other + i/o functions set it */ + if (ttisfport(port)) { + FILE *file = kfport_file(port); + int res = fputc(ivalue(u8), file); + + if (res == EOF) { + clearerr(file); /* clear error for next time */ + kwrite_error(K, "error writing u8"); + } + } else { + kwrite_error(K, "mem ports not yet supported"); + return; + } +} + +void kwrite_flush_port(klisp_State *K, TValue port) +{ + K->curr_port = port; /* this isn't needed but all other + i/o functions set it */ + if (ttisfport(port)) { /* only necessary for file ports */ + FILE *file = kfport_file(port); + klisp_assert(file); + if ((fflush(file)) == EOF) { + clearerr(file); /* clear error for next time */ + kwrite_error(K, "error writing"); + } } } diff --git a/src/kwrite.h b/src/kwrite.h @@ -18,6 +18,7 @@ void kwrite_display_to_port(klisp_State *K, TValue port, TValue obj, void kwrite_newline_to_port(klisp_State *K, TValue port); void kwrite_char_to_port(klisp_State *K, TValue port, TValue ch); void kwrite_u8_to_port(klisp_State *K, TValue port, TValue u8); +void kwrite_flush_port(klisp_State *K, TValue port); #endif