aboutsummaryrefslogtreecommitdiffstats
path: root/forth.c
diff options
context:
space:
mode:
authordan <[email protected]>2023-05-26 14:59:16 -0400
committerdan <[email protected]>2023-05-26 14:59:16 -0400
commit2b7ea0857da80e1353ce0a72239093f108fdc1e9 (patch)
treebdcfe9a653c94d0385cea58156225149f92dc3ad /forth.c
parent4e26b8c0a1b7fc843741105d57da863997e7284b (diff)
downloadforth-2b7ea0857da80e1353ce0a72239093f108fdc1e9.tar.gz
forth-2b7ea0857da80e1353ce0a72239093f108fdc1e9.tar.bz2
forth-2b7ea0857da80e1353ce0a72239093f108fdc1e9.zip
refactor: if and : moved to optable too
Diffstat (limited to 'forth.c')
-rw-r--r--forth.c53
1 files changed, 18 insertions, 35 deletions
diff --git a/forth.c b/forth.c
index 0b4a99f..a9407ef 100644
--- a/forth.c
+++ b/forth.c
@@ -26,60 +26,43 @@ char isnumber(char *text) {
void eval(stack* s, int len, char* line);
-void exec(stack *s, char *word) {
+void exec(stack *s, char *word, int len, char* line, int* i) {
wordop* op = getop(word);
if (op) {
- if (op->isscript) {
+ if (op->optype == script) {
eval(s, op->scriptlen, op->script);
- } else {
+ } else if (op->optype == builtin) {
op->op(s);
+ } else if (op->optype == directive) {
+ op->directive(s, len, line, i);
}
- return;
- }
- if (isnumber(word)) {
+ } else if (isnumber(word)) {
push(s, atoi(word));
- return;
}
}
+bool notdelim(char c) {
+ return c != ' ' && c != '\n' && c != '\t' && c != '\0';
+}
+
void eval(stack* s, int len, char* line) {
- char word[WORD_LEN_LIMIT];
+ char word[WORD_LEN_LIMIT];
int wordi = 0;
for (int i = 0; i < len; i++) {
- // end of input is \n, char after end of input is \0
- if (line[i] == '\0') {
- return;
- }
- if (line[i] != ' ' &&
- line[i] != '\n' && wordi < WORD_LEN_LIMIT - 1) {
- if (line[i] == ':') {
- i = defineop(i, line);
- wordi = 0;
- } else {
- word[wordi++] = line[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';
- if (!strcmp(word, "if")) {
- stackitem predicate = pop(s);
- if (!predicate) {
- while (len > i && !(
- line[i-3] == 't' &&
- line[i-2] == 'h' &&
- line[i-1] == 'e' &&
- line[i] == 'n'
- )) {
- i++;
- }
- }
- } else {
- exec(s, word);
- }
+ exec(s, word, len, line, &i);
}
// start new word
wordi = 0;
}
+ // end of input string
+ if (line[i] == '\0') {
+ return;
+ }
}
}