aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordan <[email protected]>2023-05-29 13:53:46 -0400
committerdan <[email protected]>2023-05-29 13:53:46 -0400
commitb72c271d8731e1f67fdef29cd64726dfce893fe7 (patch)
tree319f74cf68c0eecd2b4764fa4fbea018af11dfb9
parent2455c38a09be3708062fef3e90bc006ab44dfacb (diff)
downloadforth-b72c271d8731e1f67fdef29cd64726dfce893fe7.tar.gz
forth-b72c271d8731e1f67fdef29cd64726dfce893fe7.tar.bz2
forth-b72c271d8731e1f67fdef29cd64726dfce893fe7.zip
feat: add .s,roll,pick,and depth commands to c forth
-rw-r--r--forth.c4
-rw-r--r--optable.c91
-rw-r--r--stack.c44
-rw-r--r--stack.h16
4 files changed, 104 insertions, 51 deletions
diff --git a/forth.c b/forth.c
index 4c5d910..0ebb7d5 100644
--- a/forth.c
+++ b/forth.c
@@ -42,7 +42,7 @@ void exec(stack *s, char *word, int len, char* line, int* i) {
break;
}
} else if (isnumber(word)) {
- push(s, atoi(word));
+ stack_push(s, atoi(word));
}
}
@@ -68,7 +68,7 @@ void eval(stack* s, int len, char* line) {
}
int main(int argc, char** argv) {
- stack* s = newstack();
+ stack* s = stack_new();
char *line = NULL;
size_t len = 0;
ssize_t read;
diff --git a/optable.c b/optable.c
index b8df8ec..5751e31 100644
--- a/optable.c
+++ b/optable.c
@@ -16,6 +16,7 @@ static void dup(stack *s);
static void popout(stack *s);
static void peekout(stack *s);
static void donothing(stack *s);
+static void depth(stack *s);
static void ifdirective(stack *s, int len, char* line, int* i);
static void defineop(stack *s, int len, char* line, int* i);
@@ -37,11 +38,15 @@ static wordop optable[OPTABLE_MAX_SIZE] = {
{"drop", builtin, {drop}},
{"over", builtin, {over}},
{"rot", builtin, {rot}},
+ {"pick", builtin, {stack_pick}},
+ {"roll", builtin, {stack_roll}},
{"then", builtin, {donothing}},
+ {"depth", builtin, {depth}},
+ {".s", builtin, {stack_printall}},
{"if", directive, {ifdirective}},
{":", directive, {defineop}},
};
-static int optablelen = 16;
+static int optablelen = 20;
#pragma clang diagnostic pop
wordop* getop(char *word) {
@@ -56,81 +61,81 @@ wordop* getop(char *word) {
/* Implementations of builtin functions */
static void not(stack *s) {
- int x = pop(s);
- push(s, !x);
+ int x = stack_pop(s);
+ stack_push(s, !x);
}
static void drop(stack *s) {
- pop(s);
+ stack_pop(s);
}
static void over(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, y);
- push(s, x);
- push(s, y);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, y);
+ stack_push(s, x);
+ stack_push(s, y);
}
static void rot(stack *s) {
- int x = pop(s);
- int y = pop(s);
- int z = pop(s);
- push(s, y);
- push(s, x);
- push(s, z);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ int z = stack_pop(s);
+ stack_push(s, y);
+ stack_push(s, x);
+ stack_push(s, z);
}
static void swap(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, x);
- push(s, y);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, x);
+ stack_push(s, y);
}
static void eq(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, x == y);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, x == y);
}
static void add(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, x + y);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, x + y);
}
static void mult(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, x * y);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, x * y);
}
static void s_div(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, y / x);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, y / x);
}
static void sub(stack *s) {
- int x = pop(s);
- int y = pop(s);
- push(s, y - x);
+ int x = stack_pop(s);
+ int y = stack_pop(s);
+ stack_push(s, y - x);
}
static void dup(stack *s) {
- int x = pop(s);
- push(s, x);
- push(s, x);
+ int x = stack_pop(s);
+ stack_push(s, x);
+ stack_push(s, x);
}
static void popout(stack *s) {
- printf("%d\n", pop(s));
+ printf("%d\n", stack_pop(s));
}
static void peekout(stack *s) {
- int x = pop(s);
- push(s, x);
+ int x = stack_pop(s);
+ stack_push(s, x);
printf("%d\n", x);
}
@@ -138,11 +143,15 @@ static void donothing(stack *s) {
// Do nothing at all (i.e. discard token)
}
+static void depth(stack *s) {
+ stack_push(s, stack_depth(s));
+}
+
/* Directives */
static void ifdirective(stack *s, int len, char* line, int* starti) {
int i = *starti;
- stackitem predicate = pop(s);
+ stackitem predicate = stack_pop(s);
if (!predicate) {
while (len > i && i >= 4 && !(
line[i-4] == 't' &&
diff --git a/stack.c b/stack.c
index 80b8ed2..617e621 100644
--- a/stack.c
+++ b/stack.c
@@ -1,6 +1,6 @@
#include "stack.h"
-stack* newstack() {
+stack* stack_new() {
stack* s = (stack*)malloc(sizeof(stack));
s->size = 0;
s->maxsize = 1024;
@@ -8,7 +8,7 @@ stack* newstack() {
return s;
}
-stackitem pop(stack* s) {
+stackitem stack_pop(stack* s) {
if (s->size > 0) {
s->size = s->size - 1;
stackitem si = s->start[s->size];
@@ -19,7 +19,7 @@ stackitem pop(stack* s) {
}
}
-stackitem peek(stack* s) {
+stackitem stack_peek(stack* s) {
if (s->size > 0) {
return s->start[s->size - 1];
} else {
@@ -28,7 +28,7 @@ stackitem peek(stack* s) {
}
}
-void push(stack *s, stackitem si) {
+void stack_push(stack *s, stackitem si) {
// fprintf(stderr, "pushing %d", si);
if (s->size >= s->maxsize) {
fprintf(stderr, "Error Stack Overflow");
@@ -38,3 +38,39 @@ void push(stack *s, stackitem si) {
s->size = s->size + 1;
}
}
+
+int stack_depth(stack *s) {
+ return s->size;
+}
+
+void stack_printall(stack *s) {
+ printf("<%d>", s->size);
+ for (int i = 0; i < s->size; i++) {
+ printf(" %d", s->start[i]);
+ }
+ printf("\n");
+}
+
+void stack_roll(stack *s) {
+ int posfromtop = stack_pop(s); // top is 0, bottom is s->size - 1
+ const int maxindex = s->size - 1;
+ int i = maxindex - posfromtop;
+ if (i >= 0) {
+ int newtop = s->start[i];
+ for (; i + 1 < s->size; i++) {
+ s->start[i] = s->start[i+1];
+ }
+ s->start[i] = newtop;
+ }
+}
+
+void stack_pick(stack *s) {
+ int posfromtop = stack_pop(s); // top is 0, bottom is s->size - 1
+ const int maxindex = s->size - 1;
+ if (s->size > posfromtop) {
+ stack_push(s, s->start[maxindex - posfromtop]);
+ } else {
+ // no item found
+ stack_push(s, 0);
+ }
+}
diff --git a/stack.h b/stack.h
index 16fe07b..30dc49c 100644
--- a/stack.h
+++ b/stack.h
@@ -13,12 +13,20 @@ typedef struct {
} stack;
-stack* newstack();
+stack* stack_new();
-stackitem pop(stack* s);
+stackitem stack_pop(stack* s);
-stackitem peek(stack* s);
+stackitem stack_peek(stack* s);
-void push(stack *s, stackitem si);
+void stack_push(stack *s, stackitem si);
+
+int stack_depth(stack *s);
+
+void stack_printall(stack *s);
+
+void stack_roll(stack *s);
+
+void stack_pick(stack *s);
#endif