diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/lcq/pit.h | 11 | ||||
| -rw-r--r-- | include/lcq/pit/arena.h | 45 | ||||
| -rw-r--r-- | include/lcq/pit/runtime.h | 34 | ||||
| -rw-r--r-- | include/lcq/pit/utils.h | 47 | ||||
| -rw-r--r-- | include/lcq/pit/vec.h | 48 |
5 files changed, 133 insertions, 52 deletions
diff --git a/include/lcq/pit.h b/include/lcq/pit.h new file mode 100644 index 0000000..3afce9f --- /dev/null +++ b/include/lcq/pit.h @@ -0,0 +1,11 @@ +#ifndef LCOLONQ_PIT_H +#define LCOLONQ_PIT_H + +#include <lcq/pit/types.h> +#include <lcq/pit/utils.h> +#include <lcq/pit/lexer.h> +#include <lcq/pit/parser.h> +#include <lcq/pit/runtime.h> +#include <lcq/pit/library.h> + +#endif diff --git a/include/lcq/pit/arena.h b/include/lcq/pit/arena.h new file mode 100644 index 0000000..fcaca55 --- /dev/null +++ b/include/lcq/pit/arena.h @@ -0,0 +1,45 @@ +#ifndef LCOLONQ_PIT_ARENA_H +#define LCOLONQ_PIT_ARENA_H + +#include <lcq/pit/types.h> + +typedef i64 pit_arena_index; + +static inline uintptr_t pit_align_down(uintptr_t addr, uintptr_t align) { + return addr & ~(align - 1); /* easy! just zero the low bits */ +} +static inline uintptr_t pit_align_up(uintptr_t addr, uintptr_t align) { + return (addr + align - 1) /* increment past the next aligned address... */ + & ~(align - 1); /* ...and then zero the low bits */ +} +typedef struct { + i64 elem_size, /* size of one element */ + capacity, /* capacity in of data in bytes - only used to reset */ + next, /* index (in elements) of next element to insert */ + back; /* index (in bytes) one past the end of data. */ + /* back starts at capacity, and decreases as you alloc_back */ + u8 data[]; +} pit_arena; + +/* create a new arena in a buffer of buf_len size in bytes that stores elements of elem_size */ +pit_arena *pit_arena_new(u8 *buf, i64 buf_len, i64 elem_size); + +/* remove all elements from an array */ +void pit_arena_reset(pit_arena *a); + +/* allocate space for one or multiple elements, and return the index of the first element */ +pit_arena_index pit_arena_alloc_index(pit_arena *a); +pit_arena_index pit_arena_alloc_array_index(pit_arena *a, i64 num); + +/* allocate space for one or multiple elements, and return a pointer */ +void *pit_arena_alloc(pit_arena *a); +void *pit_arena_alloc_array(pit_arena *a, i64 num); + +/* retrieve a pointer to the element(s) at a given index */ +void *pit_arena_get(pit_arena *a, pit_arena_index idx); + +/* allocate arbitrary bytes on the "back" of the arena. + this can be an arbitrary size in bytes */ +void *pit_arena_alloc_back(pit_arena *a, i64 sz); + +#endif diff --git a/include/lcq/pit/runtime.h b/include/lcq/pit/runtime.h index da93dda..da3cbdd 100644 --- a/include/lcq/pit/runtime.h +++ b/include/lcq/pit/runtime.h @@ -3,6 +3,8 @@ #include <lcq/pit/types.h> #include <lcq/pit/utils.h> +#include <lcq/pit/vec.h> +#include <lcq/pit/arena.h> #include <lcq/pit/lexer.h> struct pit_runtime; @@ -23,13 +25,7 @@ typedef u64 pit_value; enum pit_value_sort pit_value_sort(pit_value v); u64 pit_value_data(pit_value v); -typedef struct { - i64 capacity, next; - pit_value data[]; -} pit_values; -pit_values *pit_values_new(u8 *buf, i64 buf_len); -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); +PIT_DECLARE_VEC(pit_value) typedef pit_value (*pit_nativefunc)(struct pit_runtime *rt, pit_value args, void *data); typedef struct { /* "heavy" values, the targets of refs */ @@ -65,21 +61,17 @@ typedef struct { /* "programs"; vectors of "instructions" for a very simple VM used by the evaluator */ typedef struct { enum { - EVAL_PROGRAM_ENTRY_LITERAL, - EVAL_PROGRAM_ENTRY_APPLY + PIT_RUNTIME_EVAL_INS_LITERAL, + PIT_RUNTIME_EVAL_INS_APPLY } sort; union { pit_value literal; i64 apply; /* arity of application */ } in; -} pit_runtime_eval_program_entry; -typedef struct { - i64 capacity, next; - pit_runtime_eval_program_entry data[]; -} pit_runtime_eval_program; -pit_runtime_eval_program *pit_runtime_eval_program_new(u8 *buf, i64 buf_len); -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); +} pit_runtime_eval_ins; +PIT_DECLARE_VEC(pit_runtime_eval_ins) +void pit_runtime_eval_program_push_literal(struct pit_runtime *rt, pit_vec(pit_runtime_eval_ins) *s, pit_value x); +void pit_runtime_eval_program_push_apply(struct pit_runtime *rt, pit_vec(pit_runtime_eval_ins) *s, i64 arity); /* annotation attached to (some) heavy values detaiking things like line numbers */ typedef struct { @@ -106,10 +98,10 @@ typedef struct pit_runtime { pit_arena *symtab; i64 symtab_len; /* all symbols - effectively an array of pit_symtab_entry */ /* 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 */ + pit_vec(pit_value) *saved_bindings; /* stack used to save old values of bindings to be restored ("shallow binding") */ + pit_vec(pit_value) *expr_stack; /* stack of subexpressions to evaluate during evaluation */ + pit_vec(pit_value) *result_stack; /* stack of intermediate values during evaluation */ + pit_vec(pit_runtime_eval_ins) *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_symtab; diff --git a/include/lcq/pit/utils.h b/include/lcq/pit/utils.h index b864637..ee51518 100644 --- a/include/lcq/pit/utils.h +++ b/include/lcq/pit/utils.h @@ -4,50 +4,35 @@ #include <stdarg.h> #include <lcq/pit/types.h> +/* macro helpers */ +#define PIT_CONCAT(a, b) a ## b +#define PIT_STRSTR(x) #x +#define PIT_STR(x) PIT_STRSTR(x) + +/* implementations of needed libc functions */ /* ctype */ -static inline bool pit_ctype_isdigit(int a) { return a >= '0' && a <= '9'; } -static inline bool pit_ctype_islower(int a) { return a >= 'a' && a <= 'z'; } -static inline bool pit_ctype_isupper(int a) { return a >= 'A' && a <= 'Z'; } -static inline bool pit_ctype_isalpha(int a) { return pit_ctype_islower(a) || pit_ctype_isupper(a); } -static inline bool pit_ctype_isprint(int a) { return a >= 0x20 && a <= 0x7f; } -static inline bool pit_ctype_isspace(int a) { return a == ' ' || a == '\r' || a == '\n' || a == '\t'; } +static inline bool pit_libc_ctype_isdigit(int a) { return a >= '0' && a <= '9'; } +static inline bool pit_libc_ctype_islower(int a) { return a >= 'a' && a <= 'z'; } +static inline bool pit_libc_ctype_isupper(int a) { return a >= 'A' && a <= 'Z'; } +static inline bool pit_libc_ctype_isalpha(int a) { return pit_libc_ctype_islower(a) || pit_libc_ctype_isupper(a); } +static inline bool pit_libc_ctype_isprint(int a) { return a >= 0x20 && a <= 0x7f; } +static inline bool pit_libc_ctype_isspace(int a) { return a == ' ' || a == '\r' || a == '\n' || a == '\t'; } /* string */ -static inline size_t pit_string_strlen(char *s) { +static inline size_t pit_libc_string_strlen(char *s) { size_t idx = 0; while (s[idx] != 0) ++idx; return idx; } -static inline u8 *pit_string_memcpy(u8 *dest, u8 *src, size_t n) { +static inline u8 *pit_libc_string_memcpy(u8 *dest, u8 *src, size_t n) { size_t i = 0; for (; i < n; ++i) dest[i] = src[i]; return dest; } -int pit_string_vsnprintf(char *str, size_t size, char *format, va_list ap); -int pit_string_snprintf(char *buf, size_t len, char *format, ...); +int pit_libc_string_vsnprintf(char *str, size_t size, char *format, va_list ap); +int pit_libc_string_snprintf(char *buf, size_t len, char *format, ...); /* assorted utilities and debugging tools */ #define pit_mul(result, a, b) *result = (i64) (a) * (i64) (b) -/* arenas */ -static inline uintptr_t pit_align_down(uintptr_t addr, uintptr_t align) { - return addr & ~(align - 1); /* easy! just zero the low bits */ -} -static inline uintptr_t pit_align_up(uintptr_t addr, uintptr_t align) { - return (addr + align - 1) /* increment past the next aligned address... */ - & ~(align - 1); /* ...and then zero the low bits */ -} -typedef struct { - i64 elem_size, capacity, next, back; - u8 data[]; -} pit_arena; -pit_arena *pit_arena_new(u8 *buf, i64 buf_len, i64 elem_size); -void pit_arena_reset(pit_arena *a); -i64 pit_arena_alloc_idx(pit_arena *a); -i64 pit_arena_alloc_bulk_idx(pit_arena *a, i64 num); -void *pit_arena_get(pit_arena *a, i64 idx); -void *pit_arena_alloc(pit_arena *a); -void *pit_arena_alloc_bulk(pit_arena *a, i64 num); -void *pit_arena_alloc_back(pit_arena *a, i64 sz); - #endif diff --git a/include/lcq/pit/vec.h b/include/lcq/pit/vec.h new file mode 100644 index 0000000..646f2e0 --- /dev/null +++ b/include/lcq/pit/vec.h @@ -0,0 +1,48 @@ +#ifndef LCOLONQ_PIT_VEC_H +#define LCOLONQ_PIT_VEC_H + +#include <lcq/pit/types.h> +#include <lcq/pit/utils.h> + +#define pit_vec(ty) pit_vec__ ## ty ## __type +#define pit_vec_new(ty) pit_vec__ ## ty ## __new +#define pit_vec_get(ty) pit_vec__ ## ty ## __get +#define pit_vec_push(ty) pit_vec__ ## ty ## __push +#define pit_vec_pop(ty) pit_vec__ ## ty ## __pop + +#define PIT_DECLARE_VEC(ty) \ + typedef struct { \ + i64 capacity, next; \ + u8 data[]; \ + } pit_vec(ty); \ + static __attribute__ ((unused)) pit_vec(ty) *pit_vec_new(ty)(u8 *buf, i64 buf_len) { \ + uintptr_t base = (uintptr_t) buf; \ + uintptr_t aligned = pit_align_up(base, sizeof(void *)); \ + pit_vec(ty) *ret = (pit_vec(ty) *) aligned; \ + uintptr_t data = aligned + (i64) sizeof(pit_vec(ty)); \ + i64 offset = (i64) data - (i64) base; \ + i64 remaining = (i64) (buf_len - offset); \ + ret->next = 0; \ + ret->capacity = remaining; \ + if ((ret->next + 1) * (i64) sizeof(ty) > ret->capacity) return NULL; \ + return ret; \ + } \ + static __attribute__ ((unused)) ty *pit_vec_get(ty)(pit_vec(ty) *s, i64 i) { \ + i64 idx = i * (i64) sizeof(ty); \ + if (idx + (i64) sizeof(ty) > s->capacity) return NULL; \ + return (ty *) &s->data[idx]; \ + } \ + static __attribute__ ((unused)) i64 pit_vec_push(ty)(pit_vec(ty) *s, ty x) { \ + i64 idx = s->next++ * (i64) sizeof(ty); \ + if (idx + (i64) sizeof(ty) > s->capacity) { return -1; } \ + *((ty *) &s->data[idx]) = x; \ + return s->next - 1; \ + } \ + static __attribute__ ((unused)) i64 pit_vec_pop(ty)(pit_vec(ty) *s, ty *v) { \ + i64 idx = (s->next - 1) * (i64) sizeof(ty); \ + if (s->next == 0 || idx + (i64) sizeof(ty) > s->capacity) return -1; \ + *v = *((ty *) &s->data[idx]); \ + return --s->next; \ + } + +#endif |
