More comments and helpful explanations
This commit is contained in:
44
alisp.h
44
alisp.h
@@ -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
8
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
|
||||
|
||||
Reference in New Issue
Block a user