diff options
| -rw-r--r-- | forthmachine.c | 15 | ||||
| -rw-r--r-- | forthmachine.h | 3 | ||||
| -rw-r--r-- | forthmachine_optable.c | 26 | 
3 files changed, 42 insertions, 2 deletions
| diff --git a/forthmachine.c b/forthmachine.c index 6cdefb5..d831106 100644 --- a/forthmachine.c +++ b/forthmachine.c @@ -11,8 +11,9 @@ forthmachine* forthmachine_new(errorhandler errorhandler) {      fm->ot = optable_new(errorhandler);      fm->s = stack_new(errorhandler);      fm->outputbuffer = (char*)malloc(sizeof(char) * MAX_OUTPUT_BUFFER_SIZE); -    fm->errorhandler = errorhandler;      strcpy(fm->outputbuffer, ""); +    fm->errorhandler = errorhandler; +    fm->lcs = stack_new(errorhandler);      return fm;  } @@ -39,6 +40,18 @@ static void op_exec(wordop* op, forthmachine* fm) {                              }                              break;                          } +                    case compileditem_doloopcontrol: +                        { +                            int index = stack_pop(fm->lcs); +                            int limit = stack_pop(fm->lcs); +                            index++; +                            if (index < limit) { +                                j = op->oplist[j].loopbackto - 1; +                                stack_push(fm->lcs, limit); +                                stack_push(fm->lcs, index); +                            } +                            break; +                        }                  }              }              break; diff --git a/forthmachine.h b/forthmachine.h index 4a55952..814e957 100644 --- a/forthmachine.h +++ b/forthmachine.h @@ -21,6 +21,7 @@ typedef enum {      compileditem_stackop = 0,      compileditem_literal = 1,      compileditem_ifcontrol = 2, +    compileditem_doloopcontrol = 3,  } compileditem_type;  typedef struct { @@ -31,6 +32,7 @@ typedef struct {          struct {              int jumpto;          }; +        int loopbackto;      };  } compileditem; @@ -72,6 +74,7 @@ struct forthmachine {      stack* s;      char* outputbuffer;      errorhandler errorhandler; +    stack* lcs;  };  #define MAX_OUTPUT_BUFFER_SIZE 1024 diff --git a/forthmachine_optable.c b/forthmachine_optable.c index cd4b46b..2a51610 100644 --- a/forthmachine_optable.c +++ b/forthmachine_optable.c @@ -30,6 +30,8 @@ static void printall(forthmachine* fm);  static void pick(forthmachine* fm);  static void roll(forthmachine* fm);  static void clearstack(forthmachine* fm); +static void doloopstart(forthmachine* fm); +static void lcsindex(forthmachine* fm);  const static wordop inittable[] = {      {".", optype_builtin, {popout}}, @@ -56,6 +58,8 @@ const static wordop inittable[] = {      {"depth", optype_builtin, {depth}},      {".s", optype_builtin, {printall}},      {"clearstack", optype_builtin, {clearstack}}, +    {"do", optype_builtin, {doloopstart}}, +    {"i", optype_builtin, {lcsindex}},  }; @@ -280,6 +284,17 @@ static void clearstack(forthmachine* fm) {      stack_clear(fm->s);  } +static void doloopstart(forthmachine* fm) { +    int index = stack_pop(fm->s); +    int limit = stack_pop(fm->s); +    stack_push(fm->lcs, limit); +    stack_push(fm->lcs, index); +} + +static void lcsindex(forthmachine* fm) { +    stack_push(fm->s, stack_peek(fm->lcs)); +} +  /* Directives */  /** @@ -318,7 +333,8 @@ void optable_defineop(optable* optable, char *input, int* starti) {      // get code      int wordi = 0;      char wordbuf[WORD_LEN_LIMIT]; -    stack* ifcounter = stack_new(NULL); +    stack* ifcounter = stack_new(optable->errorhandler); +    stack* doloopcounter = stack_new(optable->errorhandler);      while (input[i] != ';' && opsi < DEFINED_FUNC_MAX_LENGTH) {          char c = input[i++];          if (notdelim(c) && wordi < WORD_LEN_LIMIT) { @@ -333,6 +349,10 @@ void optable_defineop(optable* optable, char *input, int* starti) {              } else if (0 == strcmp(wordbuf, "then")) {                  int ifopi = stack_pop(ifcounter);                  oplist[ifopi].jumpto = opsi; +            } else if (0 == strcmp(wordbuf, "loop")) { +                oplist[opsi].type = compileditem_doloopcontrol; +                oplist[opsi].loopbackto = stack_pop(doloopcounter); +                opsi++;              } else if (0 == strcmp(wordbuf, opcode)) {                  oplist[opsi].type = compileditem_stackop;                  oplist[opsi].wordop = &optable->optable[optable->len]; @@ -343,6 +363,9 @@ void optable_defineop(optable* optable, char *input, int* starti) {                  if (wordop) {                      oplist[opsi].type = compileditem_stackop;                      oplist[opsi].wordop = wordop; +                    if (0 == strcmp(wordbuf, "do")) { +                        stack_push(doloopcounter, opsi+1); +                    }                  } else {                      oplist[opsi].type = compileditem_literal;                      oplist[opsi].literal = atoi(wordbuf); @@ -353,6 +376,7 @@ void optable_defineop(optable* optable, char *input, int* starti) {          }      }      stack_free(ifcounter); +    stack_free(doloopcounter);      wordop* existingop = optable_getop(optable, opcode);      if (existingop) { | 
