]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Added a typedef for values that should match the width of a pointer type. Compile...
authorMichael D. Lowis <mike@mdlowis.com>
Wed, 23 Apr 2014 17:32:07 +0000 (13:32 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Wed, 23 Apr 2014 17:32:07 +0000 (13:32 -0400)
source/slvm/main.c
source/slvm/slvm.h

index 3d45d77762478df305c4ffc854d7629acb381d53..75952fa9c0a712642a26dd57185911d4fe7eb586 100644 (file)
 /* Built-in Constants
  *****************************************************************************/
 /** The argument stack */
-long ArgStack[ARG_STACK_SIZE];
+val_t ArgStack[ARG_STACK_SIZE];
 
 /** Pointer to current position on the stack */
-long* ArgStackPtr = ArgStack-1;
+val_t* ArgStackPtr = ArgStack-1;
 
 /** Pointer to current instruction being executed */
-long* CodePtr = 0;
+val_t* CodePtr = 0;
 
 /** A state variable used to flag when the interpreter reads a line of input */
-long Line_Read = 0;
+val_t Line_Read = 0;
 
 /* Built-in Constants
  *****************************************************************************/
-void docolon(long* code) {
+void docolon(val_t* code) {
     word_t* word;
     /* We may have previously been executing a word so we should save off our
      * previous position */
-    long* prev_code = CodePtr;
+    val_t* prev_code = CodePtr;
     /* Set the next instruction to execute */
     CodePtr = code;
     /* And loop through until we get the bytecode instruction of 0 (NEXT) */
@@ -46,8 +46,8 @@ void docolon(long* code) {
 /* Built-in Constants
  *****************************************************************************/
 defconst("VERSION", version, 0, 0,        1);
-defconst("EXECDEF", execdef, 0, &version, (long)&docolon);
-defconst("WORDSZ",  wordsz,  0, &execdef, sizeof(long));
+defconst("EXECDEF", execdef, 0, &version, (val_t)&docolon);
+defconst("WORDSZ",  wordsz,  0, &execdef, sizeof(val_t));
 
 /* Built-in Variables
  *****************************************************************************/
@@ -103,7 +103,7 @@ defcode("getw", get_word, 0, &is_ws){
 
     /* Return the word */
     ArgStackPtr++;
-    *(ArgStackPtr) = (long)&buffer;
+    *(ArgStackPtr) = (val_t)&buffer;
 }
 
 defcode("findw", find_word, 0, &get_word){
@@ -117,7 +117,7 @@ defcode("findw", find_word, 0, &get_word){
         }
         curr = curr->link;
     }
-    *(ArgStackPtr) = (long)curr;
+    *(ArgStackPtr) = (val_t)curr;
 }
 
 /* Branching and Literal Words
@@ -129,13 +129,13 @@ defcode("lit", literal, 0, &find_word){
 }
 
 defcode("br", branch, 0, &literal){
-    CodePtr = (long*)(((long)CodePtr) + *(CodePtr));
+    CodePtr = (val_t*)(((val_t)CodePtr) + *(CodePtr));
 }
 
 defcode("0br", zbranch, 0, &branch){
     if (*ArgStackPtr == 0)
     {
-        CodePtr = (long*)(((long)CodePtr) + *(CodePtr));
+        CodePtr = (val_t*)(((val_t)CodePtr) + *(CodePtr));
     }
     else
     {
@@ -177,12 +177,12 @@ defcode("create", create, 0, &rbrack){
     /* Initialize the name, codeword, and bytecode */
     word->name     = name;
     word->codeword = &docolon;
-    word->code     = (long*)malloc(sizeof(long));
-    word->code[0]  = (long)&ret;
+    word->code     = (val_t*)malloc(sizeof(val_t));
+    word->code[0]  = (val_t)&ret;
     /* Update Latest and Return the new word */
-    latest_val     = (long)word;
-    here_val       = (long)word->code;
-    *(ArgStackPtr) = (long)word;
+    latest_val     = (val_t)word;
+    here_val       = (val_t)word->code;
+    *(ArgStackPtr) = (val_t)word;
 }
 
 defcode(",", comma, 0, &create){
@@ -190,14 +190,14 @@ defcode(",", comma, 0, &create){
     word_t* word  = (word_t*)latest_val;
     /* Put the next instruction in place of the terminating 'ret' that "here"
      * points too */
-    *((long*)here_val) = *(ArgStackPtr);
+    *((val_t*)here_val) = *(ArgStackPtr);
     ArgStackPtr--;
     /* Resize the code section and relocate if necessary */
     word->flags.codesize++;
-    word->code = (long*)realloc(word->code, word->flags.codesize * sizeof(long));
+    word->code = (val_t*)realloc(word->code, word->flags.codesize * sizeof(val_t));
     /* Update "here" and terminate the code section */
-    here_val = (long)(&word->code[word->flags.codesize-1]);
-    *((long*)here_val) = (long)&ret;
+    here_val = (val_t)(&word->code[word->flags.codesize-1]);
+    *((val_t*)here_val) = (val_t)&ret;
 }
 
 defcode("hidden", hidden, 1, &comma){
@@ -235,7 +235,7 @@ defcode("execw", exec_word, 0, &tick){
 
 defcode("parsenum", parse_num, 0, &exec_word){
     char* end;
-    long num = strtol((const char *)*(ArgStackPtr), &end, 10);
+    val_t num = strtol((const char *)*(ArgStackPtr), &end, 10);
     if(end != (char *)*(ArgStackPtr))
     {
         *(ArgStackPtr) = num;
@@ -273,12 +273,12 @@ defcode("interpret", interpret, 0, &parse_num){
     /* else parse it as a number */
     else
     {
-        *(ArgStackPtr) = (long)curr_word;
+        *(ArgStackPtr) = (val_t)curr_word;
         EXEC(parse_num);
         if (state_val == 1)
         {
             ArgStackPtr++;
-            *(ArgStackPtr) = (long)&literal;
+            *(ArgStackPtr) = (val_t)&literal;
             EXEC(comma);
             EXEC(comma);
         }
@@ -298,7 +298,7 @@ defcode("quit", quit, 0, &interpret){
         EXEC(interpret);
         if(Line_Read)
         {
-            long stacksz = ArgStackPtr - ArgStack + 1;
+            val_t stacksz = ArgStackPtr - ArgStack + 1;
             if (stacksz > 5)
                 printf("( ... ");
             else
@@ -322,7 +322,7 @@ defcode("drop", drop, 0, &quit){
 }
 
 defcode("swap", swap, 0, &drop){
-    long temp = *(ArgStackPtr);
+    val_t temp = *(ArgStackPtr);
     *(ArgStackPtr) = *(ArgStackPtr-1);
     *(ArgStackPtr-1) = temp;
 }
@@ -338,14 +338,14 @@ defcode("over", over, 0, &dup){
 }
 
 defcode("rot", rot, 0, &over){
-    long temp = *(ArgStackPtr);
+    val_t temp = *(ArgStackPtr);
     *(ArgStackPtr) = *(ArgStackPtr-1);
     *(ArgStackPtr-1) = *(ArgStackPtr-2);
     *(ArgStackPtr-2) = temp;
 }
 
 defcode("-rot", nrot, 0, &rot){
-    long temp = *(ArgStackPtr-2);
+    val_t temp = *(ArgStackPtr-2);
     *(ArgStackPtr-2) = *(ArgStackPtr-1);
     *(ArgStackPtr-1) = *(ArgStackPtr);
     *(ArgStackPtr) = temp;
@@ -448,21 +448,21 @@ defcode("bnot", bnot, 0, &bxor){
 /* Memory Manipulation Words
  *****************************************************************************/
 defcode("!", store, 0, &bnot){
-    *((long*)*(ArgStackPtr)) = *(ArgStackPtr-1);
+    *((val_t*)*(ArgStackPtr)) = *(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
 defcode("@", fetch, 0, &store){
-    *(ArgStackPtr) = *((long*)*(ArgStackPtr));
+    *(ArgStackPtr) = *((val_t*)*(ArgStackPtr));
 }
 
 defcode("+!", addstore, 0, &fetch){
-    *((long*)*(ArgStackPtr)) += *(ArgStackPtr-1);
+    *((val_t*)*(ArgStackPtr)) += *(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
 defcode("-!", substore, 0, &addstore){
-    *((long*)*(ArgStackPtr)) -= *(ArgStackPtr-1);
+    *((val_t*)*(ArgStackPtr)) -= *(ArgStackPtr-1);
     ArgStackPtr -= 2;
 }
 
@@ -487,7 +487,7 @@ defcode("if", _if, 1, &bytemove){
     // : IF IMMEDIATE
     //         ' 0BRANCH ,     \ compile 0BRANCH
     ArgStackPtr++;
-    *(ArgStackPtr) = (long)&zbranch;
+    *(ArgStackPtr) = (val_t)&zbranch;
     EXEC(comma);
     //         HERE @          \ save location of the offset on the stack
     ArgStackPtr++;
@@ -510,7 +510,7 @@ defcode("then", _then, 1, &_if){
     EXEC(sub);
     //         SWAP !          \ store the offset in the back-filled location
     EXEC(swap);
-    *((long*)*ArgStackPtr) = *(ArgStackPtr-1);
+    *((val_t*)*ArgStackPtr) = *(ArgStackPtr-1);
     ArgStackPtr -= 2;
     // ;
 }
@@ -519,7 +519,7 @@ defcode("else", _else, 1, &_then){
     // : ELSE IMMEDIATE
     //         ' BRANCH ,      \ definite branch to just over the false-part
     ArgStackPtr++;
-    *(ArgStackPtr) = (long)&branch;
+    *(ArgStackPtr) = (val_t)&branch;
     EXEC(comma);
     //         HERE @          \ save location of the offset on the stack
     ArgStackPtr++;
@@ -539,7 +539,7 @@ defcode("else", _else, 1, &_then){
     EXEC(sub);
     //         SWAP !
     EXEC(swap);
-    *((long*)*ArgStackPtr) = *(ArgStackPtr-1);
+    *((val_t*)*ArgStackPtr) = *(ArgStackPtr-1);
     ArgStackPtr -= 2;
     // ;
 }
@@ -548,7 +548,7 @@ defcode("else", _else, 1, &_then){
  *****************************************************************************/
 defcode("printw", printw, 0, &_else){
     word_t* word = (word_t*)*(ArgStackPtr);
-    long* bytecode = word->code;
+    val_t* bytecode = word->code;
     ArgStackPtr--;
 
     printf("Name:     %s\n", word->name);
@@ -559,12 +559,12 @@ defcode("printw", printw, 0, &_else){
         puts("Bytecode:");
         while(bytecode)
         {
-            if (*bytecode == (long)&literal)
+            if (*bytecode == (val_t)&literal)
             {
                 bytecode++;
                 printf("\tlit %ld\n", *bytecode);
             }
-            else if (*bytecode == (long)&zbranch)
+            else if (*bytecode == (val_t)&zbranch)
             {
                 bytecode++;
                 printf("\t0br %ld\n", *bytecode);
@@ -574,7 +574,7 @@ defcode("printw", printw, 0, &_else){
                 printf("\t%s\n", ((word_t*) *bytecode)->name);
             }
 
-            if (*bytecode == (long)&ret)
+            if (*bytecode == (val_t)&ret)
             {
                 bytecode = 0;
                 break;
@@ -587,7 +587,7 @@ defcode("printw", printw, 0, &_else){
     }
     else
     {
-        printf("CodeFn:   0x%lX\n",(long)word->codeword);
+        printf("CodeFn:   0x%lX\n",(val_t)word->codeword);
         printf("Bytecode: (native)\n");
     }
 }
@@ -617,7 +617,8 @@ defcode("printdefw", printdefw, 0, &printallw){
  *****************************************************************************/
 int main(int argc, char** argv)
 {
-    latest_val = (long)&printdefw;
+    CT_ASSERT(sizeof(val_t) == sizeof(val_t*));
+    latest_val = (val_t)&printdefw;
     EXEC(quit);
     return 0;
 }
index 6a68710d8a70e769c0aab79b725bb5b678f07f6e..67a781afd539c1e7fbcddbbf7637e1cd5f078d21 100644 (file)
@@ -7,12 +7,23 @@
 #ifndef SLVM_H
 #define SLVM_H
 
-//#if defined(_16BIT_)
-//#elif defined(_32BIT_)
-//#elif defined(_64BIT_)
-//#else
-//    #error "Invalid architecture"
-//#endif
+#include <stdint.h>
+
+/* Choose a width for val_t that matches the pointer size of the target
+ * architecture. Defaults to simply a long but can be overridden for specific
+ * cases */
+#if defined(_16BIT_)
+    typedef int16_t val_t;
+#elif defined(_32BIT_)
+    typedef int32_t val_t;
+#elif defined(_64BIT_)
+    typedef int64_t val_t;
+#else
+    /* hope for the best? */
+    typedef long val_t;
+#endif
+
+#define CODE_SZ_BITS ((sizeof(val_t) * 8) - 8u)
 
 /**
     This type represents a pointer to a function handler for executing a word.
@@ -22,7 +33,7 @@
     @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);
+typedef void (*codeword_t)(val_t* code);
 
 /**
     This structure contains all of the relevant attributes of a word definition
@@ -32,10 +43,10 @@ typedef struct word_t {
     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 */
+        val_t f_hidden : 1;  /*< Flag if this word should be hidden from the interpreter */
+        val_t f_immed  : 1;  /*< flag if this word should be executed at compile time */
+        val_t padding  : 6;  /*< Pads the flags to 8-bits */
+        val_t codesize : CODE_SZ_BITS; /*< The length of the bytecode section of the word */
     } flags;
     /** Pointer to the null terminated string that holds the name of the word. */
     char const* name;
@@ -47,7 +58,7 @@ typedef struct word_t {
     /**
      * A pointer to the list of instructions that make up this word. For words
      * defined in C this will be 0u (NULL). */
-    long* code;
+    val_t* code;
 } word_t;
 
 /** Execute a built-in word directly */
@@ -61,7 +72,7 @@ typedef struct word_t {
 /**
  * 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 void c_name##_code(val_t* code);    \
     static word_t const c_name = {            \
         prev,                                 \
         { 0, immed, 0, 0 },                   \
@@ -69,32 +80,41 @@ typedef struct word_t {
         &c_name##_code,                       \
         0                                     \
     };                                        \
-    static void c_name##_code(long* inst_ptr) \
+    static void c_name##_code(val_t* 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;            \
+    static val_t c_name##_val = initial;            \
     defcode(name_str,c_name,immed,prev) {          \
         ArgStackPtr++;                             \
-        *(ArgStackPtr) = (long)&(c_name##_val);    \
+        *(ArgStackPtr) = (val_t)&(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;        \
+    static val_t const c_name##_val = value;        \
     defcode(name_str,c_name,immed,prev) {          \
         ArgStackPtr++;                             \
         *(ArgStackPtr) = c_name##_val;             \
     }
 
+/**
+ * A little C macro hack that allows for some compile time assertions. When the
+ * expression evaluates to false (0) at compile time, the expanded switch
+ * statement will contain two case statements for the value 0 which is a compile
+ * error. Thus the build will break alerting the user that something went
+ * horribly wrong. */
+#define CT_ASSERT(expr) \
+    switch(1){ case(0):break; case(expr):break; default: break; }
+
 /**
  * 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);
+void docolon(val_t* code);
 
 #endif /* SLVM_H */