#include <stdint.h>
#include <string.h>
-typedef void (*codeword_t)(long*);
+/**
+ This type represents a pointer to a function handler for executing a word.
+ For built-in words this typically points to the C function that implements
+ the word. For compiled words, this typically points to the docolon function.
+
+ @param code This is a pointer to the next bytecode instruction to execute.
+ For built-in words this pointer is 0.
+ */
+typedef void (*codeword_t)(long* code);
+/**
+ This structure contains all of the relevant attributes of a word definition
+*/
typedef struct word_t {
+ /** Pointer to the next most recently defined word in the dictionary. */
struct word_t const* link;
+ /** A collection of flags describing attributes of the word. */
long flags;
+ /** Pointer to the null terminated string that holds the name of the word. */
char const* name;
+ /**
+ * Pointer to the execution handler for this word. For words defined in C
+ * This points to the implementation function. For words defined in
+ * bytecode this will point to the docolon function. */
codeword_t codeword;
+ /**
+ * A pointer to the list of instructions that make up this word. For words
+ * defined in C this will be 0u (NULL). */
long* code;
} word_t;
/** Pointer to current position on the stack */
static long* ArgStackPtr;
+/** The argument stack */
+long ArgStack[32];
+
/**
* Define a built-in word that executes native code */
#define defcode(name_str,c_name,flags,prev) \
*****************************************************************************/
defconst("VERSION", version, 0, 0, 1);
defconst("EXECDEF", execdef, 0, &version, (long)&docolon);
-defconst("F_IMMED", f_immed, 0, &execdef, 1);
-defconst("F_HIDDEN", f_hidden, 0, &f_immed, 2);
+defconst("F_IMMED", f_immed, 0, &execdef, 0x01);
+defconst("F_HIDDEN", f_hidden, 0, &f_immed, 0x02);
/* Built-in Variables
*****************************************************************************/
defvar("tos", tos, 0, &latest, 0);
defvar("base", base, 0, &tos, 0);
+/* Compiler Words
+ *****************************************************************************/
+defcode("[", lbrack, 0, &base){
+ state_val = 1;
+}
+
+defcode("]", rbrack, f_immed_val, &lbrack){
+ state_val = 0;
+}
+
+defcode("create", create, 0, &rbrack){
+ puts("Creating a new word");
+ /* Copy the name string */
+ char* name = 0u;
+ if (*(ArgStackPtr))
+ {
+ printf("not null!\n");
+ size_t namesz = strlen((char*)*(ArgStackPtr));
+ name = (char*)malloc( namesz );
+ strcpy(name, (char*)*(ArgStackPtr));
+ }
+ /* Create the word entry */
+ word_t* word = (word_t*)malloc(sizeof(word_t));
+ word->link = (word_t*)latest_val;
+ word->flags = f_hidden_val;
+ word->name = name;
+ word->codeword = &docolon;
+ word->code = (long*)malloc(sizeof(long));
+ word->code[0] = 0;
+ /* Update Latest and Return the new word */
+ latest_val = (long)word;
+ here_val = (long)word->code;
+ *(ArgStackPtr) = (long)word;
+ printf("new word: %d %lu\n", (int)*(ArgStackPtr), (long)*(ArgStackPtr));
+}
+
+defcode(",", comma, 0, &create){
+ /* Get the word we are currently compiling */
+ word_t* word = (word_t*)latest_val;
+ /* Put the next instruction in place of the terminating NULL that "here"
+ * points too */
+ *((long*)here_val) = *(ArgStackPtr);
+ ArgStackPtr--;
+ /* Resize the code section and relocate if necessary */
+ long currsize = sizeof(long) + (here_val - (long)word->code);
+ word->code = (long*)realloc(word->code, currsize + sizeof(long));
+ /* Update "here" and null terminate the code section */
+ here_val = (long)&(word->code[ (currsize / sizeof(long)) ]);
+ *((long*)here_val) = 0;
+}
+
/* Interpreter Words
*****************************************************************************/
-defcode("getc", get_char, 0, &base){
+defcode("getc", get_char, 0, &comma){
ArgStackPtr++;
*(ArgStackPtr) = getc(stdin);
}
*(ArgStackPtr) = (long)&buffer;
}
-defcode("findw", findw, 0, &get_word){
+defcode("findw", find_word, 0, &get_word){
word_t const* curr = (word_t const*)latest_val;
char* name = (char*)*(ArgStackPtr);
while(curr)
*(ArgStackPtr) = (long)curr;
}
-defcode("execute", execute, 0, &findw){
- EXEC( *((word_t*)(*ArgStackPtr)) );
+defcode("execw", exec_word, 0, &find_word){
+ word_t* word = (word_t*)(*ArgStackPtr);
ArgStackPtr--;
+ EXEC( *(word) );
}
-defcode("parsenum", parse_num, 0, &execute){
+defcode("parsenum", parse_num, 0, &exec_word){
*(ArgStackPtr) = atoi((const char *)*(ArgStackPtr));
}
defcode("interpret", interpret, 0, &parse_num){
char* curr_word;
- //printf((0 == state_val) ? "=> " : ".. ");
/* Parse a word */
EXEC(get_word);
curr_word = (char*)*(ArgStackPtr);
/* Find the word */
- EXEC(findw);
+ EXEC(find_word);
+ printf("Compile Mode: %lu\n", (long)(state_val == 1));
/* Execute the word */
if (*ArgStackPtr)
{
- EXEC(execute);
+ puts("found word");
+ /* If were are in immediate mode or the word is flagged 'immediate' */
+ if((state_val == 0) || (((word_t*)*ArgStackPtr)->flags & f_immed_val))
+ {
+ puts("executing word");
+ EXEC(exec_word);
+ }
+ /* Or compile mode */
+ else
+ {
+ puts("comma");
+ EXEC(comma);
+ }
}
/* or parse it as a number */
else
{
+ puts("Parsing number");
*(ArgStackPtr) = (long)curr_word;
EXEC(parse_num);
}
+ printf("Compile Mode: %lu\n", (long)(state_val == 1));
}
defcode("quit", quit, 0, &interpret){
while(1)
{
EXEC(interpret);
- }
-}
-/* Compiler Words
- *****************************************************************************/
-defcode("create", create, 0, &quit){
- /* Copy the name string */
- size_t namesz = strlen((char*)*(ArgStackPtr));
- char* name = (char*)malloc( namesz );
- strcpy(name, (char*)*(ArgStackPtr));
- /* Create the word entry */
- word_t* word = (word_t*)malloc(sizeof(word_t));
- word->link = (word_t*)latest_val; //LatestWord;
- word->flags = f_hidden_val;
- word->name = name;
- word->codeword = &docolon;
- word->code = (long*)malloc(sizeof(long));
- word->code[0] = 0;
- /* Update Latest and Return the new word */
- latest_val = (long)word;
- here_val = (long)word->code;
- *(ArgStackPtr) = (long)word;
-}
-
-
-
-
-
-
-defcode("wcwa", code_word_addr, 0, &put_io_c){
- word_t const* word = (word_t const*)*(ArgStackPtr);
- *(ArgStackPtr) = (long)word->codeword;
-}
-
-defcode("wcda", code_data_addr, 0, &code_word_addr){
- word_t const* word = (word_t const*)*(ArgStackPtr);
- *(ArgStackPtr) = (long)word->code;
-}
-
-defcode("immediate", immediate, 0, &code_data_addr){
- ((word_t*)latest_val)->flags ^= f_immed_val;
-}
-
-defcode("hidden", hidden, 0, &immediate){
- ((word_t*)latest_val)->flags ^= f_hidden_val;
-}
-
-defcode(",", comma, 0, &hidden){
- /* Get the word we are currently compiling */
- word_t* word = (word_t*)latest_val;
- /* Put the next instruction in place of the terminating NULL that "here"
- * points too */
- *((long*)here_val) = *(ArgStackPtr);
- ArgStackPtr--;
- /* Resize the code section and relocate if necessary */
- long currsize = sizeof(long) + (here_val - (long)word->code);
- word->code = (long*)realloc(word->code, currsize + sizeof(long));
- /* Update "here" and null terminate the code section */
- here_val = (long)&(word->code[ (currsize / sizeof(long)) ]);
- *((long*)here_val) = 0;
+ printf("%d - %lu %s\n", 0, ArgStack[0], &ArgStack[0] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 1, ArgStack[1], &ArgStack[1] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 2, ArgStack[2], &ArgStack[2] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 3, ArgStack[3], &ArgStack[3] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 4, ArgStack[4], &ArgStack[4] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 5, ArgStack[5], &ArgStack[5] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 6, ArgStack[6], &ArgStack[6] == ArgStackPtr ? "<-" : "");
+ }
}
-defcode("[", lbrack, 0, &comma){
- state_val = 1;
-}
-defcode("]", rbrack, 0, &lbrack){
- state_val = 0;
-}
-
-defcode(":", colon, 0, &rbrack){
- EXEC(get_word);
- EXEC(create);
- EXEC(rbrack);
-}
-defcode(";", semicolon, 0, &colon){
- ((word_t*)latest_val)->flags ^= f_hidden_val;
- state_val = 0;
-}
+//defcode(":", colon, 0, &rbrack){
+// EXEC(get_word);
+// EXEC(create);
+// EXEC(rbrack);
+//}
+//
+//defcode(";", semicolon, 0, &colon){
+// ((word_t*)latest_val)->flags ^= f_hidden_val;
+// state_val = 0;
+//}
+//
+//defcode("wcwa", code_word_addr, 0, &put_io_c){
+// word_t const* word = (word_t const*)*(ArgStackPtr);
+// *(ArgStackPtr) = (long)word->codeword;
+//}
+//
+//defcode("wcda", code_data_addr, 0, &code_word_addr){
+// word_t const* word = (word_t const*)*(ArgStackPtr);
+// *(ArgStackPtr) = (long)word->code;
+//}
+//
+//defcode("immediate", immediate, 0, &code_data_addr){
+// ((word_t*)latest_val)->flags ^= f_immed_val;
+//}
+//
+//defcode("hidden", hidden, 0, &immediate){
+// ((word_t*)latest_val)->flags ^= f_hidden_val;
+//}
+//
/* Branching Words
*****************************************************************************/
-defcode("branch", branch, 0, &semicolon){
-}
-
-defcode("0branch", branch_if_0, 0, &branch){
-}
+//defcode("branch", branch, 0, &semicolon){
+//}
+//
+//defcode("0branch", branch_if_0, 0, &branch){
+//}
/* Built-in Primitive Words
*****************************************************************************/
// *(ArgStackPtr) -= 1;
//}
//
-//defcode("+", add, 0, &decr4){
+//defcode("+", add, 0, &create){
// *(ArgStackPtr-1) += *(ArgStackPtr);
// ArgStackPtr--;
//}
/* Input/Output Words
*****************************************************************************/
-defcode("putc", put_io_c, 0, &bytemove){
- putc((char)*(ArgStackPtr), stdout);
- ArgStackPtr--;
-}
+//defcode("putc", put_io_c, 0, &bytemove){
+// putc((char)*(ArgStackPtr), stdout);
+// ArgStackPtr--;
+//}
/* Compiler Words
*****************************************************************************/
*****************************************************************************/
int main(int argc, char** argv)
{
- long stack[32] = {0};
- ArgStackPtr = stack;
- latest_val = (long)&branch_if_0;
+ ArgStack[0] = 1111;
+ ArgStack[1] = 2222;
+ ArgStack[2] = 3333;
+ ArgStack[3] = 4444;
+ ArgStackPtr = ArgStack;
+ latest_val = (long)]
+ printf("StackBottom: %lu\n", (long)ArgStackPtr);
EXEC(quit);
+ //EXEC(get_word);
+ //EXEC(find_word);
+ //EXEC(exec_word);
+ printf("%d - %lu %s\n", 0, ArgStack[0], &ArgStack[0] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 1, ArgStack[1], &ArgStack[1] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 2, ArgStack[2], &ArgStack[2] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 3, ArgStack[3], &ArgStack[3] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 4, ArgStack[4], &ArgStack[4] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 5, ArgStack[5], &ArgStack[5] == ArgStackPtr ? "<-" : "");
+ printf("%d - %lu %s\n", 6, ArgStack[6], &ArgStack[6] == ArgStackPtr ? "<-" : "");
+
return 0;
}