Compare commits
14 Commits
2a13c89496
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d88523d39f | ||
|
|
13f3de726b | ||
|
|
8231cf4e14 | ||
|
|
55ed8c5939 | ||
|
|
edce319957 | ||
|
|
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
|
TEST=$(DIST)/test.out
|
||||||
|
|
||||||
LDFLAGS=
|
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
|
DFLAGS=-ggdb -fsanitize=address -fsanitize=undefined
|
||||||
RFLAGS=-O3
|
RFLAGS=-O3
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,14 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u64 references;
|
u64 padding : 56;
|
||||||
tag_t tag : 8;
|
tag_t tag : 8;
|
||||||
|
u64 references;
|
||||||
} alloc_metadata_t;
|
} alloc_metadata_t;
|
||||||
|
|
||||||
|
static_assert(sizeof(alloc_metadata_t) == 16,
|
||||||
|
"16 byte metadata required for alignment purposes");
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
alloc_metadata_t metadata;
|
alloc_metadata_t metadata;
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ typedef enum Tag
|
|||||||
#define INT_MIN (-(INT_MAX + 1))
|
#define INT_MIN (-(INT_MAX + 1))
|
||||||
|
|
||||||
tag_t tag_get(const lisp_t *);
|
tag_t tag_get(const lisp_t *);
|
||||||
|
u64 tag_sizeof(tag_t);
|
||||||
|
u64 lisp_sizeof(lisp_t *);
|
||||||
|
lisp_t *lisp_reset(lisp_t *);
|
||||||
|
void lisp_print(FILE *, lisp_t *);
|
||||||
|
|
||||||
lisp_t *tag_smi(const i64);
|
lisp_t *tag_smi(const i64);
|
||||||
lisp_t *tag_sym(const char *);
|
lisp_t *tag_sym(const char *);
|
||||||
lisp_t *tag_cons(const cons_t *);
|
lisp_t *tag_cons(const cons_t *);
|
||||||
@@ -65,10 +70,6 @@ str_t *as_str(lisp_t *);
|
|||||||
#define CAR(L) (as_cons(L)->car)
|
#define CAR(L) (as_cons(L)->car)
|
||||||
#define CDR(L) (as_cons(L)->cdr)
|
#define CDR(L) (as_cons(L)->cdr)
|
||||||
|
|
||||||
void lisp_print(FILE *, lisp_t *);
|
|
||||||
u64 tag_sizeof(tag_t);
|
|
||||||
u64 lisp_sizeof(lisp_t *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copyright (C) 2026 Aryadev Chavali
|
/* Copyright (C) 2026 Aryadev Chavali
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ typedef enum
|
|||||||
READ_ERR_EOF,
|
READ_ERR_EOF,
|
||||||
READ_ERR_EXPECTED_CLOSED_BRACE,
|
READ_ERR_EXPECTED_CLOSED_BRACE,
|
||||||
READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET,
|
READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET,
|
||||||
|
READ_ERR_EXPECTED_CLOSING_SPEECHMARKS,
|
||||||
READ_ERR_UNEXPECTED_CLOSED_BRACE,
|
READ_ERR_UNEXPECTED_CLOSED_BRACE,
|
||||||
READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET,
|
READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET,
|
||||||
READ_ERR_UNKNOWN_CHAR,
|
READ_ERR_UNKNOWN_CHAR,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ typedef struct
|
|||||||
|
|
||||||
void sys_init(sys_t *);
|
void sys_init(sys_t *);
|
||||||
lisp_t *sys_alloc(sys_t *, tag_t type);
|
lisp_t *sys_alloc(sys_t *, tag_t type);
|
||||||
|
void sys_delete(sys_t *, lisp_t *);
|
||||||
void sys_free(sys_t *);
|
void sys_free(sys_t *);
|
||||||
|
|
||||||
// Debugging function: provides total memory usage from system.
|
// Debugging function: provides total memory usage from system.
|
||||||
@@ -30,6 +31,7 @@ u64 sys_cost(sys_t *);
|
|||||||
lisp_t *make_int(i64);
|
lisp_t *make_int(i64);
|
||||||
lisp_t *intern(sys_t *, sv_t);
|
lisp_t *intern(sys_t *, sv_t);
|
||||||
lisp_t *cons(sys_t *, lisp_t *, lisp_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_vec(sys_t *, u64);
|
||||||
lisp_t *make_str(sys_t *, u64);
|
lisp_t *make_str(sys_t *, u64);
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ static_assert(sizeof(vec_t) == 64, "vec_t has to be 64 bytes as part of SBO");
|
|||||||
|
|
||||||
void vec_init(vec_t *, u64);
|
void vec_init(vec_t *, u64);
|
||||||
void vec_free(vec_t *);
|
void vec_free(vec_t *);
|
||||||
|
void vec_reset(vec_t *);
|
||||||
u8 *vec_data(vec_t *);
|
u8 *vec_data(vec_t *);
|
||||||
|
|
||||||
// Append, possibly reallocating memory
|
// Append, possibly reallocating memory
|
||||||
|
|||||||
@@ -158,8 +158,35 @@ end:
|
|||||||
|
|
||||||
void alloc_delete(alloc_t *alloc, lisp_t *lisp)
|
void alloc_delete(alloc_t *alloc, lisp_t *lisp)
|
||||||
{
|
{
|
||||||
|
switch (tag_get(lisp))
|
||||||
|
{
|
||||||
|
case TAG_CONS:
|
||||||
|
case TAG_VEC:
|
||||||
|
case TAG_STR:
|
||||||
|
break;
|
||||||
|
case TAG_NIL: // These can't be deleted (not allocated)
|
||||||
|
case TAG_SMI:
|
||||||
|
case TAG_SYM:
|
||||||
|
default:
|
||||||
|
FAIL("Unreachable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
alloc_node_t *node = lisp_to_node(lisp);
|
alloc_node_t *node = lisp_to_node(lisp);
|
||||||
assert(node && node->metadata.references == 0);
|
assert(node && node->metadata.references == 0);
|
||||||
|
|
||||||
|
// If already present in the free vector, stop.
|
||||||
|
FOR_VEC(i, &alloc->free_vec, alloc_node_t *)
|
||||||
|
{
|
||||||
|
alloc_node_t *other = VEC_GET(&alloc->pages, i, alloc_node_t *);
|
||||||
|
if (other == node)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, add to the free vector.
|
||||||
|
lisp_reset(lisp);
|
||||||
vec_append(&alloc->free_vec, &node, sizeof(node));
|
vec_append(&alloc->free_vec, &node, sizeof(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +206,7 @@ void alloc_free(alloc_t *alloc)
|
|||||||
FOR_VEC(i, &alloc->pages, page_t *)
|
FOR_VEC(i, &alloc->pages, page_t *)
|
||||||
{
|
{
|
||||||
page_t *page = VEC_GET(&alloc->pages, i, page_t *);
|
page_t *page = VEC_GET(&alloc->pages, i, page_t *);
|
||||||
// Iterate through every alloc_node in this page
|
// Iterate through every alloc_node in this page (dynamic walk)
|
||||||
for (u64 j = 0; j < VEC_SIZE(&page->data, u8);)
|
for (u64 j = 0; j < VEC_SIZE(&page->data, u8);)
|
||||||
{
|
{
|
||||||
alloc_node_t *node = (alloc_node_t *)(vec_data(&page->data) + j);
|
alloc_node_t *node = (alloc_node_t *)(vec_data(&page->data) + j);
|
||||||
|
|||||||
53
src/lisp.c
53
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_t *item = VEC_GET(vec, i, lisp_t *);
|
||||||
lisp_print(fp, item);
|
lisp_print(fp, item);
|
||||||
if (i < VEC_SIZE(vec, lisp_t *))
|
if (i < VEC_SIZE(vec, lisp_t *) - 1)
|
||||||
{
|
{
|
||||||
fprintf(fp, " ");
|
fprintf(fp, " ");
|
||||||
}
|
}
|
||||||
@@ -188,8 +188,23 @@ void lisp_print(FILE *fp, lisp_t *lisp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TAG_STR:
|
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;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FAIL("Unreachable");
|
FAIL("Unreachable");
|
||||||
break;
|
break;
|
||||||
@@ -223,6 +238,40 @@ u64 lisp_sizeof(lisp_t *lisp)
|
|||||||
return tag_sizeof(tag_get(lisp));
|
return tag_sizeof(tag_get(lisp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lisp_t *lisp_reset(lisp_t *lisp)
|
||||||
|
{
|
||||||
|
switch (tag_get(lisp))
|
||||||
|
{
|
||||||
|
case TAG_NIL:
|
||||||
|
case TAG_SMI:
|
||||||
|
case TAG_SYM:
|
||||||
|
// Nothing to "reset" here.
|
||||||
|
return lisp;
|
||||||
|
case TAG_CONS:
|
||||||
|
{
|
||||||
|
// Make `car` and `cons` NIL
|
||||||
|
CAR(lisp) = NIL;
|
||||||
|
CDR(lisp) = NIL;
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
case TAG_VEC:
|
||||||
|
{
|
||||||
|
vec_reset(as_vec(lisp));
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
case TAG_STR:
|
||||||
|
{
|
||||||
|
vec_reset(&as_str(lisp)->data);
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FAIL("Unreachable");
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Copyright (C) 2025, 2026 Aryadev Chavali
|
/* Copyright (C) 2025, 2026 Aryadev Chavali
|
||||||
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
FOR_VEC(i, &ast, lisp_t *)
|
FOR_VEC(i, &ast, lisp_t *)
|
||||||
{
|
{
|
||||||
lisp_t *expr = VEC_GET(&ast, i, lisp_t *);
|
|
||||||
#if VERBOSE_LOGS
|
#if VERBOSE_LOGS
|
||||||
|
lisp_t *expr = VEC_GET(&ast, i, lisp_t *);
|
||||||
printf("\t[%lu]: ", i);
|
printf("\t[%lu]: ", i);
|
||||||
lisp_print(stdout, expr);
|
lisp_print(stdout, expr);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|||||||
62
src/reader.c
62
src/reader.c
@@ -20,11 +20,12 @@ const char *read_err_to_cstr(read_err_t err)
|
|||||||
return "EOF";
|
return "EOF";
|
||||||
case READ_ERR_UNKNOWN_CHAR:
|
case READ_ERR_UNKNOWN_CHAR:
|
||||||
return "UNKNOWN_CHAR";
|
return "UNKNOWN_CHAR";
|
||||||
break;
|
|
||||||
case READ_ERR_EXPECTED_CLOSED_BRACE:
|
case READ_ERR_EXPECTED_CLOSED_BRACE:
|
||||||
return "EXPECTED_CLOSED_BRACE";
|
return "EXPECTED_CLOSED_BRACE";
|
||||||
case READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET:
|
case READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET:
|
||||||
return "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:
|
case READ_ERR_UNEXPECTED_CLOSED_BRACE:
|
||||||
return "UNEXPECTED_CLOSED_BRACE";
|
return "UNEXPECTED_CLOSED_BRACE";
|
||||||
case READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET:
|
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.
|
// Accepted characters for symbols.
|
||||||
static const char *SYMBOL_CHARS =
|
static const char *SYMBOL_CHARS =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*+,-./"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*+,-./"
|
||||||
":<=>?@\\^_`{|}~0123456789";
|
":<=>?@\\^_{|}~0123456789";
|
||||||
|
|
||||||
// Little predicate using SYMBOL_CHARS
|
// Little predicate using SYMBOL_CHARS
|
||||||
bool is_sym(char c)
|
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);
|
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;
|
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
|
// => i > (INT_MAX - digit) / 10
|
||||||
if (n > (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;
|
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);
|
read_err_t err = read_int(sys, stream, ret);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
i64 n = as_smi(*ret);
|
*ret = make_int(as_smi(*ret) * -1);
|
||||||
n *= -1;
|
|
||||||
*ret = make_int(n);
|
|
||||||
return READ_ERR_OK;
|
return READ_ERR_OK;
|
||||||
}
|
}
|
||||||
else if (is_sym(c) || isspace(c))
|
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);
|
return read_sym(sys, stream, ret);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return READ_ERR_UNKNOWN_CHAR;
|
return READ_ERR_UNKNOWN_CHAR;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
|
read_err_t read_list(sys_t *sys, stream_t *stream, lisp_t **ret)
|
||||||
{
|
{
|
||||||
|
u64 old_pos = stream->position;
|
||||||
// skip past the open parentheses '('
|
// skip past the open parentheses '('
|
||||||
(void)stream_next(stream);
|
(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);
|
read_err_t err = read(sys, stream, &item);
|
||||||
if (err == READ_ERR_EOF)
|
if (err == READ_ERR_EOF)
|
||||||
{
|
{
|
||||||
return READ_ERR_EXPECTED_CLOSED_BRACE;
|
goto no_close_brace;
|
||||||
}
|
}
|
||||||
else if (err)
|
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) != ')')
|
if (stream_peek(stream) != ')')
|
||||||
return READ_ERR_EXPECTED_CLOSED_BRACE;
|
{
|
||||||
|
goto no_close_brace;
|
||||||
|
}
|
||||||
|
|
||||||
stream_next(stream);
|
stream_next(stream);
|
||||||
*ret = top;
|
*ret = top;
|
||||||
return READ_ERR_OK;
|
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)
|
read_err_t read_vec(sys_t *sys, stream_t *stream, lisp_t **ret)
|
||||||
{
|
{
|
||||||
|
u64 old_pos = stream->position;
|
||||||
(void)stream_next(stream);
|
(void)stream_next(stream);
|
||||||
|
|
||||||
lisp_t *container = make_vec(sys, 0);
|
lisp_t *container = make_vec(sys, 0);
|
||||||
while (!stream_eoc(stream) && stream_peek(stream) != ']')
|
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);
|
read_err_t err = read(sys, stream, &item);
|
||||||
if (err == READ_ERR_EOF)
|
if (err == READ_ERR_EOF)
|
||||||
{
|
{
|
||||||
return READ_ERR_EXPECTED_CLOSED_BRACE;
|
goto no_close_square_bracket;
|
||||||
}
|
}
|
||||||
else if (err)
|
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) != ']')
|
if (stream_peek(stream) != ']')
|
||||||
return READ_ERR_EXPECTED_CLOSED_SQUARE_BRACKET;
|
goto no_close_square_bracket;
|
||||||
|
|
||||||
stream_next(stream);
|
stream_next(stream);
|
||||||
*ret = container;
|
*ret = container;
|
||||||
return READ_ERR_OK;
|
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)
|
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);
|
read_err_t err = read(sys, stream, &to_quote);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
*ret = cons(sys, to_quote, NIL);
|
lisp_t *items[] = {intern(sys, SV_AUTO("quote")), to_quote};
|
||||||
*ret = cons(sys, intern(sys, SV_AUTO("quote")), *ret);
|
*ret = make_list(sys, items, ARRSIZE(items));
|
||||||
return READ_ERR_OK;
|
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);
|
return read_vec(sys, stream, ret);
|
||||||
else if (c == ']')
|
else if (c == ']')
|
||||||
return READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET;
|
return READ_ERR_UNEXPECTED_CLOSED_SQUARE_BRACKET;
|
||||||
|
else if (c == '\"')
|
||||||
|
return read_str(sys, stream, ret);
|
||||||
|
|
||||||
return READ_ERR_UNKNOWN_CHAR;
|
return READ_ERR_UNKNOWN_CHAR;
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/sys.c
16
src/sys.c
@@ -34,6 +34,11 @@ lisp_t *sys_alloc(sys_t *sys, tag_t type)
|
|||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sys_delete(sys_t *sys, lisp_t *lisp)
|
||||||
|
{
|
||||||
|
alloc_delete(&sys->memory, lisp);
|
||||||
|
}
|
||||||
|
|
||||||
u64 sys_cost(sys_t *sys)
|
u64 sys_cost(sys_t *sys)
|
||||||
{
|
{
|
||||||
return alloc_cost(&sys->memory) + sym_table_cost(&sys->symtable);
|
return alloc_cost(&sys->memory) + sym_table_cost(&sys->symtable);
|
||||||
@@ -59,6 +64,17 @@ lisp_t *cons(sys_t *sys, lisp_t *car, lisp_t *cdr)
|
|||||||
return cons;
|
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 *make_vec(sys_t *sys, u64 capacity)
|
||||||
{
|
{
|
||||||
lisp_t *vec = sys_alloc(sys, TAG_VEC);
|
lisp_t *vec = sys_alloc(sys, TAG_VEC);
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ void vec_free(vec_t *vec)
|
|||||||
memset(vec, 0, sizeof(*vec));
|
memset(vec, 0, sizeof(*vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vec_reset(vec_t *vec)
|
||||||
|
{
|
||||||
|
if (!vec)
|
||||||
|
return;
|
||||||
|
memset(vec_data(vec), 0, vec->capacity);
|
||||||
|
vec->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
u8 *vec_data(vec_t *vec)
|
u8 *vec_data(vec_t *vec)
|
||||||
{
|
{
|
||||||
return vec->not_inlined ? vec->ptr : vec->inlined;
|
return vec->not_inlined ? vec->ptr : vec->inlined;
|
||||||
|
|||||||
Reference in New Issue
Block a user