More comments and helpful explanations

This commit is contained in:
2026-01-21 09:27:43 +00:00
parent dae6382f4b
commit eda23c8278
2 changed files with 29 additions and 23 deletions

38
alisp.h
View File

@@ -22,7 +22,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
/// The bare fucking minimum /// Essential macros
#define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B))
#define ARRSIZE(A) (sizeof(A) / sizeof((A)[0])) #define ARRSIZE(A) (sizeof(A) / sizeof((A)[0]))
@@ -30,6 +30,7 @@
#define FAIL(MSG) assert(false && "FAIL: " #MSG) #define FAIL(MSG) assert(false && "FAIL: " #MSG)
#define TODO(MSG) assert(false && "TODO: " #MSG) #define TODO(MSG) assert(false && "TODO: " #MSG)
/// Numeric aliases
typedef uint8_t u8; typedef uint8_t u8;
typedef uint16_t u16; typedef uint16_t u16;
typedef uint32_t u32; typedef uint32_t u32;
@@ -40,28 +41,31 @@ typedef int16_t i16;
typedef int32_t i32; typedef int32_t i32;
typedef int64_t i64; typedef int64_t i64;
/// String Views for my String Needs /// String Views
typedef struct typedef struct
{ {
u64 size; u64 size;
char *data; char *data;
} sv_t; } sv_t;
// String view macro constructor
#define SV(DATA, SIZE) ((sv_t){.data = (DATA), .size = (SIZE)}) #define SV(DATA, SIZE) ((sv_t){.data = (DATA), .size = (SIZE)})
// Pretty printers
#define SV_FMT(SV) (int)(SV).size, (SV).data #define SV_FMT(SV) (int)(SV).size, (SV).data
#define PR_SV "%.*s" #define PR_SV "%.*s"
#define PRD_SV "%d@%p" #define PRD_SV "%d@%p"
// String view functions
sv_t sv_copy(sv_t); sv_t sv_copy(sv_t);
/// Dynamic arrays /// Dynamic arrays
#define VEC_INLINE_CAPACITY 32 #define VEC_INLINE_CAPACITY 32
#define VEC_MULT 2 #define VEC_MULT 2
typedef struct Vector typedef struct Vector
{ {
u64 size, capacity; u64 size, capacity;
// Small buffer optimisation
u8 is_inlined; u8 is_inlined;
union union
{ {
@@ -70,7 +74,7 @@ typedef struct Vector
}; };
} vec_t; } 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)) #define VEC_GET(V, T) ((T *)vec_data(V))
@@ -91,15 +95,16 @@ typedef struct
#define SYM_TABLE_INIT_SIZE (1 << 10) #define SYM_TABLE_INIT_SIZE (1 << 10)
u64 djb2(sv_t string);
void sym_table_init(sym_table_t *); void sym_table_init(sym_table_t *);
char *sym_table_find(sym_table_t *, sv_t); char *sym_table_find(sym_table_t *, sv_t);
void sym_table_cleanup(sym_table_t *); void sym_table_cleanup(sym_table_t *);
// Hashing algorithm
u64 djb2(sv_t string);
/// Streams /// Streams
typedef enum typedef enum
{ {
STREAM_TYPE_STRING, STREAM_TYPE_STRING = 0,
STREAM_TYPE_PIPE, STREAM_TYPE_PIPE,
STREAM_TYPE_FILE, STREAM_TYPE_FILE,
} stream_type_t; } stream_type_t;
@@ -147,15 +152,14 @@ u64 stream_size(stream_t *);
char stream_next(stream_t *); char stream_next(stream_t *);
// Peek current character, do not push position // Peek current character, do not push position
char stream_peek(stream_t *); 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(stream_t *, i64);
bool stream_seek_forward(stream_t *, u64); bool stream_seek_forward(stream_t *, u64);
bool stream_seek_backward(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); sv_t stream_substr(stream_t *, u64);
// Return an absolutely located substring (using sv_t) at given index and of // Return an absolute substring at given index and of given size.
// given size.
sv_t stream_substr_abs(stream_t *, u64, u64); sv_t stream_substr_abs(stream_t *, u64, u64);
// Skip forward in stream till one of the characters in the given C string is // 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 /// Lisp type definitions
#define NIL 0 #define NIL 0
// Opaque object for tagged pointers
typedef struct Obj lisp_t; typedef struct Obj lisp_t;
typedef struct typedef struct
@@ -175,10 +180,10 @@ typedef struct
lisp_t *car, *cdr; lisp_t *car, *cdr;
} cons_t; } cons_t;
/// System context - essentially something to help with system management /// System context
typedef struct typedef struct
{ {
lisp_t *memory; lisp_t *conses;
sym_table_t symtable; sym_table_t symtable;
} sys_t; } sys_t;
@@ -203,8 +208,7 @@ vec_t *as_vec(lisp_t *);
lisp_t *car(lisp_t *); lisp_t *car(lisp_t *);
lisp_t *cdr(lisp_t *); lisp_t *cdr(lisp_t *);
/// Pointer tagging scheme for lisps /// Tagging scheme
typedef enum Tag typedef enum Tag
{ {
TAG_NIL = 0b00000000, // Start of atomic types TAG_NIL = 0b00000000, // Start of atomic types
@@ -215,6 +219,7 @@ typedef enum Tag
NUM_TAGS = 5, NUM_TAGS = 5,
} tag_t; } tag_t;
static_assert(NUM_TAGS == 5, "Expected NUM_TAGS == 5 for enum SHIFT");
enum Shift enum Shift
{ {
SHIFT_INT = 1, SHIFT_INT = 1,
@@ -223,6 +228,7 @@ enum Shift
SHIFT_VEC = 8, SHIFT_VEC = 8,
}; };
static_assert(NUM_TAGS == 5, "Expected NUM_TAGS == 5 for enum MASK");
enum Mask enum Mask
{ {
MASK_INT = 0b00000001, MASK_INT = 0b00000001,
@@ -231,6 +237,7 @@ enum Mask
MASK_VEC = 0b11111111, MASK_VEC = 0b11111111,
}; };
// Some helper macros for tagging
#define TAG(PTR, TYPE) ((lisp_t *)(((PTR) << SHIFT_##TYPE) | TAG_##TYPE)) #define TAG(PTR, TYPE) ((lisp_t *)(((PTR) << SHIFT_##TYPE) | TAG_##TYPE))
#define IS_TAG(PTR, TYPE) (((u64)(PTR) & MASK_##TYPE) == TAG_##TYPE) #define IS_TAG(PTR, TYPE) (((u64)(PTR) & MASK_##TYPE) == TAG_##TYPE)
#define UNTAG(PTR, TYPE) (((u64)PTR) >> SHIFT_##TYPE) #define UNTAG(PTR, TYPE) (((u64)PTR) >> SHIFT_##TYPE)
@@ -239,7 +246,6 @@ enum Mask
#define INT_MIN (-(1L << 62)) #define INT_MIN (-(1L << 62))
tag_t get_tag(lisp_t *); tag_t get_tag(lisp_t *);
lisp_t *tag_int(i64); lisp_t *tag_int(i64);
lisp_t *tag_sym(char *); lisp_t *tag_sym(char *);
lisp_t *tag_cons(cons_t *); lisp_t *tag_cons(cons_t *);
@@ -252,7 +258,7 @@ typedef enum
} read_err_t; } read_err_t;
// Attempt to read an expression from the stream, storing it in a pointer, // 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 **); read_err_t read(sys_t *, stream_t *, lisp_t **);
// Attempt to read all expressions from a stream till end of content, storing // Attempt to read all expressions from a stream till end of content, storing

8
sys.c
View File

@@ -28,8 +28,8 @@ void sys_register(sys_t *sys, lisp_t *ptr)
// Generate an unmanaged cons // Generate an unmanaged cons
cons_t *cons = calloc(1, sizeof(*cons)); cons_t *cons = calloc(1, sizeof(*cons));
cons->car = ptr; cons->car = ptr;
cons->cdr = sys->memory; cons->cdr = sys->conses;
sys->memory = tag_cons(cons); sys->conses = tag_cons(cons);
} }
void sys_cleanup(sys_t *sys) void sys_cleanup(sys_t *sys)
@@ -38,11 +38,11 @@ void sys_cleanup(sys_t *sys)
sym_table_cleanup(&sys->symtable); sym_table_cleanup(&sys->symtable);
if (!sys->memory) if (!sys->conses)
return; return;
// Iterate through each element of memory // 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)) cell = next, next = cdr(next))
{ {
// Only reason allocated exists is because we had to allocate memory on the // Only reason allocated exists is because we had to allocate memory on the