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:
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);