diff options
author | dan <[email protected]> | 2023-05-25 11:00:58 -0400 |
---|---|---|
committer | dan <[email protected]> | 2023-05-25 11:00:58 -0400 |
commit | 40e23d550506659f7a33057bbbc23cb1cf0632f1 (patch) | |
tree | c7c7a53e78f7186b352c9e6a43113d6679257231 /optable.c | |
parent | 7463bbc06285690b5b644362d115aa9e82ac6cb4 (diff) | |
download | forth-40e23d550506659f7a33057bbbc23cb1cf0632f1.tar.gz forth-40e23d550506659f7a33057bbbc23cb1cf0632f1.tar.bz2 forth-40e23d550506659f7a33057bbbc23cb1cf0632f1.zip |
refactor: split optable and stack into sep files
Diffstat (limited to 'optable.c')
-rw-r--r-- | optable.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/optable.c b/optable.c new file mode 100644 index 0000000..fe7409b --- /dev/null +++ b/optable.c @@ -0,0 +1,159 @@ +#include "optable.h" +#include <string.h> + +static void dump(stack* s); +static void not(stack *s); +static void drop(stack *s); +static void over(stack *s); +static void rot(stack *s); +static void swap(stack *s); +static void eq(stack *s); +static void add(stack *s); +static void mult(stack *s); +static void s_div(stack *s); +static void sub(stack *s); +static void dup(stack *s); + +static wordop optable[OPTABLE_MAX_SIZE] = { + {"+", false, add}, + {"-", false, sub}, + {"*", false, mult}, + {"/", false, s_div}, + {"dup", false, dup}, + {"dump", false, dump}, + {"not", false, not}, + {"=", false, eq}, + {"swap", false, swap}, + {"drop", false, drop}, + {"over", false, over}, + {"rot", false, rot}, +}; +static int optablelen = 12; + +int defineop(int starti, char *input) { + // name by which the function will be called + char *opcode = malloc(sizeof(char) * WORD_LEN_LIMIT); + int opcodei = 0; + + // code to be evaluated when function is called + char *funcscript = malloc(sizeof(char) * DEFINED_FUNC_MAX_LENGTH); + int funcscripti = 0; + + // skip ' ' and ':' + while (input[starti] == ' ' || input[starti] == ':') { + starti++; + } + + // get name + while (input[starti] != ' ' && opcodei < WORD_LEN_LIMIT) { + opcode[opcodei++] = input[starti++]; + } + opcode[opcodei] = '\0'; + + // get code + while (input[starti] != ';' && funcscripti < DEFINED_FUNC_MAX_LENGTH) { + funcscript[funcscripti++] = input[starti++]; + } + funcscript[funcscripti] = '\0'; + + // optable bounds check + if (optablelen >= OPTABLE_MAX_SIZE) { + // Error + fprintf(stderr, "Error: optable reached max size, failed to create new user defined operation"); + exit(1); + } + // add op to end of table, and increment size + optable[optablelen].word = opcode; + optable[optablelen].isscript = true; + optable[optablelen].script = funcscript; + optable[optablelen].scriptlen = funcscripti; + optablelen++; + return starti; +} + +wordop* getop(char *word) { + for (int i = 0; i < optablelen; i++) { + if (!strcmp(optable[i].word, word)) { + return &optable[i]; + } + } + return 0; +} + +/* Implementations of builtin functions */ + +static void dump(stack* s) { + for (int i = 0; i < s->size; i++) { + printf("%d,", s->start[i]); + } + printf("\n"); +} + +static void not(stack *s) { + int x = pop(s); + push(s, !x); +} + +static void drop(stack *s) { + pop(s); +} + +static void over(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, y); + push(s, x); + 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); +} + +static void swap(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, x); + push(s, y); +} + +static void eq(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, x == y); +} + +static void add(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, x + y); +} + +static void mult(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, x * y); +} + +static void s_div(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, y / x); +} + +static void sub(stack *s) { + int x = pop(s); + int y = pop(s); + push(s, y - x); +} + +static void dup(stack *s) { + int x = pop(s); + push(s, x); + push(s, x); +} |