aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2024-01-05 17:16:57 -0800
committerPreston Pan <preston@nullring.xyz>2024-01-05 17:16:57 -0800
commit77262bf18c407e04b926a0efbea09b31c672f374 (patch)
tree368bc955d817aeb832e720bad9c7291f1ca8aa6f
parenta9be28f347585c787215ffb2c3b43fba93cacb0e (diff)
fix floats
-rw-r--r--README.org4
-rw-r--r--parser.c122
2 files changed, 121 insertions, 5 deletions
diff --git a/README.org b/README.org
index bcd9697..3337be5 100644
--- a/README.org
+++ b/README.org
@@ -1,4 +1,4 @@
#+title: Stem
-* Stem
-stem aims to be a small implementation of something like the forth programming language.
+* Introduction
+Stem aims to be a small implementation of something like the forth programming language.
diff --git a/parser.c b/parser.c
index 5dd21f1..7c84008 100644
--- a/parser.c
+++ b/parser.c
@@ -91,7 +91,7 @@ value_t *value_copy(value_t *v) {
}
void value_free(value_t *v) {
- if (v->type == VSTR || v->type == VSTR || v->type == VWORD) {
+ if (v->type == VSTR || v->type == VWORD) {
string_free(v->str_word);
}
if (v->type == VQUOTE) {
@@ -177,7 +177,7 @@ value_t *parse_num(parser_t *p) {
value_t *retv;
string_t *s = init_string(NULL);
bool is_float = false;
- while (isdigit(p->c) || p->c == '.') {
+ while (isdigit(p->c) || (p->c == '.') && !is_float) {
if (p->c == '.')
is_float = true;
string_append(s, p->c);
@@ -268,7 +268,7 @@ value_t *sll_get(sll_t *l, string_t *k) {
}
return NULL;
}
-/* TODO */
+
void sll_free(sll_t *l) {
node_t *cur = l->head;
node_t *tmp;
@@ -720,6 +720,122 @@ bool eval_builtins(value_t *v) {
array_append(STACK, retval);
value_free(v1);
value_free(v2);
+ } else if (strcmp(str, "<=") == 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();
+ }
+
+ retval = init_value(VINT);
+ if (v1->type == VSTR && v2->type == VSTR ||
+ v1->type == VWORD && v2->type == VWORD) {
+ retval->int_float = strcmp(v1->str_word->value, v2->str_word->value) <= 0;
+ } else if ((v1->type == VINT || v1->type == VFLOAT) &&
+ (v2->type == VINT || v2->type == VFLOAT)) {
+ retval->int_float = v1->int_float <= v2->int_float;
+ } else {
+ value_free(v);
+ array_append(STACK, v1);
+ array_append(STACK, v2);
+ return eval_error();
+ }
+ array_append(STACK, retval);
+ value_free(v1);
+ value_free(v2);
+ } else if (strcmp(str, "<") == 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();
+ }
+
+ retval = init_value(VINT);
+ if (v1->type == VSTR && v2->type == VSTR ||
+ v1->type == VWORD && v2->type == VWORD) {
+ retval->int_float = strcmp(v1->str_word->value, v2->str_word->value) < 0;
+ } else if ((v1->type == VINT || v1->type == VFLOAT) &&
+ (v2->type == VINT || v2->type == VFLOAT)) {
+ retval->int_float = v1->int_float < v2->int_float;
+ } else {
+ value_free(v);
+ array_append(STACK, v1);
+ array_append(STACK, v2);
+ return eval_error();
+ }
+ array_append(STACK, retval);
+ value_free(v1);
+ value_free(v2);
+ } else if (strcmp(str, ">") == 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();
+ }
+
+ retval = init_value(VINT);
+ if (v1->type == VSTR && v2->type == VSTR ||
+ v1->type == VWORD && v2->type == VWORD) {
+ retval->int_float = strcmp(v1->str_word->value, v2->str_word->value) > 0;
+ } else if ((v1->type == VINT || v1->type == VFLOAT) &&
+ (v2->type == VINT || v2->type == VFLOAT)) {
+ retval->int_float = v1->int_float > v2->int_float;
+ } else {
+ value_free(v);
+ array_append(STACK, v1);
+ array_append(STACK, v2);
+ return eval_error();
+ }
+ array_append(STACK, retval);
+ value_free(v1);
+ value_free(v2);
+ } else if (strcmp(str, ">=") == 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();
+ }
+
+ retval = init_value(VINT);
+ if (v1->type == VSTR && v2->type == VSTR ||
+ v1->type == VWORD && v2->type == VWORD) {
+ retval->int_float = strcmp(v1->str_word->value, v2->str_word->value) >= 0;
+ } else if ((v1->type == VINT || v1->type == VFLOAT) &&
+ (v2->type == VINT || v2->type == VFLOAT)) {
+ retval->int_float = v1->int_float >= v2->int_float;
+ } else {
+ value_free(v);
+ array_append(STACK, v1);
+ array_append(STACK, v2);
+ return eval_error();
+ }
+ array_append(STACK, retval);
+ value_free(v1);
+ value_free(v2);
} else if (strcmp(str, "if") == 0) {
v3 = array_pop(STACK);
if (v3 == NULL) {