]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Moved typedefs and defines to a header and removed some unneeded code in main.c
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 23 Apr 2014 01:51:31 +0000 (21:51 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 23 Apr 2014 01:51:31 +0000 (21:51 -0400)
source/slvm/main.c
source/slvm/slvm.h [new file with mode: 0644]

index a8ecb72a30634a4c7cf9d2b485fcb496063d4916..c9f6cf3db2e8593ef62ab7ac2431a7d1b8b11f68 100644 (file)
@@ -5,64 +5,25 @@
 #include <errno.h>
 #include <limits.h>
 
-/**
-    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. */
-    struct {
-        long f_hidden : 1;  /*< Flag if this word should be hidden from the interpreter */
-        long f_immed  : 1;  /*< flag if this word should be executed at compile time */
-        long padding  : 6;  /*< Pads the flags to 8-bits */
-        long codesize : 24; /*< The lenght of the bytecode section of the word */
-    } 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;
-
-/** Execute a built-in word directly */
-#define EXEC(word) (word).codeword((word).code)
+#include "slvm.h"
+
+/* Built-in Constants
+ *****************************************************************************/
+/** The argument stack */
+long ArgStack[ARG_STACK_SIZE];
 
 /** Pointer to current position on the stack */
-static long* ArgStackPtr;
+long* ArgStackPtr = ArgStack-1;
 
 /** Pointer to current instruction being executed */
-static long* CodePtr;
-
-/** The argument stack */
-static long ArgStack[32];
+long* CodePtr = 0;
 
 /** A state variable used to flag when the interpreter reads a line of input */
-static long Line_Read;
-
-/**
- * This is the "inner" interpreter. This function is responsible for running
- * the threaded code that make up colon defintions.
- *
- * @param code This is a pointer to the next instruction to be executed.
- * */
-static void docolon(long* code) {
+long Line_Read = 0;
+
+/* Built-in Constants
+ *****************************************************************************/
+void docolon(long* code) {
     word_t* word;
     /* We may have previously been executing a word so we should save off our
      * previous position */
@@ -82,74 +43,26 @@ static void docolon(long* code) {
     CodePtr = prev_code;
 }
 
-/** A barebones stack integrity check. Check to see if we overflowed or
- * underflowed the stack and bail if we did. */
-static void check_stack(void)
-{
-    if(ArgStackPtr < (ArgStack-1))
-    {
-        puts("Stack Underflow!");
-        //exit(1);
-    }
-
-    if(ArgStackPtr > (ArgStack+30))
-    {
-        puts("Stack Overflow!");
-        //exit(1);
-    }
-}
-
-/**
- * Define a built-in word that executes native code */
-#define defcode(name_str,c_name,immed,hide,prev) \
-    static void c_name##_code(long* code);       \
-    static word_t const c_name = {               \
-        prev,                                    \
-        { immed, hide, 0, 0 },                   \
-        name_str,                                \
-        &c_name##_code,                          \
-        0                                        \
-    };                                           \
-    static void c_name##_code(long* inst_ptr)    \
-
-/**
- * Define a built-in word representing a variable with the provided initial value */
-#define defvar(name_str,c_name,immed,hide,prev,initial) \
-    static long c_name##_val = initial;            \
-    defcode(name_str,c_name,immed,hide,prev) {          \
-        ArgStackPtr++;                             \
-        *(ArgStackPtr) = (long)&(c_name##_val);    \
-    }
-
-/**
- * Define a built-in word representing a constant with the provided value */
-#define defconst(name_str,c_name,immed,hide,prev,value) \
-    static long const c_name##_val = value;        \
-    defcode(name_str,c_name,immed,hide,prev) {          \
-        ArgStackPtr++;                             \
-        *(ArgStackPtr) = c_name##_val;             \
-    }
-
 /* Built-in Constants
  *****************************************************************************/
-defconst("VERSION",  version,  0, 0, 0,        1);
-defconst("EXECDEF",  execdef,  0, 0, &version, (long)&docolon);
-defconst("WORDSZ",   wordsz,   0, 0, &execdef, sizeof(long));
+defconst("VERSION",  version, 0, 0,        1);
+defconst("EXECDEF",  execdef, 0, &version, (long)&docolon);
+defconst("WORDSZ",   wordsz,  0, &execdef, sizeof(long));
 
 /* Built-in Variables
  *****************************************************************************/
-defvar("state",  state,  0, 0, &wordsz, 0);
-defvar("here",   here,   0, 0, &state,  0);
-defvar("latest", latest, 0, 0, &here,   0);
+defvar("state",  state,  0, &wordsz, 0);
+defvar("here",   here,   0, &state,  0);
+defvar("latest", latest, 0, &here,   0);
 
 /* Input Words
  *****************************************************************************/
-defcode("getc", get_char, 0, 0, &latest){
+defcode("getc", get_char, 0, &latest){
     ArgStackPtr++;
     *(ArgStackPtr) = getc(stdin);
 }
 
-defcode("ws?", is_ws, 0, 0, &get_char){
+defcode("ws?", is_ws, 0, &get_char){
     char ch = *(ArgStackPtr);
     *(ArgStackPtr) = ((ch == ' ')  || (ch == '\t') ||
                       (ch == '\r') || (ch == '\n'));
@@ -160,7 +73,7 @@ defcode("ws?", is_ws, 0, 0, &get_char){
         Line_Read = 1;
 }
 
-defcode("getw", get_word, 0, 0, &is_ws){
+defcode("getw", get_word, 0, &is_ws){
     static char buffer[32];
     int i = 0;
     int wschar = 0;
@@ -193,7 +106,7 @@ defcode("getw", get_word, 0, 0, &is_ws){
     *(ArgStackPtr) = (long)&buffer;
 }
 
-defcode("findw", find_word, 0, 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)
@@ -209,17 +122,17 @@ defcode("findw", find_word, 0, 0, &get_word){
 
 /* Branching and Literal Words
  *****************************************************************************/
-defcode("lit", literal, 0, 0, &find_word){
+defcode("lit", literal, 0, &find_word){
     ArgStackPtr++;
     *(ArgStackPtr) = *CodePtr;
     CodePtr++;
 }
 
-defcode("br", branch, 0, 0, &literal){
+defcode("br", branch, 0, &literal){
     CodePtr = (long*)(((long)CodePtr) + *(CodePtr));
 }
 
-defcode("0br", zbranch, 0, 0, &branch){
+defcode("0br", zbranch, 0, &branch){
     if (*ArgStackPtr == 0)
     {
         CodePtr = (long*)(((long)CodePtr) + *(CodePtr));
@@ -233,19 +146,19 @@ defcode("0br", zbranch, 0, 0, &branch){
 
 /* Compiler Words
  *****************************************************************************/
-defcode("ret", ret, 0, 0, &zbranch){
+defcode("ret", ret, 0, &zbranch){
     CodePtr = 0;
 }
 
-defcode("[", lbrack, 0, 0, &ret){
+defcode("[", lbrack, 0, &ret){
     state_val = 0;
 }
 
-defcode("]", rbrack, 0, 1, &lbrack){
+defcode("]", rbrack, 1, &lbrack){
     state_val = 1;
 }
 
-defcode("create", create, 0, 0, &rbrack){
+defcode("create", create, 0, &rbrack){
     /* Copy the name string */
     char* name = 0u;
     if (*(ArgStackPtr))
@@ -272,7 +185,7 @@ defcode("create", create, 0, 0, &rbrack){
     *(ArgStackPtr) = (long)word;
 }
 
-defcode(",", comma, 0, 0, &create){
+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 'ret' that "here"
@@ -287,40 +200,40 @@ defcode(",", comma, 0, 0, &create){
     *((long*)here_val) = (long)&ret;
 }
 
-defcode("hidden", hidden, 0, 1, &comma){
+defcode("hidden", hidden, 1, &comma){
     ((word_t*)*(ArgStackPtr))->flags.f_hidden ^= 1;
 }
 
-defcode("immediate", immediate, 0, 1, &hidden){
+defcode("immediate", immediate, 1, &hidden){
     ((word_t*)*(ArgStackPtr))->flags.f_immed ^= 1;
 }
 
-defcode(":", colon, 0, 0, &immediate){
+defcode(":", colon, 0, &immediate){
     EXEC(get_word);
     EXEC(create);
     EXEC(rbrack);
 }
 
-defcode(";", semicolon, 0, 1, &colon){
+defcode(";", semicolon, 1, &colon){
     EXEC(lbrack);
     EXEC(hidden);
     ArgStackPtr--;
 }
 
-defcode("'", tick, 0, 1, &semicolon){
+defcode("'", tick, 1, &semicolon){
     EXEC(get_word);
     EXEC(find_word);
 }
 
 /* Interpreter Words
  *****************************************************************************/
-defcode("execw", exec_word, 0, 0, &tick){
+defcode("execw", exec_word, 0, &tick){
     word_t* word = (word_t*)(*ArgStackPtr);
     ArgStackPtr--;
     EXEC( *(word) );
 }
 
-defcode("parsenum", parse_num, 0, 0, &exec_word){
+defcode("parsenum", parse_num, 0, &exec_word){
     char* end;
     long num = strtol((const char *)*(ArgStackPtr), &end, 10);
     if(end != (char *)*(ArgStackPtr))
@@ -334,7 +247,7 @@ defcode("parsenum", parse_num, 0, 0, &exec_word){
     }
 }
 
-defcode("interpret", interpret, 0, 0, &parse_num){
+defcode("interpret", interpret, 0, &parse_num){
     char* curr_word;
     /* Parse a word */
     EXEC(get_word);
@@ -376,7 +289,7 @@ defcode("interpret", interpret, 0, 0, &parse_num){
     }
 }
 
-defcode("quit", quit, 0, 0, &interpret){
+defcode("quit", quit, 0, &interpret){
     int i;
     printf("=> ");
     Line_Read = 0;
@@ -385,7 +298,6 @@ defcode("quit", quit, 0, 0, &interpret){
         EXEC(interpret);
         if(Line_Read)
         {
-            check_stack();
             long stacksz = ArgStackPtr - ArgStack + 1;
             if (stacksz > 5)
                 printf("( ... ");
@@ -405,34 +317,34 @@ defcode("quit", quit, 0, 0, &interpret){
 
 /* Stack Manipulation Words
  *****************************************************************************/
-defcode("drop", drop, 0, 0, &quit){
+defcode("drop", drop, 0, &quit){
     ArgStackPtr--;
 }
 
-defcode("swap", swap, 0, 0, &drop){
+defcode("swap", swap, 0, &drop){
     long temp = *(ArgStackPtr);
     *(ArgStackPtr) = *(ArgStackPtr-1);
     *(ArgStackPtr-1) = temp;
 }
 
-defcode("dup", dup, 0, 0, &swap){
+defcode("dup", dup, 0, &swap){
     ArgStackPtr++;
     *(ArgStackPtr) = *(ArgStackPtr-1);
 }
 
-defcode("over", over, 0, 0, &dup){
+defcode("over", over, 0, &dup){
     ArgStackPtr++;
     *(ArgStackPtr) = *(ArgStackPtr-2);
 }
 
-defcode("rot", rot, 0, 0, &over){
+defcode("rot", rot, 0, &over){
     long temp = *(ArgStackPtr);
     *(ArgStackPtr) = *(ArgStackPtr-1);
     *(ArgStackPtr-1) = *(ArgStackPtr-2);
     *(ArgStackPtr-2) = temp;
 }
 
-defcode("-rot", nrot, 0, 0, &rot){
+defcode("-rot", nrot, 0, &rot){
     long temp = *(ArgStackPtr-2);
     *(ArgStackPtr-2) = *(ArgStackPtr-1);
     *(ArgStackPtr-1) = *(ArgStackPtr);
@@ -441,137 +353,137 @@ defcode("-rot", nrot, 0, 0, &rot){
 
 /* Arithmetic Words
  *****************************************************************************/
-defcode("+", add, 0, 0, &nrot){
+defcode("+", add, 0, &nrot){
     *(ArgStackPtr-1) += *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("-", sub, 0, 0, &add){
+defcode("-", sub, 0, &add){
     *(ArgStackPtr-1) -= *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("*", mul, 0, 0, &sub){
+defcode("*", mul, 0, &sub){
     *(ArgStackPtr-1) *= *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("/", divide, 0, 0, &mul){
+defcode("/", divide, 0, &mul){
     *(ArgStackPtr-1) /= *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("%", mod, 0, 0, &divide){
+defcode("%", mod, 0, &divide){
     *(ArgStackPtr-1) %= *(ArgStackPtr);
     ArgStackPtr--;
 }
 
 /* Boolean Conditional Words
  *****************************************************************************/
-defcode("=", equal, 0, 0, &mod){
+defcode("=", equal, 0, &mod){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) == *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("!=", notequal, 0, 0, &equal){
+defcode("!=", notequal, 0, &equal){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) != *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("<", lessthan, 0, 0, &notequal){
+defcode("<", lessthan, 0, &notequal){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) < *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode(">", greaterthan, 0, 0, &lessthan){
+defcode(">", greaterthan, 0, &lessthan){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) > *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("<=", lessthaneq, 0, 0, &greaterthan){
+defcode("<=", lessthaneq, 0, &greaterthan){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) <= *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode(">=", greaterthaneq, 0, 0, &lessthaneq){
+defcode(">=", greaterthaneq, 0, &lessthaneq){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) >= *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("and", and, 0, 0, &greaterthaneq){
+defcode("and", and, 0, &greaterthaneq){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) && *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("or", or, 0, 0, &and){
+defcode("or", or, 0, &and){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) || *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("not", not, 0, 0, &or){
+defcode("not", not, 0, &or){
     *(ArgStackPtr) = !(*(ArgStackPtr));
 }
 
 /* Bitwise Words
  *****************************************************************************/
-defcode("band", band, 0, 0, &not){
+defcode("band", band, 0, &not){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) & *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("bor", bor, 0, 0, &band){
+defcode("bor", bor, 0, &band){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) | *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("bxor", bxor, 0, 0, &bor){
+defcode("bxor", bxor, 0, &bor){
     *(ArgStackPtr-1) = *(ArgStackPtr-1) ^ *(ArgStackPtr);
     ArgStackPtr--;
 }
 
-defcode("bnot", bnot, 0, 0, &bxor){
+defcode("bnot", bnot, 0, &bxor){
     *(ArgStackPtr) = ~(*(ArgStackPtr));
 }
 
 /* Memory Manipulation Words
  *****************************************************************************/
-defcode("!", store, 0, 0, &bnot){
+defcode("!", store, 0, &bnot){
     *((long*)*(ArgStackPtr)) = *(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
-defcode("@", fetch, 0, 0, &store){
+defcode("@", fetch, 0, &store){
     *(ArgStackPtr) = *((long*)*(ArgStackPtr));
 }
 
-defcode("+!", addstore, 0, 0, &fetch){
+defcode("+!", addstore, 0, &fetch){
     *((long*)*(ArgStackPtr)) += *(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
-defcode("-!", substore, 0, 0, &addstore){
+defcode("-!", substore, 0, &addstore){
     *((long*)*(ArgStackPtr)) -= *(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
-defcode("b!", bytestore, 0, 0, &substore){
+defcode("b!", bytestore, 0, &substore){
     *((char*)*(ArgStackPtr)) = (char)*(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
-defcode("b@", bytefetch, 0, 0, &bytestore){
+defcode("b@", bytefetch, 0, &bytestore){
     *(ArgStackPtr) = *((char*)*(ArgStackPtr));
 }
 
-defcode("b@b!", bytecopy, 0, 0, &bytefetch){
+defcode("b@b!", bytecopy, 0, &bytefetch){
 }
 
-defcode("bmove", bytemove, 0, 0, &bytecopy){
+defcode("bmove", bytemove, 0, &bytecopy){
 }
 
 /* Control Flow Words
  *****************************************************************************/
-defcode("if", _if, 0, 1, &bytemove){
+defcode("if", _if, 1, &bytemove){
     // : IF IMMEDIATE
     //         ' 0BRANCH ,     \ compile 0BRANCH
     ArgStackPtr++;
@@ -587,7 +499,7 @@ defcode("if", _if, 0, 1, &bytemove){
     // ;
 }
 
-defcode("then", _then, 0, 1, &_if){
+defcode("then", _then, 1, &_if){
     // : THEN IMMEDIATE
     //         DUP
     EXEC(dup);
@@ -603,7 +515,7 @@ defcode("then", _then, 0, 1, &_if){
     // ;
 }
 
-defcode("else", _else, 0, 1, &_then){
+defcode("else", _else, 1, &_then){
     // : ELSE IMMEDIATE
     //         ' BRANCH ,      \ definite branch to just over the false-part
     ArgStackPtr++;
@@ -634,7 +546,7 @@ defcode("else", _else, 0, 1, &_then){
 
 /* Debugging Words
  *****************************************************************************/
-defcode("printw", printw, 0, 0, &_else){
+defcode("printw", printw, 0, &_else){
     word_t* word = (word_t*)*(ArgStackPtr);
     long* bytecode = word->code;
     ArgStackPtr--;
@@ -680,7 +592,7 @@ defcode("printw", printw, 0, 0, &_else){
     }
 }
 
-defcode("printallw", printallw, 0, 0, &printw){
+defcode("printallw", printallw, 0, &printw){
     const word_t* word = (word_t*)latest_val;
     while(word)
     {
@@ -689,7 +601,7 @@ defcode("printallw", printallw, 0, 0, &printw){
     }
 }
 
-defcode("printdefw", printdefw, 0, 0, &printallw){
+defcode("printdefw", printdefw, 0, &printallw){
     const word_t* word = (word_t*)latest_val;
     while(word != &printdefw)
     {
@@ -703,43 +615,11 @@ defcode("printdefw", printdefw, 0, 0, &printallw){
 
 /* Main
  *****************************************************************************/
-static void run_tests(void);
-
 int main(int argc, char** argv)
 {
-    run_tests();
     ArgStackPtr = ArgStack - 1;
     latest_val = (long)&printdefw;
     EXEC(quit);
     return 0;
 }
 
-/* Unit Tests
- *****************************************************************************/
-static char* Current_Test_Desc;
-
-#define TEST(desc) \
-    Current_Test_Desc = desc; \
-    test_setup(); \
-    for(int i=0; i == 0; i++)
-
-#define CHECK(expr) \
-    if (!(expr)) {  \
-        test_setup(); \
-        printf(__FILE__ ":%d:0:FAIL:%s\n\t" #expr "\n", __LINE__-1, Current_Test_Desc); \
-        continue;   \
-    }
-
-static void test_setup(void)
-{
-    ArgStackPtr = ArgStack - 1;
-    CodePtr = 0;
-    latest_val = (long)&printw;
-}
-
-static void run_tests(void) {
-    TEST("Expected 0 to be 1"){
-        CHECK(0 == 1);
-    }
-}
-
diff --git a/source/slvm/slvm.h b/source/slvm/slvm.h
new file mode 100644 (file)
index 0000000..58c8596
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+  @file slvm.h
+  @brief TODO: Describe this file
+  $Revision$
+  $HeadURL$
+  */
+#ifndef SLVM_H
+#define SLVM_H
+
+/**
+    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. */
+    struct {
+        long f_hidden : 1;  /*< Flag if this word should be hidden from the interpreter */
+        long f_immed  : 1;  /*< flag if this word should be executed at compile time */
+        long padding  : 6;  /*< Pads the flags to 8-bits */
+        long codesize : 24; /*< The lenght of the bytecode section of the word */
+    } 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;
+
+/** Execute a built-in word directly */
+#define EXEC(word) (word).codeword((word).code)
+
+/** The maximum number of entries that can be on the argument stack */
+#ifndef ARG_STACK_SIZE
+#define ARG_STACK_SIZE 32
+#endif
+
+/**
+ * Define a built-in word that executes native code */
+#define defcode(name_str,c_name,immed,prev)   \
+    static void c_name##_code(long* code);    \
+    static word_t const c_name = {            \
+        prev,                                 \
+        { 0, immed, 0, 0 },                   \
+        name_str,                             \
+        &c_name##_code,                       \
+        0                                     \
+    };                                        \
+    static void c_name##_code(long* inst_ptr) \
+
+/**
+ * Define a built-in word representing a variable with the provided initial value */
+#define defvar(name_str,c_name,immed,prev,initial) \
+    static long c_name##_val = initial;            \
+    defcode(name_str,c_name,immed,prev) {          \
+        ArgStackPtr++;                             \
+        *(ArgStackPtr) = (long)&(c_name##_val);    \
+    }
+
+/**
+ * Define a built-in word representing a constant with the provided value */
+#define defconst(name_str,c_name,immed,prev,value) \
+    static long const c_name##_val = value;        \
+    defcode(name_str,c_name,immed,prev) {          \
+        ArgStackPtr++;                             \
+        *(ArgStackPtr) = c_name##_val;             \
+    }
+
+/**
+ * This is the "inner" interpreter. This function is responsible for running
+ * the threaded code that make up colon defintions.
+ *
+ * @param code This is a pointer to the next instruction to be executed.
+ * */
+void docolon(long* code);
+
+#endif /* SLVM_H */