]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
tabulators->four spaces
authorDale Weiler <killfieldengine@gmail.com>
Tue, 17 Apr 2012 20:24:22 +0000 (16:24 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Tue, 17 Apr 2012 20:24:22 +0000 (16:24 -0400)
assembler.c
code.c
error.c
gmqcc.h
lex.c
main.c
parse.c
typedef.c
util.c

index 14255ff36030d8bfa20d881c65fad015d1b185be..9111e2b9d1c8b263034b1631509919f74981c4fd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
  * and also I plan to allow inline assembly for the compiler.
  */
 static const struct {
-       const char  *m; /* menomic     */
-       const size_t o; /* operands    */ 
-       const size_t l; /* menomic len */
+    const char  *m; /* menomic     */
+    const size_t o; /* operands    */ 
+    const size_t l; /* menomic len */
 } const asm_instr[] = {
-       [INSTR_DONE]       = { "DONE"      , 1, 4 },
-       [INSTR_MUL_F]      = { "MUL_F"     , 3, 5 },
-       [INSTR_MUL_V]      = { "MUL_V"     , 3, 5 },
-       [INSTR_MUL_FV]     = { "MUL_FV"    , 3, 6 },
-       [INSTR_MUL_VF]     = { "MUL_VF"    , 3, 6 },
-       [INSTR_DIV_F]      = { "DIV"       , 0, 3 },
-       [INSTR_ADD_F]      = { "ADD_F"     , 3, 5 },
-       [INSTR_ADD_V]      = { "ADD_V"     , 3, 5 },
-       [INSTR_SUB_F]      = { "SUB_F"     , 3, 5 },
-       [INSTR_SUB_V]      = { "DUB_V"     , 3, 5 },
-       [INSTR_EQ_F]       = { "EQ_F"      , 0, 4 },
-       [INSTR_EQ_V]       = { "EQ_V"      , 0, 4 },
-       [INSTR_EQ_S]       = { "EQ_S"      , 0, 4 },
-       [INSTR_EQ_E]       = { "EQ_E"      , 0, 4 },
-       [INSTR_EQ_FNC]     = { "ES_FNC"    , 0, 6 },
-       [INSTR_NE_F]       = { "NE_F"      , 0, 4 },
-       [INSTR_NE_V]       = { "NE_V"      , 0, 4 },
-       [INSTR_NE_S]       = { "NE_S"      , 0, 4 },
-       [INSTR_NE_E]       = { "NE_E"      , 0, 4 },
-       [INSTR_NE_FNC]     = { "NE_FNC"    , 0, 6 },
-       [INSTR_LE]         = { "LE"        , 0, 2 },
-       [INSTR_GE]         = { "GE"        , 0, 2 },
-       [INSTR_LT]         = { "LT"        , 0, 2 },
-       [INSTR_GT]         = { "GT"        , 0, 2 },
-       [INSTR_LOAD_F]     = { "FIELD_F"   , 0, 7 },
-       [INSTR_LOAD_V]     = { "FIELD_V"   , 0, 7 },
-       [INSTR_LOAD_S]     = { "FIELD_S"   , 0, 7 },
-       [INSTR_LOAD_ENT]   = { "FIELD_ENT" , 0, 9 },
-       [INSTR_LOAD_FLD]   = { "FIELD_FLD" , 0, 9 },
-       [INSTR_LOAD_FNC]   = { "FIELD_FNC" , 0, 9 },
-       [INSTR_ADDRESS]    = { "ADDRESS"   , 0, 7 },
-       [INSTR_STORE_F]    = { "STORE_F"   , 0, 7 },
-       [INSTR_STORE_V]    = { "STORE_V"   , 0, 7 },
-       [INSTR_STORE_S]    = { "STORE_S"   , 0, 7 },
-       [INSTR_STORE_ENT]  = { "STORE_ENT" , 0, 9 },
-       [INSTR_STORE_FLD]  = { "STORE_FLD" , 0, 9 },
-       [INSTR_STORE_FNC]  = { "STORE_FNC" , 0, 9 },
-       [INSTR_STOREP_F]   = { "STOREP_F"  , 0, 8 },
-       [INSTR_STOREP_V]   = { "STOREP_V"  , 0, 8 },
-       [INSTR_STOREP_S]   = { "STOREP_S"  , 0, 8 },
-       [INSTR_STOREP_ENT] = { "STOREP_ENT", 0, 10},
-       [INSTR_STOREP_FLD] = { "STOREP_FLD", 0, 10},
-       [INSTR_STOREP_FNC] = { "STOREP_FNC", 0, 10},
-       [INSTR_RETURN]     = { "RETURN"    , 0, 6 },
-       [INSTR_NOT_F]      = { "NOT_F"     , 0, 5 },
-       [INSTR_NOT_V]      = { "NOT_V"     , 0, 5 },
-       [INSTR_NOT_S]      = { "NOT_S"     , 0, 5 },
-       [INSTR_NOT_ENT]    = { "NOT_ENT"   , 0, 7 },
-       [INSTR_NOT_FNC]    = { "NOT_FNC"   , 0, 7 },
-       [INSTR_IF]         = { "IF"        , 0, 2 },
-       [INSTR_IFNOT]      = { "IFNOT"     , 0, 5 },
-       [INSTR_CALL0]      = { "CALL0"     , 0, 5 },
-       [INSTR_CALL1]      = { "CALL1"     , 0, 5 },
-       [INSTR_CALL2]      = { "CALL2"     , 0, 5 },
-       [INSTR_CALL3]      = { "CALL3"     , 0, 5 },
-       [INSTR_CALL4]      = { "CALL4"     , 0, 5 },
-       [INSTR_CALL5]      = { "CALL5"     , 0, 5 },
-       [INSTR_CALL6]      = { "CALL6"     , 0, 5 },
-       [INSTR_CALL7]      = { "CALL7"     , 0, 5 },
-       [INSTR_CALL8]      = { "CALL8"     , 0, 5 },
-       [INSTR_STATE]      = { "STATE"     , 0, 5 },
-       [INSTR_GOTO]       = { "GOTO"      , 0, 4 },
-       [INSTR_AND]        = { "AND"       , 0, 3 },
-       [INSTR_OR]         = { "OR"        , 0, 2 },
-       [INSTR_BITAND]     = { "BITAND"    , 0, 6 },
-       [INSTR_BITOR]      = { "BITOR"     , 0, 5 }
+    [INSTR_DONE]       = { "DONE"      , 1, 4 },
+    [INSTR_MUL_F]      = { "MUL_F"     , 3, 5 },
+    [INSTR_MUL_V]      = { "MUL_V"     , 3, 5 },
+    [INSTR_MUL_FV]     = { "MUL_FV"    , 3, 6 },
+    [INSTR_MUL_VF]     = { "MUL_VF"    , 3, 6 },
+    [INSTR_DIV_F]      = { "DIV"       , 0, 3 },
+    [INSTR_ADD_F]      = { "ADD_F"     , 3, 5 },
+    [INSTR_ADD_V]      = { "ADD_V"     , 3, 5 },
+    [INSTR_SUB_F]      = { "SUB_F"     , 3, 5 },
+    [INSTR_SUB_V]      = { "DUB_V"     , 3, 5 },
+    [INSTR_EQ_F]       = { "EQ_F"      , 0, 4 },
+    [INSTR_EQ_V]       = { "EQ_V"      , 0, 4 },
+    [INSTR_EQ_S]       = { "EQ_S"      , 0, 4 },
+    [INSTR_EQ_E]       = { "EQ_E"      , 0, 4 },
+    [INSTR_EQ_FNC]     = { "ES_FNC"    , 0, 6 },
+    [INSTR_NE_F]       = { "NE_F"      , 0, 4 },
+    [INSTR_NE_V]       = { "NE_V"      , 0, 4 },
+    [INSTR_NE_S]       = { "NE_S"      , 0, 4 },
+    [INSTR_NE_E]       = { "NE_E"      , 0, 4 },
+    [INSTR_NE_FNC]     = { "NE_FNC"    , 0, 6 },
+    [INSTR_LE]         = { "LE"        , 0, 2 },
+    [INSTR_GE]         = { "GE"        , 0, 2 },
+    [INSTR_LT]         = { "LT"        , 0, 2 },
+    [INSTR_GT]         = { "GT"        , 0, 2 },
+    [INSTR_LOAD_F]     = { "FIELD_F"   , 0, 7 },
+    [INSTR_LOAD_V]     = { "FIELD_V"   , 0, 7 },
+    [INSTR_LOAD_S]     = { "FIELD_S"   , 0, 7 },
+    [INSTR_LOAD_ENT]   = { "FIELD_ENT" , 0, 9 },
+    [INSTR_LOAD_FLD]   = { "FIELD_FLD" , 0, 9 },
+    [INSTR_LOAD_FNC]   = { "FIELD_FNC" , 0, 9 },
+    [INSTR_ADDRESS]    = { "ADDRESS"   , 0, 7 },
+    [INSTR_STORE_F]    = { "STORE_F"   , 0, 7 },
+    [INSTR_STORE_V]    = { "STORE_V"   , 0, 7 },
+    [INSTR_STORE_S]    = { "STORE_S"   , 0, 7 },
+    [INSTR_STORE_ENT]  = { "STORE_ENT" , 0, 9 },
+    [INSTR_STORE_FLD]  = { "STORE_FLD" , 0, 9 },
+    [INSTR_STORE_FNC]  = { "STORE_FNC" , 0, 9 },
+    [INSTR_STOREP_F]   = { "STOREP_F"  , 0, 8 },
+    [INSTR_STOREP_V]   = { "STOREP_V"  , 0, 8 },
+    [INSTR_STOREP_S]   = { "STOREP_S"  , 0, 8 },
+    [INSTR_STOREP_ENT] = { "STOREP_ENT", 0, 10},
+    [INSTR_STOREP_FLD] = { "STOREP_FLD", 0, 10},
+    [INSTR_STOREP_FNC] = { "STOREP_FNC", 0, 10},
+    [INSTR_RETURN]     = { "RETURN"    , 0, 6 },
+    [INSTR_NOT_F]      = { "NOT_F"     , 0, 5 },
+    [INSTR_NOT_V]      = { "NOT_V"     , 0, 5 },
+    [INSTR_NOT_S]      = { "NOT_S"     , 0, 5 },
+    [INSTR_NOT_ENT]    = { "NOT_ENT"   , 0, 7 },
+    [INSTR_NOT_FNC]    = { "NOT_FNC"   , 0, 7 },
+    [INSTR_IF]         = { "IF"        , 0, 2 },
+    [INSTR_IFNOT]      = { "IFNOT"     , 0, 5 },
+    [INSTR_CALL0]      = { "CALL0"     , 0, 5 },
+    [INSTR_CALL1]      = { "CALL1"     , 0, 5 },
+    [INSTR_CALL2]      = { "CALL2"     , 0, 5 },
+    [INSTR_CALL3]      = { "CALL3"     , 0, 5 },
+    [INSTR_CALL4]      = { "CALL4"     , 0, 5 },
+    [INSTR_CALL5]      = { "CALL5"     , 0, 5 },
+    [INSTR_CALL6]      = { "CALL6"     , 0, 5 },
+    [INSTR_CALL7]      = { "CALL7"     , 0, 5 },
+    [INSTR_CALL8]      = { "CALL8"     , 0, 5 },
+    [INSTR_STATE]      = { "STATE"     , 0, 5 },
+    [INSTR_GOTO]       = { "GOTO"      , 0, 4 },
+    [INSTR_AND]        = { "AND"       , 0, 3 },
+    [INSTR_OR]         = { "OR"        , 0, 2 },
+    [INSTR_BITAND]     = { "BITAND"    , 0, 6 },
+    [INSTR_BITOR]      = { "BITOR"     , 0, 5 }
 };
 
 /*
@@ -104,23 +104,23 @@ static const struct {
  * for creating functions, or constants.
  */
 const char *const asm_keys[] = {
-       "FLOAT"    , /* define float  */
-       "VECTOR"   , /* define vector */
-       "ENTITY"   , /* define ent    */
-       "FIELD"    , /* define field  */
-       "STRING"   , /* define string */
-       "FUNCTION"
+    "FLOAT"    , /* define float  */
+    "VECTOR"   , /* define vector */
+    "ENTITY"   , /* define ent    */
+    "FIELD"    , /* define field  */
+    "STRING"   , /* define string */
+    "FUNCTION"
 };
 
 static char *const asm_getline(size_t *byte, FILE *fp) {
-       char   *line = NULL;
-       ssize_t read = util_getline(&line, byte, fp);
-       *byte = read;
-       if (read == -1) {
-               mem_d (line);
-               return NULL;
-       }
-       return line;
+    char   *line = NULL;
+    ssize_t read = util_getline(&line, byte, fp);
+    *byte = read;
+    if (read == -1) {
+        mem_d (line);
+        return NULL;
+    }
+    return line;
 }
 
 #define asm_rmnewline(L,S) *((L)+*(S)-1) = '\0'
@@ -130,199 +130,199 @@ static char *const asm_getline(size_t *byte, FILE *fp) {
     }
     
 void asm_init(const char *file, FILE **fp) {
-       *fp = fopen(file, "r");
-       code_init();
+    *fp = fopen(file, "r");
+    code_init();
 }
 
 void asm_close(FILE *fp) {
-       fclose(fp);
-       code_write();
+    fclose(fp);
+    code_write();
 }
 
 /*
  * Following parse states:
- *     ASM_FUNCTION -- in a function accepting input statements
- *     ....
+ *     ASM_FUNCTION -- in a function accepting input statements
+ *     ....
  */
 typedef enum {
-       ASM_NULL,
-       ASM_FUNCTION
+    ASM_NULL,
+    ASM_FUNCTION
 } asm_state;
 
 typedef struct {
-       char *name;   /* name of constant    */
-       int   offset; /* location in globals */
+    char *name;   /* name of constant    */
+    int   offset; /* location in globals */
 } globals;
 VECTOR_MAKE(globals, assembly_constants);
-       
+    
 void asm_parse(FILE *fp) {
-       char     *data  = NULL;
-       char     *skip  = NULL;
-       long      line  = 1; /* current line */
-       size_t    size  = 0; /* size of line */
-       asm_state state = ASM_NULL;
-       
-       while ((data = asm_getline(&size, fp)) != NULL) {
-               skip = data;
-               asm_skipwhite(skip);
-               asm_rmnewline(skip, &size);
-               
-               #define DECLTYPE(X, CODE)                                         \
-                   if (!strncmp(X, skip, strlen(X))) {                           \
-                       if (skip[strlen(X)] != ':') {                             \
-                           printf("%li: Missing `:` after decltype\n",line);     \
-                           exit (1);                                             \
-                       }                                                         \
-                       skip += strlen(X)+1;                                      \
-                       asm_skipwhite(skip);                                      \
-                       if(!isalpha(*skip)) {                                     \
-                           printf("%li: Invalid identififer: %s\n", line, skip); \
-                           exit (1);                                             \
-                       } else {                                                  \
-                           size_t offset_code      = code_statements_elements+1; \
-                           size_t offset_chars     = code_strings_elements   +1; \
-                           size_t offset_globals   = code_globals_elements   +1; \
-                           size_t offset_functions = code_functions_elements +1; \
-                           size_t offset_fields    = code_fields_elements    +1; \
-                           size_t offset_defs      = code_defs_elements      +1; \
-                           CODE                                                  \
-                           /* silent unused warnings */                          \
-                           (void)offset_code;                                    \
-                           (void)offset_chars;                                   \
-                           (void)offset_globals;                                 \
-                           (void)offset_functions;                               \
-                           (void)offset_fields;                                  \
-                           (void)offset_defs;                                    \
-                           assembly_constants_add((globals){                     \
-                               .name   = util_strdup(skip),                      \
-                               .offset = offset_globals                          \
-                           });                                                   \
-                       }                                                         \
-                       goto end;                                                 \
-                   }
-               
-               /* FLOAT    */
-               DECLTYPE(asm_keys[0], {
-                       code_defs_add((prog_section_def){
-                               .type   = TYPE_FLOAT,
-                               .offset = offset_globals, /* global table */
-                               .name   = offset_chars    /* string table TODO */
-                       });
-                       float f = 0; /*TODO*/
-                       code_globals_add(*(int*)&f);
-                       
-               });
-               DECLTYPE(asm_keys[1], {
-                       code_defs_add((prog_section_def){
-                               .type   = TYPE_FLOAT,
-                               .offset = offset_globals, /* global table */
-                               .name   = offset_chars    /* string table TODO */
-                       });
-                       float f1 = 0;
-                       float f2 = 0;
-                       float f3 = 0;
-                       code_globals_add(*(int*)&f1);
-                       code_globals_add(*(int*)&f2);
-                       code_globals_add(*(int*)&f3);
-               });
-               /* ENTITY   */ DECLTYPE(asm_keys[2], {});
-               /* FIELD    */ DECLTYPE(asm_keys[3], {});
-               /* STRING   */
-               DECLTYPE(asm_keys[4], {
-                       code_defs_add((prog_section_def){
-                               .type   = TYPE_STRING,    
-                               .offset = offset_globals, /* offset to offset in string table (for data)*/
-                               .name   = offset_chars    /* location of name in string table (for name)*/
-                       });
-                       code_strings_add('h');
-               });
-               /* FUNCTION */
-               DECLTYPE(asm_keys[5], {
-                       /* TODO: parse */
-                       if (state != ASM_NULL) {
-                               printf("%li: Error unfinished function block, expected DONE or RETURN\n", line);
-                               goto end;
-                       }
-                       
-                       state = ASM_FUNCTION;
-                       code_defs_add((prog_section_def){
-                               .type   = TYPE_VOID,
-                               .offset = offset_globals,
-                               .name   = offset_chars
-                       });
-                       code_globals_add(offset_functions);
-                       code_functions_add((prog_section_function){
-                               .entry      =  offset_code,      
-                               .firstlocal =  0,
-                               .locals     =  0,
-                               .profile    =  0,
-                               .name       =  offset_chars,
-                               .file       =  0,
-                               .nargs      =  0,
-                               .argsize    = {0}
-                       });
-               });
-               
-               /* if we make it this far then we have statements */
-               {
-                       size_t i = 0;    /* counter   */
-                       size_t o = 0;    /* operands  */
-                       char  *t = NULL; /* token     */
-                       
-                       /*
-                        * Most ops a single statement can have is three.
-                        * lets allocate some space for all of those here.
-                        */
-                       char op[3][32768] = {{0},{0},{0}};
-                       for (; i < sizeof(asm_instr)/sizeof(*asm_instr); i++) {
-                               if (!strncmp(skip, asm_instr[i].m, asm_instr[i].l)) {
-                                       if (state != ASM_FUNCTION) {
-                                               printf("%li: Statement not inside function block\n", line);
-                                               goto end;
-                                       }
-                                       
-                                       /* update parser state */
-                                       if (i == INSTR_DONE || i == INSTR_RETURN) {
-                                               goto end;
-                                               state = ASM_NULL;
-                                       }
-                                       
-                                       /* parse the statement */
-                                       o     = asm_instr[i].o; /* operands         */
-                                       skip += asm_instr[i].l; /* skip instruction */
-                                       t     = strtok(skip, " ,");
-                                       i     = 0;
-                                       while (t != NULL && i < 3) {
-                                               strcpy(op[i], t);
-                                               t = strtok(NULL, " ,");
-                                               i ++;
-                                       }
-                                       
-                                       util_debug("ASM", "Operand 1: %s\n", util_strrnl(op[0]));
-                                       util_debug("ASM", "Operand 2: %s\n", util_strrnl(op[1]));
-                                       util_debug("ASM", "Operand 3: %s\n", util_strrnl(op[2]));
-                                       
-                                       /* check */
-                                       if (i != o) {
-                                               printf("not enough operands, expected: %li, got %li\n", o, i);
-                                       }
-                                       
-                                       /* TODO: hashtable value LOAD .... etc */
-                                       code_statements_add((prog_section_statement){
-                                               i, {0}, {0}, {0}
-                                       });
-                                       goto end;
-                               }
-                       }
-               }
-               
-               /* if we made it this far something is wrong */
-               if (*skip != '\0')
-                       printf("%li: Invalid statement, expression, or decleration\n", line);
-               
-               end:
-               //free(data);
-               mem_d(data);
-               line ++;
-       }
+    char     *data  = NULL;
+    char     *skip  = NULL;
+    long      line  = 1; /* current line */
+    size_t    size  = 0; /* size of line */
+    asm_state state = ASM_NULL;
+    
+    while ((data = asm_getline(&size, fp)) != NULL) {
+        skip = data;
+        asm_skipwhite(skip);
+        asm_rmnewline(skip, &size);
+        
+        #define DECLTYPE(X, CODE)                                         \
+            if (!strncmp(X, skip, strlen(X))) {                           \
+                if (skip[strlen(X)] != ':') {                             \
+                    printf("%li: Missing `:` after decltype\n",line);     \
+                    exit (1);                                             \
+                }                                                         \
+                skip += strlen(X)+1;                                      \
+                asm_skipwhite(skip);                                      \
+                if(!isalpha(*skip)) {                                     \
+                    printf("%li: Invalid identififer: %s\n", line, skip); \
+                    exit (1);                                             \
+                } else {                                                  \
+                    size_t offset_code      = code_statements_elements+1; \
+                    size_t offset_chars     = code_strings_elements   +1; \
+                    size_t offset_globals   = code_globals_elements   +1; \
+                    size_t offset_functions = code_functions_elements +1; \
+                    size_t offset_fields    = code_fields_elements    +1; \
+                    size_t offset_defs      = code_defs_elements      +1; \
+                    CODE                                                  \
+                    /* silent unused warnings */                          \
+                    (void)offset_code;                                    \
+                    (void)offset_chars;                                   \
+                    (void)offset_globals;                                 \
+                    (void)offset_functions;                               \
+                    (void)offset_fields;                                  \
+                    (void)offset_defs;                                    \
+                    assembly_constants_add((globals){                     \
+                        .name   = util_strdup(skip),                      \
+                        .offset = offset_globals                          \
+                    });                                                   \
+                }                                                         \
+                goto end;                                                 \
+            }
+        
+        /* FLOAT    */
+        DECLTYPE(asm_keys[0], {
+            code_defs_add((prog_section_def){
+                .type   = TYPE_FLOAT,
+                .offset = offset_globals, /* global table */
+                .name   = offset_chars    /* string table TODO */
+            });
+            float f = 0; /*TODO*/
+            code_globals_add(*(int*)&f);
+            
+        });
+        DECLTYPE(asm_keys[1], {
+            code_defs_add((prog_section_def){
+                .type   = TYPE_FLOAT,
+                .offset = offset_globals, /* global table */
+                .name   = offset_chars    /* string table TODO */
+            });
+            float f1 = 0;
+            float f2 = 0;
+            float f3 = 0;
+            code_globals_add(*(int*)&f1);
+            code_globals_add(*(int*)&f2);
+            code_globals_add(*(int*)&f3);
+        });
+        /* ENTITY   */ DECLTYPE(asm_keys[2], {});
+        /* FIELD    */ DECLTYPE(asm_keys[3], {});
+        /* STRING   */
+        DECLTYPE(asm_keys[4], {
+            code_defs_add((prog_section_def){
+                .type   = TYPE_STRING,    
+                .offset = offset_globals, /* offset to offset in string table (for data)*/
+                .name   = offset_chars    /* location of name in string table (for name)*/
+            });
+            code_strings_add('h');
+        });
+        /* FUNCTION */
+        DECLTYPE(asm_keys[5], {
+            /* TODO: parse */
+            if (state != ASM_NULL) {
+                printf("%li: Error unfinished function block, expected DONE or RETURN\n", line);
+                goto end;
+            }
+            
+            state = ASM_FUNCTION;
+            code_defs_add((prog_section_def){
+                .type   = TYPE_VOID,
+                .offset = offset_globals,
+                .name   = offset_chars
+            });
+            code_globals_add(offset_functions);
+            code_functions_add((prog_section_function){
+                .entry      =  offset_code,      
+                .firstlocal =  0,
+                .locals     =  0,
+                .profile    =  0,
+                .name       =  offset_chars,
+                .file       =  0,
+                .nargs      =  0,
+                .argsize    = {0}
+            });
+        });
+        
+        /* if we make it this far then we have statements */
+        {
+            size_t i = 0;    /* counter   */
+            size_t o = 0;    /* operands  */
+            char  *t = NULL; /* token     */
+            
+            /*
+             * Most ops a single statement can have is three.
+             * lets allocate some space for all of those here.
+             */
+            char op[3][32768] = {{0},{0},{0}};
+            for (; i < sizeof(asm_instr)/sizeof(*asm_instr); i++) {
+                if (!strncmp(skip, asm_instr[i].m, asm_instr[i].l)) {
+                    if (state != ASM_FUNCTION) {
+                        printf("%li: Statement not inside function block\n", line);
+                        goto end;
+                    }
+                    
+                    /* update parser state */
+                    if (i == INSTR_DONE || i == INSTR_RETURN) {
+                        goto end;
+                        state = ASM_NULL;
+                    }
+                    
+                    /* parse the statement */
+                    o     = asm_instr[i].o; /* operands         */
+                    skip += asm_instr[i].l; /* skip instruction */
+                    t     = strtok(skip, " ,");
+                    i     = 0;
+                    while (t != NULL && i < 3) {
+                        strcpy(op[i], t);
+                        t = strtok(NULL, " ,");
+                        i ++;
+                    }
+                    
+                    util_debug("ASM", "Operand 1: %s\n", util_strrnl(op[0]));
+                    util_debug("ASM", "Operand 2: %s\n", util_strrnl(op[1]));
+                    util_debug("ASM", "Operand 3: %s\n", util_strrnl(op[2]));
+                    
+                    /* check */
+                    if (i != o) {
+                        printf("not enough operands, expected: %li, got %li\n", o, i);
+                    }
+                    
+                    /* TODO: hashtable value LOAD .... etc */
+                    code_statements_add((prog_section_statement){
+                        i, {0}, {0}, {0}
+                    });
+                    goto end;
+                }
+            }
+        }
+        
+        /* if we made it this far something is wrong */
+        if (*skip != '\0')
+            printf("%li: Invalid statement, expression, or decleration\n", line);
+        
+        end:
+        //free(data);
+        mem_d(data);
+        line ++;
+    }
 }
diff --git a/code.c b/code.c
index f6b64adb79b6caab0b8c5f636edebbb9f2330d17..e391292d0f68cfc09ac0227fce307b06caaf8058 100644 (file)
--- a/code.c
+++ b/code.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
 #include "gmqcc.h"
 
 typedef struct {
-       uint32_t offset;      /* Offset in file of where data begins  */
-       uint32_t length;      /* Length of section (how many of)      */
+    uint32_t offset;      /* Offset in file of where data begins  */
+    uint32_t length;      /* Length of section (how many of)      */
 } prog_section;
 
 typedef struct {
-       uint32_t     version;      /* Program version (6)     */
-       uint32_t     crc16;        /* What is this?           */
-       prog_section statements;   /* prog_section_statement  */
-       prog_section defs;         /* prog_section_def        */
-       prog_section fields;       /* prog_section_field      */
-       prog_section functions;    /* prog_section_function   */
-       prog_section strings;      /* What is this?           */
-       prog_section globals;      /* What is this?           */
-       uint32_t     entfield;     /* Number of entity fields */
+    uint32_t     version;      /* Program version (6)     */
+    uint32_t     crc16;        /* What is this?           */
+    prog_section statements;   /* prog_section_statement  */
+    prog_section defs;         /* prog_section_def        */
+    prog_section fields;       /* prog_section_field      */
+    prog_section functions;    /* prog_section_function   */
+    prog_section strings;      /* What is this?           */
+    prog_section globals;      /* What is this?           */
+    uint32_t     entfield;     /* Number of entity fields */
 } prog_header;
 
 /*
@@ -81,91 +81,91 @@ VECTOR_MAKE(int,                    code_globals   );
 VECTOR_MAKE(char,                   code_strings   );
 
 void code_init() {
-       /*
-        * The way progs.dat is suppose to work is odd, there needs to be
-        * some null (empty) statements, functions, and 28 globals
-        */
-       prog_section_function  empty_function  = {0,0,0,0,0,0,0,{0}};
-       prog_section_statement empty_statement = {0,{0},{0},{0}};
-       int i;
-       for(i = 0; i < 28; i++)
-               code_globals_add(0);
-               
-       code_strings_add   ('\0');
-       code_functions_add (empty_function);
-       code_statements_add(empty_statement);
+    /*
+     * The way progs.dat is suppose to work is odd, there needs to be
+     * some null (empty) statements, functions, and 28 globals
+     */
+    prog_section_function  empty_function  = {0,0,0,0,0,0,0,{0}};
+    prog_section_statement empty_statement = {0,{0},{0},{0}};
+    int i;
+    for(i = 0; i < 28; i++)
+        code_globals_add(0);
+        
+    code_strings_add   ('\0');
+    code_functions_add (empty_function);
+    code_statements_add(empty_statement);
 }
 
 void code_test() {
-       const char *X;
-       size_t size = sizeof(X);
-       size_t iter = 0;
-       
-       #define FOO(Y) \
-               X = Y; \
-               size = sizeof(Y); \
-               for (iter=0; iter < size; iter++) { \
-                       code_strings_add(X[iter]);    \
-               }
-               
-       FOO("m_init");
-       FOO("print");
-       FOO("hello world\n");
-       FOO("m_keydown");
-       FOO("m_draw");
-       FOO("m_toggle");
-       FOO("m_shutdown");
-       
-       code_globals_add(1);  /* m_init */
-       code_globals_add(2);  /* print  */
-       code_globals_add(14); /* hello world in string table */
-       
-       /* now the defs */
-       code_defs_add((prog_section_def){.type=TYPE_VOID,    .offset=28/*globals[28]*/, .name=1 }); /* m_init */
-       code_defs_add((prog_section_def){.type=TYPE_FUNCTION,.offset=29/*globals[29]*/, .name=8 }); /* print  */
-       code_defs_add((prog_section_def){.type=TYPE_STRING,  .offset=30/*globals[30]*/, .name=14}); /*hello_world*/
-       
-       code_functions_add((prog_section_function){1,  0, 0, 0, .name=1, 0, 0, {0}}); /* m_init */
-       code_functions_add((prog_section_function){-4, 0, 0, 0, .name=8, 0, 0, {0}}); /* print  */
-       code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13,        0,0, {0}}); /* m_keydown */
-       code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13+10,     0,0, {0}});
-       code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13+10+7,   0,0, {0}});
-       code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13+10+7+9, 0,0, {0}});
-       
-       code_statements_add((prog_section_statement){INSTR_STORE_F, {30}/*30 is hello_world */, {OFS_PARM0}, {0}});
-       code_statements_add((prog_section_statement){INSTR_CALL1,   {29}/*29 is print       */, {0},         {0}});
-       code_statements_add((prog_section_statement){INSTR_RETURN,  {0},                        {0},         {0}});
+    const char *X;
+    size_t size = sizeof(X);
+    size_t iter = 0;
+    
+    #define FOO(Y) \
+        X = Y; \
+        size = sizeof(Y); \
+        for (iter=0; iter < size; iter++) { \
+            code_strings_add(X[iter]);    \
+        }
+        
+    FOO("m_init");
+    FOO("print");
+    FOO("hello world\n");
+    FOO("m_keydown");
+    FOO("m_draw");
+    FOO("m_toggle");
+    FOO("m_shutdown");
+    
+    code_globals_add(1);  /* m_init */
+    code_globals_add(2);  /* print  */
+    code_globals_add(14); /* hello world in string table */
+    
+    /* now the defs */
+    code_defs_add((prog_section_def){.type=TYPE_VOID,    .offset=28/*globals[28]*/, .name=1 }); /* m_init */
+    code_defs_add((prog_section_def){.type=TYPE_FUNCTION,.offset=29/*globals[29]*/, .name=8 }); /* print  */
+    code_defs_add((prog_section_def){.type=TYPE_STRING,  .offset=30/*globals[30]*/, .name=14}); /*hello_world*/
+    
+    code_functions_add((prog_section_function){1,  0, 0, 0, .name=1, 0, 0, {0}}); /* m_init */
+    code_functions_add((prog_section_function){-4, 0, 0, 0, .name=8, 0, 0, {0}}); /* print  */
+    code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13,        0,0, {0}}); /* m_keydown */
+    code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13+10,     0,0, {0}});
+    code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13+10+7,   0,0, {0}});
+    code_functions_add((prog_section_function){0,  0, 0, 0, .name=14+13+10+7+9, 0,0, {0}});
+    
+    code_statements_add((prog_section_statement){INSTR_STORE_F, {30}/*30 is hello_world */, {OFS_PARM0}, {0}});
+    code_statements_add((prog_section_statement){INSTR_CALL1,   {29}/*29 is print       */, {0},         {0}});
+    code_statements_add((prog_section_statement){INSTR_RETURN,  {0},                        {0},         {0}});
 }
 
 void code_write() {
-       prog_header code_header={0};
-       code_header.version    = 6;
-       code_header.crc16      = 0; /* TODO: */
-       code_header.statements = (prog_section){sizeof(prog_header), code_statements_elements };
-       code_header.defs       = (prog_section){code_header.statements.offset + sizeof(prog_section_statement)*code_statements_elements,  code_defs_elements       };
-       code_header.fields     = (prog_section){code_header.defs.offset       + sizeof(prog_section_def)      *code_defs_elements,        code_fields_elements     };
-       code_header.functions  = (prog_section){code_header.fields.offset     + sizeof(prog_section_field)    *code_fields_elements,      code_functions_elements  };
-       code_header.globals    = (prog_section){code_header.functions.offset  + sizeof(prog_section_function) *code_functions_elements,   code_globals_elements    };
-       code_header.strings    = (prog_section){code_header.globals.offset    + sizeof(int)                   *code_globals_elements,     code_strings_elements    };
-       code_header.entfield   = 0; /* TODO: */
-       
-       FILE *fp = fopen("program.dat", "wb");
-       fwrite(&code_header,         1, sizeof(prog_header), fp);
-       fwrite(code_statements_data, 1, sizeof(prog_section_statement)*code_statements_elements, fp);
-       fwrite(code_defs_data,       1, sizeof(prog_section_def)      *code_defs_elements,       fp);
-       fwrite(code_fields_data,     1, sizeof(prog_section_field)    *code_fields_elements,     fp);
-       fwrite(code_functions_data,  1, sizeof(prog_section_function) *code_functions_elements,  fp);
-       fwrite(code_globals_data,    1, sizeof(int)                   *code_globals_elements,    fp);
-       fwrite(code_strings_data,    1, 1                             *code_strings_elements,    fp);
-       
-       mem_d(code_statements_data);
-       mem_d(code_defs_data);
-       mem_d(code_fields_data);
-       mem_d(code_functions_data);
-       mem_d(code_globals_data);
-       mem_d(code_strings_data);
-       
-       util_debug("GEN","wrote program.dat:\n\
+    prog_header code_header={0};
+    code_header.version    = 6;
+    code_header.crc16      = 0; /* TODO: */
+    code_header.statements = (prog_section){sizeof(prog_header), code_statements_elements };
+    code_header.defs       = (prog_section){code_header.statements.offset + sizeof(prog_section_statement)*code_statements_elements,  code_defs_elements       };
+    code_header.fields     = (prog_section){code_header.defs.offset       + sizeof(prog_section_def)      *code_defs_elements,        code_fields_elements     };
+    code_header.functions  = (prog_section){code_header.fields.offset     + sizeof(prog_section_field)    *code_fields_elements,      code_functions_elements  };
+    code_header.globals    = (prog_section){code_header.functions.offset  + sizeof(prog_section_function) *code_functions_elements,   code_globals_elements    };
+    code_header.strings    = (prog_section){code_header.globals.offset    + sizeof(int)                   *code_globals_elements,     code_strings_elements    };
+    code_header.entfield   = 0; /* TODO: */
+    
+    FILE *fp = fopen("program.dat", "wb");
+    fwrite(&code_header,         1, sizeof(prog_header), fp);
+    fwrite(code_statements_data, 1, sizeof(prog_section_statement)*code_statements_elements, fp);
+    fwrite(code_defs_data,       1, sizeof(prog_section_def)      *code_defs_elements,       fp);
+    fwrite(code_fields_data,     1, sizeof(prog_section_field)    *code_fields_elements,     fp);
+    fwrite(code_functions_data,  1, sizeof(prog_section_function) *code_functions_elements,  fp);
+    fwrite(code_globals_data,    1, sizeof(int)                   *code_globals_elements,    fp);
+    fwrite(code_strings_data,    1, 1                             *code_strings_elements,    fp);
+    
+    mem_d(code_statements_data);
+    mem_d(code_defs_data);
+    mem_d(code_fields_data);
+    mem_d(code_functions_data);
+    mem_d(code_globals_data);
+    mem_d(code_strings_data);
+    
+    util_debug("GEN","wrote program.dat:\n\
     version:    = %d\n\
     crc16:      = %d\n\
     entfield:   = %d\n\
@@ -175,22 +175,22 @@ void code_write() {
     functions  {.offset = % 8d, .length = % 8d}\n\
     globals    {.offset = % 8d, .length = % 8d}\n\
     strings    {.offset = % 8d, .length = % 8d}\n",
-               code_header.version,
-               code_header.crc16,
-               code_header.entfield,
-               code_header.statements.offset,
-               code_header.statements.length,
-               code_header.defs.offset,
-               code_header.defs.length,
-               code_header.fields.offset,
-               code_header.fields.length,
-               code_header.functions.offset,
-               code_header.functions.length,
-               code_header.strings.offset,
-               code_header.strings.length,
-               code_header.globals.offset,
-               code_header.globals.length
-       );
-       
-       fclose(fp);
+        code_header.version,
+        code_header.crc16,
+        code_header.entfield,
+        code_header.statements.offset,
+        code_header.statements.length,
+        code_header.defs.offset,
+        code_header.defs.length,
+        code_header.fields.offset,
+        code_header.fields.length,
+        code_header.functions.offset,
+        code_header.functions.length,
+        code_header.strings.offset,
+        code_header.strings.length,
+        code_header.globals.offset,
+        code_header.globals.length
+    );
+    
+    fclose(fp);
 }
