diff --git a/ink.h b/ink.h index 0ef9278..22afddc 100644 --- a/ink.h +++ b/ink.h @@ -91,7 +91,7 @@ struct ink_routine { */ struct ink_collection_list { struct elem* elements; - size_t count; + int count; }; struct element_slab { @@ -104,13 +104,13 @@ struct element_slab { * Contains all the data for every element of any type and its garbage collection information. */ struct ink_type { - const char* name; //< The name of the type - int element_size; //< The size of individual elements of the type, 0 for int adjacent, negative for unmanaged size - struct element_slab* elements; //< The elements that are still live - int elements_top; //< The top of the elements list - int elements_capacity; //< The allocated capacity of the elements list - void (*collect)(struct context*,void*); //< The "destructor" of the object - struct ink_collection_list (*gc)(struct context*,void*); //< A function that returns an in-interpreter allocated list of elem references within the object + const char* name; /**< The name of the type */ + int element_size; /**< The size of individual elements of the type, 0 for int adjacent, negative for unmanaged size */ + struct element_slab* elements; /**< The elements that are still live */ + int elements_top; /**< The top of the elements list */ + int elements_capacity; /**< The allocated capacity of the elements list */ + void (*collect)(struct context*,void*); /**< The "destructor" of the object */ + struct ink_collection_list (*gc)(struct context*,void*); /**< A function that returns an in-interpreter allocated list of elem references within the object */ }; /** @@ -218,7 +218,7 @@ struct context* ink_make_context(void *(*malloc)(size_t), void *(*realloc)(void * Creates a context that includes the standard library of ink, as well as uses the C standard library to operate * @return a pointer to a context allocated with malloc and with predefined functions added */ -struct context* ink_make_default_context(); +struct context* ink_make_default_context(void); #endif /** diff --git a/lib.c b/lib.c index e81302e..18eeb97 100644 --- a/lib.c +++ b/lib.c @@ -194,14 +194,15 @@ static int ink_add_indigenous(struct context* ctx, const char* name, struct elem */ static int ink_add_lex_string(struct context* ctx, const char* name) { int i; + int len; if(ctx->lex_reserved_words == NULL) { ctx->lex_reserved_words = ctx->inner_malloc(sizeof(char*) * 8); ctx->lex_reserved_words_top = 0; ctx->lex_reserved_words_capacity = 8; } else if(ctx->lex_reserved_words_top == ctx->lex_reserved_words_capacity) { int new_count; - new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2); void* renewed; + new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2); renewed = ctx->inner_realloc(ctx->lex_reserved_words, sizeof(struct native_fn) * new_count); if(renewed == NULL) { return -5; @@ -215,7 +216,6 @@ static int ink_add_lex_string(struct context* ctx, const char* name) { return i; } } - int len; len = strlen(name); i = ctx->lex_reserved_words_top; ctx->lex_reserved_words[i] = ctx->malloc(len+1); @@ -332,9 +332,11 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, * @internal this function is slightly cursed */ static char* ink_itoa(struct context* _, int cpy) { - char* n = _->malloc(16); + char* n; + char* it; + n = _->malloc(16); n[15] = 0; - char* it = n+15; + it = n+15; do { it--; *it = (cpy % 10) + '0'; @@ -345,7 +347,7 @@ static char* ink_itoa(struct context* _, int cpy) { } #ifndef NOSTDLIB -struct context* ink_make_default_context() { +struct context* ink_make_default_context(void) { struct context* ctx; ctx = ink_make_context(malloc, realloc, free, putchar); ink_std_library(ctx); @@ -357,6 +359,7 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch int i; int done; struct elem value; + int err; if(*end == 0) { return 0; } @@ -383,7 +386,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch done = 1; } if(done) { - int err; err = ink_push(pContext, value); if(err < 0) { return -19; @@ -394,7 +396,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch if (strcmp(r, pContext->words[i].name) == 0) { value.value = i; value.type = INK_FUNCTION; - int err; err = ink_push(pContext, value); if(err < 0) { return -20; @@ -409,7 +410,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch if (strcmp(r, pContext->native_words[i].name) == 0) { value.value = i; value.type = INK_NATIVE_FUNCTION; - int err; err = ink_push(pContext, value); if(err < 0) { return -21; @@ -427,7 +427,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch } value.value = atoi(r); value.type = INK_INTEGER; - int err; err = ink_push(pContext, value); if(err < 0) { return -22; @@ -447,7 +446,6 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch } else { value.type = INK_RESERVED; } - int err; err = ink_push(pContext, value); if(err < 0) { return -23; @@ -458,8 +456,7 @@ static int ink_consume_one(int* end, struct context* pContext, char** buffer, ch } static int ink_lex(struct context *pContext, char* buffer) { - int i; - // Limits the token size to 127 chars + /* Limits the token size to 127 chars */ char r[128]; int end; int err; @@ -501,7 +498,7 @@ int ink_make_routine(struct context* ctx) { struct ink_routine* it; struct ink_routine* end; - // Allocate space if needed + /* Allocate space if needed */ if(ctx->routines == NULL) { ctx->routines = ctx->inner_malloc(sizeof(struct ink_routine) * 8); ctx->routines_top = 0; @@ -533,7 +530,7 @@ int ink_make_routine(struct context* ctx) { it = ctx->routines; end = ctx->routines + ctx->routines_capacity; - // Looks for a reusable routine space then uses it + /* Looks for a reusable routine space then uses it */ for(;it != end;++it) { if(it->panic == INK_ROUTINE_CAN_REUSE) { int idx; @@ -551,6 +548,7 @@ int ink_make_routine(struct context* ctx) { return idx; } } + return -758; } int ink_kill_routine(struct context* ctx, int routine){ @@ -584,6 +582,7 @@ int ink_kill_routine(struct context* ctx, int routine){ static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) { struct ink_routine* currentRoutine; int i, function_buffer_top, function_name, mode; + int err; #define LABEL_BUFFER 128 #define FUNCTION_BUFFER 256 struct label labels[LABEL_BUFFER]; @@ -597,7 +596,7 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i mode = MODE_EXECUTABLE; memset(labels, 0, sizeof(struct label)*LABEL_BUFFER); - // Loop from hell, good luck, pro-tip: leave the parser alone + /* Loop from hell, good luck, pro-tip: leave the parser alone */ for(i = 0; i < currentRoutine->top; ++i) { struct elem current; current = currentRoutine->stack[i]; @@ -665,7 +664,6 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i struct elem pt; pt = function_buffer[j]; if(pt.type == INK_RESERVED) { - const char* str = pContext->lex_reserved_words[pt.value]; int k; for(k = 0; k < LABEL_BUFFER; k++) { if(labels[k].active) { @@ -682,7 +680,6 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i } } } - int err; err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top); if(err < 0) { pContext->panic = 1; @@ -774,33 +771,36 @@ int ink_step(struct context *pContext) { } void ink_compile(struct context *pContext, char* buffer) { - int routine, saved, i, executable_buffer_top; - // Main function has a size limit of 256 (need to know that for REPL + int routine, saved, executable_buffer_top; + /* Main function has a size limit of 256 (need to know that for REPL */ struct elem executable_buffer[256]; + struct ink_routine* currentRoutine; + int err; + struct stack_frame frame; + char* integer; + size_t integer_size; + char main_fn[32] = "__-MAIN-__"; + routine = ink_make_routine(pContext); saved = pContext->routine_current; pContext->routine_current = routine; - struct ink_routine* currentRoutine = pContext->routines + routine; + currentRoutine = pContext->routines + routine; currentRoutine->stack = NULL; currentRoutine->top = 0; currentRoutine->capacity = 0; - int err; err = ink_lex(pContext, buffer); if(err < 0) { pContext->panic = 1; return; } - i = 0; executable_buffer_top = 0; err = ink_parse(pContext, executable_buffer, &executable_buffer_top); if(err < 0) { pContext->panic = 1; return; } - struct stack_frame frame; - char main_fn[32] = "__-MAIN-__"; - char* integer = ink_itoa(pContext, routine); - size_t integer_size = strlen(integer); + integer = ink_itoa(pContext, routine); + integer_size = strlen(integer); memcpy(main_fn+10, integer, integer_size); pContext->free(integer); main_fn[10+integer_size] = 0; @@ -835,19 +835,19 @@ int ink_step_everyone(struct context* pContext) { int out; pContext->routine_current = -1; for(;;) { - // Increment to next runnable routine + /* Increment to next runnable routine */ do{ ++(pContext->routine_current); } while(pContext->routine_current < pContext->routines_top && pContext->routines[pContext->routine_current].panic != 0); - // Exit condition + /* Exit condition */ if(pContext->routine_current >= pContext->routines_top) break; - // Kill? + /* Kill? */ if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) { ink_kill_routine(pContext, pContext->routine_current); } - //Step! + /* Step! */ out = ink_step(pContext); if(out == 0) { pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS; @@ -866,7 +866,7 @@ int ink_new_type( struct ink_collection_list (*gc)(struct context*,void*) ) { if(ctx->panic) return -128; - // Resize for push + /* Resize for push */ if(ctx->types == NULL) { ctx->types = ctx->inner_malloc(sizeof(struct ink_type) * 8); ctx->types_top = 0; @@ -884,7 +884,7 @@ int ink_new_type( } } - // Push + /* Push */ ctx->types[ctx->types_top].name = type_name; ctx->types[ctx->types_top].element_size = size; ctx->types[ctx->types_top].elements = NULL; @@ -894,7 +894,7 @@ int ink_new_type( ctx->types[ctx->types_top].gc = gc; ctx->types_top++; - // Satisfying the minimal value requirement + /* Satisfying the minimal value requirement */ return ctx->types_top - 1 + 16; } @@ -920,13 +920,15 @@ void* ink_get_value(struct context* ctx, struct elem ref) { struct elem ink_make_native(struct context* ctx, int type, void* ptr) { int type_id; struct elem ret; + int g, i; + if(type < 16) { ret.type = 0; ret.value = -130; return ret; } - // Apply invariant of the user defined types + /* Apply invariant of the user defined types */ type_id = type - 16; if(type_id >= ctx->types_top) { ret.type = 0; @@ -940,7 +942,7 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) { return ret; } - // Resize for push of value in store + /* Resize for push of value in store */ if(ctx->types[type_id].elements == NULL) { ctx->types[type_id].elements = ctx->inner_malloc(sizeof(struct element_slab) * 8); ctx->types[type_id].elements_top = 0; @@ -962,8 +964,7 @@ struct elem ink_make_native(struct context* ctx, int type, void* ptr) { } } - // Push value in store - int g, i; + /* Push value in store */ g = ctx->types[type_id].elements_capacity; for(i = 0; i < g; ++i) { if(! ctx->types[type_id].elements[i].in_use) { @@ -1003,7 +1004,7 @@ void ink_gc(struct context* ctx) { } } - // Start by marking the roots of the routines + /* Start by marking the roots of the routines */ for(i = 0; i < ctx->routines_top; ++i) { for(j = 0; j < ctx->routines[i].top; ++j) { v = ink_get_value_link(ctx, ctx->routines[i].stack[j]); @@ -1011,19 +1012,18 @@ void ink_gc(struct context* ctx) { } } - // Mark the rest of the data + /* Mark the rest of the data */ do { marked = 0; for (i = 0; i < ctx->types_top; ++i) { for (j = 0; j < ctx->types[i].elements_top; ++j) { - // Only mark from things that are active and detected as in use + /* Only mark from things that are active and detected as in use */ if (ctx->types[i].elements[j].in_use && ctx->types[i].elements[j].uses) { struct ink_collection_list c; c = ctx->types[i].gc(ctx, ctx->types[i].elements[j].data); for (k = 0; k < c.count; ++k) { - struct element_slab *v; v = ink_get_value_link(ctx, c.elements[k]); - // Never mark twice to avoid infinite loops with e.g. arrays that contain themselves + /* Never mark twice to avoid infinite loops with e.g. arrays that contain themselves */ if (v != NULL && !v->uses) { ++v->uses; marked = 1; @@ -1035,7 +1035,7 @@ void ink_gc(struct context* ctx) { } } while(marked); - // Sweep phase: explore any allocated data and sweep the unused away + /* Sweep phase: explore any allocated data and sweep the unused away */ for(i = 0; i < ctx->types_top; ++i) { for(j = 0; j < ctx->types[i].elements_top; ++j) { if(ctx->types[i].elements[j].uses == 0 && ctx->types[i].elements[j].in_use) { @@ -1201,7 +1201,7 @@ static void dupe_elem(struct context* ctx) { } a = currentRoutine->stack[currentRoutine->top-1]; err = ink_push(ctx, a); - if(err < 0) ctx->panic; + if(err < 0) ctx->panic = 1; } static void drop_elem(struct context* ctx) { @@ -1235,7 +1235,7 @@ static void pluck_elem(struct context* ctx) { } ink_pop(ctx); err = ink_push(ctx, currentRoutine->stack[position]); - if(err < 0) ctx->panic; + if(err < 0) ctx->panic = 1; } static void swap_elem(struct context* ctx) { @@ -1473,9 +1473,9 @@ static void run_gc(struct context* ctx) { int ink_std_library(struct context* ctx) { - int v, array_t; + int v; v = 0; - array_t = ink_new_type(ctx, "array", sizeof(struct ink_array), collect_array, gc_array); + ink_new_type(ctx, "array", sizeof(struct ink_array), collect_array, gc_array); v += ink_add_native(ctx, "array.new", new_array); v += ink_add_native(ctx, "array.push", push_array); v += ink_add_native(ctx, "array.index", index_array);