diff options
author | Preston Pan <preston@nullring.xyz> | 2024-01-06 14:59:49 -0800 |
---|---|---|
committer | Preston Pan <preston@nullring.xyz> | 2024-01-06 14:59:49 -0800 |
commit | a70b986d42c89def265a396f8cedd23c749be1f9 (patch) | |
tree | 72b88443b5ce0c1af914dc3b34906fbbde032dec | |
parent | 77afa3abf898c0535f9d2c96f6c6fc6939932c60 (diff) |
fix all bug part 2
-rw-r--r-- | README.org | 4 | ||||
-rw-r--r-- | examples/repl.stem | 4 | ||||
-rw-r--r-- | main.c | 11 | ||||
-rw-r--r-- | parser.c | 91 |
4 files changed, 81 insertions, 29 deletions
@@ -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 @@ -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; } @@ -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) { |