diff --git a/error.c b/error.c
index c0df2072ecd73f05b3be5f81657cded4610dfcd4..2f96caf9ab2a14a324906aae9b57fed4978270f7 100644 (file)
--- a/error.c
+++ b/error.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
  * intereting like colors for the console.
  */
 #ifndef WIN32
-#      define CON_BLACK   30
-#      define CON_RED     31
-#      define CON_GREEN   32
-#      define CON_BROWN   33
-#      define CON_BLUE    34
-#      define CON_MAGENTA 35
-#      define CON_CYAN    36
-#      define CON_WHITE   37
+#    define CON_BLACK   30
+#    define CON_RED     31
+#    define CON_GREEN   32
+#    define CON_BROWN   33
+#    define CON_BLUE    34
+#    define CON_MAGENTA 35
+#    define CON_CYAN    36
+#    define CON_WHITE   37
 static const int error_color[] = {
-       CON_RED,
-       CON_CYAN,
-       CON_MAGENTA,
-       CON_BLUE,
-       CON_BROWN,
-       CON_WHITE
+    CON_RED,
+    CON_CYAN,
+    CON_MAGENTA,
+    CON_BLUE,
+    CON_BROWN,
+    CON_WHITE
 };
 #endif
 int error_total = 0;
 int error_max   = 10;
 
 static const char *const error_list[] = {
-       "Parsing Error:",
-       "Lexing Error:",
-       "Internal Error:",
-       "Compilation Error:",
-       "Preprocessor Error:"
+    "Parsing Error:",
+    "Lexing Error:",
+    "Internal Error:",
+    "Compilation Error:",
+    "Preprocessor Error:"
 };
 
 int error(struct lex_file *file, int status, const char *msg, ...) {
-       char      bu[1024*4]; /* enough? */
-       char      fu[1024*4]; /* enough? */
-       va_list   va;
-       
-       if (error_total + 1 > error_max) {
-               fprintf(stderr, "%d errors and more following, bailing\n", error_total);
-               exit (-1);
-       }
-       error_total ++;
+    char      bu[1024*4]; /* enough? */
+    char      fu[1024*4]; /* enough? */
+    va_list   va;
+    
+    if (error_total + 1 > error_max) {
+        fprintf(stderr, "%d errors and more following, bailing\n", error_total);
+        exit (-1);
+    }
+    error_total ++;
 /* color */
-#      ifndef WIN32
-       sprintf  (bu, "\033[0;%dm%s \033[0;%dm %s:%d ", error_color[status-SHRT_MAX], error_list[status-SHRT_MAX], error_color[(status-1)-SHRT_MAX], file->name, file->line);
+#    ifndef WIN32
+    sprintf  (bu, "\033[0;%dm%s \033[0;%dm %s:%d ", error_color[status-SHRT_MAX], error_list[status-SHRT_MAX], error_color[(status-1)-SHRT_MAX], file->name, file->line);
 #else
-       sprintf  (bu, "%s ", error_list[status-SHRT_MAX]);
+    sprintf  (bu, "%s ", error_list[status-SHRT_MAX]);
 #endif
-       va_start (va, msg);
-       vsprintf (fu, msg, va);
-       va_end   (va);
-       fputs    (bu, stderr);
-       fputs    (fu, stderr);
+    va_start (va, msg);
+    vsprintf (fu, msg, va);
+    va_end   (va);
+    fputs    (bu, stderr);
+    fputs    (fu, stderr);
 
 /* color */
-#      ifndef WIN32
-       fputs    ("\033[0m", stderr);
-#      endif
-       
-       fflush   (stderr);
-       
-       return status;
+#    ifndef WIN32
+    fputs    ("\033[0m", stderr);
+#    endif
+    
+    fflush   (stderr);
+    
+    return status;
 }
