瀏覽代碼

Added more basic math

main
Ludovic 'Archivist' Lagouardette 4 月之前
父節點
當前提交
3e5ddb7a7b
共有 2 個檔案被更改,包括 261 行新增190 行删除
  1. +1
    -0
      ink.h
  2. +260
    -190
      lib.c

+ 1
- 0
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);

+ 260
- 190
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);
}

Loading…
取消
儲存