diff options
author | dan <[email protected]> | 2023-06-02 16:22:29 -0400 |
---|---|---|
committer | dan <[email protected]> | 2023-06-02 16:22:29 -0400 |
commit | ac8a2fd77f7661b60cf2b272090ece67f65951db (patch) | |
tree | d45442d8bcf5c40febb85fc35d02c6c4f1d3684e /optable.c | |
parent | 558b0646c5580454dd35a6bdee07bcc711db134e (diff) | |
download | forth-ac8a2fd77f7661b60cf2b272090ece67f65951db.tar.gz forth-ac8a2fd77f7661b60cf2b272090ece67f65951db.tar.bz2 forth-ac8a2fd77f7661b60cf2b272090ece67f65951db.zip |
refactor: always output via buffer
Diffstat (limited to 'optable.c')
-rw-r--r-- | optable.c | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/optable.c b/optable.c deleted file mode 100644 index de2aab0..0000000 --- a/optable.c +++ /dev/null @@ -1,340 +0,0 @@ -#include "optable.h" -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -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 mod(stack *s); -static void negate(stack *s); -static void s_abs(stack *s); -static void max(stack *s); -static void min(stack *s); -static void sub(stack *s); -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, optable* ot); -static void defineop(stack *s, int len, char* line, int* i, optable* ot); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types" -// clang seems to not realise that the union can contain fp types beyond the first -const static wordop inittable[] = { - {".", builtin, {popout}}, - {"peek", builtin, {peekout}}, - {"+", builtin, {add}}, - {"-", builtin, {sub}}, - {"*", builtin, {mult}}, - {"/", builtin, {s_div}}, - {"negate", builtin, {negate}}, - {"abs", builtin, {s_abs}}, - {"mod", builtin, {mod}}, - {"max", builtin, {max}}, - {"min", builtin, {min}}, - {"dup", builtin, {dup}}, - {"not", builtin, {not}}, - {"=", builtin, {eq}}, - {"swap", builtin, {swap}}, - {"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}}, - {"clearstack", builtin, {stack_clear}}, - {"if", directive, {ifdirective}}, - {":", directive, {defineop}}, -}; - -//static int optable->len = 26; -#pragma clang diagnostic pop - -compileditem* optable_compilewords(optable* ot, int len, char** script) { - compileditem* oplist = malloc(sizeof(compileditem) * len); - for (int i = 0; i < len; i++) { - wordop* wordop = optable_getop(ot, script[i]); - if (wordop) { - oplist[i].isliteral = false; - oplist[i].wordop = wordop; - } else { - oplist[i].isliteral = true; - oplist[i].literal = atoi(script[i]); - } - } - return oplist; -} - -void optable_addop(optable* ot, char* name, int len, char** words) { - ot->optable[ot->len].word = malloc(sizeof(name)); - strcpy(ot->optable[ot->len].word, name); - ot->optable[ot->len].optype = compiled; - ot->optable[ot->len].oplistlen = len; - compileditem* oplist = optable_compilewords(ot, len, words); - ot->optable[ot->len].oplist = oplist; - ot->len++; -} - -optable* optable_new() { - optable* ot = malloc(sizeof(optable)); - ot->optable = malloc(sizeof(wordop) * OPTABLE_MAX_SIZE); - int inittablesize = sizeof(inittable); - ot->len = inittablesize / sizeof(*inittable); - memcpy(ot->optable, inittable, inittablesize); - - typedef struct { - char* name; - int len; - char** words; - } tocompile; - tocompile defs[] = { - {"nip", 2, (char*[]){"swap","drop"}}, - {"tuck", 3, (char*[]){"dup", "rot", "rot"}}, - {"incr", 2, (char*[]){"1", "+"}}, - }; - int defslen = sizeof(defs) / sizeof(*defs); - for (int i = 0; i < defslen; i++) { - tocompile d = defs[i]; - char* nm = defs[i].name; - char** ws = d.words; - optable_addop(ot,nm, d.len,ws); - } - return ot; -} - -wordop* optable_getop(optable* optable, char *word) { - for (int i = 0; i < optable->len; i++) { - if (!strcmp(optable->optable[i].word, word)) { - return &optable->optable[i]; - } - } - return 0; -} - -/* Implementations of builtin functions */ - -static void not(stack *s) { - int x = stack_pop(s); - stack_push(s, !x); -} - -static void drop(stack *s) { - stack_pop(s); -} - -static void over(stack *s) { - 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 = 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 = stack_pop(s); - int y = stack_pop(s); - stack_push(s, x); - stack_push(s, y); -} - -static void eq(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - stack_push(s, x == y); -} - -static void add(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - stack_push(s, x + y); -} - -static void mult(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - stack_push(s, x * y); -} - -static void s_div(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - stack_push(s, y / x); -} - -static void mod(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - stack_push(s, y % x); -} - -static void sub(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - stack_push(s, y - x); -} - -static void dup(stack *s) { - int x = stack_pop(s); - stack_push(s, x); - stack_push(s, x); -} - -//#ifdef __EMSCRIPTEN__ -int outputline = 0; -char* outputbuffer; -//#endif - -static void popout(stack *s) { -if (outputbuffer) { - char x[WORD_LEN_LIMIT]; - sprintf(x, "%d\n", stack_pop(s)); - strcat(outputbuffer, x); - outputline++; -} else { - printf("%d\n", stack_pop(s)); -} -} - -static void peekout(stack *s) { - int x = stack_pop(s); - stack_push(s, x); -if (outputbuffer) { - char y[WORD_LEN_LIMIT]; - sprintf(y, "%d\n", x); - strcat(outputbuffer, y); - outputline++; -} else { - printf("%d\n", x); -} -} - -static void donothing(stack *s) { - // Do nothing at all (i.e. discard token) -} - -static void depth(stack *s) { - stack_push(s, stack_depth(s)); -} - -static void max(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - if (x > y) { - stack_push(s, x); - } else { - stack_push(s, y); - } -} - -static void min(stack *s) { - int x = stack_pop(s); - int y = stack_pop(s); - if (x < y) { - stack_push(s, x); - } else { - stack_push(s, y); - } -} - -static void negate(stack *s) { - stack_push(s, 0 - stack_pop(s)); -} - -static void s_abs(stack *s) { - int x = stack_pop(s); - stack_push(s, x < 0 ? 0 - x : x); -} - -/* Directives */ - -static void ifdirective(stack *s, int len, char* line, int* starti, optable* ot_IDNORED) { - int i = *starti; - stackitem predicate = stack_pop(s); - if (!predicate) { - while (len > i && i >= 4 && !( - line[i-4] == 't' && - line[i-3] == 'h' && - line[i-2] == 'e' && - line[i-1] == 'n' - )) { - i++; - } - } - *starti = i; -} - - -/** - * defineop reads a function identifier, followed by the commands to run when the function - * is called, stopping when a semicolon is reached. - * Reading is done from the input string. - * - * returns new position of input index - * - */ -static void defineop(stack* s_IGNORED, int len_IGNORED, char *input, int* starti, optable* optable) { - // value easier to deal with (than pointer) - int i = *starti; - // 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[i] == ' ' || input[i] == ':') { - i++; - } - - // get name - while (input[i] != ' ' && opcodei < WORD_LEN_LIMIT) { - opcode[opcodei++] = input[i++]; - } - opcode[opcodei] = '\0'; - - // get code - while (input[i] != ';' && funcscripti < DEFINED_FUNC_MAX_LENGTH) { - funcscript[funcscripti++] = input[i++]; - } - funcscript[funcscripti] = '\0'; - - // optable->optable bounds check - if (optable->len >= OPTABLE_MAX_SIZE) { - // Error - fprintf(stderr, "Error: optable->optable reached max size, failed to create new user defined operation"); - exit(1); - } - // add op to end of table, and increment size - optable->optable[optable->len].word = opcode; - optable->optable[optable->len].optype = script; - optable->optable[optable->len].script = funcscript; - optable->optable[optable->len].scriptlen = funcscripti; - optable->len++; - - // move read position forwards - *starti = i; -} |