diff --git a/gmqcc.h b/gmqcc.h
index d9e3a9c4c1a1ad7d4b9f8de5b9bf1ff46b0e4d68..14a4022d3bc15d05292381f055226129e7275c17 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
  * assume is all systems. (int8_t not required)
  */
 #if   CHAR_MIN  == -128
-       typedef unsigned char  uint8_t; /* same as below */
+    typedef unsigned char  uint8_t; /* same as below */
 #elif SCHAR_MIN == -128
-       typedef unsigned char  uint8_t; /* same as above */
+    typedef unsigned char  uint8_t; /* same as above */
 #endif
 #if   SHRT_MAX  == 0x7FFF
-       typedef short          int16_t;
-       typedef unsigned short uint16_t;
+    typedef short          int16_t;
+    typedef unsigned short uint16_t;
 #elif INT_MAX   == 0x7FFF
-       typedef int            int16_t;
-       typedef unsigned int   uint16_t;
+    typedef int            int16_t;
+    typedef unsigned int   uint16_t;
 #endif
 #if   INT_MAX   == 0x7FFFFFFF 
-       typedef int            int32_t;
-       typedef unsigned int   uint32_t;
+    typedef int            int32_t;
+    typedef unsigned int   uint32_t;
 #elif LONG_MAX  == 0x7FFFFFFF
