Compare commits

...

9 Commits

Author SHA1 Message Date
Aryadev Chavali
775d9f51bf reader: add position restoration for read_vec and read_list
Same as read_str really, using a label to push control flow.
2026-03-05 20:27:13 +00:00
Aryadev Chavali
c65ec319f5 lisp: lisp_print: implement support for strings 2026-03-05 20:27:00 +00:00
Aryadev Chavali
fd9cc93c45 lisp: lisp_print: fix issue with extra space when printing vectors 2026-03-05 20:26:40 +00:00
Aryadev Chavali
e594b6ce70 reader: read_str restores stream position for no closing speechmarks
Say you have the following Lisp code: `"hello world` (no closing
speechmark).  This read_str implementation will now place
stream->position at the first speechmark rather than at the
EOF (what happened previously) which is a bit nicer.
2026-03-05 20:25:03 +00:00
Aryadev Chavali
fee6614670 reader: implement reader for strings 2026-03-05 20:13:52 +00:00
Aryadev Chavali
1998954b56 reader: slight adjustments based on change INT -> SMI 2026-03-05 20:13:18 +00:00
Aryadev Chavali
e629b9919e Makefile: added -Wswitch-enum to warning flags 2026-03-05 19:59:59 +00:00
Aryadev Chavali
37d1764c6e reader: use make_list in read_quote 2026-03-05 19:59:46 +00:00
Aryadev Chavali
cb8d1b1139 sys: make_list constructor
Takes a fixed array of lisp_t pointers, and makes a cons list out of
them.
2026-03-05 19:59:23 +00:00
6 changed files with 79 additions and 17 deletions

View File

@@ -5,7 +5,7 @@ OUT=$(DIST)/alisp.out
TEST=$(DIST)/test.out
LDFLAGS=
GFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c23 -I./include/
GFLAGS=-Wall -Wextra -Wswitch-enum -Wpedantic -Werror -std=c23 -I./include/
DFLAGS=-ggdb -fsanitize=address -fsanitize=undefined
RFLAGS=-O3

View File

@@ -17,6 +17,7 @@ typedef enum
READ_ERR_EOF,
READ_ERR_EXPECTED_CLOSED_BRACE,
READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET,
READ_ERR_EXPECTED_CLOSING_SPEECHMARKS,
READ_ERR_UNEXPECTED_CLOSED_BRACE,
READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET,
READ_ERR_UNKNOWN_CHAR,

View File

@@ -30,6 +30,7 @@ u64 sys_cost(sys_t *);
lisp_t *make_int(i64);
lisp_t *intern(sys_t *, sv_t);
lisp_t *cons(sys_t *, lisp_t *, lisp_t *);
lisp_t *make_list(sys_t *, lisp_t **, u64);
lisp_t *make_vec(sys_t *, u64);
lisp_t *make_str(sys_t *, u64);

View File

@@ -174,7 +174,7 @@ void lisp_print(FILE *fp, lisp_t *lisp)
{
lisp_t *item = VEC_GET(vec, i, lisp_t *);
lisp_print(fp, item);
if (i < VEC_SIZE(vec, lisp_t *))
if (i < VEC_SIZE(vec, lisp_t *) - 1)
{
fprintf(fp, " ");
}
@@ -188,8 +188,23 @@ void lisp_print(FILE *fp, lisp_t *lisp)
break;
}
case TAG_STR:
TODO("Implement lisp_print for strings");
{
#if VERBOSE_LOGS == 2
fprintf(fp, "STR[");
#else
fprintf(fp, "\"");
#endif
sv_t sv = string_sv(as_str(lisp));
fprintf(fp, PR_SV, SV_FMT(sv));
#if VERBOSE_LOGS == 2
fprintf(fp, "]");
#else
fprintf(fp, "\"");
#endif
break;
}
default:
FAIL("Unreachable");
break;

View File

