Skip to content

Commit

Permalink
Merge branch 'reduce-str-impl'
Browse files Browse the repository at this point in the history
  • Loading branch information
tadd committed Jul 18, 2024
2 parents d37fa2c + 1d5460e commit c8ee118
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 75 deletions.
39 changes: 5 additions & 34 deletions lisp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
};

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -258,7 +258,6 @@ typedef enum {
TTYPE_RPAREN,
TTYPE_INT,
TTYPE_DOT,
TTYPE_STR,
TTYPE_IDENT,
TTYPE_CONST,
TTYPE_EOF
Expand All @@ -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)

Expand All @@ -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)
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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, "<function>");
break;
Expand Down
2 changes: 0 additions & 2 deletions lisp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
47 changes: 8 additions & 39 deletions test_lisp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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("<function>", value_of_func(value_of_func, 1));

assert_stringify("(1)", cons(value_of_int(1), Qnil));
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand Down

0 comments on commit c8ee118

Please sign in to comment.