klisp

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

commit 3ca515c7e8aee79d3847ba3ee495af1d11529b80
parent 66534051fd2ca953cb3e5fe3f63302b25f450276
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 18 Mar 2011 16:25:37 -0300

Added char->integer & integer->char. Restricted char constants and string constants to ASCII in tokenizer (non ASCII chars allowed in comments).

Diffstat:
Msrc/kgchars.c | 29++++++++++++++++++++++++++++-
Msrc/kgchars.h | 5++++-
Msrc/kground.c | 3++-
Msrc/ktoken.c | 15+++++++++++++--
4 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/src/kgchars.c b/src/kgchars.c @@ -39,7 +39,34 @@ bool kchar_upper_casep(TValue ch) { return isupper(chvalue(ch)) != 0; } bool kchar_lower_casep(TValue ch) { return islower(chvalue(ch)) != 0; } /* 14.1.4? char->integer, integer->char */ -/* TODO */ +void kchar_to_integer(klisp_State *K, TValue *xparams, TValue ptree, + TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + bind_1tp(K, "char->integer", ptree, "character", ttischar, ch); + + kapply_cc(K, i2tv((int32_t) chvalue(ch))); +} + +/* TEMP: this should arbitrary integers (and throw an error if out of + range */ +void kinteger_to_char(klisp_State *K, TValue *xparams, TValue ptree, + TValue denv) +{ + UNUSED(xparams); + UNUSED(denv); + bind_1tp(K, "integer->char", ptree, "finite integer", ttisfixint, itv); + + int32_t i = ivalue(itv); + + /* for now only allow ASCII */ + if (i < 0 || i > 127) { + klispE_throw(K, "integer->char: integer out of ASCII range [0 - 127]"); + return; + } + kapply_cc(K, ch2tv((char) i)); +} /* 14.1.4? char-upcase, char-downcase */ /* TODO */ diff --git a/src/kgchars.h b/src/kgchars.h @@ -38,7 +38,10 @@ bool kchar_upper_casep(TValue ch); bool kchar_lower_casep(TValue ch); /* 14.1.4? char->integer, integer->char */ -/* TODO */ +void kchar_to_integer(klisp_State *K, TValue *xparams, TValue ptree, + TValue denv); +void kinteger_to_char(klisp_State *K, TValue *xparams, TValue ptree, + TValue denv); /* 14.1.4? char-upcase, char-downcase */ /* TODO */ diff --git a/src/kground.c b/src/kground.c @@ -511,7 +511,8 @@ void kinit_ground_env(klisp_State *K) /* 14.1.4? char->integer, integer->char */ - /* TODO */ + add_applicative(K, ground_env, "char->integer", kchar_to_integer, 0); + add_applicative(K, ground_env, "integer->char", kinteger_to_char, 0); /* 14.1.4? char-upcase, char-downcase */ /* TODO */ diff --git a/src/ktoken.c b/src/ktoken.c @@ -436,7 +436,11 @@ TValue ktok_read_string(klisp_State *K) /* avoid warning */ return KINERT; } - if (ch == '"') { + if (ch < 0 || ch > 127) { + ktok_error(K, "Non ASCII char found while reading a string"); + /* avoid warning */ + return KINERT; + } else if (ch == '"') { ks_tbadd(K, '\0'); done = true; } else { @@ -545,7 +549,6 @@ TValue ktok_read_special(klisp_State *K) ** For now we follow the scheme report */ chi = ktok_getc(K); - ch = (char) chi; if (chi == EOF) { ktok_error(K, "EOF found while reading a char constant"); @@ -553,6 +556,14 @@ TValue ktok_read_special(klisp_State *K) return KINERT; } + ch = (char) chi; + + if (ch < 0 || ch > 127) { + ktok_error(K, "Non ASCII char found as character constant"); + /* avoid warning */ + return KINERT; + } + if (!ktok_is_alphabetic(ch) || ktok_check_delimiter(K)) return ch2tv(ch);