diff options
author | Preston Pan <preston@nullring.xyz> | 2024-01-20 16:37:26 -0800 |
---|---|---|
committer | Preston Pan <preston@nullring.xyz> | 2024-01-20 16:37:26 -0800 |
commit | ff43bd2fb2c2617b53a0157d62d07cf96b2ef92f (patch) | |
tree | 3dbd2aa8f7c1af171edb232fb56c00879b3876ab | |
parent | a9d6c221d7686e3055593359b02125a3f20ab3e5 (diff) |
add more detailed error messages; fix a couple bugs
-rw-r--r-- | include/builtins.h | 4 | ||||
-rw-r--r-- | include/stem.h | 6 | ||||
-rw-r--r-- | src/builtins.c | 242 | ||||
-rw-r--r-- | src/stem.c | 35 | ||||
-rw-r--r-- | stemlib/fib.stem | 4 | ||||
-rw-r--r-- | stemlib/math.stem | 4 | ||||
-rw-r--r-- | stemlib/repl.stem | 2 | ||||
-rw-r--r-- | stemlib/stdlib.stem | 13 |
8 files changed, 205 insertions, 105 deletions
diff --git a/include/builtins.h b/include/builtins.h index 629b935..38b9965 100644 --- a/include/builtins.h +++ b/include/builtins.h @@ -154,6 +154,10 @@ void stemfwrite(value_t *v); /*! @brief [VINT/VFLOAT] sleep; sleeps for an amount of seconds. */ void stemsleep(value_t *v); +void stemcut(value_t *v); + +void undef(value_t *v); + /*! @brief adds all the custom objects defined to OBJ_TABLE */ void add_objs(); diff --git a/include/stem.h b/include/stem.h index 69bfcb4..381b0ad 100644 --- a/include/stem.h +++ b/include/stem.h @@ -197,6 +197,9 @@ void sll_add(sll_t *l, string_t *key, void *v, void (*freefunc)(void *)); /*! Gets value by key from singly linked list. */ void *sll_get(sll_t *l, string_t *key); +/*! deletes item from singly linked list */ +void sll_delete(sll_t *l, string_t *k, void (*freefunc)(void *)); + /*! Frees singly linked list */ void sll_free(sll_t *l, void (*freefunc)(void *)); @@ -210,6 +213,9 @@ void ht_add(ht_t *h, string_t *key, void *v, void (*freefunc)(void *)); /*! Gets value from hash table by key */ void *ht_get(ht_t *h, string_t *key); +/*! Deletes item from hash table */ +void ht_delete(ht_t *h, string_t *key, void (*freefunc)(void *)); + /*! returns true if key exists in hash table. false otherwise */ bool ht_exists(ht_t *h, string_t *key); diff --git a/src/builtins.c b/src/builtins.c index a659171..baeaafc 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1,6 +1,7 @@ #include <builtins.h> #include <ctype.h> #include <dlfcn.h> +#include <macros.h> #include <math.h> #include <stdio.h> #include <stdlib.h> @@ -61,13 +62,14 @@ void print_value(value_t *v) { printf("W: %s\n", v->str_word->value); break; case VQUOTE: - printf("Q:\n"); + printf("Q: [\n"); for (int i = 0; i < v->quote->size; i++) { print_value(v->quote->items[i]); } + printf("]\n"); break; case VERR: - printf("STACK ERR\n"); + printf("%sERROR%s: %s\n", RED, COLOR_RESET, v->str_word->value); break; case VCUSTOM: c = ht_get(OBJ_TABLE, v->str_word); @@ -76,21 +78,22 @@ void print_value(value_t *v) { } } -void eval_error() { +void eval_error(char *s) { value_t *v = init_value(VERR); + v->str_word = init_string(s); array_append(STACK, v); } void stemadd(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -101,7 +104,7 @@ void stemadd(value_t *v) { v2->type != VINT && v2->type != VFLOAT) { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } retval->int_float = v1->int_float + v2->int_float; @@ -113,19 +116,26 @@ void stemadd(value_t *v) { void stemsub(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); if (v1->type == VINT && v2->type == VINT) { retval->type = VINT; } + if (v1->type != VINT && v1->type != VFLOAT || + v2->type != VINT && v2->type != VFLOAT) { + array_append(STACK, v1); + array_append(STACK, v2); + eval_error("INCORRECT TYPE ARGUMENT"); + return; + } retval->int_float = v1->int_float - v2->int_float; array_append(STACK, retval); value_free(v1); @@ -135,19 +145,26 @@ void stemsub(value_t *v) { void stemmul(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); if (v1->type == VINT && v2->type == VINT) { retval->type = VINT; } + if (v1->type != VINT && v1->type != VFLOAT || + v2->type != VINT && v2->type != VFLOAT) { + array_append(STACK, v1); + array_append(STACK, v2); + eval_error("INCORRECT TYPE ARGUMENT"); + return; + } retval->int_float = v1->int_float * v2->int_float; array_append(STACK, retval); value_free(v1); @@ -157,19 +174,26 @@ void stemmul(value_t *v) { void stemdiv(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); if (v1->type == VINT && v2->type == VINT) { retval->type = VINT; } + if (v1->type != VINT && v1->type != VFLOAT || + v2->type != VINT && v2->type != VFLOAT) { + array_append(STACK, v1); + array_append(STACK, v2); + eval_error("INCORRECT TYPE ARGUMENT"); + return; + } retval->int_float = v1->int_float / v2->int_float; array_append(STACK, retval); value_free(v1); @@ -179,17 +203,17 @@ void stemdiv(value_t *v) { void stemfunc(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type != VWORD) { - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } ht_add(WORD_TABLE, string_copy(v1->str_word), v2, value_free); @@ -201,13 +225,13 @@ void nop(value_t *v) {} void stempow(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -223,7 +247,7 @@ void stempow(value_t *v) { void stemsin(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -235,7 +259,7 @@ void stemsin(value_t *v) { void stemcos(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -247,7 +271,7 @@ void stemcos(value_t *v) { void stemexp(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -260,7 +284,7 @@ void stemeval(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v1); - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type == VQUOTE) { @@ -280,7 +304,7 @@ void stemeval(value_t *v) { void stemln(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -292,7 +316,7 @@ void stemln(value_t *v) { void stemceil(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -304,7 +328,7 @@ void stemceil(value_t *v) { void stemfloor(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *retval = init_value(VFLOAT); @@ -316,12 +340,12 @@ void stemfloor(value_t *v) { void strquote(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type != VSTR) { array_append(STACK, v1); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } value_t *retval = init_value(VQUOTE); @@ -345,20 +369,20 @@ void strquote(value_t *v) { void curry(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMTPY STACK"); return; } if (v2->type != VQUOTE) { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } @@ -369,12 +393,12 @@ void curry(value_t *v) { void stemfread(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type != VSTR) { array_append(STACK, v1); - eval_error(); + eval_error("EMPTY STACK"); return; } char *val = NULL; @@ -382,7 +406,7 @@ void stemfread(value_t *v) { FILE *fp = fopen(v1->str_word->value, "rb"); if (!fp) { array_append(STACK, v1); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } ssize_t bytes_read = getdelim(&val, &len, '\0', fp); @@ -416,7 +440,7 @@ void stemexit(value_t *v) { void quote(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -429,7 +453,7 @@ void quote(value_t *v) { void stemtype(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -442,7 +466,7 @@ void stemtype(value_t *v) { void dsc(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -452,13 +476,13 @@ void dsc(value_t *v) { void swap(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } array_append(STACK, v2); @@ -468,7 +492,7 @@ void swap(value_t *v) { void isdef(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -485,7 +509,7 @@ void isdef(value_t *v) { void stemdup(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -503,7 +527,7 @@ void questionmark(value_t *v) { void period(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } print_value(v1); @@ -513,7 +537,7 @@ void period(value_t *v) { void stemlen(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -532,13 +556,13 @@ void stemlen(value_t *v) { void dip(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -556,17 +580,16 @@ void dip(value_t *v) { array_append(STACK, v1); } -/* 3 4 4 [ + ] keep */ void keep(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -585,20 +608,20 @@ void keep(value_t *v) { void del(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } if (v2->type != VINT) { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } switch (v1->type) { @@ -624,13 +647,13 @@ void clear(value_t *v) { void stemif(value_t *v) { value_t *v3 = array_pop(STACK); if (v3 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v2 = array_pop(STACK); if (v2 == NULL) { array_append(STACK, v3); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -638,7 +661,7 @@ void stemif(value_t *v) { if (v1 == NULL) { array_append(STACK, v2); array_append(STACK, v3); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -646,7 +669,7 @@ void stemif(value_t *v) { array_append(STACK, v1); array_append(STACK, v2); array_append(STACK, v3); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } @@ -687,13 +710,13 @@ void stemif(value_t *v) { void gtequals(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -707,7 +730,7 @@ void gtequals(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -718,13 +741,13 @@ void gtequals(value_t *v) { void ltequals(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -738,7 +761,7 @@ void ltequals(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -751,7 +774,7 @@ void clib(value_t *v) { void *handle = dlopen(v1->str_word->value, RTLD_LAZY); if (!handle) { array_append(STACK, v1); - eval_error(); + eval_error("NOLIB"); return; } dlerror(); @@ -763,7 +786,7 @@ void clib(value_t *v) { if ((error = dlerror()) != NULL) { value_free(v1); fprintf(stderr, "%s\n", error); - eval_error(); + eval_error("DLSYM CANNOT FIND FUNCTION"); return; } else { (*af)(); @@ -776,13 +799,13 @@ void clib(value_t *v) { void gthan(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -796,7 +819,7 @@ void gthan(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -807,13 +830,13 @@ void gthan(value_t *v) { void lthan(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -827,7 +850,7 @@ void lthan(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -838,13 +861,13 @@ void lthan(value_t *v) { void equals(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -858,7 +881,7 @@ void equals(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -869,13 +892,13 @@ void equals(value_t *v) { void nequals(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -889,7 +912,7 @@ void nequals(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -900,13 +923,13 @@ void nequals(value_t *v) { void wtostr(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type != VWORD) { array_append(STACK, v1); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } v1->type = VSTR; @@ -916,13 +939,13 @@ void wtostr(value_t *v) { void compose(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -947,7 +970,7 @@ void compose(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } array_append(STACK, retval); @@ -956,7 +979,7 @@ void compose(value_t *v) { void isnum(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -980,7 +1003,7 @@ void isnum(value_t *v) { void stoi(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } @@ -1005,27 +1028,27 @@ void qstack(value_t *v) { void vat(value_t *v) { value_t *v2 = array_pop(STACK); if (v2 == NULL) { - eval_error(); + eval_error("EMTPY STACK"); return; } value_t *v1 = array_pop(STACK); if (v1 == NULL) { array_append(STACK, v2); - eval_error(); + eval_error("EMTPY STACK"); return; } if (v1->type != VINT) { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } if (v2->type == VQUOTE) { if (v2->quote->size <= v1->int_float) { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INDEX ERROR"); return; } array_append(STACK, v2); @@ -1035,7 +1058,7 @@ void vat(value_t *v) { if (v2->str_word->length <= v1->int_float) { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INDEX ERROR"); return; } char *a = (char[]){v2->str_word->value[(int)v1->int_float], '\0'}; @@ -1048,7 +1071,7 @@ void vat(value_t *v) { } else { array_append(STACK, v1); array_append(STACK, v2); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); return; } } @@ -1056,12 +1079,12 @@ void vat(value_t *v) { void stemfwrite(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type != VSTR) { array_append(STACK, v1); - eval_error(); + eval_error("EMPTY STACK"); return; } char *val; @@ -1069,7 +1092,7 @@ void stemfwrite(value_t *v) { FILE *fp = fopen(v1->str_word->value, "w+"); if (!fp) { array_append(STACK, v1); - eval_error(); + eval_error("FOPEN ERROR"); return; } fprintf(fp, "%s", v1->str_word->value); @@ -1080,18 +1103,51 @@ void stemfwrite(value_t *v) { void stemsleep(value_t *v) { value_t *v1 = array_pop(STACK); if (v1 == NULL) { - eval_error(); + eval_error("EMPTY STACK"); return; } if (v1->type != VINT && v1->type != VFLOAT) { array_append(STACK, v1); - eval_error(); + eval_error("INCORRECT TYPE ARGUMENT"); + return; } sleep(v1->int_float); value_free(v1); } +void stemcut(value_t *v) {} + +void undef(value_t *v) { + value_t *v1 = array_pop(STACK); + if (v1 == NULL) { + eval_error("EMPTY STACK"); + return; + } + if (v1->type != VWORD) { + array_append(STACK, v1); + eval_error("INCORRECT TYPE ARGUMENT"); + return; + } + ht_delete(WORD_TABLE, v1->str_word, value_free); + ht_delete(FLIT, v1->str_word, value_free); + value_free(v1); +} + +void errtostr(value_t *v) { + value_t *v1 = array_pop(STACK); + if (v1 == NULL) { + eval_error("EMPTY STACK"); + return; + } + if (v1->type == VERR) + v1->type = VSTR; + else { + array_append(STACK, v1); + eval_error("INVALID TYPE ARGUMENT"); + } + array_append(STACK, v1); +} void add_objs() {} void add_funcs() { @@ -1108,6 +1164,7 @@ void add_funcs() { add_func(FLIT, strquote, "strquote"); add_func(FLIT, stemeval, "eval"); add_func(FLIT, stemfunc, "func"); + add_func(FLIT, stemfunc, "def"); add_func(FLIT, nop, "nop"); add_func(FLIT, stemln, "ln"); add_func(FLIT, stemfloor, "floor"); @@ -1140,6 +1197,9 @@ void add_funcs() { add_func(FLIT, swap, "swap"); add_func(FLIT, isdef, "isdef"); add_func(FLIT, dsc, "dsc"); + add_func(FLIT, dsc, "drop"); add_func(FLIT, clib, "clib"); add_func(FLIT, stemsleep, "sleep"); + add_func(FLIT, undef, "undef"); + add_func(FLIT, errtostr, "errtostr"); } @@ -106,7 +106,7 @@ value_t *value_copy(value_t *v) { void value_free(void *vtmp) { value_t *v = (value_t *)vtmp; - if (v->type == VSTR || v->type == VWORD) { + if (v->type == VSTR || v->type == VWORD || v->type == VERR) { string_free(v->str_word); } if (v->type == VQUOTE) { @@ -244,6 +244,9 @@ value_t *parse_quote(parser_t *p) { parser_move(p); parser_skip_whitespace(p); while (p->c != ']') { + if (p->c == '\0') { + parser_error(p); + } array_append(retv->quote, parser_get_next(p)); parser_skip_whitespace(p); } @@ -251,7 +254,10 @@ value_t *parse_quote(parser_t *p) { return retv; } -void parser_error(parser_t *p) { exit(1); } +void parser_error(parser_t *p) { + fprintf(stderr, "PARSER ERROR!\n"); + exit(1); +} value_t *parse_word(parser_t *p) { value_t *retv = init_value(VWORD); @@ -371,6 +377,27 @@ void *sll_get(sll_t *l, string_t *k) { return NULL; } +void sll_delete(sll_t *l, string_t *k, void (*freefunc)(void *)) { + node_t *cur = l->head; + node_t *tmp; + if (cur == NULL) + return; + if (strcmp(cur->key->value, k->value) == 0) { + node_free(cur, freefunc); + l->head = NULL; + return; + } + while (cur->next != NULL) { + if (strcmp(cur->next->key->value, k->value) == 0) { + tmp = cur->next->next; + node_free(cur->next, freefunc); + cur->next = tmp; + return; + } + cur = cur->next; + } +} + void sll_free(sll_t *l, void (*func)(void *)) { node_t *cur = l->head; node_t *tmp; @@ -406,6 +433,10 @@ void *ht_get(ht_t *h, string_t *key) { bool ht_exists(ht_t *h, string_t *key) { return ht_get(h, key) != NULL; } +void ht_delete(ht_t *h, string_t *key, void (*freefunc)(void *)) { + sll_delete(h->buckets[hash(h, key->value)], key, freefunc); +} + void ht_free(ht_t *h, void (*func)(void *)) { for (int i = 0; i < h->size; i++) { sll_free(h->buckets[i], func); diff --git a/stemlib/fib.stem b/stemlib/fib.stem index de02b5c..90a59d8 100644 --- a/stemlib/fib.stem +++ b/stemlib/fib.stem @@ -8,13 +8,13 @@ fib [ dsc + ] if -] func +] def main [ dup 10 <= [ dup fib . 1 + main ] [ exit ] if -] func +] def 0 main diff --git a/stemlib/math.stem b/stemlib/math.stem index 1a6f931..0444717 100644 --- a/stemlib/math.stem +++ b/stemlib/math.stem @@ -1,2 +1,2 @@ -factorial [ dup 0 <= [ 1 + ] [ dup 1 - factorial * ] if ] func -PI 3.1415926 func +factorial [ dup 0 <= [ 1 + ] [ dup 1 - factorial * ] if ] def +PI 3.1415926 def diff --git a/stemlib/repl.stem b/stemlib/repl.stem index 0131c18..2b0a83c 100644 --- a/stemlib/repl.stem +++ b/stemlib/repl.stem @@ -3,4 +3,4 @@ # You can make your own REPL by changing the code! -repl [ "> " . read strquote eval repl ] func repl +repl [ "> " . read strquote eval repl ] def repl diff --git a/stemlib/stdlib.stem b/stemlib/stdlib.stem index 6b2edac..59ead4b 100644 --- a/stemlib/stdlib.stem +++ b/stemlib/stdlib.stem @@ -21,6 +21,7 @@ swapt [ [ [ swap ] keep ] keep ] func dscd [ swap dsc ] func dsct [ swapd swap dsc ] func +dsc2 [ dsc dsc ] func dsc3 [ dsc dsc dsc ] func # Author: Matthew H @@ -42,7 +43,7 @@ while [ dup2 [ [ ] if ] dip2 over [ while ] [ dsc dsc ] if ] func when [ [ ] if ] func loop-times [ dup2 [ swap [ ] if ] dip2 -dup [ 1 - loop-times ] [ dsc dsc ] if ] func +dup [ 1 - loop-times ] [ dsc2 ] if ] func # d>base [ [ pow * "" swap ] keep2 @@ -51,10 +52,8 @@ dup [ 1 - loop-times ] [ dsc dsc ] if ] func # - dup2 tail [ head "." ] dip + + ] func # Author: Preston Pan -map [ [ ] over2 over2 len 0 swap [ dup4 swap vat over2 eval dscd dscd quote compose swap 1 + dsct dsct dsct over3 swap over3 swap ] swap loop-times dsc3 dscd dscd ] func -filter [ [ ] over2 over2 len 0 swap [ dup4 swap vat over2 eval dscd dscd [ quote compose ] when swap 1 + dsct dsct dsct over3 swap over3 swap ] swap loop-times dsc3 dscd dscd ] func +map [ [ ] over2 over2 len 0 swap +[ dup4 swap vat over2 eval dscd dscd quote compose swap 1 + dsct dsct dsct over3 swap over3 swap ] swap loop-times dsc3 dscd dscd ] func -# [map][quote][valnew][1] - -# [map][quote][val][map][quote][0] -# [val][map][quote][map][1] +filter [ [ ] over2 over2 len 0 swap +[ dup4 swap vat dup over3 eval dsct dsct [ quote compose ] [ dsc ] if swap 1 + dsct dsct dsct over3 swap over3 swap ] swap loop-times dsc3 dscd dscd ] func |