From d88978877758e1545aace1084100ec9c22371824 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Wed, 15 May 2024 21:57:00 +0200 Subject: [PATCH] Added coroutine handling --- CMakeLists.txt | 3 + bench.c | 38 ++++++ ink.h | 36 ++++- lib.c | 350 +++++++++++++++++++++++++++++++++--------------- main.c | 8 +- report.csv | 5 + test/bench01.nk | 6 + test/bench02.nk | 7 + test/bench03.nk | 1 + test/test01.nk | 7 + test/test03.nk | 2 +- test/test04.nk | 1 + 12 files changed, 347 insertions(+), 117 deletions(-) create mode 100644 bench.c create mode 100644 report.csv create mode 100644 test/bench01.nk create mode 100644 test/bench02.nk create mode 100644 test/bench03.nk create mode 100644 test/test04.nk diff --git a/CMakeLists.txt b/CMakeLists.txt index 4500333..f7a54e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,3 +6,6 @@ set(CMAKE_C_STANDARD 90) add_library(ink lib.c ink.h) add_executable(ink_exe main.c) target_link_libraries(ink_exe PUBLIC ink) + +add_executable(ink_bench bench.c) +target_link_libraries(ink_bench PUBLIC ink) diff --git a/bench.c b/bench.c new file mode 100644 index 0000000..d1753db --- /dev/null +++ b/bench.c @@ -0,0 +1,38 @@ +#include "ink.h" +#include +#include +#include + +int nop_putchar(int n) { + return n; +} + +int main(int _1, char** _2) { + char read_buffer[2048]; + struct context* ctx = ink_make_default_context(); + + ctx->putchar = nop_putchar; + char* argv_d[3]; + argv_d[0] = "test/bench01.nk"; + argv_d[1] = "test/bench02.nk"; + argv_d[2] = "test/bench03.nk"; + char** it = argv_d; + char** end_argv = it + 3; + for(; it != end_argv; it++) { + FILE* file = fopen(*it, "r"); + size_t cnt = fread(read_buffer, 1, 2047, file); + if(cnt == 0) { + + } + read_buffer[cnt] = 0; + ink_compile(ctx, read_buffer); + + if(ctx->panic) { + perror("Panicked !!"); + } + + fclose(file); + } + + return ctx->panic; +} \ No newline at end of file diff --git a/ink.h b/ink.h index d50c8a1..545bd4e 100644 --- a/ink.h +++ b/ink.h @@ -5,6 +5,9 @@ #define INK_NATIVE_FUNCTION 1 #define INK_FUNCTION 2 +#define INK_ROUTINE_CAN_REUSE 32 +#define INK_ROUTINE_SUCCESS 1 + struct elem { int type; int value; @@ -28,12 +31,8 @@ struct native_fn { void(*value)(struct context*); }; -struct context { +struct ink_routine { int panic; - void*(*malloc)(size_t); - void*(*realloc)(void*, size_t); - void(*free)(void*); - int(*putchar)(int); struct elem* stack; int capacity; @@ -43,6 +42,21 @@ struct context { int function_stack_capacity; int function_stack_top; + void* routine_userdata; +}; + +struct context { + int panic; + void*(*malloc)(size_t); + void*(*realloc)(void*, size_t); + void(*free)(void*); + int(*putchar)(int); + + struct ink_routine* routines; + int routines_capacity; + int routines_top; + int routine_current; + struct native_fn* native_words; int native_words_capacity; int native_words_top; @@ -54,8 +68,14 @@ struct context { char** lex_reserved_words; int lex_reserved_words_capacity; int lex_reserved_words_top; + + unsigned int steps; + + void* persistent_userdata; }; +int ink_make_routine(struct context* ctx); +int ink_kill_routine(struct context* ctx, int routine); 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); @@ -64,5 +84,9 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, struct context* ink_make_default_context(); #endif int ink_step(struct context *pContext); -void ink_run(struct context *pContext, char* buffer); +int ink_can_run(struct context *pContext); +int ink_step_everyone(struct context* pContext); +void ink_compile(struct context *pContext, char* buffer); int ink_std_library(struct context* ctx); +void ink_pop_fn(struct context* ctx); +void ink_pop(struct context* ctx); \ No newline at end of file diff --git a/lib.c b/lib.c index 45e0fbb..745f5dd 100644 --- a/lib.c +++ b/lib.c @@ -4,6 +4,9 @@ #include #include #include +#ifndef NOINSTR + #include +#endif #endif #define INK_RESERVED (-1) @@ -195,55 +198,64 @@ static int ink_add_lex_string(struct context* ctx, const char* name) { } int ink_push(struct context* ctx, struct elem value) { - if(ctx->stack == NULL) { - ctx->stack = ctx->malloc(sizeof(struct elem) * 8); - ctx->top = 0; - ctx->capacity = 8; - } else if(ctx->top == ctx->capacity) { - int new_count = (ctx->capacity + ctx->capacity/2); - void* renewed = ctx->realloc(ctx->stack, sizeof(struct elem) * new_count); + if(ctx->routine_current >= ctx->routines_top) return -65; + struct ink_routine* current = ctx->routines + ctx->routine_current; + if(current->stack == NULL) { + current->stack = ctx->malloc(sizeof(struct elem) * 8); + current->top = 0; + current->capacity = 8; + } else if(current->top == current->capacity) { + int new_count = (current->capacity + current->capacity/2); + void* renewed = ctx->realloc(current->stack, sizeof(struct elem) * new_count); if(renewed == NULL) { return -18; } else { - ctx->stack = renewed; - ctx->capacity = new_count; + current->stack = renewed; + current->capacity = new_count; } } - ctx->stack[ctx->top] = value; - ctx->top++; + current->stack[current->top] = value; + current->top++; return 0; } 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; - ctx->function_stack_capacity = 8; - } else if(ctx->function_stack_top == ctx->function_stack_capacity) { - 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(ctx->routine_current >= ctx->routines_top) return -55; + struct ink_routine* current = ctx->routines + ctx->routine_current; + if(current->panic) return -56; + if(current->function_stack == NULL) { + current->function_stack = ctx->malloc(sizeof(struct stack_frame) * 8); + current->function_stack_top = 0; + current->function_stack_capacity = 8; + } else if(current->function_stack_top == current->function_stack_capacity) { + int new_count = (current->function_stack_capacity + current->function_stack_capacity/2); + void* renewed = ctx->realloc(current->function_stack, sizeof(struct stack_frame) * new_count); if(renewed == NULL) { return -9; } else { - ctx->function_stack = renewed; - ctx->function_stack_capacity = new_count; + current->function_stack = renewed; + current->function_stack_capacity = new_count; } } - ctx->function_stack[ctx->function_stack_top] = value; - ctx->function_stack_top++; + current->function_stack[current->function_stack_top] = value; + current->function_stack_top++; return 0; } -static void ink_pop_fn(struct context* ctx) { - if(ctx->function_stack == NULL) return; - if(ctx->function_stack_top == 0) return; - ctx->function_stack_top--; +void ink_pop_fn(struct context* ctx) { + if(ctx->routine_current >= ctx->routines_top) return; + if(ctx->routines[ctx->routine_current].panic) return; + if(ctx->routines[ctx->routine_current].function_stack == NULL) return; + if(ctx->routines[ctx->routine_current].function_stack_top == 0) return; + ctx->routines[ctx->routine_current].function_stack_top--; } -static void ink_pop(struct context* ctx) { - if(ctx->stack == NULL) return; - if(ctx->top == 0) return; - ctx->top--; +void ink_pop(struct context* ctx) { + if(ctx->routine_current >= ctx->routines_top) return; + if(ctx->routines[ctx->routine_current].panic) return; + if(ctx->routines[ctx->routine_current].stack == NULL) return; + if(ctx->routines[ctx->routine_current].top == 0) return; + ctx->routines[ctx->routine_current].top--; } struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, size_t), void(*free)(void*), int(*putchar)(int)) { @@ -253,12 +265,9 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, ctx->free = free; ctx->putchar = putchar; ctx->panic = 0; - ctx->stack = NULL; - ctx->capacity = 0; - ctx->top = 0; - ctx->function_stack = NULL; - ctx->function_stack_capacity = 0; - ctx->function_stack_top = 0; + ctx->routines = NULL; + ctx->routines_capacity = 0; + ctx->routines_top = 0; ctx->native_words = NULL; ctx->native_words_capacity = 0; ctx->native_words_top = 0; @@ -268,6 +277,7 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, ctx->lex_reserved_words = NULL; ctx->lex_reserved_words_capacity = 0; ctx->lex_reserved_words_top = 0; + ctx->steps = 0; return ctx; } @@ -276,6 +286,7 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, * @param _ context (used to allocate) * @param cpy the value * @return the allocated string, needs to be freed by ctx->free + * @internal this function is slightly cursed */ static char* ink_itoa(struct context* _, int cpy) { char* n = _->malloc(16); @@ -439,6 +450,74 @@ static int lblcmp(const char* label, const char* other, size_t label_sz) { return 0; } +int ink_make_routine(struct context* ctx) { + if(ctx->routines == NULL) { + ctx->routines = ctx->malloc(sizeof(struct ink_routine) * 8); + ctx->routines_top = 0; + ctx->routines_capacity = 8; + struct ink_routine* it = ctx->routines; + struct ink_routine* end = ctx->routines + 8; + for(;it != end;++it) { + it->stack = NULL; + it->function_stack = NULL; + it->panic = INK_ROUTINE_CAN_REUSE; + } + } else if(ctx->routines_top == ctx->routines_capacity) { + int new_count = (ctx->routines_capacity + ctx->routines_capacity/2); + void* renewed = ctx->realloc(ctx->routines, sizeof(struct stack_frame) * new_count); + if(renewed == NULL) { + return -99; + } else { + ctx->routines = renewed; + struct ink_routine* it = ctx->routines + ctx->routines_capacity; + struct ink_routine* end = ctx->routines + new_count; + for(;it != end;++it) { + it->panic = INK_ROUTINE_CAN_REUSE; + } + ctx->routines_capacity = new_count; + } + } + + struct ink_routine* it = ctx->routines; + struct ink_routine* end = ctx->routines + ctx->routines_capacity; + + for(;it != end;++it) { + if(it->panic == INK_ROUTINE_CAN_REUSE) { + it->panic = 0; + it->stack = NULL; + it->top = 0; + it->capacity = 0; + it->function_stack = NULL; + it->function_stack_top = 0; + it->function_stack_capacity = 0; + int idx = it - ctx->routines; + if(idx >= ctx->routines_top) { + ctx->routines_top = idx + 1; + } + return idx; + } + } +} + +int ink_kill_routine(struct context* ctx, int routine){ + if(routine < 0 || routine >= ctx->routines_top) { + return 0; + } + struct ink_routine* curr = ctx->routines + routine; + if(curr->panic == INK_ROUTINE_CAN_REUSE) { + return 0; + } + if(curr->stack != NULL) { + ctx->free(curr->stack); + curr->stack = NULL; + } + if(curr->function_stack != NULL) { + ctx->free(curr->function_stack); + curr->function_stack = NULL; + } + curr->panic = INK_ROUTINE_CAN_REUSE; +} + /** * * @param pContext @@ -447,6 +526,7 @@ static int lblcmp(const char* label, const char* other, size_t label_sz) { * @internal Loop from hell */ static int ink_parse(struct context* pContext, struct elem* executable_buffer, int* executable_buffer_top) { + struct ink_routine* currentRoutine = pContext->routines + pContext->routine_current; int i; #define LABEL_BUFFER 128 #define FUNCTION_BUFFER 256 @@ -459,9 +539,9 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i #define MODE_DO 2 int mode = 0; memset(labels, 0, sizeof(struct label)*LABEL_BUFFER); - for(i = 0; i < pContext->top; ++i) { + for(i = 0; i < currentRoutine->top; ++i) { struct elem current; - current = pContext->stack[i]; + current = currentRoutine->stack[i]; switch (mode) { case MODE_EXECUTABLE: switch(current.type) { @@ -570,7 +650,9 @@ static int ink_parse(struct context* pContext, struct elem* executable_buffer, i } int ink_step(struct context *pContext) { - if(pContext->function_stack_top == 0) return 0; + struct ink_routine* currentRoutine = pContext->routines + pContext->routine_current; + pContext->steps++; + if(currentRoutine->function_stack_top == 0) return 0; if(pContext->panic) { return -1; } @@ -578,7 +660,7 @@ int ink_step(struct context *pContext) { struct stack_frame* top; struct elem next; int t; - top = &pContext->function_stack[pContext->function_stack_top-1]; + top = ¤tRoutine->function_stack[currentRoutine->function_stack_top-1]; t = top->executing.type; switch(t) { case INK_NATIVE_FUNCTION: @@ -628,11 +710,14 @@ int ink_step(struct context *pContext) { return 1; } -void ink_run(struct context *pContext, char* buffer) { - pContext->free(pContext->stack); - pContext->stack = NULL; - pContext->top = 0; - pContext->capacity = 0; +void ink_compile(struct context *pContext, char* buffer) { + int routine = ink_make_routine(pContext); + int saved = pContext->routine_current; + pContext->routine_current = routine; + struct ink_routine* currentRoutine = pContext->routines + routine; + currentRoutine->stack = NULL; + currentRoutine->top = 0; + currentRoutine->capacity = 0; int err; err = ink_lex(pContext, buffer); if(err < 0) { @@ -648,7 +733,13 @@ void ink_run(struct context *pContext, char* buffer) { return; } struct stack_frame frame; - frame.executing.value = ink_add_indigenous(pContext, "__-MAIN-__", executable_buffer, executable_buffer_top); + char main_fn[32] = "__-MAIN-__"; + char* integer = ink_itoa(pContext, routine); + size_t integer_size = strlen(integer); + memcpy(main_fn+10, integer, integer_size); + pContext->free(integer); + main_fn[10+integer_size] = 0; + frame.executing.value = ink_add_indigenous(pContext, main_fn, executable_buffer, executable_buffer_top); if(frame.executing.value < 0) { pContext->panic = 1; return; @@ -661,19 +752,49 @@ void ink_run(struct context *pContext, char* buffer) { return; } + pContext->routine_current = saved; + return; +} + +int ink_can_run(struct context* pContext) { + int it = 0; + for(;it < pContext->routines_top; ++it) { + if(pContext->routines[it].panic == 0) { + return 1; + } + } + return 0; +} + +int ink_step_everyone(struct context* pContext) { int out; - do { + pContext->routine_current = -1; + for(;;) { + do{ + ++(pContext->routine_current); + } while(pContext->routine_current < pContext->routines_top && pContext->routines[pContext->routine_current].panic != 0); + if(pContext->routine_current >= pContext->routines_top) break; + if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) { + ink_kill_routine(pContext, pContext->routine_current); + } out = ink_step(pContext); - } while(out > 0); + if(out == 0) { + pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS; + } else if(out < 0) { + pContext->routines[pContext->routine_current].panic = out; + } + } + return 0; } /**********************************************************************************************************************/ static void print_stacktrace(struct context* _) { int i = 0; - for(; i < _->function_stack_top; ++i) { + struct ink_routine* currentRoutine = _->routines + _->routine_current; + for(; i < currentRoutine->function_stack_top; ++i) { struct elem thing; - thing = _->function_stack[i].executing; + thing = currentRoutine->function_stack[i].executing; switch(thing.type) { case INK_NATIVE_FUNCTION: { char *n = _->native_words[thing.value].name; @@ -691,7 +812,7 @@ static void print_stacktrace(struct context* _) { ++n; } _->putchar(':'); - n = ink_itoa(_, _->function_stack[i].index); + n = ink_itoa(_, currentRoutine->function_stack[i].index); while (*n) { _->putchar(*n); ++n; @@ -707,104 +828,111 @@ static void print_stacktrace(struct context* _) { } static void add_int(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 2) { + currentRoutine->panic = 1; return; } struct elem a; struct elem b; - a = ctx->stack[ctx->top-1]; - b = ctx->stack[ctx->top-2]; + a = currentRoutine->stack[currentRoutine->top-1]; + b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { ctx->panic = 1; return; } ink_pop(ctx); - ctx->stack[ctx->top-1].value = a.value + b.value; + currentRoutine->stack[currentRoutine->top-1].value = a.value + b.value; } static void sub_int(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 2) { + currentRoutine->panic = 1; return; } struct elem a; struct elem b; - a = ctx->stack[ctx->top-1]; - b = ctx->stack[ctx->top-2]; + a = currentRoutine->stack[currentRoutine->top-1]; + b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - ctx->panic = 1; + currentRoutine->panic = 1; return; } ink_pop(ctx); - ctx->stack[ctx->top-1].value = b.value - a.value; + currentRoutine->stack[currentRoutine->top-1].value = b.value - a.value; } static void mult_int(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 2) { + currentRoutine->panic = 1; return; } struct elem a; struct elem b; - a = ctx->stack[ctx->top-1]; - b = ctx->stack[ctx->top-2]; + a = currentRoutine->stack[currentRoutine->top-1]; + b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - ctx->panic = 1; + currentRoutine->panic = 1; return; } ink_pop(ctx); - ctx->stack[ctx->top-1].value = b.value * a.value; + currentRoutine->stack[currentRoutine->top-1].value = b.value * a.value; } static void div_int(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 2) { + currentRoutine->panic = 1; return; } struct elem a; struct elem b; - a = ctx->stack[ctx->top-1]; - b = ctx->stack[ctx->top-2]; + a = currentRoutine->stack[currentRoutine->top-1]; + b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - ctx->panic = 1; + currentRoutine->panic = 1; return; } ink_pop(ctx); - ctx->stack[ctx->top-1].value = b.value / a.value; + currentRoutine->stack[currentRoutine->top-1].value = b.value / a.value; } static void rem_int(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 2) { + currentRoutine->panic = 1; return; } struct elem a; struct elem b; - a = ctx->stack[ctx->top-1]; - b = ctx->stack[ctx->top-2]; + a = currentRoutine->stack[currentRoutine->top-1]; + b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - ctx->panic = 1; + currentRoutine->panic = 1; return; } ink_pop(ctx); - ctx->stack[ctx->top-1].value = b.value % a.value; + currentRoutine->stack[currentRoutine->top-1].value = b.value % a.value; } static void dupe_elem(struct context* ctx) { - if(ctx->top < 1) { + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1) { ctx->panic = 1; return; } struct elem a; - a = ctx->stack[ctx->top-1]; + a = currentRoutine->stack[currentRoutine->top-1]; int err; err = ink_push(ctx, a); if(err < 0) ctx->panic; } static void drop_elem(struct context* ctx) { - if(ctx->top < 1) { + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1) { ctx->panic = 1; return; } @@ -812,47 +940,50 @@ static void drop_elem(struct context* ctx) { } static void pluck_elem(struct context* ctx) { - if(ctx->top < 1) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1) { + currentRoutine->panic = 1; return; } struct elem a; - a = ctx->stack[ctx->top-1]; + a = currentRoutine->stack[currentRoutine->top-1]; if(a.type != INK_INTEGER) { ctx->panic = 1; return; } - int position = ctx->top - (a.value + 1); - if(position >= ctx->top || position < 0) { + int position = currentRoutine->top - (a.value + 1); + if(position >= currentRoutine->top || position < 0) { ctx->panic = 1; return; } ink_pop(ctx); int err; - err = ink_push(ctx, ctx->stack[position]); + err = ink_push(ctx, currentRoutine->stack[position]); if(err < 0) ctx->panic; } static void swap_elem(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 2) { + currentRoutine->panic = 1; return; } 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; + a = currentRoutine->stack[currentRoutine->top-1]; + b = currentRoutine->stack[currentRoutine->top-2]; + currentRoutine->stack[currentRoutine->top-2] = a; + currentRoutine->stack[currentRoutine->top-1] = b; } static void return_if(struct context* ctx) { - if(ctx->top < 1) { + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1) { ctx->panic = 1; return; } struct elem a; - a = ctx->stack[ctx->top-1]; + a = currentRoutine->stack[currentRoutine->top-1]; if(a.type != INK_INTEGER) { ctx->panic = 1; return; @@ -866,12 +997,13 @@ static void return_if(struct context* ctx) { } static void jump_if(struct context* ctx) { - if(ctx->top < 1) { + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1) { ctx->panic = 1; return; } struct elem a; - a = ctx->stack[ctx->top-1]; + a = currentRoutine->stack[currentRoutine->top-1]; if(a.type != INK_INTEGER) { ctx->panic = 1; return; @@ -879,21 +1011,21 @@ static void jump_if(struct context* ctx) { ink_pop(ctx); if(a.value) { ink_pop_fn(ctx); - a = ctx->stack[ctx->top-1]; - ctx->function_stack[ctx->function_stack_top - 1].index += a.value - 3; - ink_pop(ctx); - //printf("\t*%d\n", ctx->function_stack[ctx->function_stack_top - 1].index); + a = currentRoutine->stack[currentRoutine->top-1]; + currentRoutine->function_stack[currentRoutine->function_stack_top - 1].index += a.value - 3; } + ink_pop(ctx); return; } static void print_int(struct context* ctx) { - if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) { - ctx->panic = 1; + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) { + currentRoutine->panic = 1; return; } struct elem a; - a = ctx->stack[ctx->top-1]; + a = currentRoutine->stack[currentRoutine->top-1]; ink_pop(ctx); char* n = ink_itoa(ctx, a.value); char* str = n; @@ -905,12 +1037,13 @@ static void print_int(struct context* ctx) { } static void print_as_utf8(struct context* ctx) { - if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) { + struct ink_routine* currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) { ctx->panic = 1; return; } struct elem a; - a = ctx->stack[ctx->top-1]; + a = currentRoutine->stack[currentRoutine->top-1]; if(a.value <= 0x7F) { ctx->putchar(a.value); } else if(a.value <= 0x7FF) { @@ -934,6 +1067,7 @@ static void print_as_utf8(struct context* ctx) { int ink_std_library(struct context* ctx) { int v; + v = 0; 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); diff --git a/main.c b/main.c index 0c06264..b0ae3f8 100644 --- a/main.c +++ b/main.c @@ -12,14 +12,18 @@ int main(int argc, char** argv) { } read_buffer[cnt] = 0; - ink_run(ctx, read_buffer); + ink_compile(ctx, read_buffer); if(ctx->panic) { - perror("Panicked !!"); + fprintf(stderr, "Panicked !! -> %d\n", ctx->panic); } fclose(file); } + while(ink_can_run(ctx)) { + ink_step_everyone(ctx); + } + printf("\nExecuted in %u steps\n", ctx->steps); return ctx->panic; } \ No newline at end of file diff --git a/report.csv b/report.csv new file mode 100644 index 0000000..536c7fe --- /dev/null +++ b/report.csv @@ -0,0 +1,5 @@ +date | ns per tick | Hz +05/14/24 05:42:51 | 10.705865 | 93406742.537313 +05/14/24 05:43:36 | 9.227817 | 108367995.670996 +05/14/24 05:43:39 | 9.227817 | 108367995.670996 +05/14/24 05:43:42 | 9.547395 | 104740615.062762 diff --git a/test/bench01.nk b/test/bench01.nk new file mode 100644 index 0000000..cf961a9 --- /dev/null +++ b/test/bench01.nk @@ -0,0 +1,6 @@ +fn potato do + start: + -1 + dup + 65 print_utf8 10 print_utf8 + start swap jump_if +end \ No newline at end of file diff --git a/test/bench02.nk b/test/bench02.nk new file mode 100644 index 0000000..3e45dc1 --- /dev/null +++ b/test/bench02.nk @@ -0,0 +1,7 @@ +fn potato2 do + start: + -1 + dup + 1000 potato drop + 65 print_utf8 10 print_utf8 + start swap jump_if +end diff --git a/test/bench03.nk b/test/bench03.nk new file mode 100644 index 0000000..c526303 --- /dev/null +++ b/test/bench03.nk @@ -0,0 +1 @@ +1000 potato2 diff --git a/test/test01.nk b/test/test01.nk index 25bd71c..082b334 100644 --- a/test/test01.nk +++ b/test/test01.nk @@ -13,4 +13,11 @@ fn potato2 do -1 + dup 65 print_utf8 10 print_utf8 start swap jump_if +end + +fn potato3 do + start: + -1 + dup + 66 print_utf8 10 print_utf8 + start swap jump_if end \ No newline at end of file diff --git a/test/test03.nk b/test/test03.nk index 0648943..51f2f9f 100644 --- a/test/test03.nk +++ b/test/test03.nk @@ -1 +1 @@ -100 108 114 111 119 32 111 108 108 101 72 11 print_n_utf8 \ No newline at end of file +4 potato2 \ No newline at end of file diff --git a/test/test04.nk b/test/test04.nk new file mode 100644 index 0000000..c31557e --- /dev/null +++ b/test/test04.nk @@ -0,0 +1 @@ +4 potato3 \ No newline at end of file