aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/builtins.h4
-rw-r--r--include/stem.h6
-rw-r--r--src/builtins.c242
-rw-r--r--src/stem.c35
-rw-r--r--stemlib/fib.stem4
-rw-r--r--stemlib/math.stem4
-rw-r--r--stemlib/repl.stem2
-rw-r--r--stemlib/stdlib.stem13
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");
}
diff --git a/src/stem.c b/src/stem.c
index 1bea532..66aaff9 100644
--- a/src/stem.c
+++ b/src/stem.c
@@ -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