diff --git a/lib.c b/lib.c index 18eeb97..dc09b8e 100644 --- a/lib.c +++ b/lib.c @@ -1392,25 +1392,7 @@ static void new_array(struct context* ctx) { ink_push(ctx, e); } -static void push_array(struct context* ctx) { - int tid; - struct elem a; - struct ink_routine* currentRoutine; - struct ink_array* ary; - 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; - return; - } - a = currentRoutine->stack[currentRoutine->top-1]; - ary= ink_get_value(ctx, a); - if(ary == NULL) { - currentRoutine->panic = 1; - return; - } - ink_pop(ctx); - +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); ary->top = 0; @@ -1428,12 +1410,31 @@ static void push_array(struct context* ctx) { ary->capacity = new_count; } } - ary->elements[ary->top] = currentRoutine->stack[currentRoutine->top-1]; + ary->elements[ary->top] = value; ary->top++; - ink_pop(ctx); } - +static void push_array(struct context* ctx) { + int tid; + struct elem a; + struct ink_routine* currentRoutine; + struct ink_array* ary; + 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; + return; + } + a = currentRoutine->stack[currentRoutine->top-1]; + ary= ink_get_value(ctx, a); + if(ary == NULL) { + currentRoutine->panic = 1; + return; + } + ink_pop(ctx); + array_push(ctx, currentRoutine, ary, currentRoutine->stack[currentRoutine->top-1]); + ink_pop(ctx); +} static void index_array(struct context* ctx) { int tid; @@ -1471,6 +1472,39 @@ static void run_gc(struct context* ctx) { ink_gc(ctx); } +static void clear_stack(struct context* ctx) { + struct ink_routine* currentRoutine; + currentRoutine = ctx->routines + ctx->routine_current; + while (currentRoutine->top >= 1) { + ink_pop(ctx); + } + return; +} + +static void arrayify_stack(struct context* ctx) { + struct ink_routine* currentRoutine; + struct elem array_ref; + struct ink_array* ary; + int idx; + currentRoutine = ctx->routines + ctx->routine_current; + new_array(ctx); + if(currentRoutine->panic < 0) return; + array_ref = currentRoutine->stack[currentRoutine->top - 1]; + ary = ink_get_value(ctx, array_ref); + if(ary == NULL) { + currentRoutine->panic = -717; + return; + } + ink_pop(ctx); + for(idx = 0; idx < currentRoutine->top; ++idx) { + array_push(ctx, currentRoutine, ary, currentRoutine->stack[idx]); + } + while (currentRoutine->top > 0) { + ink_pop(ctx); + } + ink_push(ctx, array_ref); + return; +} int ink_std_library(struct context* ctx) { int v; @@ -1491,6 +1525,8 @@ int ink_std_library(struct context* ctx) { 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, "stack.clear", clear_stack); + v += ink_add_native(ctx, "stack.to_array", arrayify_stack); 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);