From 3e5ddb7a7b5662b46d2e07a30a4d146e748e63be Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Mon, 13 May 2024 20:21:39 +0200 Subject: [PATCH] Added more basic math --- ink.h | 1 + lib.c | 450 +++++++++++++++++++++++++++++++++------------------------- 2 files changed, 261 insertions(+), 190 deletions(-) diff --git a/ink.h b/ink.h index 649b1c8..75792d1 100644 --- a/ink.h +++ b/ink.h @@ -63,3 +63,4 @@ struct context* ink_make_context(void*(*malloc)(size_t), void*(*realloc)(void*, struct context* ink_make_default_context(); int ink_step(struct context *pContext); void ink_run(struct context *pContext, char* buffer); +void ink_std_library(struct context* ctx); diff --git a/lib.c b/lib.c index 360a4ab..ff1c7d1 100644 --- a/lib.c +++ b/lib.c @@ -288,199 +288,10 @@ static char* ink_itoa(struct context* _, int cpy) { return n; } -static void print_stacktrace(struct context* _) { - int i = 0; - for(; i < _->function_stack_top; ++i) { - struct elem thing = _->function_stack[i].executing; - switch(thing.type) { - case INK_NATIVE_FUNCTION: { - char *n = _->native_words[thing.value].name; - while (*n) { - _->putchar(*n); - ++n; - } - _->putchar(10); - break; - } - case INK_FUNCTION:{ - char *n = _->native_words[thing.value].name; - while (*n) { - _->putchar(*n); - ++n; - } - _->putchar(':'); - n = ink_itoa(_, _->function_stack[i].index); - while (*n) { - _->putchar(*n); - ++n; - } - _->free(n); - _->putchar(10); - break; - } - default: - break; - } - } -} - -static void add_int(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->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; -} - -static void dupe_elem(struct context* ctx) { - if(ctx->top < 1) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - ink_push(ctx, a); -} - -static void drop_elem(struct context* ctx) { - if(ctx->top < 1) { - ctx->panic = 1; - return; - } - ink_pop(ctx); -} - -static void pluck_elem(struct context* ctx) { - if(ctx->top < 1) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - if(a.type != INK_INTEGER) { - ctx->panic = 1; - return; - } - int position = ctx->top - (a.value + 1); - if(position >= ctx->top || position < 0) { - ctx->panic = 1; - return; - } - ink_pop(ctx); - ink_push(ctx, ctx->stack[position]); -} - -static void swap_elem(struct context* ctx) { - if(ctx->top < 2) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - struct elem b = ctx->stack[ctx->top-2]; - ctx->stack[ctx->top-2] = a; - ctx->stack[ctx->top-1] = b; -} - -static void return_if(struct context* ctx) { - if(ctx->top < 1) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - if(a.type != INK_INTEGER) { - ctx->panic = 1; - return; - } - if(a.value) { - ink_pop_fn(ctx); - ink_pop_fn(ctx); - } - ink_pop(ctx); - return; -} - -static void jump_if(struct context* ctx) { - if(ctx->top < 1) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - if(a.type != INK_INTEGER) { - ctx->panic = 1; - return; - } - 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); - } - return; -} - -static void print_int(struct context* ctx) { - if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - ink_pop(ctx); - char* n = ink_itoa(ctx, a.value); - char* str = n; - while (*str) { - ctx->putchar(*str); - ++str; - } - ctx->free(n); -} - -static void print_as_utf8(struct context* ctx) { - if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) { - ctx->panic = 1; - return; - } - struct elem a = ctx->stack[ctx->top-1]; - if(a.value <= 0x7F) { - ctx->putchar(a.value); - } else if(a.value <= 0x7FF) { - ctx->putchar(((a.value & 0xFC0) >> 6) | 192); - ctx->putchar((a.value & 0x3F) | 128); - } else if(a.value <= 0xFFFF) { - ctx->putchar(((a.value & 0x3F000) >> 12) | 224); - ctx->putchar(((a.value & 0xFC0) >> 6) | 128); - ctx->putchar((a.value & 0x3F) | 128); - } else if(a.value <= 0x10FFFF) { - ctx->putchar(((a.value & 0x3C0000) >> 18) | 240); - ctx->putchar(((a.value & 0x3F000) >> 12) | 128); - ctx->putchar(((a.value & 0xFC0) >> 6) | 128); - ctx->putchar((a.value & 0x3F) | 128); - } else { - ctx->panic = 1; - return; - } - ink_pop(ctx); -} - #ifndef NOSTDLIB struct context* ink_make_default_context() { struct context* ctx = ink_make_context(malloc, realloc, free, putchar); - 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, "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); + ink_std_library(ctx); return ctx; } #endif @@ -785,4 +596,263 @@ void ink_run(struct context *pContext, char* buffer) { do { out = ink_step(pContext); } while(out > 0); +} + +/**********************************************************************************************************************/ + +static void print_stacktrace(struct context* _) { + int i = 0; + for(; i < _->function_stack_top; ++i) { + struct elem thing = _->function_stack[i].executing; + switch(thing.type) { + case INK_NATIVE_FUNCTION: { + char *n = _->native_words[thing.value].name; + while (*n) { + _->putchar(*n); + ++n; + } + _->putchar(10); + break; + } + case INK_FUNCTION:{ + char *n = _->native_words[thing.value].name; + while (*n) { + _->putchar(*n); + ++n; + } + _->putchar(':'); + n = ink_itoa(_, _->function_stack[i].index); + while (*n) { + _->putchar(*n); + ++n; + } + _->free(n); + _->putchar(10); + break; + } + default: + break; + } + } +} + +static void add_int(struct context* ctx) { + if(ctx->top < 2) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + struct elem b = ctx->stack[ctx->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; +} + +static void sub_int(struct context* ctx) { + if(ctx->top < 2) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + struct elem b = ctx->stack[ctx->top-2]; + if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { + ctx->panic = 1; + return; + } + ink_pop(ctx); + ctx->stack[ctx->top-1].value = b.value - a.value; +} + +static void mult_int(struct context* ctx) { + if(ctx->top < 2) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + struct elem b = ctx->stack[ctx->top-2]; + if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { + ctx->panic = 1; + return; + } + ink_pop(ctx); + ctx->stack[ctx->top-1].value = b.value * a.value; +} + +static void div_int(struct context* ctx) { + if(ctx->top < 2) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + struct elem b = ctx->stack[ctx->top-2]; + if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { + ctx->panic = 1; + return; + } + ink_pop(ctx); + ctx->stack[ctx->top-1].value = b.value / a.value; +} + +static void rem_int(struct context* ctx) { + if(ctx->top < 2) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + struct elem b = ctx->stack[ctx->top-2]; + if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { + ctx->panic = 1; + return; + } + ink_pop(ctx); + ctx->stack[ctx->top-1].value = b.value % a.value; +} + +static void dupe_elem(struct context* ctx) { + if(ctx->top < 1) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + ink_push(ctx, a); +} + +static void drop_elem(struct context* ctx) { + if(ctx->top < 1) { + ctx->panic = 1; + return; + } + ink_pop(ctx); +} + +static void pluck_elem(struct context* ctx) { + if(ctx->top < 1) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + if(a.type != INK_INTEGER) { + ctx->panic = 1; + return; + } + int position = ctx->top - (a.value + 1); + if(position >= ctx->top || position < 0) { + ctx->panic = 1; + return; + } + ink_pop(ctx); + ink_push(ctx, ctx->stack[position]); +} + +static void swap_elem(struct context* ctx) { + if(ctx->top < 2) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + struct elem b = ctx->stack[ctx->top-2]; + ctx->stack[ctx->top-2] = a; + ctx->stack[ctx->top-1] = b; +} + +static void return_if(struct context* ctx) { + if(ctx->top < 1) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + if(a.type != INK_INTEGER) { + ctx->panic = 1; + return; + } + if(a.value) { + ink_pop_fn(ctx); + ink_pop_fn(ctx); + } + ink_pop(ctx); + return; +} + +static void jump_if(struct context* ctx) { + if(ctx->top < 1) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + if(a.type != INK_INTEGER) { + ctx->panic = 1; + return; + } + 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); + } + return; +} + +static void print_int(struct context* ctx) { + if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + ink_pop(ctx); + char* n = ink_itoa(ctx, a.value); + char* str = n; + while (*str) { + ctx->putchar(*str); + ++str; + } + ctx->free(n); +} + +static void print_as_utf8(struct context* ctx) { + if(ctx->top < 1 || ctx->stack[ctx->top-1].type != INK_INTEGER) { + ctx->panic = 1; + return; + } + struct elem a = ctx->stack[ctx->top-1]; + if(a.value <= 0x7F) { + ctx->putchar(a.value); + } else if(a.value <= 0x7FF) { + ctx->putchar(((a.value & 0xFC0) >> 6) | 192); + ctx->putchar((a.value & 0x3F) | 128); + } else if(a.value <= 0xFFFF) { + ctx->putchar(((a.value & 0x3F000) >> 12) | 224); + ctx->putchar(((a.value & 0xFC0) >> 6) | 128); + ctx->putchar((a.value & 0x3F) | 128); + } else if(a.value <= 0x10FFFF) { + ctx->putchar(((a.value & 0x3C0000) >> 18) | 240); + ctx->putchar(((a.value & 0x3F000) >> 12) | 128); + ctx->putchar(((a.value & 0xFC0) >> 6) | 128); + ctx->putchar((a.value & 0x3F) | 128); + } else { + ctx->panic = 1; + return; + } + 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); } \ No newline at end of file