diff options
author | dan <[email protected]> | 2023-05-29 13:53:46 -0400 |
---|---|---|
committer | dan <[email protected]> | 2023-05-29 13:53:46 -0400 |
commit | b72c271d8731e1f67fdef29cd64726dfce893fe7 (patch) | |
tree | 319f74cf68c0eecd2b4764fa4fbea018af11dfb9 | |
parent | 2455c38a09be3708062fef3e90bc006ab44dfacb (diff) | |
download | forth-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.c | 4 | ||||
-rw-r--r-- | optable.c | 91 | ||||
-rw-r--r-- | stack.c | 44 | ||||
-rw-r--r-- | stack.h | 16 |
4 files changed, 104 insertions, 51 deletions
@@ -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; @@ -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' && @@ -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); + } +} @@ -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 |