From 2ac6807d25e6f5696dcf0e7b2e360e99286863a5 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sun, 26 Nov 2023 01:00:39 -0500 Subject: Flush out Type struct --- compiler.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 206 insertions(+), 3 deletions(-) (limited to 'compiler.c') diff --git a/compiler.c b/compiler.c index 9a456d7..a3e6957 100644 --- a/compiler.c +++ b/compiler.c @@ -5,6 +5,7 @@ #include + // Vector utils #define VECT_MAX_GROW 100 @@ -114,9 +115,9 @@ Vector vect_clone(Vector *v) { out._el_sz = v->_el_sz; out.count = 0; - out.size = v->size; + out.size = v->count + 1; - out.data = malloc(out.size * out._el_sz); + out.data = malloc((out.count + 1) * out._el_sz); char *former = v->data; char *latter = out.data; @@ -139,21 +140,223 @@ Vector vect_from_string(char *s) { return out; } +// Returns the vector data as a null-terminated string +// do NOT free this pointer. Not safe to use this string +// at the same time as you are adding or removing from the +// vector. Instead consider cloning the vector if you must +// have both, or want an independant copy of the string. char *vect_as_string(Vector *v) { - ((char*)v->data)[v->count] = 0; + ((char*)v->data)[v->count * v->_el_sz] = 0; return v->data; } void vect_end(Vector *v) { + v->_el_sz = 0; + v->count = 0; + v->size = 0; free(v->data); + v->data = NULL; } + // Artifacts (vect of strings) +typedef Vector Artifact; + +/* Splits the string via the given character, and + * stores the split strings in an artifact + */ +Artifact art_from_str(const char *str, char split) { + Artifact out = vect_init(sizeof(char *)); + + char *cur = malloc(1); + cur[0] = 0; + int cur_len = 0; + + for (int i = 0; str[i] != 0; i++) { + if (str[i] == split) { + cur[cur_len] = 0; + vect_push(&out, &cur); + cur = malloc(1); + cur_len = 0; + } else { + cur_len += 1; + cur = realloc(cur, cur_len + 1); + cur[cur_len - 1] = str[i]; + } + } + + if (cur_len > 0) { + cur[cur_len] = 0; + vect_push(&out, &cur); + } else { + free(cur); + } + + return out; +} + +// Joins the string together with the provided character in between +// must free the returned data after use. +char *art_to_str(Artifact *art, char join) { + char *out = malloc(1); + int out_len = 0; + + for (int i = 0; i < art->count; i++) { + char ** cpy = vect_get(art, i); + for(int j = 0; cpy[j] != 0; j++) { + out[out_len] = (*cpy)[j]; + out_len += 1; + out = realloc(out, out_len + 1); + } + } + + out[out_len] = 0; + + return out; +} + +// Pops a string off the end of the artifact, +// freeing the data associated +void art_pop_str(Artifact *art) { + if (art->count == 0) + return; + + char ** to_free = vect_get(art, art->count - 1); + free(*to_free); + vect_pop(art); +} + +// Copies a string onto the artifact, +// you must free the original string +// manually if it was malloc-ed +void art_add_str(Artifact *art, char *str) { + Vector copy = vect_from_string(str); + char * copy_ptr = vect_as_string(©); + vect_push(art, ©_ptr); +} + + + +// Types + +typedef struct { + char *name; // Name of the type + int size; // Size (bytes) of the type + Vector members; // Member variables (Stored as variables) + void *module; // Module (for methods and member-type resolution) to tie the type to. +} Type; + +typedef struct { + char *name; + Type *type; + Vector ptr_chain; + int location; // negative for on stack, positive or zero for in register +} Variable; + +#define PTYPE_PTR 0 +#define PTYPE_REF 1 +#define PTYPE_ARR 2 + + + +// Copies the name, does not copy the module. +// Types should be freed at the end of the second pass, +// as they are shared among all variable structs +Type typ_init(char *name, void *module) { + Type out = {0}; + + Vector name_cpy = vect_from_string(name); + out.name = vect_as_string(&name_cpy); + out.members = vect_init(sizeof(Variable)); + out.module = module; + out.size = 0; + + return out; +} + +// Only for use by type_end on variable clean up +// at the end of the second pass +void var_deep_end(Variable *var); + +// Deep end, will free all memory associated with the +// struct, including name and sub-member variables +void typ_end(Type *t) { + free(t->name); + t->module = NULL; + + for (int i = 0; i < t->members.count; i++) { + Variable *to_end = vect_get(&(t->members), i); + var_deep_end(to_end); + } + + vect_end(&(t->members)); +} + + + +// Variables + +// Initializes the variable, copying name, not copying type. +Variable var_init(char *name, Type *type) { + Variable out = {0}; + + Vector name_cpy = vect_from_string(name); + out.name = vect_as_string(&name_cpy); + out.type = type; + out.ptr_chain = vect_init(sizeof(int)); + out.location = 0; + + return out; +} + +void var_deep_end(Variable *var) { + Variable *v = var; + free(v->name); + vect_end(&(v->ptr_chain)); + typ_end(v->type); +} + +// Simple cleanup for variables while the second pass is ongoing. +void var_end(Variable *v) { + free(v->name); + vect_end(&(v->ptr_chain)); +} + +// Variable operations + +// Type coercion engine +// TODO: all +Variable _op_coerce(Variable *base, Variable *to_coerce) { + Variable out = {0}; + return out; +} + + + +// Functions + +typedef struct { + char *name; + Vector inputs, outputs; + void *module; +} Function; + + + +// Modules + +typedef struct { + char *name; + bool exported; + Vector vars, funcs, submods; +} Module; + +// Whatev void help() { printf("\n"); -- cgit v1.2.3