diff --git a/lisp.c b/lisp.c index 2a1b829..57a9111 100644 --- a/lisp.c +++ b/lisp.c @@ -33,7 +33,7 @@ static const char *TYPE_NAMES[] = { [TYPE_SYMBOL] = "symbol", [TYPE_UNDEF] = "undef", [TYPE_PAIR] = "pair", - [TYPE_STR] = "string", + [TYPE_STR] = "internal string", [TYPE_FUNC] = "function", }; @@ -109,7 +109,7 @@ static inline bool tagged_value_is(Value v, ValueTag expected) return !is_immediate(v) && VALUE_TAG(v) == expected; } -inline bool value_is_string(Value v) +static inline bool value_is_string(Value v) { return tagged_value_is(v, TAG_STR); } @@ -147,7 +147,7 @@ static inline Type value_typeof(Value v) } switch (VALUE_TAG(v)) { case TAG_STR: - return TYPE_STR; + UNREACHABLE(); // internal string case TAG_PAIR: return TYPE_PAIR; case TAG_FUNC: @@ -200,7 +200,7 @@ static inline void *tagged_new(size_t size, ValueTag t) return p; } -inline Value value_of_string(const char *s) +static inline Value value_of_string(const char *s) { String *str = tagged_new(sizeof(String), TAG_STR); str->body = xstrdup(s); @@ -258,7 +258,6 @@ typedef enum { TTYPE_RPAREN, TTYPE_INT, TTYPE_DOT, - TTYPE_STR, TTYPE_IDENT, TTYPE_CONST, TTYPE_EOF @@ -279,7 +278,6 @@ static const Token // and ctor #define TOK_V(t, v) ((Token) { .type = TTYPE_ ## t, .value = v }) #define TOK_INT(i) TOK_V(INT, value_of_int(i)) -#define TOK_STR(s) TOK_V(STR, value_of_string(s)) #define TOK_IDENT(s) TOK_V(IDENT, value_of_symbol(s)) #define TOK_CONST(c) TOK_V(CONST, c) @@ -297,26 +295,6 @@ static Token get_token_int(Parser *p, int sign) return TOK_INT(sign * i); } -static Token get_token_string(Parser *p) -{ - char buf[BUFSIZ], *pbuf = buf, *end = pbuf + sizeof(buf) - 2; - for (;;) { - int c = fgetc(p->in); - if (c == '"') - break; - if (c == '\\') { - c = fgetc(p->in); - if (c != '\\' && c != '"') - unexpected("'\\' or '\"' in string literal", "'%c'", c); - } - if (pbuf == end) - unexpected("string literal", "too long: \"%s...\"", pbuf); - *pbuf++ = c; - } - *pbuf = '\0'; - return TOK_STR(buf); -} - static Value symbol_names = Qnil; static Symbol intern(const char *name) @@ -423,8 +401,6 @@ static Token get_token(Parser *p) return TOK_RPAREN; case '.': return TOK_DOT; - case '"': - return get_token_string(p); case '#': c = fgetc(p->in); if (c == 't') @@ -497,9 +473,6 @@ static const char *token_stringify(Token t) break; case TTYPE_IDENT: return value_to_string(t.value); - case TTYPE_STR: - snprintf(buf, sizeof(buf), "\"%s\"", STRING(t.value)->body); - break; case TTYPE_CONST: return t.value == Qtrue ? "#t" : "#f"; case TTYPE_EOF: @@ -546,7 +519,6 @@ static Value parse_expr(Parser *p) unexpected("expression", "')'"); case TTYPE_DOT: unexpected("expression", "'.'"); - case TTYPE_STR: case TTYPE_INT: case TTYPE_CONST: case TTYPE_IDENT: @@ -790,8 +762,7 @@ static void fprint(FILE* f, Value v) fprintf(f, ")"); break; case TYPE_STR: - fprintf(f, "\"%s\"", value_to_string(v)); - break; + UNREACHABLE(); // internal string case TYPE_FUNC: fprintf(f, ""); break; diff --git a/lisp.h b/lisp.h index fc01df2..55367b5 100644 --- a/lisp.h +++ b/lisp.h @@ -17,7 +17,6 @@ extern const Value Qnil, Qundef, Qfalse, Qtrue; bool value_is_int(Value v); bool value_is_symbol(Value v); -bool value_is_string(Value v); bool value_is_func(Value v); bool value_is_atom(Value v); bool value_is_pair(Value v); @@ -29,7 +28,6 @@ const char *value_to_string(Value v); Value value_of_int(int64_t i); Value value_of_symbol(const char *s); -Value value_of_string(const char *s); Value value_of_func(CFunc cfunc, long arity); Value cons(Value car, Value cdr); diff --git a/test_lisp.c b/test_lisp.c index 15a65d6..d91454c 100644 --- a/test_lisp.c +++ b/test_lisp.c @@ -11,12 +11,12 @@ Test(lisp, nil) { Value a = Qnil; cr_assert(value_is_nil(a)); } -static void assert_stringify(const char *expected, Value v) -{ - char *s = stringify(v); - cr_assert(streq(expected, s)); - free(s); -} + +#define assert_stringify(expected, v) do { \ + char *s = stringify(v); \ + cr_assert(streq(expected, s)); \ + free(s); \ + } while (0) Test(lisp, printing) { assert_stringify("#t", Qtrue); @@ -30,9 +30,6 @@ Test(lisp, printing) { assert_stringify("'foo", value_of_symbol("foo")); - assert_stringify("\"bar\"", value_of_string("bar")); - assert_stringify("\"\\\"", value_of_string("\\")); - assert_stringify("", value_of_func(value_of_func, 1)); assert_stringify("(1)", cons(value_of_int(1), Qnil)); @@ -61,34 +58,6 @@ Test(lisp, parse_list) { cr_assert(value_is_nil(cddr(v))); } -Test(lisp, parse_string) { - Value v = parse_expr_string("\"abc\""); - cr_assert(value_is_string(v)); - cr_assert(streq("abc", value_to_string(v))); - - v = parse_expr_string("\"a\\\\b\""); - cr_assert(value_is_string(v)); - cr_assert(streq("a\\b", value_to_string(v))); - - v = parse_expr_string("\"a\\\"b\""); - cr_assert(value_is_string(v)); - cr_assert(streq("a\"b", value_to_string(v))); -} - -Test(lisp, parse_string_list) { - Value v = parse_expr_string("(\"abc\" \"def\")"); - cr_assert(value_is_pair(v)); - cr_assert(not(value_is_nil(v))); - - Value s = car(v); - cr_assert(value_is_string(s)); - cr_assert(streq("abc", value_to_string(s))); - - Value t = car(cdr(v)); - cr_assert(value_is_string(t)); - cr_assert(streq("def", value_to_string(t))); -} - Test(lisp, cxr) { Value v = parse_expr_string("((((42))))"); Value i = caaaar(v); @@ -198,7 +167,7 @@ Test(lisp, list) { cr_assert(eq(42, value_to_int(car(v)))); v = list(value_of_int(42), - value_of_string("foo"), + value_of_symbol("foo"), value_of_func(value_of_func, 0), Qundef); cr_assert(value_is_pair(v)); @@ -207,7 +176,7 @@ Test(lisp, list) { cr_assert(value_is_int(v0)); cr_assert(eq(42, value_to_int(v0))); Value v1 = cadr(v); - cr_assert(value_is_string(v1)); + cr_assert(value_is_symbol(v1)); cr_assert(streq("foo", value_to_string(v1))); Value v2 = caddr(v); cr_assert(value_is_func(v2));