Compare commits
9 Commits
2a13c89496
...
775d9f51bf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
775d9f51bf | ||
|
|
c65ec319f5 | ||
|
|
fd9cc93c45 | ||
|
|
e594b6ce70 | ||
|
|
fee6614670 | ||
|
|
1998954b56 | ||
|
|
e629b9919e | ||
|
|
37d1764c6e | ||
|
|
cb8d1b1139 |
2
Makefile
2
Makefile
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
19
src/lisp.c
19
src/lisp.c
@@ -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;
|
||||
|
||||
62
src/reader.c
62
src/reader.c
@@ -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;
|
||||
}
|
||||
|
||||
11
src/sys.c
11
src/sys.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user