-       typedef long           int32_t;
-       typedef unsigned long  uint32_t;
+    typedef long           int32_t;
+    typedef unsigned long  uint32_t;
 #endif
 #ifdef _LP64 /* long pointer == 64 */
-       typedef unsigned long  uintptr_t;
-       typedef long           intptr_t;
+    typedef unsigned long  uintptr_t;
+    typedef long           intptr_t;
 #else
-       typedef unsigned int   uintptr_t;
-       typedef int            intptr_t;
+    typedef unsigned int   uintptr_t;
+    typedef int            intptr_t;
 #endif 
 /* Ensure type sizes are correct: */
 typedef char uint8_size_is_correct  [sizeof(uint8_t)  == 1?1:-1];
@@ -73,16 +73,16 @@ typedef char uintptr_size_is_correct[sizeof(uintptr_t)== sizeof(int*)?1:-1];
 //============================ lex.c ================================
 //===================================================================
 struct lex_file {
-       FILE *file;        /* file handler */
-       char *name;        /* name of file */
-       char  peek  [5];  
-       char  lastok[8192];
-       
-       int   last;    /* last token                   */
-       int   current; /* current token                */
-       int   length;  /* bytes left to parse          */
-       int   size;    /* never changes (size of file) */
-       int   line;    /* what line are we on?         */
+    FILE *file;        /* file handler */
+    char *name;        /* name of file */
+    char  peek  [5];  
+    char  lastok[8192];
+    
+    int   last;    /* last token                   */
+    int   current; /* current token                */
+    int   length;  /* bytes left to parse          */
+    int   size;    /* never changes (size of file) */
+    int   line;    /* what line are we on?         */
 };
 
 /*
@@ -144,7 +144,7 @@ int parse_gen(struct lex_file *);
 //========================== typedef.c ==============================
 //===================================================================
 typedef struct typedef_node_t {
-       char      *name;
+    char      *name;
 } typedef_node;
 
 void          typedef_init();
@@ -165,11 +165,11 @@ void  util_debug   (const char *, const char *, ...);
 int   util_getline (char **, size_t *, FILE *);
 
 #ifdef NOTRACK
-#      define mem_a(x) malloc(x)
-#      define mem_d(x) free  (x)
+#    define mem_a(x) malloc(x)
+#    define mem_d(x) free  (x)
 #else
-#      define mem_a(x) util_memory_a((x), __LINE__, __FILE__)
-#      define mem_d(x) util_memory_d((x), __LINE__, __FILE__)
+#    define mem_a(x) util_memory_a((x), __LINE__, __FILE__)
+#    define mem_d(x) util_memory_d((x), __LINE__, __FILE__)
 #endif
 
 #define VECTOR_MAKE(T,N)                                                 \
@@ -211,75 +211,75 @@ int   util_getline (char **, size_t *, FILE *);
  * Each paramater incerements by 3 since vector types hold
  * 3 components (x,y,z).
  */
