klisp

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

commit 1fd77306e1272028f751d976d666cf682e43e9dd
parent 317177e992151c6ba0e5ce27ad86cf019ed1ea2f
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Thu, 17 Mar 2011 16:32:22 -0300

Added write and read to the ground environment. BUG: the check for [EOF] of the repl is after eval instead of after read so when EOF is evaluated in the repl the repl exits.

Diffstat:
Msrc/Makefile | 2+-
Msrc/kgports.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kgports.h | 6++++++
Msrc/kground.c | 4++--
Msrc/kread.c | 15++++++---------
Msrc/krepl.c | 8++++++++
Msrc/ktoken.c | 11++++++++++-
Msrc/ktoken.h | 4++++
8 files changed, 90 insertions(+), 13 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -123,4 +123,4 @@ kgks_vars.o: kgks_vars.c kgks_vars.h kghelpers.h kstate.h klisp.h \ kpair.h kenvironment.h kgports.o: kgports.c kgports.h kghelpers.h kstate.h klisp.h \ kobject.h kerror.h kapplicative.h koperative.h kcontinuation.h \ - kport.h ksymbol.h + kport.h ksymbol.h kread.h kwrite.h diff --git a/src/kgports.c b/src/kgports.c @@ -18,6 +18,8 @@ #include "kcontinuation.h" #include "kerror.h" #include "ksymbol.h" +#include "kread.h" +#include "kwrite.h" #include "kghelpers.h" #include "kgports.h" @@ -67,6 +69,57 @@ void close_file(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) } } +/* 15.1.7 read */ +/* TEMP: the port parameter is not optional yet */ +void read(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + + bind_1tp(K, "read", ptree, "port", ttisport, port); + + if (!kport_is_input(port)) { + klispE_throw(K, "read: the port should be an input port"); + return; + } else if (kport_is_closed(port)) { + klispE_throw(K, "read: the port is already closed"); + return; + } + + /* TEMP: for now set this by hand */ + K->curr_in = tv2port(port)->file; + ktok_reset_source_info(K); /* this should be saved in the port + and restored before the call to + read and saved after it */ + TValue obj = kread(K); /* this may throw an error, that's ok */ + kapply_cc(K, obj); +} + +/* 15.1.8 write */ +/* TEMP: the port parameter is not optional yet */ +void write(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + + bind_2tp(K, "write", ptree, "any", anytype, obj, + "port", ttisport, port); + + if (!kport_is_output(port)) { + klispE_throw(K, "write: the port should be an output port"); + return; + } else if (kport_is_closed(port)) { + klispE_throw(K, "write: the port is already closed"); + return; + } + + /* TEMP: for now set this by hand */ + K->curr_out = tv2port(port)->file; + + kwrite(K, obj); + kapply_cc(K, KINERT); +} + /* 15.2.1 call-with-input-file, call-with-output-file */ /* TODO */ diff --git a/src/kgports.h b/src/kgports.h @@ -36,6 +36,12 @@ void open_file(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); /* 15.1.6 close-input-file, close-output-file */ void close_file(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); +/* 15.1.7 read */ +void read(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); + +/* 15.1.8 write */ +void write(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); + /* 15.2.1 call-with-input-file, call-with-output-file */ /* TODO */ diff --git a/src/kground.c b/src/kground.c @@ -513,10 +513,10 @@ void kinit_ground_env(klisp_State *K) b2tv(true)); /* 15.1.7 read */ - /* TODO */ + add_applicative(K, ground_env, "read", read, 0); /* 15.1.8 write */ - /* TODO */ + add_applicative(K, ground_env, "write", write, 0); /* ** 15.2 Library features diff --git a/src/kread.c b/src/kread.c @@ -65,8 +65,10 @@ typedef enum { */ void kread_error(klisp_State *K, char *str) { - /* clear the stack */ + /* clear up before throwing */ + ks_tbclear(K); ks_sclear(K); + clear_shared_dict(K); klispE_throw(K, str); } @@ -74,12 +76,8 @@ void kread_error(klisp_State *K, char *str) ** Shared Reference Management (srfi-38) */ -/* This is called after kread to clear the shared alist */ -void clear_shared_dict(klisp_State *K) -{ - K->shared_dict = KNIL; -} - +/* clear_shared_dict is defined in ktoken to allow cleaning up before errors */ +/* It is called after kread to clear the shared alist */ TValue try_shared_ref(klisp_State *K, TValue ref_token) { /* TEMP: for now, only allow fixints in shared tokens */ @@ -466,8 +464,7 @@ TValue kread(klisp_State *K) { TValue obj; - /* TEMP: for now assume we are in the repl: reset source info */ - ktok_reset_source_info(K); + assert(ttisnil(K->shared_dict)); obj = kread_fsm(K); diff --git a/src/krepl.c b/src/krepl.c @@ -38,6 +38,11 @@ void read_fn(klisp_State *K, TValue *xparams, TValue obj) /* show prompt */ fprintf(stdout, "klisp> "); + + /* TEMP: for now set this by hand */ + K->curr_in = stdin; + ktok_reset_source_info(K); + obj = kread(K); kapply_cc(K,obj); } @@ -78,6 +83,9 @@ void loop_fn(klisp_State *K, TValue *xparams, TValue obj) /* this will in turn call main_cont */ kapply_cc(K, obj); } else { + /* TEMP: for now set this by hand */ + K->curr_out = stdout; + kwrite(K, obj); knewline(K); TValue denv = xparams[0]; diff --git a/src/ktoken.c b/src/ktoken.c @@ -218,10 +218,18 @@ TValue ktok_get_source_info(klisp_State *K) /* ** Error management */ + +void clear_shared_dict(klisp_State *K) +{ + K->shared_dict = KNIL; +} + void ktok_error(klisp_State *K, char *str) { - /* clear the buffer before throwing an error */ + /* clear up before throwing */ ks_tbclear(K); + ks_sclear(K); + clear_shared_dict(K); klispE_throw(K, str); } @@ -623,3 +631,4 @@ TValue ktok_read_identifier(klisp_State *K) return new_sym; } + diff --git a/src/ktoken.h b/src/ktoken.h @@ -20,4 +20,8 @@ TValue ktok_read_token(klisp_State *K); void ktok_reset_source_info(klisp_State *K); TValue ktok_get_source_info(klisp_State *K); +/* This is needed here to allow cleanup of shared dict from tokenizer */ +void clear_shared_dict(klisp_State *K); + + #endif