summaryrefslogtreecommitdiff
path: root/src/runtime.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime.h')
-rw-r--r--src/runtime.h120
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);