-#define        OFS_NULL      0
-#define        OFS_RETURN    1
-#define        OFS_PARM0     (OFS_RETURN+3)
-#define        OFS_PARM1     (OFS_PARM0 +3)
-#define        OFS_PARM2     (OFS_PARM1 +3)
-#define        OFS_PARM3     (OFS_PARM2 +3)
-#define        OFS_PARM4     (OFS_PARM3 +3)
+#define    OFS_NULL      0
+#define    OFS_RETURN    1
+#define    OFS_PARM0     (OFS_RETURN+3)
+#define    OFS_PARM1     (OFS_PARM0 +3)
+#define    OFS_PARM2     (OFS_PARM1 +3)
+#define    OFS_PARM3     (OFS_PARM2 +3)
+#define    OFS_PARM4     (OFS_PARM3 +3)
 #define OFS_PARM5     (OFS_PARM4 +3)
 #define OFS_PARM6     (OFS_PARM5 +3)
 #define OFS_PARM7     (OFS_PARM6 +3)
 
 typedef struct {
-       uint16_t opcode;
-       
-       /* operand 1 */
-       union {
-               int16_t  s1; /* signed   */
-               uint16_t u1; /* unsigned */
-       };
-       /* operand 2 */
-       union {
-               int16_t  s2; /* signed   */
-               uint16_t u2; /* unsigned */
-       };
-       /* operand 3 */
-       union {
-               int16_t  s3; /* signed   */
-               uint16_t u3; /* unsigned */
-       };
-       
-       /*
-        * This is the same as the structure in darkplaces
-        * {
-        *     unsigned short op;
-        *     short          a,b,c;
-        * }
-        * But this one is more sane to work with, and the
-        * type sizes are guranteed.
-        */
+    uint16_t opcode;
+    
+    /* operand 1 */
+    union {
+        int16_t  s1; /* signed   */
+        uint16_t u1; /* unsigned */
+    };
+    /* operand 2 */
+    union {
+        int16_t  s2; /* signed   */
+        uint16_t u2; /* unsigned */
+    };
+    /* operand 3 */
+    union {
+        int16_t  s3; /* signed   */
+        uint16_t u3; /* unsigned */
+    };
+    
+    /*
+     * This is the same as the structure in darkplaces
+     * {
+     *     unsigned short op;
+     *     short          a,b,c;
+     * }
+     * But this one is more sane to work with, and the
+     * type sizes are guranteed.
+     */
 } prog_section_statement;
 
 typedef struct {
-       /* The types:
-        * 0 = ev_void
-        * 1 = ev_string
-        * 2 = ev_float
-        * 3 = ev_vector
-        * 4 = ev_entity
-        * 5 = ev_field
-        * 6 = ev_function
-        * 7 = ev_pointer -- engine only
-        * 8 = ev_bad     -- engine only
-        */
-       uint16_t type;
-       uint16_t offset;
-       uint32_t name;
+    /* The types:
+     * 0 = ev_void
+     * 1 = ev_string
+     * 2 = ev_float
+     * 3 = ev_vector
+     * 4 = ev_entity
+     * 5 = ev_field
+     * 6 = ev_function
+     * 7 = ev_pointer -- engine only
+     * 8 = ev_bad     -- engine only
+     */
+    uint16_t type;
+    uint16_t offset;
+    uint32_t name;
 } prog_section_both;
 typedef prog_section_both prog_section_def;
 typedef prog_section_both prog_section_field;
 
 typedef struct {
-       int32_t   entry;      /* in statement table for instructions  */
-       uint32_t  firstlocal; /* First local in local table           */
-       uint32_t  locals;     /* Total ints of params + locals        */
-       uint32_t  profile;    /* Always zero (engine uses this)       */
-       uint32_t  name;       /* name of function in string table     */
-       uint32_t  file;       /* file of the source file              */
-       uint32_t  nargs;      /* number of arguments                  */
-       uint8_t   argsize[8]; /* size of arguments (keep 8 always?)   */
+    int32_t   entry;      /* in statement table for instructions  */
+    uint32_t  firstlocal; /* First local in local table           */
+    uint32_t  locals;     /* Total ints of params + locals        */
+    uint32_t  profile;    /* Always zero (engine uses this)       */
+    uint32_t  name;       /* name of function in string table     */
+    uint32_t  file;       /* file of the source file              */
+    uint32_t  nargs;      /* number of arguments                  */
+    uint8_t   argsize[8]; /* size of arguments (keep 8 always?)   */
 } prog_section_function;
 
 /* 
@@ -288,72 +288,72 @@ typedef struct {
  * this is what things compile to (from the C code).
  */
 enum {
-       INSTR_DONE,
-       INSTR_MUL_F,
-       INSTR_MUL_V,
-       INSTR_MUL_FV,
-       INSTR_MUL_VF,
-       INSTR_DIV_F,
-       INSTR_ADD_F,
-       INSTR_ADD_V,
-       INSTR_SUB_F,
-       INSTR_SUB_V,
-       INSTR_EQ_F,
-       INSTR_EQ_V,
-       INSTR_EQ_S,
-       INSTR_EQ_E,
-       INSTR_EQ_FNC,
-       INSTR_NE_F,
-       INSTR_NE_V,
-       INSTR_NE_S,
-       INSTR_NE_E,
-       INSTR_NE_FNC,
-       INSTR_LE,
-       INSTR_GE,
-       INSTR_LT,
-       INSTR_GT,
-       INSTR_LOAD_F,
-       INSTR_LOAD_V,
-       INSTR_LOAD_S,
-       INSTR_LOAD_ENT,
-       INSTR_LOAD_FLD,
-       INSTR_LOAD_FNC,
-       INSTR_ADDRESS,
-       INSTR_STORE_F,
-       INSTR_STORE_V,
-       INSTR_STORE_S,
-       INSTR_STORE_ENT,
-       INSTR_STORE_FLD,
-       INSTR_STORE_FNC,
-       INSTR_STOREP_F,
-       INSTR_STOREP_V,
-       INSTR_STOREP_S,
-       INSTR_STOREP_ENT,
-       INSTR_STOREP_FLD,
-       INSTR_STOREP_FNC,
-       INSTR_RETURN,
-       INSTR_NOT_F,
-       INSTR_NOT_V,
-       INSTR_NOT_S,
-       INSTR_NOT_ENT,
-       INSTR_NOT_FNC,
-       INSTR_IF,
-       INSTR_IFNOT,
-       INSTR_CALL0,
-       INSTR_CALL1,
-       INSTR_CALL2,
-       INSTR_CALL3,
-       INSTR_CALL4,
-       INSTR_CALL5,
-       INSTR_CALL6,
-       INSTR_CALL7,
-       INSTR_CALL8,
-       INSTR_STATE,
-       INSTR_GOTO,
-       INSTR_AND,
-       INSTR_OR,
-       INSTR_BITAND,
-       INSTR_BITOR
+    INSTR_DONE,
+    INSTR_MUL_F,
+    INSTR_MUL_V,
+    INSTR_MUL_FV,
+    INSTR_MUL_VF,
+    INSTR_DIV_F,
+    INSTR_ADD_F,
+    INSTR_ADD_V,
+    INSTR_SUB_F,
+    INSTR_SUB_V,
+    INSTR_EQ_F,
+    INSTR_EQ_V,
+    INSTR_EQ_S,
+    INSTR_EQ_E,
+    INSTR_EQ_FNC,
+    INSTR_NE_F,
+    INSTR_NE_V,
+    INSTR_NE_S,
+    INSTR_NE_E,
+    INSTR_NE_FNC,
+    INSTR_LE,
+    INSTR_GE,
+    INSTR_LT,
+    INSTR_GT,
+    INSTR_LOAD_F,
+    INSTR_LOAD_V,
+    INSTR_LOAD_S,
+    INSTR_LOAD_ENT,
+    INSTR_LOAD_FLD,
+    INSTR_LOAD_FNC,
+    INSTR_ADDRESS,
+    INSTR_STORE_F,
+    INSTR_STORE_V,
+    INSTR_STORE_S,
+    INSTR_STORE_ENT,
+    INSTR_STORE_FLD,
+    INSTR_STORE_FNC,
+    INSTR_STOREP_F,
+    INSTR_STOREP_V,
+    INSTR_STOREP_S,
+    INSTR_STOREP_ENT,
+    INSTR_STOREP_FLD,
+    INSTR_STOREP_FNC,
+    INSTR_RETURN,
+    INSTR_NOT_F,
+    INSTR_NOT_V,
+    INSTR_NOT_S,
+    INSTR_NOT_ENT,
+    INSTR_NOT_FNC,
+    INSTR_IF,
+    INSTR_IFNOT,
+    INSTR_CALL0,
+    INSTR_CALL1,
+    INSTR_CALL2,
+    INSTR_CALL3,
+    INSTR_CALL4,
+    INSTR_CALL5,
+    INSTR_CALL6,
+    INSTR_CALL7,
+    INSTR_CALL8,
+    INSTR_STATE,
+    INSTR_GOTO,
+    INSTR_AND,
+    INSTR_OR,
+    INSTR_BITAND,
+    INSTR_BITOR
 };
 
 /*
diff --git a/lex.c b/lex.c
index 5673701157a7aaf1b47fd043d821054dcaa0e488..48f58d8f6e81683a429823035af526f82b24e3e8 100644 (file)
--- a/lex.c
+++ b/lex.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
  * than keyword lexing.
  */
 static const char *const lex_keywords[] = {
-       "do",    "else",     "if",     "while",
-       "break", "continue", "return", "goto",
-       "for",   "typedef"
+    "do",    "else",     "if",     "while",
+    "break", "continue", "return", "goto",
+    "for",   "typedef"
 };
 
 struct lex_file *lex_open(FILE *fp) {
-       struct lex_file *lex = mem_a(sizeof(struct lex_file));
-       if (!lex || !fp)
-               return NULL;
-               
-       lex->file = fp;
-       fseek(lex->file, 0, SEEK_END);
-       lex->length = ftell(lex->file);
-       lex->size   = lex->length; /* copy, this is never changed */
-       fseek(lex->file, 0, SEEK_SET);
-       lex->last = 0;
-       lex->line = 0;
-       
-       memset(lex->peek, 0, sizeof(lex->peek));
-       return lex;
+    struct lex_file *lex = mem_a(sizeof(struct lex_file));
+    if (!lex || !fp)
+        return NULL;
+        
+    lex->file = fp;
+    fseek(lex->file, 0, SEEK_END);
+    lex->length = ftell(lex->file);
+    lex->size   = lex->length; /* copy, this is never changed */
+    fseek(lex->file, 0, SEEK_SET);
+    lex->last = 0;
+    lex->line = 0;
+    
+    memset(lex->peek, 0, sizeof(lex->peek));
+    return lex;
 }
 
 void lex_close(struct lex_file *file) {
-       if (!file) return;
-       
-       fclose(file->file); /* may already be closed */
-       mem_d (file);
+    if (!file) return;
+    
+    fclose(file->file); /* may already be closed */
+    mem_d (file);
 }
 
 static void lex_addch(int ch, struct lex_file *file) {
-       if (file->current <  sizeof(file->lastok)-1)
-               file->lastok[file->current++] = (char)ch;
-       if (file->current == sizeof(file->lastok)-1)
-               file->lastok[file->current]   = (char)'\0';
+    if (file->current <  sizeof(file->lastok)-1)
+        file->lastok[file->current++] = (char)ch;
+    if (file->current == sizeof(file->lastok)-1)
+        file->lastok[file->current]   = (char)'\0';
 }
 static inline void lex_clear(struct lex_file *file) {
-       file->current = 0;
+    file->current = 0;
 }
 
 /*
@@ -72,15 +72,15 @@ static inline void lex_clear(struct lex_file *file) {
  * it's own internal state for this.
  */
 static int lex_inget(struct lex_file *file) {
-       file->length --;
-       if (file->last > 0)
-               return file->peek[--file->last];
-       return fgetc(file->file);
+    file->length --;
+    if (file->last > 0)
+        return file->peek[--file->last];
+    return fgetc(file->file);
 }
 static void lex_unget(int ch, struct lex_file *file) {
-       if (file->last < sizeof(file->peek))
-               file->peek[file->last++] = ch;
-       file->length ++;
+    if (file->last < sizeof(file->peek))
+        file->peek[file->last++] = ch;
+    file->length ++;
 }
 
 /*
@@ -88,249 +88,249 @@ static void lex_unget(int ch, struct lex_file *file) {
  * supports.  Moving up in this world!
  */
 static int lex_trigraph(struct lex_file *file) {
-       int  ch;
-       if ((ch = lex_inget(file)) != '?') {
-               lex_unget(ch, file);
-               return '?';
-       }
-       
-       ch = lex_inget(file);
-       switch (ch) {
-               case '(' : return '[' ;
-               case ')' : return ']' ;
-               case '/' : return '\\';
-               case '\'': return '^' ;
-               case '<' : return '{' ;
-               case '>' : return '}' ;
-               case '!' : return '|' ;
-               case '-' : return '~' ;
-               case '=' : return '#' ;
-               default:
-                       lex_unget('?', file);
-                       lex_unget(ch , file);
-                       return '?';
-       }
-       return '?';
+    int  ch;
+    if ((ch = lex_inget(file)) != '?') {
+        lex_unget(ch, file);
+        return '?';
+    }
+    
+    ch = lex_inget(file);
+    switch (ch) {
+        case '(' : return '[' ;
+        case ')' : return ']' ;
+        case '/' : return '\\';
+        case '\'': return '^' ;
+        case '<' : return '{' ;
+        case '>' : return '}' ;
+        case '!' : return '|' ;
+        case '-' : return '~' ;
+        case '=' : return '#' ;
+        default:
+            lex_unget('?', file);
+            lex_unget(ch , file);
+            return '?';
+    }
+    return '?';
 }
 static int lex_digraph(struct lex_file *file, int first) {
-       int ch = lex_inget(file);
-       switch (first) {
-               case '<':
-                       if (ch == '%') return '{';
-                       if (ch == ':') return '[';
-                       break;
-               case '%':
-                       if (ch == '>') return '}';
-                       if (ch == ':') return '#';
-                       break;
-               case ':':
-                       if (ch == '>') return ']';
-                       break;
-       }
-       
-       lex_unget(ch, file);
-       return first;
+    int ch = lex_inget(file);
+    switch (first) {
+        case '<':
+            if (ch == '%') return '{';
+            if (ch == ':') return '[';
+            break;
+        case '%':
+            if (ch == '>') return '}';
+            if (ch == ':') return '#';
+            break;
+        case ':':
+            if (ch == '>') return ']';
+            break;
+    }
+    
+    lex_unget(ch, file);
+    return first;
 }
 
 static int lex_getch(struct lex_file *file) {
-       int ch = lex_inget(file);
+    int ch = lex_inget(file);
 
-       static int str = 0;
-       switch (ch) {
-               case '?' :
-                       return lex_trigraph(file);
-               case '<' :
-               case ':' :
-               case '%' :
-               case '"' : str = !str; if (str) { file->line ++; }
-                       return lex_digraph(file, ch);
-                       
-               case '\n':
-                       if (!str)
-                               file->line++;
-       }
-               
-       return ch;
+    static int str = 0;
+    switch (ch) {
+        case '?' :
+            return lex_trigraph(file);
+        case '<' :
+        case ':' :
+        case '%' :
+        case '"' : str = !str; if (str) { file->line ++; }
+            return lex_digraph(file, ch);
+            
+        case '\n':
+            if (!str)
+                file->line++;
+    }
+        
+    return ch;
 }
 
 static int lex_get(struct lex_file *file) {
-       int ch;
-       if (!isspace(ch = lex_getch(file)))
-               return ch;
-               
-       /* skip over all spaces */
-       while (isspace(ch) && ch != '\n')
-               ch = lex_getch(file);
-               
-       if (ch == '\n')
-               return ch;
-       lex_unget(ch, file);
-       return ' ';
+    int ch;
+    if (!isspace(ch = lex_getch(file)))
+        return ch;
+        
+    /* skip over all spaces */
+    while (isspace(ch) && ch != '\n')
+        ch = lex_getch(file);
+        
+    if (ch == '\n')
+        return ch;
+    lex_unget(ch, file);
+    return ' ';
 }
 
 static int lex_skipchr(struct lex_file *file) {
-       int ch;
-       int it;
-       
-       lex_clear(file);
-       lex_addch('\'', file);
-       
-       for (it = 0; it < 2 && ((ch = lex_inget(file)) != '\''); it++) {
-               lex_addch(ch, file);
-               
-               if (ch == '\n')
-                       return ERROR_LEX;
-               if (ch == '\\')
-                       lex_addch(lex_getch(file), file);
-       }
-       lex_addch('\'', file);
-       lex_addch('\0', file);
-       
-       if (it > 2)
-               return ERROR_LEX;
-               
-       return LEX_CHRLIT;
+    int ch;
+    int it;
+    
+    lex_clear(file);
+    lex_addch('\'', file);
+    
+    for (it = 0; it < 2 && ((ch = lex_inget(file)) != '\''); it++) {
+        lex_addch(ch, file);
+        
+        if (ch == '\n')
+            return ERROR_LEX;
+        if (ch == '\\')
+            lex_addch(lex_getch(file), file);
+    }
+    lex_addch('\'', file);
+    lex_addch('\0', file);
+    
+    if (it > 2)
+        return ERROR_LEX;
+        
+    return LEX_CHRLIT;
 }
 
 static int lex_skipstr(struct lex_file *file) {
-       int ch;
-       lex_clear(file);
-       lex_addch('"', file);
-       
-       while ((ch = lex_getch(file)) != '"') {
-               if (ch == '\n' || ch == EOF)
-                       return ERROR_LEX;
-                       
-               lex_addch(ch, file);
-               if (ch == '\\')
-                       lex_addch(lex_inget(file), file);
-       }
-       
-       lex_addch('"', file);
-       lex_addch('\0', file);
-       
-       return LEX_STRLIT;
+    int ch;
+    lex_clear(file);
+    lex_addch('"', file);
+    
+    while ((ch = lex_getch(file)) != '"') {
+        if (ch == '\n' || ch == EOF)
+            return ERROR_LEX;
+            
+        lex_addch(ch, file);
+        if (ch == '\\')
+            lex_addch(lex_inget(file), file);
+    }
+    
+    lex_addch('"', file);
+    lex_addch('\0', file);
+    
+    return LEX_STRLIT;
 }
 static int lex_skipcmt(struct lex_file *file) {
-       int ch;
-       lex_clear(file);
-       ch = lex_getch(file);
-       
-       if (ch == '/') {
-               lex_addch('/', file);
-               lex_addch('/', file);
-               
-               while ((ch = lex_getch(file)) != '\n') {
-                       if (ch == '\\') {
-                               lex_addch(ch, file);
-                               lex_addch(lex_getch(file), file);
-                       } else {
-                               lex_addch(ch, file);
-                       }
-               }
-               lex_addch('\0', file);
-               return LEX_COMMENT;
-       }
-       
-       if (ch != '*') {
-               lex_unget(ch, file);
-               return '/';
-       }
-       
-       lex_addch('/', file);
-       
-       /* hate this */
-       do {
-               lex_addch(ch, file);
-               while ((ch = lex_getch(file)) != '*') {
-                       if (ch == EOF)
-                               return error(file, ERROR_LEX, "malformatted comment");
-                       else
-                               lex_addch(ch, file);
-               }
-               lex_addch(ch, file);
-       } while ((ch = lex_getch(file)) != '/');
-       
-       lex_addch('/',  file);
-       lex_addch('\0', file);
-       
-       return LEX_COMMENT;
+    int ch;
+    lex_clear(file);
+    ch = lex_getch(file);
+    
+    if (ch == '/') {
+        lex_addch('/', file);
+        lex_addch('/', file);
+        
+        while ((ch = lex_getch(file)) != '\n') {
+            if (ch == '\\') {
+                lex_addch(ch, file);
+                lex_addch(lex_getch(file), file);
+            } else {
+                lex_addch(ch, file);
+            }
+        }
+        lex_addch('\0', file);
+        return LEX_COMMENT;
+    }
+    
+    if (ch != '*') {
+        lex_unget(ch, file);
+        return '/';
+    }
+    
+    lex_addch('/', file);
+    
+    /* hate this */
+    do {
+        lex_addch(ch, file);
+        while ((ch = lex_getch(file)) != '*') {
+            if (ch == EOF)
+                return error(file, ERROR_LEX, "malformatted comment");
+            else
+                lex_addch(ch, file);
+        }
+        lex_addch(ch, file);
+    } while ((ch = lex_getch(file)) != '/');
+    
+    lex_addch('/',  file);
+    lex_addch('\0', file);
+    
+    return LEX_COMMENT;
 }
 
 static int lex_getsource(struct lex_file *file) {
-       int ch = lex_get(file);
-       
-       /* skip char/string/comment */
-       switch (ch) {
-               case '\'': return lex_skipchr(file);
-               case '"':  return lex_skipstr(file);
-               case '/':  return lex_skipcmt(file);
-               default:
-                       return ch;
-       }
+    int ch = lex_get(file);
+    
+    /* skip char/string/comment */
+    switch (ch) {
+        case '\'': return lex_skipchr(file);
+        case '"':  return lex_skipstr(file);
+        case '/':  return lex_skipcmt(file);
+        default:
+            return ch;
+    }
 }
 
 int lex_token(struct lex_file *file) {
-       int ch = lex_getsource(file);
-       int it;
-       
-       /* valid identifier */
-       if (ch > 0 && (ch == '_' || isalpha(ch))) {
-               lex_clear(file);
-               
-               /*
-                * Yes this is dirty, but there is no other _sane_ easy
-                * way to do it, this is what I call defensive programming
-                * if something breaks, add more defense :-)
-                */
-               while (ch >   0   && ch != ' ' && ch != '(' &&
-                      ch != '\n' && ch != ';' && ch != ')') {
-                       lex_addch(ch, file);
-                       ch = lex_getsource(file);
-               }
-               lex_unget(ch,   file);
-               lex_addch('\0', file);
-               
-               /* look inside the table for a keyword .. */
-               for (it = 0; it < sizeof(lex_keywords)/sizeof(*lex_keywords); it++)
-                       if (!strncmp(file->lastok, lex_keywords[it], sizeof(lex_keywords[it])))
-                               return it;
-                               
-               /* try a type? */
-               #define TEST_TYPE(X)                                 \
-                   do {                                             \
-                       if (!strncmp(X, "float",  sizeof("float")))  \
-                           return TOKEN_FLOAT;                      \
-                       if (!strncmp(X, "vector", sizeof("vector"))) \
-                           return TOKEN_VECTOR;                     \
-                       if (!strncmp(X, "string", sizeof("string"))) \
-                           return TOKEN_STRING;                     \
-                       if (!strncmp(X, "entity", sizeof("entity"))) \
-                           return TOKEN_ENTITY;                     \
-                       if (!strncmp(X, "void"  , sizeof("void")))   \
-                           return TOKEN_VOID;                       \
-                   } while(0)
-               
-               TEST_TYPE(file->lastok);
-               
-               /* try the hashtable for typedefs? */
-               if (typedef_find(file->lastok))
-                       TEST_TYPE(typedef_find(file->lastok)->name);
-                       
-               #undef TEST_TYPE
-               return LEX_IDENT;
-       }
-       return ch;
+    int ch = lex_getsource(file);
+    int it;
+    
+    /* valid identifier */
+    if (ch > 0 && (ch == '_' || isalpha(ch))) {
+        lex_clear(file);
+        
+        /*
+         * Yes this is dirty, but there is no other _sane_ easy
+         * way to do it, this is what I call defensive programming
+         * if something breaks, add more defense :-)
+         */
+        while (ch >   0   && ch != ' ' && ch != '(' &&
+               ch != '\n' && ch != ';' && ch != ')') {
+            lex_addch(ch, file);
+            ch = lex_getsource(file);
+        }
+        lex_unget(ch,   file);
+        lex_addch('\0', file);
+        
+        /* look inside the table for a keyword .. */
+        for (it = 0; it < sizeof(lex_keywords)/sizeof(*lex_keywords); it++)
+            if (!strncmp(file->lastok, lex_keywords[it], sizeof(lex_keywords[it])))
+                return it;
+                
+        /* try a type? */
+        #define TEST_TYPE(X)                                 \
+            do {                                             \
+                if (!strncmp(X, "float",  sizeof("float")))  \
+                    return TOKEN_FLOAT;                      \
+                if (!strncmp(X, "vector", sizeof("vector"))) \
+                    return TOKEN_VECTOR;                     \
+                if (!strncmp(X, "string", sizeof("string"))) \
+                    return TOKEN_STRING;                     \
+                if (!strncmp(X, "entity", sizeof("entity"))) \
+                    return TOKEN_ENTITY;                     \
+                if (!strncmp(X, "void"  , sizeof("void")))   \
+                    return TOKEN_VOID;                       \
+            } while(0)
+        
+        TEST_TYPE(file->lastok);
+        
+        /* try the hashtable for typedefs? */
+        if (typedef_find(file->lastok))
+            TEST_TYPE(typedef_find(file->lastok)->name);
+            
+        #undef TEST_TYPE
+        return LEX_IDENT;
+    }
+    return ch;
 }
 
 void lex_reset(struct lex_file *file) {
-       file->current = 0;
-       file->last    = 0;
-       file->length  = file->size;
-       fseek(file->file, 0, SEEK_SET);
-       
-       memset(file->peek,   0, sizeof(file->peek  ));
-       memset(file->lastok, 0, sizeof(file->lastok));
+    file->current = 0;
+    file->last    = 0;
+    file->length  = file->size;
+    fseek(file->file, 0, SEEK_SET);
+    
+    memset(file->peek,   0, sizeof(file->peek  ));
+    memset(file->lastok, 0, sizeof(file->lastok));
 }
 
 /*
@@ -339,17 +339,17 @@ void lex_reset(struct lex_file *file) {
  * recrusion.
  */
 struct lex_file *lex_include(struct lex_file *lex, char *file) {
-       util_strrq(file);
-       if (strncmp(lex->name, file, strlen(lex->name)) == 0) {
-               error(lex, ERROR_LEX, "Source file cannot include itself\n");
-               exit (-1);
-       }
-       
-       FILE *fp = fopen(file, "r");
-       if  (!fp) {
-               error(lex, ERROR_LEX, "Include file `%s` doesn't exist\n", file);
-               exit (-1);
-       }
-       
-       return lex_open(fp);
+    util_strrq(file);
+    if (strncmp(lex->name, file, strlen(lex->name)) == 0) {
+        error(lex, ERROR_LEX, "Source file cannot include itself\n");
+        exit (-1);
+    }
+    
+    FILE *fp = fopen(file, "r");
+    if  (!fp) {
+        error(lex, ERROR_LEX, "Include file `%s` doesn't exist\n", file);
+        exit (-1);
+    }
+    
+    return lex_open(fp);
 }
