diff options
| -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 | 
