diff options
author | dan <[email protected]> | 2023-06-02 22:38:16 -0400 |
---|---|---|
committer | dan <[email protected]> | 2023-06-02 22:38:16 -0400 |
commit | 31ae9a14ef4d76eaf3ad79fb31477ea4596d047e (patch) | |
tree | a00850c3d809fc7b31ed9183c5f617125df18ac9 | |
parent | e0fcdc6e3577f8c40b019396b400928379d928b9 (diff) | |
download | forth-31ae9a14ef4d76eaf3ad79fb31477ea4596d047e.tar.gz forth-31ae9a14ef4d76eaf3ad79fb31477ea4596d047e.tar.bz2 forth-31ae9a14ef4d76eaf3ad79fb31477ea4596d047e.zip |
feat: can overwrite existing functions
-rw-r--r-- | forthmachine.c | 2 | ||||
-rw-r--r-- | forthmachine.h | 2 | ||||
-rw-r--r-- | forthmachine_optable.c | 60 |
3 files changed, 34 insertions, 30 deletions
diff --git a/forthmachine.c b/forthmachine.c index 3820dde..4532f78 100644 --- a/forthmachine.c +++ b/forthmachine.c @@ -45,7 +45,7 @@ static void op_exec(wordop* op, forthmachine* fm) { static void forthmachine_exec(forthmachine* fm, char *word, int len, char* line, int* i) { if (0 == strcmp(word, ":")) { - defineop(fm, line, i); + optable_defineop(fm->ot, line, i); return; } wordop* op = optable_getop(fm->ot, word); diff --git a/forthmachine.h b/forthmachine.h index 50eb4d8..28f3932 100644 --- a/forthmachine.h +++ b/forthmachine.h @@ -65,7 +65,7 @@ struct optable { */ wordop* optable_getop(optable* optable, char *word); -void defineop(forthmachine* fm, char *input, int* starti); +void optable_defineop(optable* optable, char *input, int* starti); optable* optable_new(); diff --git a/forthmachine_optable.c b/forthmachine_optable.c index 47ad009..aa379bb 100644 --- a/forthmachine_optable.c +++ b/forthmachine_optable.c @@ -90,22 +90,17 @@ optable* optable_new() { 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", "+"}}, + char* defs[] = { + ": nip swap drop ;", + ": tuck dup rot rot ;", + ": incr 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); + char* d = defs[i]; + int x = 0; + optable_defineop(ot, d, &x); } return ot; } @@ -286,15 +281,14 @@ static void clearstack(forthmachine* fm) { /* Directives */ /** - * defineop reads a function identifier, followed by the commands to run when the function + * optable_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 * */ -void defineop(forthmachine* fm, char *input, int* starti) { - optable* optable = fm->ot; +void optable_defineop(optable* optable, char *input, int* starti) { // value easier to deal with (than pointer) int i = *starti; // name by which the function will be called @@ -358,19 +352,29 @@ void defineop(forthmachine* fm, char *input, int* starti) { } stack_free(ifcounter); - // 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 = compiled; - optable->optable[optable->len].oplist = oplist; - optable->optable[optable->len].oplistlen = opsi; - optable->len++; + wordop* existingop = optable_getop(optable, opcode); + if (existingop) { + if (existingop->optype == compiled && existingop->oplist) { + free(existingop->oplist); + } + existingop->optype = compiled; + existingop->oplist = oplist; + existingop->oplistlen = opsi; + } else { + // 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 = compiled; + optable->optable[optable->len].oplist = oplist; + optable->optable[optable->len].oplistlen = opsi; + optable->len++; + } // move read position forwards *starti = i; } |