From eda23c82784775d78ea720ca18b5b1abb70d4ab7 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Wed, 21 Jan 2026 09:27:43 +0000 Subject: [PATCH] More comments and helpful explanations --- alisp.h | 44 +++++++++++++++++++++++++------------------- sys.c | 8 ++++---- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/alisp.h b/alisp.h index a9d254c..7f4c909 100644 --- a/alisp.h +++ b/alisp.h @@ -22,7 +22,7 @@ #include #include -/// The bare fucking minimum +/// Essential macros #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define ARRSIZE(A) (sizeof(A) / sizeof((A)[0])) @@ -30,6 +30,7 @@ #define FAIL(MSG) assert(false && "FAIL: " #MSG) #define TODO(MSG) assert(false && "TODO: " #MSG) +/// Numeric aliases typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; @@ -40,28 +41,31 @@ typedef int16_t i16; typedef int32_t i32; typedef int64_t i64; -/// String Views for my String Needs +/// String Views typedef struct { u64 size; char *data; } sv_t; +// String view macro constructor #define SV(DATA, SIZE) ((sv_t){.data = (DATA), .size = (SIZE)}) -#define SV_FMT(SV) (int)(SV).size, (SV).data -#define PR_SV "%.*s" -#define PRD_SV "%d@%p" +// Pretty printers +#define SV_FMT(SV) (int)(SV).size, (SV).data +#define PR_SV "%.*s" +#define PRD_SV "%d@%p" +// String view functions sv_t sv_copy(sv_t); /// Dynamic arrays - #define VEC_INLINE_CAPACITY 32 #define VEC_MULT 2 typedef struct Vector { u64 size, capacity; + // Small buffer optimisation u8 is_inlined; union { @@ -70,7 +74,7 @@ typedef struct Vector }; } vec_t; -static_assert(sizeof(vec_t) == 64, "vec_t has to be 64 bytes"); +static_assert(sizeof(vec_t) == 64, "vec_t has to be 64 bytes as part of SBO"); #define VEC_GET(V, T) ((T *)vec_data(V)) @@ -91,15 +95,16 @@ typedef struct #define SYM_TABLE_INIT_SIZE (1 << 10) -u64 djb2(sv_t string); void sym_table_init(sym_table_t *); char *sym_table_find(sym_table_t *, sv_t); void sym_table_cleanup(sym_table_t *); +// Hashing algorithm +u64 djb2(sv_t string); /// Streams typedef enum { - STREAM_TYPE_STRING, + STREAM_TYPE_STRING = 0, STREAM_TYPE_PIPE, STREAM_TYPE_FILE, } stream_type_t; @@ -147,15 +152,14 @@ u64 stream_size(stream_t *); char stream_next(stream_t *); // Peek current character, do not push position char stream_peek(stream_t *); -// Seek forward or backward in the stream, return success +// Move forward or backward in the stream, return success of operation bool stream_seek(stream_t *, i64); bool stream_seek_forward(stream_t *, u64); bool stream_seek_backward(stream_t *, u64); -// Return a relative substring (using sv_t) of a given size +// Return a relative substring of a given size sv_t stream_substr(stream_t *, u64); -// Return an absolutely located substring (using sv_t) at given index and of -// given size. +// Return an absolute substring at given index and of given size. sv_t stream_substr_abs(stream_t *, u64, u64); // Skip forward in stream till one of the characters in the given C string is @@ -168,6 +172,7 @@ sv_t stream_while(stream_t *, const char *); /// Lisp type definitions #define NIL 0 +// Opaque object for tagged pointers typedef struct Obj lisp_t; typedef struct @@ -175,10 +180,10 @@ typedef struct lisp_t *car, *cdr; } cons_t; -/// System context - essentially something to help with system management +/// System context typedef struct { - lisp_t *memory; + lisp_t *conses; sym_table_t symtable; } sys_t; @@ -203,8 +208,7 @@ vec_t *as_vec(lisp_t *); lisp_t *car(lisp_t *); lisp_t *cdr(lisp_t *); -/// Pointer tagging scheme for lisps - +/// Tagging scheme typedef enum Tag { TAG_NIL = 0b00000000, // Start of atomic types @@ -215,6 +219,7 @@ typedef enum Tag NUM_TAGS = 5, } tag_t; +static_assert(NUM_TAGS == 5, "Expected NUM_TAGS == 5 for enum SHIFT"); enum Shift { SHIFT_INT = 1, @@ -223,6 +228,7 @@ enum Shift SHIFT_VEC = 8, }; +static_assert(NUM_TAGS == 5, "Expected NUM_TAGS == 5 for enum MASK"); enum Mask { MASK_INT = 0b00000001, @@ -231,6 +237,7 @@ enum Mask MASK_VEC = 0b11111111, }; +// Some helper macros for tagging #define TAG(PTR, TYPE) ((lisp_t *)(((PTR) << SHIFT_##TYPE) | TAG_##TYPE)) #define IS_TAG(PTR, TYPE) (((u64)(PTR) & MASK_##TYPE) == TAG_##TYPE) #define UNTAG(PTR, TYPE) (((u64)PTR) >> SHIFT_##TYPE) @@ -239,7 +246,6 @@ enum Mask #define INT_MIN (-(1L << 62)) tag_t get_tag(lisp_t *); - lisp_t *tag_int(i64); lisp_t *tag_sym(char *); lisp_t *tag_cons(cons_t *); @@ -252,7 +258,7 @@ typedef enum } read_err_t; // Attempt to read an expression from the stream, storing it in a pointer, -// returning any errors if failed +// returning any errors if failed. read_err_t read(sys_t *, stream_t *, lisp_t **); // Attempt to read all expressions from a stream till end of content, storing diff --git a/sys.c b/sys.c index d01b493..ac3cb6e 100644 --- a/sys.c +++ b/sys.c @@ -28,8 +28,8 @@ void sys_register(sys_t *sys, lisp_t *ptr) // Generate an unmanaged cons cons_t *cons = calloc(1, sizeof(*cons)); cons->car = ptr; - cons->cdr = sys->memory; - sys->memory = tag_cons(cons); + cons->cdr = sys->conses; + sys->conses = tag_cons(cons); } void sys_cleanup(sys_t *sys) @@ -38,11 +38,11 @@ void sys_cleanup(sys_t *sys) sym_table_cleanup(&sys->symtable); - if (!sys->memory) + if (!sys->conses) return; // Iterate through each element of memory - for (lisp_t *cell = sys->memory, *next = cdr(cell); cell; + for (lisp_t *cell = sys->conses, *next = cdr(cell); cell; cell = next, next = cdr(next)) { // Only reason allocated exists is because we had to allocate memory on the