@@ -20,11 +20,12 @@ const char *read_err_to_cstr(read_err_t err)
return "EOF";
case READ_ERR_UNKNOWN_CHAR:
return "UNKNOWN_CHAR";
break;
case READ_ERR_EXPECTED_CLOSED_BRACE:
return "EXPECTED_CLOSED_BRACE";
case READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET:
return "EXPECTED_CLOSED_SQUARE_BRACKET";
case READ_ERR_EXPECTED_CLOSING_SPEECHMARKS:
return "EXPECTED_CLOSING_SPEECHMARKS";
case READ_ERR_UNEXPECTED_CLOSED_BRACE:
return "UNEXPECTED_CLOSED_BRACE";
case READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET:
@@ -37,7 +38,7 @@ const char *read_err_to_cstr(read_err_t err)
// Accepted characters for symbols.
static const char *SYMBOL_CHARS =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*+,-./"
":<=>?@\\^_`{|}~0123456789";
":<=>?@\\^_{|}~0123456789";
// Little predicate using SYMBOL_CHARS
bool is_sym(char c)
@@ -76,9 +77,9 @@ read_err_t read_int(sys_t *sys, stream_t *stream, lisp_t **ret)
return read_sym(sys, stream, ret);
}
if (digits_sv.size > 19)
if (digits_sv.size >= 18)
{
TODO("alisp doesn't support big integers (bigger than 63 bits) yet");
TODO("alisp doesn't support big integers (bigger than 56 bits) yet");
}
i64 n = 0;
@@ -92,7 +93,7 @@ read_err_t read_int(sys_t *sys, stream_t *stream, lisp_t **ret)
// => i > (INT_MAX - digit) / 10
if (n > (INT_MAX - digit) / 10)
{
TODO("alisp doesn't support big integers (bigger than 63 bits) yet");
TODO("alisp doesn't support big integers (bigger than 56 bits) yet");
}
n *= 10;
@@ -111,9 +112,7 @@ read_err_t read_negative(sys_t *sys, stream_t *stream, lisp_t **ret)
read_err_t err = read_int(sys, stream, ret);
if (err)
return err;
i64 n = as_smi(*ret);
n *= -1;
*ret = make_int(n);
*ret = make_int(as_smi(*ret) * -1);
return READ_ERR_OK;
}
else if (is_sym(c) || isspace(c))
@@ -122,11 +121,14 @@ read_err_t read_negative(sys_t *sys, stream_t *stream, lisp_t **ret)
return read_sym(sys, stream, ret);
}
else
{
return READ_ERR_UNKNOWN_CHAR;
}
}
read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
{
u64 old_pos = stream->position;
// skip past the open parentheses '('
(void)stream_next(stream);
@@ -138,7 +140,7 @@ read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
read_err_t err = read(sys, stream, &item);
if (err == READ_ERR_EOF)
{
return READ_ERR_EXPECTED_CLOSED_BRACE;
goto no_close_brace;
}
else if (err)
{
@@ -157,16 +159,23 @@ read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
}
if (stream_peek(stream) != ')')
return READ_ERR_EXPECTED_CLOSED_BRACE;
{
goto no_close_brace;
}
stream_next(stream);
*ret = top;
return READ_ERR_OK;
no_close_brace:
stream->position = old_pos;
return READ_ERR_EXPECTED_CLOSED_BRACE;
}
read_err_t read_vec(sys_t *sys, stream_t *stream, lisp_t **ret)
{
u64 old_pos = stream->position;
(void)stream_next(stream);
lisp_t *container = make_vec(sys, 0);
while (!stream_eoc(stream) && stream_peek(stream) != ']')
{
@@ -174,7 +183,7 @@ read_err_t read_vec(sys_t *sys, stream_t *stream, lisp_t **ret)
read_err_t err = read(sys, stream, &item);
if (err == READ_ERR_EOF)
{
return READ_ERR_EXPECTED_CLOSED_BRACE;
goto no_close_square_bracket;
}
else if (err)
{
@@ -187,10 +196,33 @@ read_err_t read_vec(sys_t *sys, stream_t *stream, lisp_t **ret)
}
if (stream_peek(stream) != ']')
return READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET;
goto no_close_square_bracket;
stream_next(stream);
*ret = container;
return READ_ERR_OK;
no_close_square_bracket:
stream->position = old_pos;
return READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET;
}
read_err_t read_str(sys_t *sys, stream_t *stream, lisp_t **ret)
{
u64 old_pos = stream->position;
(void)stream_next(stream);
sv_t contents = stream_till(stream, "\"");
if (stream_eoc(stream) || stream_peek(stream) != '\"')
{
stream->position = old_pos;
return READ_ERR_EXPECTED_CLOSING_SPEECHMARKS;
}
stream_next(stream);
lisp_t *lisp = make_str(sys, contents.size);
vec_append(&as_str(lisp)->data, contents.data, contents.size);
*ret = lisp;
return READ_ERR_OK;
}
read_err_t read_quote(sys_t *sys, stream_t *stream, lisp_t **ret)
@@ -200,8 +232,8 @@ read_err_t read_quote(sys_t *sys, stream_t *stream, lisp_t **ret)
read_err_t err = read(sys, stream, &to_quote);
if (err)
return err;
*ret = cons(sys, to_quote, NIL);
*ret = cons(sys, intern(sys, SV_AUTO("quote")), *ret);
lisp_t *items[] = {intern(sys, SV_AUTO("quote")), to_quote};
*ret = make_list(sys, items, ARRSIZE(items));
return READ_ERR_OK;
}
@@ -243,6 +275,8 @@ read_err_t read(sys_t *sys, stream_t *stream, lisp_t **ret)
return read_vec(sys, stream, ret);
else if (c == ']')
return READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET;
else if (c == '\"')
return read_str(sys, stream, ret);
return READ_ERR_UNKNOWN_CHAR;
}

View File

@@ -59,6 +59,17 @@ lisp_t *cons(sys_t *sys, lisp_t *car, lisp_t *cdr)
return cons;
}
lisp_t *make_list(sys_t *sys, lisp_t **lisps, u64 size)
{
lisp_t *root = NIL;
for (u64 i = size; i > 0; --i)
{
lisp_t *node = lisps[i - 1];
root = cons(sys, node, root);
}
return root;
}
lisp_t *make_vec(sys_t *sys, u64 capacity)
{
lisp_t *vec = sys_alloc(sys, TAG_VEC);