klisp

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

commit 80f6c37599fc6090074e3fc0ee155390b4cc160e
parent b226936ee1069b7195c2720ac7c01bac5802fb5e
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 18 Nov 2011 15:29:06 -0300

Added reading from both string and bytevector ports (all input applicatives).

Diffstat:
Msrc/Makefile | 2+-
Msrc/ktoken.c | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 89 insertions(+), 17 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -280,7 +280,7 @@ ktable.o: ktable.c klisp.h kobject.h klimits.h klispconf.h kgc.h kstate.h \ kenvironment.h ksymbol.h kstring.h ktoken.o: ktoken.c ktoken.h kobject.h klimits.h klisp.h klispconf.h \ kstate.h kmem.h kinteger.h imath.h krational.h imrat.h kreal.h kpair.h \ - kgc.h kstring.h ksymbol.h kerror.h kport.h + kgc.h kstring.h ksymbol.h kerror.h kport.h kbytevector.h kwrite.o: kwrite.c kwrite.h kobject.h klimits.h klisp.h klispconf.h \ kstate.h ktoken.h kmem.h kinteger.h imath.h krational.h imrat.h kreal.h \ kpair.h kgc.h kstring.h ksymbol.h kerror.h ktable.h kport.h \ diff --git a/src/ktoken.c b/src/ktoken.c @@ -39,6 +39,7 @@ #include "kreal.h" #include "kpair.h" #include "kstring.h" +#include "kbytevector.h" #include "ksymbol.h" #include "kerror.h" #include "kport.h" @@ -162,6 +163,91 @@ void ktok_error_g(klisp_State *K, char *str, bool extra, TValue extra_value) /* ** Underlying stream interface & source code location tracking */ + +/* TODO/OPTIMIZE We should use buffering to shorten the + average code path to read each char */ +/* this reads one character from curr_port */ +int ktok_ggetc(klisp_State *K) +{ + /* XXX when full unicode is used (uint32_t) a different way should + be use to signal EOF */ + + TValue port = K->curr_port; + if (ttisfport(port)) { + /* fport */ + FILE *file = kfport_file(port); + int chi = getc(file); + if (chi == EOF) { + /* NOTE: eof doesn't change source code location info */ + if (ferror(file) != 0) { + /* clear error marker to allow retries later */ + clearerr(file); + /* TODO put error info on the error obj */ + ktok_error(K, "reading error"); + return 0; + } else { /* if (feof(file) != 0) */ + /* let the eof marker set */ + K->ktok_seen_eof = true; + return EOF; + } + } else + return chi; + } else { + /* mport */ + if (kport_is_binary(port)) { + /* bytevector port */ + if (kmport_off(port) >= kbytevector_size(kmport_buf(port))) { + K->ktok_seen_eof = true; + return EOF; + } + int chi = kbytevector_buf(kmport_buf(port))[kmport_off(port)]; + ++kmport_off(port); + return chi; + } else { + /* string port */ + if (kmport_off(port) >= kstring_size(kmport_buf(port))) { + K->ktok_seen_eof = true; + return EOF; + } + int chi = kstring_buf(kmport_buf(port))[kmport_off(port)]; + ++kmport_off(port); + return chi; + } + } +} + +/* this returns one character to curr_port */ +void ktok_gungetc(klisp_State *K, int chi) +{ + if (chi == EOF) + return; + + TValue port = K->curr_port; + if (ttisfport(port)) { + /* fport */ + FILE *file = kfport_file(port); + + if (ungetc(chi, file) == EOF) { + if (ferror(file) != 0) { + /* clear error marker to allow retries later */ + clearerr(file); + } + /* TODO put error info on the error obj */ + ktok_error(K, "reading error"); + return; + } + } else { + /* mport */ + if (kport_is_binary(port)) { + /* bytevector port */ + --kmport_off(port); + } else { + /* string port */ + --kmport_off(port); + } + } +} + int ktok_peekc_getc(klisp_State *K, bool peekp) { /* WORKAROUND: for stdin line buffering & reading of EOF, this flag @@ -171,24 +257,10 @@ int ktok_peekc_getc(klisp_State *K, bool peekp) if (K->ktok_seen_eof) return EOF; - int chi = getc(K->curr_in); - if (chi == EOF) { - /* NOTE: eof doesn't change source code location info */ - if (ferror(K->curr_in) != 0) { - /* clear error marker to allow retries later */ - clearerr(K->curr_in); -/* TODO put error info on the error obj */ - ktok_error(K, "reading error"); - return 0; - } else { /* if (feof(K->curr_in) != 0) */ - /* let the eof marker set */ - K->ktok_seen_eof = true; - return EOF; - } - } + int chi = ktok_ggetc(K); if (peekp) { - ungetc(chi, K->curr_in); + ktok_gungetc(K, chi); return chi; }