diff --git a/main.c b/main.c
index d087c4eaab733423098f6e2b742cf116c4e08297..b8117f042806bef33b12f0e8663dd12ca74ad4ae 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
  */
 #include "gmqcc.h"
 int main(int argc, char **argv) {
-       argc--;
-       argv++;
-       
-       //const char *ifile = argv[0];
-       FILE *fp;
-       
-       /*TODO: proper interface swith switches*/
-       
-       asm_init ("test.qs", &fp);
-       asm_parse(fp);
-       asm_close(fp);
-       return 0;
+    argc--;
+    argv++;
+    
+    //const char *ifile = argv[0];
+    FILE *fp;
+    
+    /*TODO: proper interface swith switches*/
+    
+    asm_init ("test.qs", &fp);
+    asm_parse(fp);
+    asm_close(fp);
+    return 0;
 }
diff --git a/parse.c b/parse.c
index e763e56bc3848aff817838c22316cd329cb0bdc0..6423f5daa4b7d14979702843f5541e86e372ee15 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
 
 /* compile-time constant for type constants */
 typedef struct {
-       char *name;
-       int   type;
-       float value[3];
-       char *string; /* string value if constant is string literal */
+    char *name;
+    int   type;
+    float value[3];
+    char *string; /* string value if constant is string literal */
 } constant;
 VECTOR_MAKE(constant, compile_constants);
 
 void compile_constant_debug() {
-       int iter = 0;
-       for(; iter < compile_constants_elements; iter++) {
-               constant *c = &compile_constants_data[iter];
-               switch(c->type) {
-                       case TYPE_FLOAT:  printf("constant: %s FLOAT   %f\n",       c->name, c->value[0]);                           break;
-                       case TYPE_VECTOR: printf("constant: %s VECTOR {%f,%f,%f}\n",c->name, c->value[0], c->value[1], c->value[2]); break;
-                       case TYPE_STRING: printf("constant: %s STRING  %s\n",       c->name, c->string); break;
-                       case TYPE_VOID:   printf("constant: %s VOID    %s\n",       c->name, c->string); break;
-               }
-       }
+    int iter = 0;
+    for(; iter < compile_constants_elements; iter++) {
+        constant *c = &compile_constants_data[iter];
+        switch(c->type) {
+            case TYPE_FLOAT:  printf("constant: %s FLOAT   %f\n",       c->name, c->value[0]);                           break;
+            case TYPE_VECTOR: printf("constant: %s VECTOR {%f,%f,%f}\n",c->name, c->value[0], c->value[1], c->value[2]); break;
+            case TYPE_STRING: printf("constant: %s STRING  %s\n",       c->name, c->string); break;
+            case TYPE_VOID:   printf("constant: %s VOID    %s\n",       c->name, c->string); break;
+        }
+    }
 }
 
 /*
  * Generates a parse tree out of the lexees generated by the lexer.  This
  * is where the tree is built.  This is where valid check is performed.
  */
