From 46a617f16e3d6d06cc7b2a031a922c745dd2fbeb Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Fri, 16 Dec 2016 23:30:33 +0100 Subject: [PATCH] core: Support keywords. * display.c (display): Handle keyword. * mes.c (type_t): Add KEYWORD. (eq_p): Handle it. (make_keyword): New function. * reader.c (lookup): Use it. * type.c (keyword_p): New function. * NEWS: Update. --- NEWS | 2 ++ display.c | 2 ++ mes.c | 16 ++++++++++++++-- reader.c | 2 ++ string.c | 14 ++++++++++++++ type.c | 6 ++++++ 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index aeda4e79..36449e0f 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,8 @@ Please send Mes bug reports to janneke@gnu.org. The C-reader needs only support reading of words and lists (s-expressions), line-comments. Quoting, characters, strings, block-comments are all handled by the Scheme reader later. +** Language +*** Keywords are supported. * Changes in 0.3 since 0.2 ** Core *** Number-based rather than pointer-based cells. diff --git a/display.c b/display.c index 4c856721..575b5bcd 100644 --- a/display.c +++ b/display.c @@ -127,6 +127,8 @@ display_helper (FILE* f, SCM x, bool cont, char const *sep, bool quote) break; } case BROKEN_HEART: fprintf (f, "<3"); break; + case KEYWORD: + fprintf (f, "#:"); default: if (STRING (x)) { diff --git a/mes.c b/mes.c index 7aaa70e7..fdb66ca5 100644 --- a/mes.c +++ b/mes.c @@ -44,7 +44,7 @@ int MAX_ARENA_SIZE = 20000000; int GC_SAFETY = 100; typedef int SCM; -enum type_t {CHAR, FUNCTION, MACRO, NUMBER, PAIR, SPECIAL, STRING, SYMBOL, REF, VALUES, VECTOR, BROKEN_HEART}; +enum type_t {CHAR, FUNCTION, KEYWORD, MACRO, NUMBER, PAIR, SPECIAL, STRING, SYMBOL, REF, VALUES, VECTOR, BROKEN_HEART}; typedef SCM (*function0_t) (void); typedef SCM (*function1_t) (SCM); typedef SCM (*function2_t) (SCM, SCM); @@ -250,6 +250,8 @@ SCM eq_p (SCM x, SCM y) { return (x == y + || ((TYPE (x) == KEYWORD && TYPE (y) == KEYWORD + && STRING (x) == STRING (y))) || (TYPE (x) == CHAR && TYPE (y) == CHAR && VALUE (x) == VALUE (y)) || (TYPE (x) == NUMBER && TYPE (y) == NUMBER @@ -676,6 +678,15 @@ make_function (SCM name, SCM id, SCM arity) return make_cell (tmp_num3, name, tmp_num4); } +SCM +make_keyword (SCM s) +{ + SCM x = internal_lookup_symbol (s); + x = x ? x : internal_make_symbol (s); + g_cells[tmp_num].value = KEYWORD; + return make_cell (tmp_num, STRING (x), 0); +} + SCM make_macro (SCM name, SCM x) { @@ -932,7 +943,8 @@ gc_loop (SCM scan) { while (scan < g_free.value) { - if (NTYPE (scan) == MACRO + if (NTYPE (scan) == KEYWORD + || NTYPE (scan) == MACRO || NTYPE (scan) == PAIR || NTYPE (scan) == REF || scan == 1 // null diff --git a/reader.c b/reader.c index 2e4ad091..47d1b246 100644 --- a/reader.c +++ b/reader.c @@ -224,6 +224,8 @@ lookup (SCM s, SCM a) if (p == cell_nil) return make_number (n * sign); } + if (VALUE (car (s)) == '#' && VALUE (cadr (s)) == ':') return make_keyword (cddr (s)); + SCM x = internal_lookup_symbol (s); if (x) return x; diff --git a/string.c b/string.c index c02b22cc..36c27816 100644 --- a/string.c +++ b/string.c @@ -110,3 +110,17 @@ symbol_to_string (SCM x) assert (TYPE (x) == SYMBOL); return make_string (STRING (x)); } + +SCM +keyword_to_symbol (SCM x) +{ + assert (TYPE (x) == KEYWORD); + return make_symbol (STRING (x)); +} + +SCM +symbol_to_keyword (SCM x) +{ + assert (TYPE (x) == SYMBOL); + return make_keyword (STRING (x)); +} diff --git a/type.c b/type.c index 50b00673..ca28387a 100644 --- a/type.c +++ b/type.c @@ -26,6 +26,12 @@ char_p (SCM x) return TYPE (x) == CHAR ? cell_t : cell_f; } +SCM +keyword_p (SCM x) +{ + return TYPE (x) == KEYWORD ? cell_t : cell_f; +} + SCM macro_p (SCM x) {