From 5c0cfba1958209a515a550b8189ed7cc930075e9 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Mon, 13 May 2024 21:26:17 +0200 Subject: [PATCH] All error handling has been badly handled --- ink.h | 10 ++- lib.c | 274 +++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 190 insertions(+), 94 deletions(-) diff --git a/ink.h b/ink.h index 75792d1..d50c8a1 100644 --- a/ink.h +++ b/ink.h @@ -56,11 +56,13 @@ struct context { int lex_reserved_words_top; }; -void ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)); -void ink_push(struct context* ctx, struct elem value); -void ink_push_fn(struct context* ctx, struct stack_frame value); +int ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)); +int ink_push(struct context* ctx, struct elem value); +int ink_push_fn(struct context* ctx, struct stack_frame value); struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, size_t), void(*free)(void*), int(*putchar)(int)); +#ifndef NOSTDLIB struct context* ink_make_default_context(); +#endif int ink_step(struct context *pContext); void ink_run(struct context *pContext, char* buffer); -void ink_std_library(struct context* ctx); +int ink_std_library(struct context* ctx); diff --git a/lib.c b/lib.c index ff1c7d1..45e0fbb 100644 --- a/lib.c +++ b/lib.c @@ -1,11 +1,10 @@ - +#include "ink.h" #ifndef NOSTDLIB #include #include #include #include #endif -#include "ink.h" #define INK_RESERVED (-1) #define INK_FUNCTION_KW (-2) @@ -98,7 +97,7 @@ static int atoi(const char* c) { #endif -void ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)) { +int ink_add_native(struct context* ctx, const char* name, void(*value)(struct context*)) { if(ctx->native_words == NULL) { ctx->native_words = ctx->malloc(sizeof(struct native_fn) * 8); ctx->native_words_top = 0; @@ -107,7 +106,7 @@ void ink_add_native(struct context* ctx, const char* name, void(*value)(struct c int new_count = (ctx->native_words_capacity + ctx->native_words_capacity/2); void* renewed = ctx->realloc(ctx->native_words, sizeof(struct native_fn) * new_count); if(renewed == NULL) { - // TODO: error + return -3; } else { ctx->native_words = renewed; ctx->native_words_capacity = new_count; @@ -116,13 +115,14 @@ void ink_add_native(struct context* ctx, const char* name, void(*value)(struct c int len = strlen(name); char* copy = ctx->malloc(len+1); if(copy == NULL) { - // TODO: error + return -4; } memcpy(copy, name, len); copy[len] = 0; ctx->native_words[ctx->native_words_top].value = value; ctx->native_words[ctx->native_words_top].name = copy; ctx->native_words_top++; + return 0; } static int ink_add_indigenous(struct context* ctx, const char* name, struct elem* m, size_t count) { @@ -134,7 +134,7 @@ static int ink_add_indigenous(struct context* ctx, const char* name, struct elem int new_count = (ctx->words_capacity + ctx->words_capacity/2); void* renewed = ctx->realloc(ctx->words, sizeof(struct native_fn) * new_count); if(renewed == NULL) { - // TODO: error + return -1; } else { ctx->words = renewed; ctx->words_capacity = new_count; @@ -153,7 +153,7 @@ static int ink_add_indigenous(struct context* ctx, const char* name, struct elem int len = strlen(name); char* copy = ctx->malloc(len+1); if(copy == NULL) { - // TODO: error + return -2; } memcpy(copy, name, len); copy[len] = 0; @@ -174,7 +174,7 @@ static int ink_add_lex_string(struct context* ctx, const char* name) { int new_count = (ctx->lex_reserved_words_capacity + ctx->lex_reserved_words_capacity/2); void* renewed = ctx->realloc(ctx->lex_reserved_words, sizeof(struct native_fn) * new_count); if(renewed == NULL) { - // TODO: error + return -5; } else { ctx->lex_reserved_words = renewed; ctx->lex_reserved_words_capacity = new_count; @@ -194,7 +194,7 @@ static int ink_add_lex_string(struct context* ctx, const char* name) { return i; } -void ink_push(struct context* ctx, struct elem value) { +int ink_push(struct context* ctx, struct elem value) { if(ctx->stack == NULL) { ctx->stack = ctx->malloc(sizeof(struct elem) * 8); ctx->top = 0; @@ -203,7 +203,7 @@ void ink_push(struct context* ctx, struct elem value) { int new_count = (ctx->capacity + ctx->capacity/2); void* renewed = ctx->realloc(ctx->stack, sizeof(struct elem) * new_count); if(renewed == NULL) { - // TODO: error + return -18; } else { ctx->stack = renewed; ctx->capacity = new_count; @@ -211,9 +211,10 @@ void ink_push(struct context* ctx, struct elem value) { } ctx->stack[ctx->top] = value; ctx->top++; + return 0; } -void ink_push_fn(struct context* ctx, struct stack_frame value) { +int ink_push_fn(struct context* ctx, struct stack_frame value) { if(ctx->function_stack == NULL) { ctx->function_stack = ctx->malloc(sizeof(struct stack_frame) * 8); ctx->function_stack_top = 0; @@ -222,7 +223,7 @@ void ink_push_fn(struct context* ctx, struct stack_frame value) { int new_count = (ctx->function_stack_capacity + ctx->function_stack_capacity/2); void* renewed = ctx->realloc(ctx->function_stack, sizeof(struct stack_frame) * new_count); if(renewed == NULL) { - // TODO: error + return -9; } else { ctx->function_stack = renewed; ctx->function_stack_capacity = new_count; @@ -230,6 +231,7 @@ void ink_push_fn(struct context* ctx, struct stack_frame value) { } ctx->function_stack[ctx->function_stack_top] = value; ctx->function_stack_top++; + return 0; } static void ink_pop_fn(struct context* ctx) { @@ -296,48 +298,51 @@ struct context* ink_make_default_context() { } #endif -static void ink_consume_one(int* end, struct context* pContext, char** buffer, char* r) { +static int ink_consume_one(int* end, struct context* pContext, char** buffer, char* r) { int i; if(*end == 0) { - return; + return 0; } r[*end] = 0; int done = 0; + struct elem value; if (strcmp(r, _KEYWORD_INK_FUNCTION) == 0) { - struct elem value; value.value = 0; value.type = INK_FUNCTION_KW; - ink_push(pContext, value); done = 1; } if (!done && strcmp(r, _KEYWORD_INK_DO) == 0) { - struct elem value; value.value = 0; value.type = INK_DO_KW; - ink_push(pContext, value); done = 1; } if (!done && strcmp(r, _KEYWORD_INK_END) == 0) { - struct elem value; value.value = 0; value.type = INK_END_KW; - ink_push(pContext, value); done = 1; } if (!done && strcmp(r, _KEYWORD_INK_RETURN) == 0) { - struct elem value; value.value = 0; value.type = INK_RETURN; - ink_push(pContext, value); done = 1; } + if(done) { + int err; + err = ink_push(pContext, value); + if(err < 0) { + return -19; + } + } if (!done) { for (i = 0; i < pContext->words_top; ++i) { if (strcmp(r, pContext->words[i].name) == 0) { - struct elem value; value.value = i; value.type = INK_FUNCTION; - ink_push(pContext, value); + int err; + err = ink_push(pContext, value); + if(err < 0) { + return -20; + } done = 1; break; } @@ -346,10 +351,13 @@ static void ink_consume_one(int* end, struct context* pContext, char** buffer, c if (!done) { for (i = 0; i < pContext->native_words_top; ++i) { if (strcmp(r, pContext->native_words[i].name) == 0) { - struct elem value; value.value = i; value.type = INK_NATIVE_FUNCTION; - ink_push(pContext, value); + int err; + err = ink_push(pContext, value); + if(err < 0) { + return -21; + } done = 1; break; } @@ -361,41 +369,63 @@ static void ink_consume_one(int* end, struct context* pContext, char** buffer, c goto not_an_int; } } - struct elem value; value.value = atoi(r); value.type = INK_INTEGER; - ink_push(pContext, value); + int err; + err = ink_push(pContext, value); + if(err < 0) { + return -22; + } done = 1; } - not_an_int: if (!done) { + not_an_int: + if (!done) { i = ink_add_lex_string(pContext, r); - struct elem value; + if(i < 0) { + pContext->panic = 1; + return -7; + } value.value = i; if(r[strlen(r) - 1] == ':') { value.type = INK_LABEL; } else { value.type = INK_RESERVED; } - ink_push(pContext, value); + int err; + err = ink_push(pContext, value); + if(err < 0) { + return -23; + } } *end = 0; + return 0; } -static void ink_lex(struct context *pContext, char* buffer) { +static int ink_lex(struct context *pContext, char* buffer) { int i; char r[128]; int end = 0; + int err; while(*buffer != 0) { if(isspace(*buffer)) { - ink_consume_one(&end, pContext, &buffer, r); + err = ink_consume_one(&end, pContext, &buffer, r); + if(err < 0) { + pContext->panic = 1; + return -8; + } } else { r[end] = *buffer; ++end; } ++buffer; } - ink_consume_one(&end, pContext, &buffer, r); + err = ink_consume_one(&end, pContext, &buffer, r); + if(err < 0) { + pContext->panic = 1; + return -9; + } + return 0; } static int lblcmp(const char* label, const char* other, size_t label_sz) { @@ -416,7 +446,7 @@ static int lblcmp(const char* label, const char* other, size_t label_sz) { * @param executable_buffer_top * @internal Loop from hell */ -static void ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) { +static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) { int i; #define LABEL_BUFFER 128 #define FUNCTION_BUFFER 256 @@ -430,16 +460,18 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, int mode = 0; memset(labels, 0, sizeof(struct label)*LABEL_BUFFER); for(i = 0; i < pContext->top; ++i) { - struct elem current = pContext->stack[i]; + struct elem current; + current = pContext->stack[i]; switch (mode) { case MODE_EXECUTABLE: switch(current.type) { case INK_FUNCTION_KW: mode = MODE_FUNCTION; + function_name = -1; goto next_token; case INK_DO_KW: case INK_END_KW: - // TODO: error + return -26; default: executable_buffer[*executable_buffer_top] = current; *executable_buffer_top += 1; @@ -448,7 +480,7 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, case MODE_FUNCTION: if(current.type == INK_DO_KW) { if(function_name == -1) { - // TODO: error (function name was not supplied) + return -27; } else { mode = MODE_DO; memset(labels, 0, sizeof(struct label)*128); @@ -456,10 +488,10 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, } } if(function_name != -1) { - // TODO: error (function name supplied already) + return -28; } if(current.type != INK_RESERVED) { - // TODO: error + return -29; } function_name = current.value; break; @@ -467,14 +499,15 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, if(current.type == INK_END_KW) { int j; for(j = 0; j < function_buffer_top; j++) { - struct elem pt = function_buffer[j]; + struct elem pt; + pt = function_buffer[j]; if(pt.type == INK_LABEL) { int k; for(k = 0; k < LABEL_BUFFER; k++) { if(labels[k].active) { if(strcmp(labels[k].name, pContext->lex_reserved_words[pt.value]) == 0) { labels[k].dest = j; - // TODO: error + return -30; break; } } else { @@ -490,7 +523,8 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, } } for(j = 0; j < function_buffer_top; j++) { - struct elem pt = function_buffer[j]; + struct elem pt; + pt = function_buffer[j]; if(pt.type == INK_RESERVED) { const char* str = pContext->lex_reserved_words[pt.value]; int k; @@ -507,7 +541,12 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, } } } - ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top); + int err; + err = ink_add_indigenous(pContext, pContext->lex_reserved_words[function_name], function_buffer, function_buffer_top); + if(err < 0) { + pContext->panic = 1; + return -33; + } function_buffer_top = 0; mode = MODE_EXECUTABLE; goto next_token; @@ -519,8 +558,9 @@ static void ink_parse(struct context* pContext, struct elem* executable_buffer, next_token: i=i; } if(mode == MODE_FUNCTION || mode == MODE_DO) { - // error, missing an end + return -32; } + return 0; #undef MODE_EXECUTABLE #undef MODE_FUNCTION #undef MODE_DO @@ -534,8 +574,13 @@ int ink_step(struct context *pContext) { if(pContext->panic) { return -1; } - struct stack_frame* top = &pContext->function_stack[pContext->function_stack_top-1]; - switch(top->executing.type) { + struct stack_frame frame; + struct stack_frame* top; + struct elem next; + int t; + top = &pContext->function_stack[pContext->function_stack_top-1]; + t = top->executing.type; + switch(t) { case INK_NATIVE_FUNCTION: if(top->index != 0) { ink_pop_fn(pContext); @@ -556,20 +601,27 @@ int ink_step(struct context *pContext) { if(top->index >= pContext->words[top->executing.value].size) { ink_pop_fn(pContext); } else { - struct elem next = pContext->words[top->executing.value].things[top->index]; + next = pContext->words[top->executing.value].things[top->index]; if(next.type == INK_RETURN) { ink_pop_fn(pContext); return 1; } - struct stack_frame frame; frame.executing = next; frame.index = 0; - ink_push_fn(pContext, frame); + t = ink_push_fn(pContext, frame); + if(t < 0) { + pContext->panic = 1; + return -11; + } top->index++; } break; default: - ink_push(pContext, top->executing); + t = ink_push(pContext, top->executing); + if(t < 0) { + pContext->panic = 1; + return -25; + } ink_pop_fn(pContext); break; } @@ -581,16 +633,33 @@ void ink_run(struct context *pContext, char* buffer) { pContext->stack = NULL; pContext->top = 0; pContext->capacity = 0; - ink_lex(pContext, buffer); + int err; + err = ink_lex(pContext, buffer); + if(err < 0) { + pContext->panic = 1; + return; + } int i = 0; struct elem executable_buffer[256]; int executable_buffer_top = 0; - ink_parse(pContext, executable_buffer, &executable_buffer_top); + err = ink_parse(pContext, executable_buffer, &executable_buffer_top); + if(err < 0) { + pContext->panic = 1; + return; + } struct stack_frame frame; frame.executing.value = ink_add_indigenous(pContext, "__-MAIN-__", executable_buffer, executable_buffer_top); + if(frame.executing.value < 0) { + pContext->panic = 1; + return; + } frame.executing.type = INK_FUNCTION; frame.index = 0; - ink_push_fn(pContext, frame); + err = ink_push_fn(pContext, frame); + if(err < 0) { + pContext->panic = 1; + return; + } int out; do { @@ -603,7 +672,8 @@ void ink_run(struct context *pContext, char* buffer) { static void print_stacktrace(struct context* _) { int i = 0; for(; i < _->function_stack_top; ++i) { - struct elem thing = _->function_stack[i].executing; + struct elem thing; + thing = _->function_stack[i].executing; switch(thing.type) { case INK_NATIVE_FUNCTION: { char *n = _->native_words[thing.value].name; @@ -641,8 +711,10 @@ static void add_int(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; + struct elem a; + struct elem b; + a = ctx->stack[ctx->top-1]; + b = ctx->stack[ctx->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { ctx->panic = 1; return; @@ -656,8 +728,10 @@ static void sub_int(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; + struct elem a; + struct elem b; + a = ctx->stack[ctx->top-1]; + b = ctx->stack[ctx->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { ctx->panic = 1; return; @@ -671,8 +745,10 @@ static void mult_int(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; + struct elem a; + struct elem b; + a = ctx->stack[ctx->top-1]; + b = ctx->stack[ctx->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { ctx->panic = 1; return; @@ -686,8 +762,10 @@ static void div_int(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; + struct elem a; + struct elem b; + a = ctx->stack[ctx->top-1]; + b = ctx->stack[ctx->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { ctx->panic = 1; return; @@ -701,8 +779,10 @@ static void rem_int(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; + struct elem a; + struct elem b; + a = ctx->stack[ctx->top-1]; + b = ctx->stack[ctx->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { ctx->panic = 1; return; @@ -716,8 +796,11 @@ static void dupe_elem(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - ink_push(ctx, a); + struct elem a; + a = ctx->stack[ctx->top-1]; + int err; + err = ink_push(ctx, a); + if(err < 0) ctx->panic; } static void drop_elem(struct context* ctx) { @@ -733,7 +816,8 @@ static void pluck_elem(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; + struct elem a; + a = ctx->stack[ctx->top-1]; if(a.type != INK_INTEGER) { ctx->panic = 1; return; @@ -744,7 +828,9 @@ static void pluck_elem(struct context* ctx) { return; } ink_pop(ctx); - ink_push(ctx, ctx->stack[position]); + int err; + err = ink_push(ctx, ctx->stack[position]); + if(err < 0) ctx->panic; } static void swap_elem(struct context* ctx) { @@ -752,8 +838,10 @@ static void swap_elem(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; + struct elem a; + struct elem b; + a = ctx->stack[ctx->top-1]; + b = ctx->stack[ctx->top-2]; ctx->stack[ctx->top-2] = a; ctx->stack[ctx->top-1] = b; } @@ -763,7 +851,8 @@ static void return_if(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; + struct elem a; + a = ctx->stack[ctx->top-1]; if(a.type != INK_INTEGER) { ctx->panic = 1; return; @@ -781,7 +870,8 @@ static void jump_if(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; + struct elem a; + a = ctx->stack[ctx->top-1]; if(a.type != INK_INTEGER) { ctx->panic = 1; return; @@ -802,7 +892,8 @@ static void print_int(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; + struct elem a; + a = ctx->stack[ctx->top-1]; ink_pop(ctx); char* n = ink_itoa(ctx, a.value); char* str = n; @@ -818,7 +909,8 @@ static void print_as_utf8(struct context* ctx) { ctx->panic = 1; return; } - struct elem a = ctx->stack[ctx->top-1]; + struct elem a; + a = ctx->stack[ctx->top-1]; if(a.value <= 0x7F) { ctx->putchar(a.value); } else if(a.value <= 0x7FF) { @@ -840,19 +932,21 @@ static void print_as_utf8(struct context* ctx) { ink_pop(ctx); } -void ink_std_library(struct context* ctx) { - ink_add_native(ctx, "trace", print_stacktrace); - ink_add_native(ctx, "print_int", print_int); - ink_add_native(ctx, "print_utf8", print_as_utf8); - ink_add_native(ctx, "+", add_int); - ink_add_native(ctx, "-", sub_int); - ink_add_native(ctx, "*", mult_int); - ink_add_native(ctx, "/", div_int); - ink_add_native(ctx, "%", rem_int); - ink_add_native(ctx, "swap", swap_elem); - ink_add_native(ctx, "dup", dupe_elem); - ink_add_native(ctx, "drop", drop_elem); - ink_add_native(ctx, "pluck", pluck_elem); - ink_add_native(ctx, "return_if", return_if); - ink_add_native(ctx, "jump_if", jump_if); +int ink_std_library(struct context* ctx) { + int v; + v += ink_add_native(ctx, "trace", print_stacktrace); + v += ink_add_native(ctx, "print_int", print_int); + v += ink_add_native(ctx, "print_utf8", print_as_utf8); + v += ink_add_native(ctx, "+", add_int); + v += ink_add_native(ctx, "-", sub_int); + v += ink_add_native(ctx, "*", mult_int); + v += ink_add_native(ctx, "/", div_int); + v += ink_add_native(ctx, "%", rem_int); + v += ink_add_native(ctx, "swap", swap_elem); + v += ink_add_native(ctx, "dup", dupe_elem); + v += ink_add_native(ctx, "drop", drop_elem); + v += ink_add_native(ctx, "pluck", pluck_elem); + v += ink_add_native(ctx, "return_if", return_if); + v += ink_add_native(ctx, "jump_if", jump_if); + return v; } \ No newline at end of file