From 01d88a6558b925826faf5f71723e85d6cced52e3 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Thu, 23 May 2024 18:20:39 +0200 Subject: [PATCH] The most practical way to print "Hello World" --- lib.c | 150 +++++++++++++++++++++++++++++++++++++++++-------- test/test01.nk | 4 +- test/test06.nk | 1 + 3 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 test/test06.nk diff --git a/lib.c b/lib.c index dc09b8e..cbfc2e3 100644 --- a/lib.c +++ b/lib.c @@ -1101,7 +1101,7 @@ static void add_int(struct context* ctx) { struct elem b; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; @@ -1120,13 +1120,13 @@ static void sub_int(struct context* ctx) { struct elem b; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_pop(ctx); @@ -1139,13 +1139,13 @@ static void mult_int(struct context* ctx) { struct elem b; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_pop(ctx); @@ -1158,13 +1158,13 @@ static void div_int(struct context* ctx) { struct elem b; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_pop(ctx); @@ -1177,13 +1177,13 @@ static void rem_int(struct context* ctx) { struct elem b; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; b = currentRoutine->stack[currentRoutine->top-2]; if(!(a.type == INK_INTEGER && b.type == INK_INTEGER)) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_pop(ctx); @@ -1220,7 +1220,7 @@ static void pluck_elem(struct context* ctx) { int position, err; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 1) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; @@ -1244,7 +1244,7 @@ static void swap_elem(struct context* ctx) { struct elem b; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; @@ -1258,7 +1258,7 @@ static void return_if(struct context* ctx) { struct elem a; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 1) { - ctx->panic = 1; + ctx->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; @@ -1279,12 +1279,12 @@ static void jump_if(struct context* ctx) { struct elem a; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 1) { - ctx->panic = 1; + ctx->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; if(a.type != INK_INTEGER) { - ctx->panic = 1; + ctx->panic = -1; return; } ink_pop(ctx); @@ -1304,7 +1304,7 @@ static void print_int(struct context* ctx) { char* str; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; @@ -1323,7 +1323,7 @@ static void print_as_utf8(struct context* ctx) { struct elem a; currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top-1].type != INK_INTEGER) { - ctx->panic = 1; + ctx->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; @@ -1342,7 +1342,7 @@ static void print_as_utf8(struct context* ctx) { ctx->putchar(((a.value & 0xFC0) >> 6) | 128); ctx->putchar((a.value & 0x3F) | 128); } else { - ctx->panic = 1; + ctx->panic = -1; return; } ink_pop(ctx); @@ -1392,6 +1392,15 @@ static void new_array(struct context* ctx) { ink_push(ctx, e); } +static void push_array_stack_delim(struct context* ctx) { + int tid; + struct elem e; + tid = get_type_by_name(ctx, "array_marker"); + e.type = tid; + e.value = 0; + ink_push(ctx, e); +} + static void array_push(struct context* ctx, struct ink_routine* currentRoutine, struct ink_array* ary, struct elem value) { if(ary->elements == NULL) { ary->elements = ctx->malloc(sizeof(struct elem) * 8); @@ -1403,7 +1412,7 @@ static void array_push(struct context* ctx, struct ink_routine* currentRoutine, new_count = (ary->capacity + ary->capacity/2); renewed = ctx->realloc(ary->elements, sizeof(struct elem) * new_count); if(renewed == NULL) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } else { ary->elements = renewed; @@ -1422,13 +1431,13 @@ static void push_array(struct context* ctx) { tid = get_type_by_name(ctx, "array"); currentRoutine = ctx->routines + ctx->routine_current; if(currentRoutine->top < 2 || currentRoutine->stack[currentRoutine->top-1].type != tid) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top-1]; ary= ink_get_value(ctx, a); if(ary == NULL) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_pop(ctx); @@ -1436,6 +1445,56 @@ static void push_array(struct context* ctx) { ink_pop(ctx); } +static void push_delimited_array(struct context* ctx) { + int tid, idx, counter, i; + struct elem a; + struct ink_routine* currentRoutine; + struct ink_array* ary; + tid = get_type_by_name(ctx, "array_marker"); + currentRoutine = ctx->routines + ctx->routine_current; + if(currentRoutine->top < 1) { + currentRoutine->panic = -1; + return; + } + new_array(ctx); + a = currentRoutine->stack[currentRoutine->top-1]; + ink_pop(ctx); + ary= ink_get_value(ctx, a); + + for(idx = 1; idx <= currentRoutine->top; ++idx) { + struct elem maybe_delim; + if(currentRoutine->stack[currentRoutine->top-idx].type == tid) { + break; + } + } + // Save for cleanup + counter = idx; + + // Don't copy the delimiter + idx -= 1; + + ary->elements = malloc(sizeof(struct elem) * idx); + if(ary->elements == NULL) { + currentRoutine->panic = -541; + return; + } + ary->capacity = idx; + ary->top = 0; + + // Copy the data + for(i = currentRoutine->top - idx; i < currentRoutine->top; ++i) { + ary->elements[ary->top] = currentRoutine->stack[i]; + ++(ary->top); + } + + // Cleanup + while(counter--) { + ink_pop(ctx); + } + // Put value in place + ink_push(ctx, a); +} + static void index_array(struct context* ctx) { int tid; struct ink_routine *currentRoutine; @@ -1446,13 +1505,13 @@ static void index_array(struct context* ctx) { tid = get_type_by_name(ctx, "array"); currentRoutine = ctx->routines + ctx->routine_current; if (currentRoutine->top < 2 || currentRoutine->stack[currentRoutine->top - 1].type != tid || currentRoutine->stack[currentRoutine->top - 2].type != INK_INTEGER) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } a = currentRoutine->stack[currentRoutine->top - 1]; ary = ink_get_value(ctx, a); if (ary == NULL) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_pop(ctx); @@ -1461,13 +1520,42 @@ static void index_array(struct context* ctx) { ink_pop(ctx); if(ary->top <= idx.value) { - currentRoutine->panic = 1; + currentRoutine->panic = -1; return; } ink_push(ctx, ary->elements[idx.value]); } +static void print_array_of_codepoints(struct context* ctx) { + int tid, i; + struct ink_routine *currentRoutine; + struct elem a; + struct ink_array *ary; + struct elem idx; + + tid = get_type_by_name(ctx, "array"); + currentRoutine = ctx->routines + ctx->routine_current; + if (currentRoutine->top < 1 || currentRoutine->stack[currentRoutine->top - 1].type != tid) { + currentRoutine->panic = -1; + return; + } + a = currentRoutine->stack[currentRoutine->top - 1]; + ary = ink_get_value(ctx, a); + + for(i = 0; i < ary->top; ++i) { + if(ary->elements[i].type != INK_INTEGER) { + currentRoutine->panic = -1; + return; + } + } + ink_pop(ctx); + for(i = 0; i < ary->top; ++i) { + ink_push(ctx, ary->elements[i]); + print_as_utf8(ctx); + } +} + static void run_gc(struct context* ctx) { ink_gc(ctx); } @@ -1506,13 +1594,27 @@ static void arrayify_stack(struct context* ctx) { return; } + +static void collect_noop(struct context*, void*) {} + +static struct ink_collection_list gc_noop(struct context*, void*) { + struct ink_collection_list c; + c.elements = NULL; + c.count = 0; + return c; +} + int ink_std_library(struct context* ctx) { int v; v = 0; - 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); + ink_new_type(ctx, "array_marker", 0, collect_noop, gc_noop); + v += ink_add_native(ctx, "[", push_array_stack_delim); + v += ink_add_native(ctx, "]", push_delimited_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); + v += ink_add_native(ctx, "array.print_utf8", print_array_of_codepoints); v += ink_add_native(ctx, "sys.trace", print_stacktrace); v += ink_add_native(ctx, "sys.gc", run_gc); v += ink_add_native(ctx, "print_int", print_int); diff --git a/test/test01.nk b/test/test01.nk index 2bde0a3..41cf486 100644 --- a/test/test01.nk +++ b/test/test01.nk @@ -1,6 +1,4 @@ -fn potato do - sys.trace return -end +fn potato do sys.trace return end fn print_n_utf8_impl do start: diff --git a/test/test06.nk b/test/test06.nk new file mode 100644 index 0000000..5b74eee --- /dev/null +++ b/test/test06.nk @@ -0,0 +1 @@ +[ 72 101 108 108 111 32 87 111 114 108 100 10 ] array.print_utf8 \ No newline at end of file