-int parse_gen(struct lex_file *file) { 
-       int     token = 0;
-       while ((token = lex_token(file)) != ERROR_LEX && file->length >= 0) {
-               switch (token) {
-                       case TOKEN_TYPEDEF: {
-                               char *f; /* from */
-                               char *t; /* to   */
-                               
-                               token = lex_token(file); 
-                               token = lex_token(file); f = util_strdup(file->lastok);
-                               token = lex_token(file); 
-                               token = lex_token(file); t = util_strdup(file->lastok);
-                               
-                               typedef_add(file, f, t);
-                               mem_d(f);
-                               mem_d(t);
-                               
-                               token = lex_token(file);
-                               if (token == ' ')
-                                       token = lex_token(file);
-                                       
-                               if (token != ';')
-                                       error(file, ERROR_PARSE, "Expected a `;` at end of typedef statement");
-                                       
-                               token = lex_token(file);
-                               break;
-                       }
-                       
-                       case TOKEN_VOID:   goto fall;
-                       case TOKEN_STRING: goto fall;
-                       case TOKEN_VECTOR: goto fall;
-                       case TOKEN_ENTITY: goto fall;
-                       case TOKEN_FLOAT:  goto fall;
-                       {
-                       fall:;
-                               char *name = NULL;
-                               int   type = token; /* story copy */
-                               
-                               /* skip over space */
-                               token = lex_token(file);
-                               if (token == ' ')
-                                       token = lex_token(file);
-                               
-                               /* save name */
-                               name = util_strdup(file->lastok);
-                               
-                               /* skip spaces */
-                               token = lex_token(file);
-                               if (token == ' ')
-                                       token = lex_token(file);
-                                       
-                               if (token == ';') {
-                                       /*
-                                        * Definitions go to the defs table, they don't have
-                                        * any sort of data with them yet.
-                                        */
-                               } else if (token == '=') {
-                                       token = lex_token(file);
-                                       if (token == ' ')
-                                               token = lex_token(file);
-                                       
-                                       /* strings are in file->lastok */
-                                       switch (type) {
-                                               case TOKEN_VOID:
-                                                       error(file, ERROR_PARSE, "Cannot assign value to type void\n");
-                                                       
-                                               /* TODO: Validate (end quote), strip quotes for constant add, name constant */
-                                               case TOKEN_STRING:
-                                                       if (*file->lastok != '"')
-                                                               error(file, ERROR_PARSE, "Expected a '\"' (quote) for string constant\n");
-                                                       /* add the compile-time constant */
-                                                       compile_constants_add((constant){
-                                                               .name   = util_strdup(name),
-                                                               .type   = TYPE_STRING,
-                                                               .value  = {0,0,0},
-                                                               .string = util_strdup(file->lastok)
-                                                       });
-                                                       break;
-                                               /* TODO: name constant, old qc vec literals, whitespace fixes, name constant */
-                                               case TOKEN_VECTOR: {
-                                                       float compile_calc_x = 0;
-                                                       float compile_calc_y = 0;
-                                                       float compile_calc_z = 0;
-                                                       int   compile_calc_d = 0; /* dot?        */
-                                                       int   compile_calc_s = 0; /* sign (-, +) */
-                                                       
-                                                       char  compile_data[1024];
-                                                       char *compile_eval = compile_data;
-                                                       
-                                                       if (token != '{')
-                                                               error(file, ERROR_PARSE, "Expected initializer list {} for vector constant\n"); 
-                                                       
-                                                       /*
-                                                        * This parses a single vector element: x,y & z.  This will handle all the
-                                                        * complicated mechanics of a vector, and can be extended as well.  This
-                                                        * is a rather large macro, and is #undef'd after it's use below.
-                                                        */
-                                                       #define PARSE_VEC_ELEMENT(NAME, BIT)                                                                                                           \
-                                                           token = lex_token(file);                                                                                                                   \
-                                                           if (token == ' ')                                                                                                                          \
-                                                               token = lex_token(file);                                                                                                               \
-                                                           if (token == '.')                                                                                                                          \
-                                                               compile_calc_d = 1;                                                                                                                    \
-                                                           if (!isdigit(token) && !compile_calc_d && token != '+' && token != '-')                                                                    \
-                                                               error(file, ERROR_PARSE,"Invalid constant initializer element %c for vector, must be numeric\n", NAME);                                \
-                                                           if (token == '+')                                                                                                                          \
-                                                               compile_calc_s = '+';                                                                                                                  \
-                                                           if (token == '-' && !compile_calc_s)                                                                                                       \
-                                                               compile_calc_s = '-';                                                                                                                  \
-                                                           while (isdigit(token) || token == '.' || token == '+' || token == '-') {                                                                   \
-                                                               *compile_eval++ = token;                                                                                                               \
-                                                               token           = lex_token(file);                                                                                                     \
-                                                               if (token == '.' && compile_calc_d) {                                                                                                  \
-                                                                   error(file, ERROR_PARSE, "Invalid constant initializer element %c for vector, must be numeric.\n", NAME);                          \
-                                                                   token = lex_token(file);                                                                                                           \
-                                                               }                                                                                                                                      \
-                                                               if ((token == '-' || token == '+') && compile_calc_s) {                                                                                \
-                                                                   error(file, ERROR_PARSE, "Invalid constant initializer sign for vector element %c\n", NAME);                                       \
-                                                                   token = lex_token(file);                                                                                                           \
-                                                               }                                                                                                                                      \
-                                                               else if (token == '.' && !compile_calc_d)                                                                                              \
-                                                                   compile_calc_d = 1;                                                                                                                \
-                                                               else if (token == '-' && !compile_calc_s)                                                                                              \
-                                                                   compile_calc_s = '-';                                                                                                              \
-                                                               else if (token == '+' && !compile_calc_s)                                                                                              \
-                                                                   compile_calc_s = '+';                                                                                                              \
-                                                           }                                                                                                                                          \
-                                                           if (token == ' ')                                                                                                                          \
-                                                               token = lex_token(file);                                                                                                               \
-                                                           if (NAME != 'z') {                                                                                                                         \
-                                                               if (token != ',' && token != ' ')                                                                                                      \
-                                                                   error(file, ERROR_PARSE, "invalid constant initializer element %c for vector (missing spaces, or comma delimited list?)\n", NAME); \
-                                                           } else if (token != '}') {                                                                                                                 \
-                                                               error(file, ERROR_PARSE, "Expected `}` on end of constant initialization for vector\n");                                               \
-                                                           }                                                                                                                                          \
-                                                           compile_calc_##BIT = atof(compile_data);                                                                                                   \
-                                                           compile_calc_d = 0;                                                                                                                        \
-                                                           compile_calc_s = 0;                                                                                                                        \
-                                                           compile_eval   = &compile_data[0];                                                                                                         \
-                                                           memset(compile_data, 0, sizeof(compile_data))
-                                                       
-                                                       /*
-                                                        * Parse all elements using the macro above.
-                                                        * We must undef the macro afterwards.
-                                                        */
-                                                       PARSE_VEC_ELEMENT('x', x);
-                                                       PARSE_VEC_ELEMENT('y', y);
-                                                       PARSE_VEC_ELEMENT('z', z);
-                                                       #undef PARSE_VEC_ELEMENT
-                                                       
-                                                       /* Check for the semi-colon... */
-                                                       token = lex_token(file);
-                                                       if (token == ' ')
-                                                               token = lex_token(file);
-                                                       if (token != ';')
-                                                               error(file, ERROR_PARSE, "Expected `;` on end of constant initialization for vector\n");
-                                                               
-                                                       /* add the compile-time constant */
-                                                       compile_constants_add((constant){
-                                                               .name   = util_strdup(name),
-                                                               .type   = TYPE_VECTOR,
-                                                               .value  = {
-                                                                       [0] = compile_calc_x,
-                                                                       [1] = compile_calc_y,
-                                                                       [2] = compile_calc_z
-                                                               },
-                                                               .string = NULL
-                                                       });
-                                                       break;
-                                               }
-                                                       
-                                               case TOKEN_ENTITY:
-                                               case TOKEN_FLOAT: /*TODO: validate, constant generation, name constant */
-                                                       if (!isdigit(token))
-                                                               error(file, ERROR_PARSE, "Expected numeric constant for float constant\n");
-                                                       compile_constants_add((constant){
-                                                               .name   = util_strdup(name),
-                                                               .type   = TOKEN_FLOAT,
-                                                               .value  = {0,0,0},
-                                                               .string = NULL
-                                                       });
-                                                       break;
-                                       }
-                               } else if (token == '(') {
-                                       printf("FUNCTION ??\n");
-                               }
-                               mem_d(name);
-                       }
-                               
-                       /*
-                        * From here down is all language punctuation:  There is no
-                        * need to actual create tokens from these because they're already
-                        * tokenized as these individual tokens (which are in a special area
-                        * of the ascii table which doesn't conflict with our other tokens
-                        * which are higer than the ascii table.)
-                        */
-                       case '#':
-                               token = lex_token(file); /* skip '#' */
-                               if (token == ' ')
-                                       token = lex_token(file);
-                               /*
-                                * If we make it here we found a directive, the supported
-                                * directives so far are #include.
-                                */
-                               if (strncmp(file->lastok, "include", sizeof("include")) == 0) {
-                                       /*
-                                        * We only suport include " ", not <> like in C (why?)
-                                        * because the latter is silly.
-                                        */
-                                       while (*file->lastok != '"' && token != '\n')
-                                               token = lex_token(file);
-                                       if (token == '\n')
-                                               return error(file, ERROR_PARSE, "Invalid use of include preprocessor directive: wanted #include \"file.h\"\n");
-                                               
-                                       char            *copy = util_strdup(file->lastok);
-                                       struct lex_file *next = lex_include(file,   copy);
-                                       
-                                       if (!next) {
-                                               error(file, ERROR_INTERNAL, "Include subsystem failure\n");
-                                               exit (-1);
-                                       }
-                                       compile_constants_add((constant) {
-                                                       .name   = "#include",
-                                                       .type   = TYPE_VOID,
-                                                       .value  = {0,0,0},
-                                                       .string = copy
-                                       });
-                                       parse_gen(next);
-                                       mem_d    (copy);
-                                       lex_close(next);
-                               }
-                               /* skip all tokens to end of directive */
-                               while (token != '\n')
-                                       token = lex_token(file);
-                               break;
-                               
-                       case LEX_IDENT:
-                               token = lex_token(file);
-                               break;
-               }
-       }
-       compile_constant_debug();
-       lex_reset(file);
-       return 1;
-}      
+int parse_gen(struct lex_file *file) {    
+    int     token = 0;
+    while ((token = lex_token(file)) != ERROR_LEX && file->length >= 0) {
+        switch (token) {
+            case TOKEN_TYPEDEF: {
+                char *f; /* from */
+                char *t; /* to   */
+                
+                token = lex_token(file); 
+                token = lex_token(file); f = util_strdup(file->lastok);
+                token = lex_token(file); 
+                token = lex_token(file); t = util_strdup(file->lastok);
+                
+                typedef_add(file, f, t);
+                mem_d(f);
+                mem_d(t);
+                
+                token = lex_token(file);
+                if (token == ' ')
+                    token = lex_token(file);
+                    
+                if (token != ';')
+                    error(file, ERROR_PARSE, "Expected a `;` at end of typedef statement");
+                    
+                token = lex_token(file);
+                break;
+            }
+            
+            case TOKEN_VOID:   goto fall;
+            case TOKEN_STRING: goto fall;
+            case TOKEN_VECTOR: goto fall;
+            case TOKEN_ENTITY: goto fall;
+            case TOKEN_FLOAT:  goto fall;
+            {
+            fall:;
+                char *name = NULL;
+                int   type = token; /* story copy */
+                
+                /* skip over space */
+                token = lex_token(file);
+                if (token == ' ')
+                    token = lex_token(file);
+                
+                /* save name */
+                name = util_strdup(file->lastok);
+                
+                /* skip spaces */
+                token = lex_token(file);
+                if (token == ' ')
+                    token = lex_token(file);
+                    
+                if (token == ';') {
+                    /*
+                     * Definitions go to the defs table, they don't have
+                     * any sort of data with them yet.
+                     */
+                } else if (token == '=') {
+                    token = lex_token(file);
+                    if (token == ' ')
+                        token = lex_token(file);
+                    
+                    /* strings are in file->lastok */
+                    switch (type) {
+                        case TOKEN_VOID:
+                            error(file, ERROR_PARSE, "Cannot assign value to type void\n");
+                            
+                        /* TODO: Validate (end quote), strip quotes for constant add, name constant */
+                        case TOKEN_STRING:
+                            if (*file->lastok != '"')
+                                error(file, ERROR_PARSE, "Expected a '\"' (quote) for string constant\n");
+                            /* add the compile-time constant */
+                            compile_constants_add((constant){
+                                .name   = util_strdup(name),
+                                .type   = TYPE_STRING,
+                                .value  = {0,0,0},
+                                .string = util_strdup(file->lastok)
+                            });
+                            break;
+                        /* TODO: name constant, old qc vec literals, whitespace fixes, name constant */
+                        case TOKEN_VECTOR: {
+                            float compile_calc_x = 0;
+                            float compile_calc_y = 0;
+                            float compile_calc_z = 0;
+                            int   compile_calc_d = 0; /* dot?        */
+                            int   compile_calc_s = 0; /* sign (-, +) */
+                            
+                            char  compile_data[1024];
+                            char *compile_eval = compile_data;
+                            
+                            if (token != '{')
+                                error(file, ERROR_PARSE, "Expected initializer list {} for vector constant\n");    
+                            
+                            /*
+                             * This parses a single vector element: x,y & z.  This will handle all the
+                             * complicated mechanics of a vector, and can be extended as well.  This
+                             * is a rather large macro, and is #undef'd after it's use below.
+                             */
+                            #define PARSE_VEC_ELEMENT(NAME, BIT)                                                                                                           \
+                                token = lex_token(file);                                                                                                                   \
+                                if (token == ' ')                                                                                                                          \
+                                    token = lex_token(file);                                                                                                               \
+                                if (token == '.')                                                                                                                          \
+                                    compile_calc_d = 1;                                                                                                                    \
+                                if (!isdigit(token) && !compile_calc_d && token != '+' && token != '-')                                                                    \
+                                    error(file, ERROR_PARSE,"Invalid constant initializer element %c for vector, must be numeric\n", NAME);                                \
+                                if (token == '+')                                                                                                                          \
+                                    compile_calc_s = '+';                                                                                                                  \
+                                if (token == '-' && !compile_calc_s)                                                                                                       \
+                                    compile_calc_s = '-';                                                                                                                  \
+                                while (isdigit(token) || token == '.' || token == '+' || token == '-') {                                                                   \
+                                    *compile_eval++ = token;                                                                                                               \
+                                    token           = lex_token(file);                                                                                                     \
+                                    if (token == '.' && compile_calc_d) {                                                                                                  \
+                                        error(file, ERROR_PARSE, "Invalid constant initializer element %c for vector, must be numeric.\n", NAME);                          \
+                                        token = lex_token(file);                                                                                                           \
+                                    }                                                                                                                                      \
+                                    if ((token == '-' || token == '+') && compile_calc_s) {                                                                                \
+                                        error(file, ERROR_PARSE, "Invalid constant initializer sign for vector element %c\n", NAME);                                       \
+                                        token = lex_token(file);                                                                                                           \
+                                    }                                                                                                                                      \
+                                    else if (token == '.' && !compile_calc_d)                                                                                              \
+                                        compile_calc_d = 1;                                                                                                                \
+                                    else if (token == '-' && !compile_calc_s)                                                                                              \
+                                        compile_calc_s = '-';                                                                                                              \
+                                    else if (token == '+' && !compile_calc_s)                                                                                              \
+                                        compile_calc_s = '+';                                                                                                              \
+                                }                                                                                                                                          \
+                                if (token == ' ')                                                                                                                          \
+                                    token = lex_token(file);                                                                                                               \
+                                if (NAME != 'z') {                                                                                                                         \
+                                    if (token != ',' && token != ' ')                                                                                                      \
+                                        error(file, ERROR_PARSE, "invalid constant initializer element %c for vector (missing spaces, or comma delimited list?)\n", NAME); \
+                                } else if (token != '}') {                                                                                                                 \
+                                    error(file, ERROR_PARSE, "Expected `}` on end of constant initialization for vector\n");                                               \
+                                }                                                                                                                                          \
+                                compile_calc_##BIT = atof(compile_data);                                                                                                   \
+                                compile_calc_d = 0;                                                                                                                        \
+                                compile_calc_s = 0;                                                                                                                        \
+                                compile_eval   = &compile_data[0];                                                                                                         \
+                                memset(compile_data, 0, sizeof(compile_data))
+                            
+                            /*
+                             * Parse all elements using the macro above.
+                             * We must undef the macro afterwards.
+                             */
+                            PARSE_VEC_ELEMENT('x', x);
+                            PARSE_VEC_ELEMENT('y', y);
+                            PARSE_VEC_ELEMENT('z', z);
+                            #undef PARSE_VEC_ELEMENT
+                            
+                            /* Check for the semi-colon... */
+                            token = lex_token(file);
+                            if (token == ' ')
+                                token = lex_token(file);
+                            if (token != ';')
+                                error(file, ERROR_PARSE, "Expected `;` on end of constant initialization for vector\n");
+                                
+                            /* add the compile-time constant */
+                            compile_constants_add((constant){
+                                .name   = util_strdup(name),
+                                .type   = TYPE_VECTOR,
+                                .value  = {
+                                    [0] = compile_calc_x,
+                                    [1] = compile_calc_y,
+                                    [2] = compile_calc_z
+                                },
+                                .string = NULL
+                            });
+                            break;
+                        }
+                            
+                        case TOKEN_ENTITY:
+                        case TOKEN_FLOAT: /*TODO: validate, constant generation, name constant */
+                            if (!isdigit(token))
+                                error(file, ERROR_PARSE, "Expected numeric constant for float constant\n");
+                            compile_constants_add((constant){
+                                .name   = util_strdup(name),
+                                .type   = TOKEN_FLOAT,
+                                .value  = {0,0,0},
+                                .string = NULL
+                            });
+                            break;
+                    }
+                } else if (token == '(') {
+                    printf("FUNCTION ??\n");
+                }
+                mem_d(name);
+            }
+                
+            /*
+             * From here down is all language punctuation:  There is no
+             * need to actual create tokens from these because they're already
+             * tokenized as these individual tokens (which are in a special area
+             * of the ascii table which doesn't conflict with our other tokens
+             * which are higer than the ascii table.)
+             */
+            case '#':
+                token = lex_token(file); /* skip '#' */
+                if (token == ' ')
+                    token = lex_token(file);
+                /*
+                 * If we make it here we found a directive, the supported
+                 * directives so far are #include.
+                 */
+                if (strncmp(file->lastok, "include", sizeof("include")) == 0) {
+                    /*
+                     * We only suport include " ", not <> like in C (why?)
+                     * because the latter is silly.
+                     */
+                    while (*file->lastok != '"' && token != '\n')
+                        token = lex_token(file);
+                    if (token == '\n')
+                        return error(file, ERROR_PARSE, "Invalid use of include preprocessor directive: wanted #include \"file.h\"\n");
+                        
+                    char            *copy = util_strdup(file->lastok);
+                    struct lex_file *next = lex_include(file,   copy);
+                    
+                    if (!next) {
+                        error(file, ERROR_INTERNAL, "Include subsystem failure\n");
+                        exit (-1);
+                    }
+                    compile_constants_add((constant) {
+                            .name   = "#include",
+                            .type   = TYPE_VOID,
+                            .value  = {0,0,0},
+                            .string = copy
+                    });
+                    parse_gen(next);
+                    mem_d    (copy);
+                    lex_close(next);
+                }
+                /* skip all tokens to end of directive */
+                while (token != '\n')
+                    token = lex_token(file);
+                break;
+                
+            case LEX_IDENT:
+                token = lex_token(file);
+                break;
+        }
+    }
+    compile_constant_debug();
+    lex_reset(file);
+    return 1;
+}    
index 011886147386068ed296bfee34e13356cd202743..0259f350c32d7de88f7e7cd02673fb246b388799 100644 (file)
--- a/typedef.c
+++ b/typedef.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
 static typedef_node *typedef_table[1024];
 
 void typedef_init() {
-       int i;
-       for(i = 0; i < sizeof(typedef_table)/sizeof(*typedef_table); i++)
-               typedef_table[i] = NULL;
+    int i;
+    for(i = 0; i < sizeof(typedef_table)/sizeof(*typedef_table); i++)
+        typedef_table[i] = NULL;
 }
 
 unsigned int typedef_hash(const char *s) {
-       unsigned int hash = 0;
-       unsigned int size = strlen(s);
-       unsigned int iter;
-       
-       for (iter = 0; iter < size; iter++) {
-               hash += s[iter];
-               hash += (hash << 10);
-               hash ^= (hash >> 6);
-       }
-       hash += (hash << 3);
-       hash ^= (hash >> 11);
-       hash += (hash << 15);
-       
-       return hash % 1024;
+    unsigned int hash = 0;
+    unsigned int size = strlen(s);
+    unsigned int iter;
+    
+    for (iter = 0; iter < size; iter++) {
+        hash += s[iter];
+        hash += (hash << 10);
+        hash ^= (hash >> 6);
+    }
+    hash += (hash << 3);
+    hash ^= (hash >> 11);
+    hash += (hash << 15);
+    
+    return hash % 1024;
 }
 
 typedef_node *typedef_find(const char *s) {
-       unsigned int  hash = typedef_hash(s);
-       typedef_node *find = typedef_table[hash];
-       return find;
+    unsigned int  hash = typedef_hash(s);
+    typedef_node *find = typedef_table[hash];
+    return find;
 }
 
 void typedef_clear() {
-       int i;
-       for(i = 1024; i > 0; i--) {
-               if(typedef_table[i]) {
-                       mem_d(typedef_table[i]->name);
-                       mem_d(typedef_table[i]);
-               }
-       }
+    int i;
+    for(i = 1024; i > 0; i--) {
+        if(typedef_table[i]) {
+            mem_d(typedef_table[i]->name);
+            mem_d(typedef_table[i]);
+        }
+    }
 }
 
 int typedef_add(struct lex_file *file, const char *from, const char *to) {
-       unsigned int  hash = typedef_hash(to);
-       typedef_node *find = typedef_table[hash];
-       
-       if (find)
-               return error(file, ERROR_PARSE, "typedef for %s already exists or conflicts\n", to);
-       
-       /* check if the type exists first */
-       if (strncmp(from, "float",  sizeof("float"))  == 0 ||
-           strncmp(from, "vector", sizeof("vector")) == 0 ||
-           strncmp(from, "string", sizeof("string")) == 0 ||
-           strncmp(from, "entity", sizeof("entity")) == 0 ||
-           strncmp(from, "void",   sizeof("void"))   == 0) {
-               
-               typedef_table[hash]       = mem_a(sizeof(typedef_node));
-               typedef_table[hash]->name = util_strdup(from);
-               return -100;
-       } else {
-               /* search the typedefs for it (typedef-a-typedef?) */
-               typedef_node *find = typedef_table[typedef_hash(from)];
-               if (find) {
-                       typedef_table[hash]       = mem_a(sizeof(typedef_node));
-                       typedef_table[hash]->name = util_strdup(find->name);
-                       return -100;
-               }
-       }
-       return error(file, ERROR_PARSE, "cannot typedef `%s` (not a type)\n", from);
+    unsigned int  hash = typedef_hash(to);
+    typedef_node *find = typedef_table[hash];
+    
+    if (find)
+        return error(file, ERROR_PARSE, "typedef for %s already exists or conflicts\n", to);
+    
+    /* check if the type exists first */
+    if (strncmp(from, "float",  sizeof("float"))  == 0 ||
+        strncmp(from, "vector", sizeof("vector")) == 0 ||
+        strncmp(from, "string", sizeof("string")) == 0 ||
+        strncmp(from, "entity", sizeof("entity")) == 0 ||
+        strncmp(from, "void",   sizeof("void"))   == 0) {
+        
+        typedef_table[hash]       = mem_a(sizeof(typedef_node));
+        typedef_table[hash]->name = util_strdup(from);
+        return -100;
+    } else {
+        /* search the typedefs for it (typedef-a-typedef?) */
+        typedef_node *find = typedef_table[typedef_hash(from)];
+        if (find) {
+            typedef_table[hash]       = mem_a(sizeof(typedef_node));
+            typedef_table[hash]->name = util_strdup(find->name);
+            return -100;
+        }
+    }
+    return error(file, ERROR_PARSE, "cannot typedef `%s` (not a type)\n", from);
 }
