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

44
alisp.h
View File

@@ -22,7 +22,7 @@
#include <stdint.h>
#include <stdio.h>
/// 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

8
sys.c
View File

@@ -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