diff --git a/src/ast.h b/src/ast.h index 241d916..1b5f1ae 100644 --- a/src/ast.h +++ b/src/ast.h @@ -581,7 +581,7 @@ typedef struct libFunction { intptr_t p; \ *sb = calloc(sz + 1, sizeof(stackval_t)); \ assert(*sb != NULL); \ - p = ((intptr_t) * sb) % sizeof(stackval_t); \ + p = ((intptr_t)*sb) % sizeof(stackval_t); \ if (p != 0) { \ p = (sizeof(stackval_t) - (p % sizeof(stackval_t))); \ } \ @@ -595,7 +595,7 @@ typedef struct libFunction { heapval_t hpbv; \ *hb = calloc(hz + 2, sizeof(heapval_t)); \ assert(*hb != NULL); \ - p = ((intptr_t) * hb) % sizeof(heapval_t); \ + p = ((intptr_t)*hb) % sizeof(heapval_t); \ p = (sizeof(heapval_t) - (p % sizeof(heapval_t))); \ hpbv.sv.type = INT32TYPE; \ hpbv.sv.i = (int32_t)hz; \ diff --git a/src/lib.c b/src/lib.c index a3ac3b8..d6a9986 100644 --- a/src/lib.c +++ b/src/lib.c @@ -23,6 +23,7 @@ libFunction_t ric_library[] = { DECLARE_LIB_FUNCTION("push", 2, ric_push), DECLARE_LIB_FUNCTION("pop", 1, ric_pop), DECLARE_LIB_FUNCTION("popFirst", 1, ric_pop_first), + DECLARE_LIB_FUNCTION("popIdx", 2, ric_pop_idx), DECLARE_LIB_FUNCTION("len", 1, ric_len), DECLARE_LIB_FUNCTION("contains", 2, ric_contains), DECLARE_LIB_FUNCTION("keys", 1, ric_keys), diff --git a/src/library/libstd.c b/src/library/libstd.c index 64e7b79..d66bf72 100644 --- a/src/library/libstd.c +++ b/src/library/libstd.c @@ -851,6 +851,86 @@ int ric_pop(LIBRARY_PARAMS()) { return 0; } +int ric_pop_idx(LIBRARY_PARAMS()) { + stackval_t stv; + vector_t *vec = NULL; + argsList_t *walk; + argsList_t *prev; + int idx = 0; + void *sp = PROVIDE_CONTEXT()->sp; + size_t *sc = PROVIDE_CONTEXT()->sc; + void *hp = PROVIDE_CONTEXT()->hp; + heapval_t *hpv = NULL; + int dummy; + int walk_count = 0; + + /* Get vector reference */ + POP_VAL(&stv, sp, sc); + + switch (stv.type) { + case VECTORTYPE: + vec = stv.vec; + break; + default: { + fprintf(stderr, "error: function call '%s' got an unexpected first argument.\n", + LIBRARY_FUNC_NAME()); + exit(1); + } break; + } + + /* Get idx */ + POP_VAL(&stv, sp, sc); + + switch (stv.type) { + case INT32TYPE: + idx = stv.i; + break; + default: { + fprintf(stderr, "error: function call '%s' got an unexpected first argument.\n", + LIBRARY_FUNC_NAME()); + exit(1); + } break; + } + + if (vec->length == 0 || idx >= vec->length) { + /* This is not very good.. Guess I will return 0 then. */ + PUSH_INT(0, sp, sc); + return 0; + } + + if (idx < 0) { + /* Negative index, wrap around */ + idx = (vec->length + idx % vec->length); + } + + walk = vec->content; + prev = NULL; + while (walk->next != NULL) { + if (walk_count == idx) { + break; + } + + prev = walk; + walk = walk->next; + walk_count++; + } + + if (prev == NULL) { + vec->content = walk->next; + } else { + prev->next = walk->next; + } + evaluate_expression(walk->arg, EXPRESSION_ARGS()); + POP_VAL(&stv, sp, sc); + + ALLOC_HEAP(&stv, hp, &hpv, &dummy); + push_stackval(&stv, PROVIDE_CONTEXT()); + + // Decrease vector size + vec->length--; + return 0; +} + int ric_pop_first(LIBRARY_PARAMS()) { stackval_t stv; vector_t *vec = NULL; @@ -1345,7 +1425,7 @@ int ric_sort(LIBRARY_PARAMS()) { vecContent = vec->content; - if (vecContent->length > 0) { + if (vec->length > 0 && vecContent->length > 0) { if (vecContent->arg->type == EXPR_TYPE_IVAL) { diff --git a/src/library/libstd.h b/src/library/libstd.h index 0b30917..a0af871 100644 --- a/src/library/libstd.h +++ b/src/library/libstd.h @@ -24,6 +24,7 @@ int ric_append(LIBRARY_PARAMS()); int ric_push(LIBRARY_PARAMS()); int ric_pop(LIBRARY_PARAMS()); int ric_pop_first(LIBRARY_PARAMS()); +int ric_pop_idx(LIBRARY_PARAMS()); int ric_len(LIBRARY_PARAMS()); int ric_contains(LIBRARY_PARAMS()); int ric_keys(LIBRARY_PARAMS());