diff --git a/util.c b/util.c
index 44b1108595bdd3cc183ae9ad418064b72da31879..e431fb2d3aa72c9cd79c4e4b27c38d05a7156840 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 
- *     Dale Weiler
+ *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
 #include "gmqcc.h"
  
 struct memblock_t {
-       const char  *file;
-       unsigned int line;
-       unsigned int byte;
+    const char  *file;
+    unsigned int line;
+    unsigned int byte;
 };
 
 void *util_memory_a(unsigned int byte, unsigned int line, const char *file) {
-       struct memblock_t *data = malloc(sizeof(struct memblock_t) + byte);
-       if (!data) return NULL;
-       data->line = line;
-       data->byte = byte;
-       data->file = file;
-       
-       util_debug("MEM", "allocation: %08u (bytes) at %s:%u\n", byte, file, line);
-       return (void*)((uintptr_t)data+sizeof(struct memblock_t));
+    struct memblock_t *data = malloc(sizeof(struct memblock_t) + byte);
+    if (!data) return NULL;
+    data->line = line;
+    data->byte = byte;
+    data->file = file;
+    
+    util_debug("MEM", "allocation: %08u (bytes) at %s:%u\n", byte, file, line);
+    return (void*)((uintptr_t)data+sizeof(struct memblock_t));
 }
 
 void util_memory_d(void *ptrn, unsigned int line, const char *file) {
-       if (!ptrn) return;
-       void              *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t));
-       struct memblock_t *info = (struct memblock_t*)data;
-       
-       util_debug("MEM", "released:   %08u (bytes) at %s:%u\n", info->byte, file, line);
-       free(data);
+    if (!ptrn) return;
+    void              *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t));
+    struct memblock_t *info = (struct memblock_t*)data;
+    
+    util_debug("MEM", "released:   %08u (bytes) at %s:%u\n", info->byte, file, line);
+    free(data);
 }
 
 #ifndef mem_d
@@ -62,21 +62,21 @@ void util_memory_d(void *ptrn, unsigned int line, const char *file) {
  * to track all memory (without replacing malloc).
  */
 char *util_strdup(const char *s) {
-       size_t  len;
-       char   *ptr;
-       
-       if (!s)
-               return NULL;
-               
-       len = strlen(s);
-       ptr = mem_a (len+1);
-       
-       if (ptr && len) {
-               memcpy(ptr, s, len);
-               ptr[len] = '\0';
-       }
-       
-       return ptr;
+    size_t  len;
+    char   *ptr;
+    
+    if (!s)
+        return NULL;
+        
+    len = strlen(s);
+    ptr = mem_a (len+1);
+    
+    if (ptr && len) {
+        memcpy(ptr, s, len);
+        ptr[len] = '\0';
+    }
+    
+    return ptr;
 }
 
 /*
@@ -85,20 +85,20 @@ char *util_strdup(const char *s) {
  * char array that is later freed (it uses pointer arith)
  */
 char *util_strrq(char *s) {
-       char *dst = s;
-       char *src = s;
-       char  chr;
-       while ((chr = *src++) != '\0') {
-               if (chr == '\\') {
-                       *dst++ = chr;
-                       if ((chr = *src++) == '\0')
-                               break;
-                       *dst++ = chr;
-               } else if (chr != '"')
-                       *dst++ = chr;
-       }
-       *dst = '\0';
-       return dst;
+    char *dst = s;
+    char *src = s;
+    char  chr;
+    while ((chr = *src++) != '\0') {
+        if (chr == '\\') {
+            *dst++ = chr;
+            if ((chr = *src++) == '\0')
+                break;
+            *dst++ = chr;
+        } else if (chr != '"')
+            *dst++ = chr;
+    }
+    *dst = '\0';
+    return dst;
 }
 
 /*
@@ -107,24 +107,24 @@ char *util_strrq(char *s) {
  * access.
  */
 char *util_strrnl(char *src) {
-       if (!src) return NULL;
-       char   *cpy = src;
-       while (*cpy && *cpy != '\n')
-               cpy++;
-               
-       *cpy = '\0';
-       return src;
+    if (!src) return NULL;
+    char   *cpy = src;
+    while (*cpy && *cpy != '\n')
+        cpy++;
+        
+    *cpy = '\0';
+    return src;
 }
 
 void util_debug(const char *area, const char *ms, ...) {
-       va_list  va;
-       va_start(va, ms);
-       fprintf (stdout, "DEBUG: ");
-       fputc   ('[',  stdout);
-       fprintf (stdout, area);
-       fputs   ("] ", stdout);
-       vfprintf(stdout, ms, va);
-       va_end  (va);
+    va_list  va;
+    va_start(va, ms);
+    fprintf (stdout, "DEBUG: ");
+    fputc   ('[',  stdout);
+    fprintf (stdout, area);
+    fputs   ("] ", stdout);
+    vfprintf(stdout, ms, va);
+    va_end  (va);
 }
 
 /*
@@ -132,51 +132,51 @@ void util_debug(const char *area, const char *ms, ...) {
  * assmed all.  This works the same as getline().
  */
 int util_getline(char **lineptr, size_t *n, FILE *stream) {
-       int   chr;
-       int   ret;
-       char *pos;      
+    int   chr;
+    int   ret;
+    char *pos;    
 
-       if (!lineptr || !n || !stream)
-               return -1;
-       if (!*lineptr) {
-               if (!(*lineptr = mem_a((*n = 64))))
-                       return -1;
-       }
+    if (!lineptr || !n || !stream)
+        return -1;
+    if (!*lineptr) {
+        if (!(*lineptr = mem_a((*n = 64))))
+            return -1;
+    }
 
-       chr = *n;
-       pos = *lineptr;
+    chr = *n;
+    pos = *lineptr;
 
-       for (;;) {
-               int c = getc(stream);
-               
-               if (chr < 2) {
-                       char *tmp = mem_a((*n+=(*n>16)?*n:64));
-                       if  (!tmp)
-                               return -1;
-                       
-                       chr = *n + *lineptr - pos;
-                       strcpy(tmp,*lineptr);
-                       
-                       if (!(*lineptr = tmp))
-                               return -1;
-                               
-                       pos = *n - chr + *lineptr;
-               }
+    for (;;) {
+        int c = getc(stream);
+        
+        if (chr < 2) {
+            char *tmp = mem_a((*n+=(*n>16)?*n:64));
+            if  (!tmp)
+                return -1;
+            
+            chr = *n + *lineptr - pos;
+            strcpy(tmp,*lineptr);
+            
+            if (!(*lineptr = tmp))
+                return -1;
+                
+            pos = *n - chr + *lineptr;
+        }
 
-               if (ferror(stream)) 
-                       return -1;
-               if (c == EOF) {
-                       if (pos == *lineptr)
-                               return -1;
-                       else
-                               break;
-               }
+        if (ferror(stream)) 
+            return -1;
+        if (c == EOF) {
+            if (pos == *lineptr)
+                return -1;
+            else
+                break;
+        }
 
-               *pos++ = c;
-                chr--;
-               if (c == '\n')
-                       break;
-       }
-       *pos = '\0';
-       return (ret = pos - *lineptr);
+        *pos++ = c;
+         chr--;
+        if (c == '\n')
+            break;
+    }
+    *pos = '\0';
+    return (ret = pos - *lineptr);
 }