klisp

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

commit 0b42ae61dc42512bddaadd57bd67d4539090aabc
parent 025be6b4696f25c850721116c1931dcb83a656a5
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat,  9 Apr 2011 13:53:46 -0300

Added implementation restriction to the size of the shared token number (fixint only). Reworded the README a little.

Diffstat:
MREADME | 11+++++++----
Msrc/kground.c | 2+-
Msrc/kread.c | 6+++---
Msrc/ktoken.c | 45+++++++++++++++++++++++++++------------------
Msrc/ktoken.h | 4++++
5 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/README b/README @@ -27,10 +27,13 @@ README for klisp 0.1 * Installation ------------ klisp is implemented in C99, with some gcc extensions for packing - and alignment. It was developed and tested in x86 under Linux. In - time it will be written so as to be compiled under many different - platforms, but right now the author's efforts are directed towards - implementing functionality. + and alignment. It was developed and tested in x86 under Linux. It + should compile fine under other Operating Systems using gcc + (MinGW in Windows also works). As time goes by, platform specific + code will have to be added (i.e. for char-ready?). Effort will be + directed to minimize the ammount of platform specific code, and + testing will be conducted at least on Linux and Windows (the systems + I have access to at the moment). * Origin ------ diff --git a/src/kground.c b/src/kground.c @@ -661,7 +661,7 @@ void kinit_ground_env(klisp_State *K) /* TEMP: for now only accept two arguments */ add_applicative(K, ground_env, "*", ktimes, 0); - /* 12.5.6 * */ + /* 12.5.6 - */ /* TEMP: for now only accept two arguments */ add_applicative(K, ground_env, "-", kminus, 0); diff --git a/src/kread.c b/src/kread.c @@ -80,7 +80,7 @@ void kread_error(klisp_State *K, char *str) /* 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 */ + /* IMPLEMENTATION RESTRICTION: only allow fixints in shared tokens */ int32_t ref_num = ivalue(kcdr(ref_token)); TValue tail = K->shared_dict; while (!ttisnil(tail)) { @@ -97,7 +97,7 @@ TValue try_shared_ref(klisp_State *K, TValue ref_token) TValue try_shared_def(klisp_State *K, TValue def_token, TValue value) { - /* TEMP: for now, only allow fixints in shared tokens */ + /* IMPLEMENTATION RESTRICTION: only allow fixints in shared tokens */ int32_t ref_num = ivalue(kcdr(def_token)); TValue tail = K->shared_dict; while (!ttisnil(tail)) { @@ -120,7 +120,7 @@ TValue try_shared_def(klisp_State *K, TValue def_token, TValue value) /* NOTE: the shared def is guaranteed to exist */ void change_shared_def(klisp_State *K, TValue def_token, TValue value) { - /* TEMP: for now, only allow fixints in shared tokens */ + /* IMPLEMENTATION RESTRICTION: only allow fixints in shared tokens */ int32_t ref_num = ivalue(kcdr(def_token)); TValue tail = K->shared_dict; while (!ttisnil(tail)) { diff --git a/src/ktoken.c b/src/ktoken.c @@ -126,6 +126,7 @@ void ktok_init(klisp_State *K) */ int ktok_getc(klisp_State *K) { /* WORKAROUND: for stdin line buffering & reading of EOF */ + /* Is this really necessary?? double check */ if (K->ktok_seen_eof) { return EOF; } else { @@ -155,6 +156,7 @@ int ktok_getc(klisp_State *K) { int ktok_peekc(klisp_State *K) { /* WORKAROUND: for stdin line buffering & reading of EOF */ + /* Is this really necessary?? double check */ if (K->ktok_seen_eof) { return EOF; } else { @@ -569,28 +571,35 @@ TValue ktok_read_special(klisp_State *K) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* srfi-38 type token (can be either a def or ref) */ - /* TODO: allow bigints */ - int32_t res = 0; - while(ch != '#' && ch != '=') { - if (!ktok_is_numeric(ch)) { - ktok_error(K, "Invalid char found in srfi-38 token"); - /* avoid warning */ - return KINERT; - } + /* IMPLEMENTATION RESTRICTION: only allow fixints in shared tokens */ + int32_t res = 0; + while(ch != '#' && ch != '=') { + if (!ktok_is_numeric(ch)) { + ktok_error(K, "Invalid char found in srfi-38 token"); + /* avoid warning */ + return KINERT; + } - res = res * 10 + ktok_digit_value(ch); + int new_digit = ktok_digit_value(ch); + if (CAN_ADD_DIGIT(res, new_digit)) { + res = res * 10 + new_digit; + } else { + ktok_error(K, "IMP. RESTRICTION: shared token too big"); + /* avoid warning */ + return KINERT; + } - chi = ktok_getc(K); - ch = (char) chi; - - if (chi == EOF) { - ktok_error(K, "EOF found while reading a srfi-38 token"); - /* avoid warning */ - return KINERT; - } + chi = ktok_getc(K); + ch = (char) chi; + + if (chi == EOF) { + ktok_error(K, "EOF found while reading a srfi-38 token"); + /* avoid warning */ + return KINERT; } - return kcons(K, ch2tv(ch), i2tv(res)); } + return kcons(K, ch2tv(ch), i2tv(res)); + } /* TODO: add real with no primary value and undefined */ default: ktok_error(K, "unexpected char in # constant"); diff --git a/src/ktoken.h b/src/ktoken.h @@ -47,6 +47,10 @@ extern kcharset ktok_delimiter, ktok_extended, ktok_subsequent; ({ unsigned char ch__ = (unsigned char) (ch_); \ kch_[KCHS_OCTANT(ch__)] & KCHS_BIT(ch__); }) +/* TODO: add other bases */ +#define CAN_ADD_DIGIT(res, new_digit) \ + ((res) <= (INT32_MAX - new_digit) / 10) + /* ** Char set contains macro interface */