diff options
| author | LLLL Colonq <llll@colonq> | 2025-10-06 05:06:16 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2025-10-06 05:06:41 -0400 |
| commit | 09435bffe025a96e0d9c3b44ee9c505973b383bd (patch) | |
| tree | d352772edc096a374d42c50ffa4a7b2b8dad59dd /src/runtime.h | |
| parent | 063ab38ce78c370c698e5d148bb9f993ee731ddb (diff) | |
Cleanup, fix bugs
Ensure everything builds on C89
Diffstat (limited to 'src/runtime.h')
| -rw-r--r-- | src/runtime.h | 120 |
1 files changed, 63 insertions, 57 deletions
diff --git a/src/runtime.h b/src/runtime.h index 101b677..2014d41 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -7,10 +7,10 @@ struct pit_runtime; -// arenas +/* arenas */ typedef struct { i64 elem_size, capacity, next; - u8 data[]; + u8 data[1]; /* flexible array member */ } pit_arena; pit_arena *pit_arena_new(i64 capacity, i64 elem_size); i32 pit_arena_next_idx(pit_arena *a); @@ -20,37 +20,38 @@ void *pit_arena_idx(pit_arena *a, i32 idx); void *pit_arena_alloc(pit_arena *a); void *pit_arena_alloc_bulk(pit_arena *a, i64 num); -// nil is always the symbol with index 0 -#define PIT_NIL 0b1111111111110100000000000000000000000000000000000000000000000000 +/* nil is always the symbol with index 0 */ +#define PIT_NIL 0xfff4000000000000 /* 0b1111111111110100000000000000000000000000000000000000000000000000 */ + enum pit_value_sort { - PIT_VALUE_SORT_DOUBLE = 0b00, // double - PIT_VALUE_SORT_INTEGER = 0b01, // NaN-boxed 49-bit integer - PIT_VALUE_SORT_SYMBOL = 0b10, // NaN-boxed index into symbol table - PIT_VALUE_SORT_REF = 0b11, // NaN-boxed index into "heavy object" arena + PIT_VALUE_SORT_DOUBLE = 0, /* 0b00 - double */ + PIT_VALUE_SORT_INTEGER = 1, /* 0b01 - NaN-boxed 49-bit integer */ + PIT_VALUE_SORT_SYMBOL = 2, /* 0b10 - NaN-boxed index into symbol table */ + PIT_VALUE_SORT_REF = 3 /* 0b11 - NaN-boxed index into "heavy object" arena */ }; -typedef i32 pit_symbol; // a symbol at runtime is an index into the runtime's symbol table -typedef i32 pit_ref; // a reference is an index into the runtime's arena +typedef i32 pit_symbol; /* a symbol at runtime is an index into the runtime's symbol table */ +typedef i32 pit_ref; /* a reference is an index into the runtime's arena */ typedef u64 pit_value; enum pit_value_sort pit_value_sort(pit_value v); u64 pit_value_data(pit_value v); typedef struct { i64 top, cap; - pit_value data[]; + pit_value data[1]; /* flexible array member */ } pit_values; pit_values *pit_values_new(i64 capacity); void pit_values_push(struct pit_runtime *rt, pit_values *s, pit_value x); pit_value pit_values_pop(struct pit_runtime *rt, pit_values *s); typedef pit_value (*pit_nativefunc)(struct pit_runtime *rt, pit_value args); -typedef struct { // "heavy" values, the targets of refs +typedef struct { /* "heavy" values, the targets of refs */ enum pit_value_heavy_sort { - PIT_VALUE_HEAVY_SORT_CELL=0, // "value cell" - basically, a "location" referred to by a variable binding - PIT_VALUE_HEAVY_SORT_CONS, // cons cell - a pair of two values - PIT_VALUE_HEAVY_SORT_ARRAY, // fixed-size array of values - PIT_VALUE_HEAVY_SORT_BYTES, // bytestring - PIT_VALUE_HEAVY_SORT_FUNC, // Lisp closure - PIT_VALUE_HEAVY_SORT_NATIVEFUNC, // native function + PIT_VALUE_HEAVY_SORT_CELL=0, /* value cell - basically, a "location" referred to by a variable binding */ + PIT_VALUE_HEAVY_SORT_CONS, /* cons cell - a pair of two values */ + PIT_VALUE_HEAVY_SORT_ARRAY, /* fixed-size array of values */ + PIT_VALUE_HEAVY_SORT_BYTES, /* bytestring */ + PIT_VALUE_HEAVY_SORT_FUNC, /* Lisp closure */ + PIT_VALUE_HEAVY_SORT_NATIVEFUNC /* native function */ } hsort; union { pit_value cell; @@ -59,64 +60,65 @@ typedef struct { // "heavy" values, the targets of refs struct { u8 *data; i64 len; } bytes; struct { pit_value env; pit_value args; pit_value body; } func; pit_nativefunc nativefunc; - }; + } in; } pit_value_heavy; typedef struct { - pit_value name; // ref to bytestring - pit_value value; // ref to cell - pit_value function; // ref to cell + pit_value name; /* ref to bytestring */ + pit_value value; /* ref to cell */ + pit_value function; /* ref to cell */ bool is_macro, is_special_form; } pit_symtab_entry; -// "programs"; vectors of "instructions" for a very simple VM used by the evaluator +/* "programs"; vectors of "instructions" for a very simple VM used by the evaluator */ typedef struct { enum { EVAL_PROGRAM_ENTRY_LITERAL, - EVAL_PROGRAM_ENTRY_APPLY, + EVAL_PROGRAM_ENTRY_APPLY } sort; union { pit_value literal; - i64 apply; // arity of application - }; + i64 apply; /* arity of application */ + } in; } pit_runtime_eval_program_entry; typedef struct { i64 top, cap; - pit_runtime_eval_program_entry data[]; + pit_runtime_eval_program_entry data[1]; /* flexible array member */ } pit_runtime_eval_program; pit_runtime_eval_program *pit_runtime_eval_program_new(i64 capacity); -void pit_runtime_eval_program_push(struct pit_runtime *rt, pit_runtime_eval_program *s, pit_runtime_eval_program_entry x); +void pit_runtime_eval_program_push_literal(struct pit_runtime *rt, pit_runtime_eval_program *s, pit_value x); +void pit_runtime_eval_program_push_apply(struct pit_runtime *rt, pit_runtime_eval_program *s, i64 arity); typedef struct pit_runtime { - // interpreter state - pit_arena *values; // all heavy values - effectively an array of pit_value_heavy - MUTABLE! - pit_arena *bytes; // all bytestrings (including symbol names) - immutable - pit_arena *symtab; i64 symtab_len; // all symbols - effectively an array of pit_symtab_entry - MUTABLE! - // temporary/"scratch" memory - pit_arena *scratch; // temporary arena used during parsing and evaluation - pit_values *saved_bindings; // stack used to save old values of bindings to be restored ("shallow binding") - pit_values *expr_stack; // stack of subexpressions to evaluate during evaluation - pit_values *result_stack; // stack of intermediate values during evaluation - pit_runtime_eval_program *program; // intermediate stack-based program constructed during evaluation - // bookkeeping - // "frozen" values offsets: values before these offsets are immutable, and we can reset here later + /* interpreter state */ + pit_arena *values; /* all heavy values - effectively an array of pit_value_heavy - MUTABLE! */ + pit_arena *bytes; /* all bytestrings (including symbol names) - immutable */ + pit_arena *symtab; i64 symtab_len; /* all symbols - effectively an array of pit_symtab_entry - MUTABLE! */ + /* temporary/"scratch" memory */ + pit_arena *scratch; /* temporary arena used during parsing and evaluation */ + pit_values *saved_bindings; /* stack used to save old values of bindings to be restored ("shallow binding") */ + pit_values *expr_stack; /* stack of subexpressions to evaluate during evaluation */ + pit_values *result_stack; /* stack of intermediate values during evaluation */ + pit_runtime_eval_program *program; /* intermediate stack-based program constructed during evaluation */ + /* bookkeeping */ + /* "frozen" values offsets: values before these offsets are immutable, and we can reset here later */ i64 frozen_values, frozen_bytes, frozen_symtab; - pit_value error; // error value - if this is non-nil, an error has occured! only tracks the first error - i64 source_line, source_column; // for error reporting only; line and column of token start - i64 error_line, error_column; // line and column of token start at time of error + pit_value error; /* error value - if this is non-nil, an error has occured! only tracks the first error */ + i64 source_line, source_column; /* for error reporting only; line and column of token start */ + i64 error_line, error_column; /* line and column of token start at time of error */ } pit_runtime; -pit_runtime *pit_runtime_new(); +pit_runtime *pit_runtime_new(void); -void pit_runtime_freeze(pit_runtime *rt); // freeze the runtime at the current point - everything currently defined becomes immutable -void pit_runtime_reset(pit_runtime *rt); // restore the runtime to the frozen point, resetting everything that has happened since -bool pit_runtime_print_error(pit_runtime *rt); // return true if an error has occured, and print to stderr +void pit_runtime_freeze(pit_runtime *rt); /* freeze the runtime at the current point - everything currently defined becomes immutable */ +void pit_runtime_reset(pit_runtime *rt); /* restore the runtime to the frozen point, resetting everything that has happened since */ +bool pit_runtime_print_error(pit_runtime *rt); /* return true if an error has occured, and print to stderr */ -i64 pit_dump(pit_runtime *rt, char *buf, i64 len, pit_value v, bool readable); // if readable is true, try to produce output that can be machine-read (quotes on strings, etc) +i64 pit_dump(pit_runtime *rt, char *buf, i64 len, pit_value v, bool readable); /* if readable is true, try to produce output that can be machine-read (quotes on strings, etc) */ #define pit_trace(rt, v) pit_trace_(rt, "Trace [" __FILE__ ":" PIT_STR(__LINE__) "] %s\n", v) void pit_trace_(pit_runtime *rt, const char *format, pit_value v); void pit_error(pit_runtime *rt, const char *format, ...); -// working with small values +/* working with small values */ pit_value pit_value_new(pit_runtime *rt, enum pit_value_sort s, u64 data); double pit_as_double(pit_runtime *rt, pit_value v); pit_value pit_double_new(pit_runtime *rt, double d); @@ -127,11 +129,11 @@ pit_value pit_symbol_new(pit_runtime *rt, pit_symbol s); pit_ref pit_as_ref(pit_runtime *rt, pit_value v); pit_value pit_ref_new(pit_runtime *rt, pit_ref r); -// working with heavy values and refs +/* working with heavy values and refs */ pit_value pit_heavy_new(pit_runtime *rt); pit_value_heavy *pit_deref(pit_runtime *rt, pit_ref p); -// convenient predicates +/* convenient predicates */ bool pit_is_integer(pit_runtime *rt, pit_value a); bool pit_is_double(pit_runtime *rt, pit_value a); bool pit_is_symbol(pit_runtime *rt, pit_value a); @@ -145,7 +147,7 @@ bool pit_is_nativefunc(pit_runtime *rt, pit_value a); bool pit_eq(pit_value a, pit_value b); bool pit_equal(pit_runtime *rt, pit_value a, pit_value b); -// working with binary data +/* working with binary data */ pit_value pit_bytes_new(pit_runtime *rt, u8 *buf, i64 len); pit_value pit_bytes_new_cstr(pit_runtime *rt, char *s); pit_value pit_bytes_new_file(pit_runtime *rt, char *path); @@ -154,12 +156,14 @@ i64 pit_as_bytes(pit_runtime *rt, pit_value v, u8 *buf, i64 maxlen); bool pit_lexer_from_bytes(pit_runtime *rt, pit_lexer *ret, pit_value v); pit_value pit_read_bytes(pit_runtime *rt, pit_value v); -// working with the symbol table +/* working with the symbol table */ pit_value pit_intern(pit_runtime *rt, u8 *nm, i64 len); pit_value pit_intern_cstr(pit_runtime *rt, char *nm); bool pit_symbol_name_match(pit_runtime *rt, pit_value sym, u8 *buf, i64 len); bool pit_symbol_name_match_cstr(pit_runtime *rt, pit_value sym, char *s); pit_symtab_entry *pit_symtab_lookup(pit_runtime *rt, pit_value sym); +pit_value pit_get_value_cell(pit_runtime *rt, pit_value sym); +pit_value pit_get_function_cell(pit_runtime *rt, pit_value sym); pit_value pit_get(pit_runtime *rt, pit_value sym); void pit_set(pit_runtime *rt, pit_value sym, pit_value v); pit_value pit_fget(pit_runtime *rt, pit_value sym); @@ -173,27 +177,29 @@ void pit_sfset(pit_runtime *rt, pit_value sym, pit_value v); void pit_bind(pit_runtime *rt, pit_value sym, pit_value v); pit_value pit_unbind(pit_runtime *rt, pit_value sym); -// working with cells +/* working with cells */ pit_value pit_cell_new(pit_runtime *rt, pit_value v); pit_value pit_cell_get(pit_runtime *rt, pit_value cell); void pit_cell_set(pit_runtime *rt, pit_value cell, pit_value v); -// working with cons cells +/* working with cons cells */ pit_value pit_cons(pit_runtime *rt, pit_value car, pit_value cdr); pit_value pit_list(pit_runtime *rt, i64 num, ...); pit_value pit_car(pit_runtime *rt, pit_value v); pit_value pit_cdr(pit_runtime *rt, pit_value v); +void pit_setcar(pit_runtime *rt, pit_value v, pit_value x); +void pit_setcdr(pit_runtime *rt, pit_value v, pit_value x); pit_value pit_append(pit_runtime *rt, pit_value xs, pit_value ys); pit_value pit_reverse(pit_runtime *rt, pit_value xs); pit_value pit_contains_eq(pit_runtime *rt, pit_value needle, pit_value haystack); -// working with functions +/* working with functions */ pit_value pit_free_vars(pit_runtime *rt, pit_value args, pit_value body); pit_value pit_lambda(pit_runtime *rt, pit_value args, pit_value body); pit_value pit_nativefunc_new(pit_runtime *rt, pit_nativefunc f); pit_value pit_apply(pit_runtime *rt, pit_value f, pit_value args); -// evaluation! +/* evaluation! */ pit_value pit_expand_macros(pit_runtime *rt, pit_value top); pit_value pit_eval(pit_runtime *rt, pit_value e); |
