aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2024-01-06 14:59:49 -0800
committerPreston Pan <preston@nullring.xyz>2024-01-06 14:59:49 -0800
commita70b986d42c89def265a396f8cedd23c749be1f9 (patch)
tree72b88443b5ce0c1af914dc3b34906fbbde032dec
parent77afa3abf898c0535f9d2c96f6c6fc6939932c60 (diff)
fix all bug part 2
-rw-r--r--README.org4
-rw-r--r--examples/repl.stem4
-rw-r--r--main.c11
-rw-r--r--parser.c91
4 files changed, 81 insertions, 29 deletions
diff --git a/README.org b/README.org
index 3782540..091549b 100644
--- a/README.org
+++ b/README.org
@@ -50,9 +50,9 @@ names functions and automatically changes what those functions do.
Looping in this language is done via recursion. Because the language is stack-based, recursion is not more memory efficient
than looping if using tail recursion. For example, the REPL for this language is implemented like so:
#+begin_example
-loop [ "> " read evalstr loop ] func loop
+loop [ "> " . read strquote eval loop ] func loop
#+end_example
-Where read takes in a string and prints it before reading a value, evalstr evaluates a string, and loop is the function that calls
+Where read takes in a string and prints it before reading a value, strquote turns a string into a quote, and loop is the function that calls
itself.
*** Curry, Compose, Qstack, Quote
diff --git a/examples/repl.stem b/examples/repl.stem
index 6c3e62c..a2faaaf 100644
--- a/examples/repl.stem
+++ b/examples/repl.stem
@@ -1,2 +1,2 @@
-"Welcome to the REPL; exit to exit"
-loop [ "> " read strquote eval loop ] func loop
+"Welcome to the REPL; exit to exit\n" .
+loop [ "> " . read strquote eval loop ] func loop
diff --git a/main.c b/main.c
index 7ffdccd..0b7ecd9 100644
--- a/main.c
+++ b/main.c
@@ -7,6 +7,7 @@ extern ht_t *WORD_TABLE;
extern array_t *STACK;
extern char *INBUF;
extern parser_t *PARSER;
+extern array_t *EVAL_STACK;
void usage() {
printf("Usage: stem [-hv] [file]\n");
@@ -15,7 +16,7 @@ void usage() {
void version() {
printf("Author: Preston Pan, MIT License 2023\n");
- printf("stem, version 1.0\n");
+ printf("stem, version 1.1\n");
exit(0);
}
@@ -34,6 +35,11 @@ int main(int argc, char **argv) {
}
FILE *FP = fopen(argv[1], "rb");
+
+ if (!FP) {
+ usage();
+ }
+
ssize_t bytes_read = getdelim(&INBUF, &len, '\0', FP);
if (FP != NULL) {
fflush(FP);
@@ -43,7 +49,7 @@ int main(int argc, char **argv) {
PARSER = init_parser(INBUF);
STACK = init_array(10);
WORD_TABLE = init_ht(500);
-
+ EVAL_STACK = init_array(10);
while (1) {
v = parser_get_next(PARSER);
if (v == NULL)
@@ -56,5 +62,6 @@ int main(int argc, char **argv) {
array_free(STACK);
free(PARSER);
free(INBUF);
+ array_free(EVAL_STACK);
return 0;
}
diff --git a/parser.c b/parser.c
index d66dd94..6240556 100644
--- a/parser.c
+++ b/parser.c
@@ -15,6 +15,7 @@
}
array_t *STACK;
+array_t *EVAL_STACK;
ht_t *WORD_TABLE;
char *INBUF;
parser_t *PARSER;
@@ -332,6 +333,8 @@ value_t *ht_get(ht_t *h, string_t *key) {
return sll_get(h->buckets[hash(h, key->value)], key);
}
+bool ht_exists(ht_t *h, string_t *key) { return ht_get(h, key) != NULL; }
+
void ht_free(ht_t *h) {
for (int i = 0; i < h->size; i++) {
sll_free(h->buckets[i]);
@@ -358,7 +361,7 @@ void print_value(value_t *v) {
printf("%Lf\n", v->int_float);
break;
case VSTR:
- printf("%s\n", v->str_word->value);
+ printf("%s", v->str_word->value);
break;
case VWORD:
printf("W: %s\n", v->str_word->value);
@@ -397,6 +400,9 @@ bool eval_error() {
return true;
}
+/* TODO: rotr, rotl, dip, map, filter, errstr, join (for strings), switch
+ * (for quotes), split (split array, string, word into two), del (deleting
+ * entries from quotes, strings, words) */
bool eval_builtins(value_t *v) {
char *str = v->str_word->value;
value_t *v1;
@@ -535,13 +541,14 @@ bool eval_builtins(value_t *v) {
array_append(STACK, v1);
return eval_error();
}
- CUR_FREE_VAL = v1;
- CUR_FREE_VAL_OP = v;
+ array_append(EVAL_STACK, v);
+ array_append(EVAL_STACK, v1);
if (v1->type == VQUOTE) {
for (int i = 0; i < v1->quote->size; i++) {
eval(value_copy(v1->quote->items[i]));
}
- value_free(v1);
+ value_free(array_pop(EVAL_STACK));
+ array_pop(EVAL_STACK);
} else {
eval(v1);
}
@@ -950,6 +957,32 @@ bool eval_builtins(value_t *v) {
array_append(v2->quote, v1);
array_append(STACK, v2);
+ } else if (strcmp(str, "keep") == 0) {
+ v2 = array_pop(STACK);
+ if (v2 == NULL) {
+ value_free(v);
+ return eval_error();
+ }
+ v1 = array_pop(STACK);
+ if (v1 == NULL) {
+ value_free(v);
+ array_append(STACK, v2);
+ return eval_error();
+ }
+
+ array_append(STACK, value_copy(v1));
+ array_append(EVAL_STACK, v);
+ array_append(EVAL_STACK, v2);
+ if (v2->type == VQUOTE) {
+ for (int i = 0; i < v2->quote->size; i++) {
+ eval(value_copy(v2->quote->items[i]));
+ }
+ value_free(array_pop(EVAL_STACK));
+ array_pop(EVAL_STACK);
+ } else {
+ eval(v1);
+ }
+ array_append(STACK, v1);
} else if (strcmp(str, "len") == 0) {
v1 = array_pop(STACK);
if (v1 == NULL) {
@@ -977,6 +1010,35 @@ bool eval_builtins(value_t *v) {
retval = value_copy(v1);
array_append(STACK, v1);
array_append(STACK, retval);
+ } else if (strcmp(str, "isdef") == 0) {
+ v1 = array_pop(STACK);
+ if (v1 == NULL) {
+ value_free(v);
+ return eval_error();
+ }
+
+ retval = init_value(VINT);
+ if (v1->type != VWORD) {
+ retval->int_float = 0;
+ } else {
+ retval->int_float = ht_exists(WORD_TABLE, v1->str_word);
+ }
+ array_append(STACK, v1);
+ array_append(STACK, retval);
+ } else if (strcmp(str, "swap") == 0) {
+ v2 = array_pop(STACK);
+ if (v2 == NULL) {
+ value_free(v);
+ return eval_error();
+ }
+ v1 = array_pop(STACK);
+ if (v1 == NULL) {
+ array_append(STACK, v2);
+ value_free(v);
+ return eval_error();
+ }
+ array_append(STACK, v2);
+ array_append(STACK, v1);
} else if (strcmp(str, "dsc") == 0) {
v1 = array_pop(STACK);
if (v1 == NULL) {
@@ -1012,32 +1074,14 @@ bool eval_builtins(value_t *v) {
array_free(STACK);
free(INBUF);
free(PARSER);
- if (CUR_FREE_VAL) {
- value_free(CUR_FREE_VAL);
- }
- if (CUR_FREE_VAL_OP) {
- value_free(CUR_FREE_VAL_OP);
- }
+ array_free(EVAL_STACK);
value_free(v);
exit(0);
} else if (strcmp(str, "read") == 0) {
- v1 = array_pop(STACK);
- if (v1 == NULL) {
- value_free(v);
- return eval_error();
- }
-
- if (v1->type != VSTR) {
- value_free(v);
- array_append(STACK, v1);
- return eval_error();
- }
- printf("%s", v1->str_word->value);
retval = init_value(VSTR);
char *a = get_line(stdin);
retval->str_word = init_string(a);
array_append(STACK, retval);
- value_free(v1);
free(a);
} else if (strcmp(str, "fread") == 0) {
v1 = array_pop(STACK);
@@ -1064,6 +1108,7 @@ bool eval_builtins(value_t *v) {
retval->str_word = init_string(val);
array_append(STACK, retval);
value_free(v1);
+ free(val);
} else if (strcmp(str, "fwrite") == 0) {
v1 = array_pop(STACK);
if (v1 == NULL) {