aboutsummaryrefslogtreecommitdiffstats
path: root/forth.c
diff options
context:
space:
mode:
authordan <[email protected]>2023-06-02 16:22:29 -0400
committerdan <[email protected]>2023-06-02 16:22:29 -0400
commitac8a2fd77f7661b60cf2b272090ece67f65951db (patch)
treed45442d8bcf5c40febb85fc35d02c6c4f1d3684e /forth.c
parent558b0646c5580454dd35a6bdee07bcc711db134e (diff)
downloadforth-ac8a2fd77f7661b60cf2b272090ece67f65951db.tar.gz
forth-ac8a2fd77f7661b60cf2b272090ece67f65951db.tar.bz2
forth-ac8a2fd77f7661b60cf2b272090ece67f65951db.zip
refactor: always output via buffer
Diffstat (limited to 'forth.c')
-rw-r--r--forth.c101
1 files changed, 8 insertions, 93 deletions
diff --git a/forth.c b/forth.c
index b2c6552..e44d372 100644
--- a/forth.c
+++ b/forth.c
@@ -5,108 +5,21 @@
#include <unistd.h>
#include <stdbool.h>
-#ifndef STACK_H
#include "stack.h"
-#endif
-#ifndef OPTABLE_H
-#include "optable.h"
-#endif
-
-bool isnumber(char *text) {
- for(int j = strlen(text); j > 0; j--) {
- if(text[j] < '0' && text[j] > '9') {
- return false;
- }
- }
- return true;
-}
-
-bool notdelim(char c) {
- return c != ' ' && c != '\n' && c != '\t' && c != '\0';
-}
-
-typedef struct {
- optable* ot;
- stack* s;
-} forthmachine;
-
-forthmachine* forthmachine_new() {
- forthmachine* fm = malloc(sizeof(forthmachine));
- fm->ot = optable_new();
- fm->s = stack_new();
- return fm;
-}
-
-void eval(forthmachine* fm, int len, char* line);
-
-void op_exec(wordop* op, forthmachine* fm, char *word, int len, char* line, int* i) {
- switch (op->optype) {
- case script:
- eval(fm, op->scriptlen, op->script);
- break;
- case builtin:
- op->op(fm->s);
- break;
- case directive:
- op->directive(fm->s, len, line, i, fm->ot);
- break;
- case compiled:
- for (int j = 0; j < op->oplistlen; j++) {
- if (op->oplist[j].isliteral) {
- stack_push(fm->s, op->oplist[j].literal);
- } else {
- op_exec(op->oplist[j].wordop, fm, word, len, line, i);
- }
- }
- }
-}
-
-void exec(forthmachine* fm, char *word, int len, char* line, int* i) {
- wordop* op = optable_getop(fm->ot, word);
- if (op) {
- op_exec(op, fm, word, len, line, i);
- } else if (isnumber(word)) {
- stack_push(fm->s, atoi(word));
- }
-}
-
-void eval(forthmachine* fm, int len, char* line) {
- char word[WORD_LEN_LIMIT];
- int wordi = 0;
- for (int i = 0; i < len; i++) {
- if (notdelim(line[i]) && wordi < WORD_LEN_LIMIT - 1) {
- word[wordi++] = line[i];
- } else { // end of word
- if (wordi > 0) { // don't exec an empty string
- word[wordi] = '\0';
- exec(fm, word, len, line, &i);
- }
- // start new word
- wordi = 0;
- }
- // end of input string
- if (line[i] == '\0') {
- return;
- }
- }
-}
+#include "forthmachine.h"
int initialised = false;
forthmachine* fm;
int lastline = 0;
-
char* buffer_eval(int len, char* line) {
if (!initialised) {
fm = forthmachine_new();
initialised = true;
- outputline = 0;
- outputbuffer = malloc(sizeof(char) * 1024);
}
- strcpy(outputbuffer, "");
- eval(fm, len, line);
- if (outputline) {
- outputline = 0;
- return outputbuffer;
+ strcpy(fm->outputbuffer, "");
+ forthmachine_eval(fm, len, line);
+ if (fm->outputbuffer && strlen(fm->outputbuffer)) {
+ return fm->outputbuffer;
} else {
return "";
}
@@ -118,7 +31,9 @@ void stdin_eval() {
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
- eval(fm, len, line);
+ forthmachine_eval(fm, len, line);
+ printf("%s", fm->outputbuffer);
+ strcpy(fm->outputbuffer, "");
}
}