]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Typedefs can now be registered, and even typedef a typedef.
authorDale Weiler <killfieldengine@gmail.com>
Tue, 10 Apr 2012 00:10:52 +0000 (20:10 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Tue, 10 Apr 2012 00:10:52 +0000 (20:10 -0400)
gmqcc.h
lex.c
parse.c
typedef.c

diff --git a/gmqcc.h b/gmqcc.h
index 142e6a1a4da3ef014cffcc2295dd8ccdfdb3d991..0aecd5c489f872973033e69efe2617e5d7be4807 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -157,12 +157,13 @@ struct lex_file {
 #define TOKEN_RETURN   6
 #define TOKEN_GOTO     7
 #define TOKEN_FOR      8   // extension
-#define TOKEN_INT      9   // extension
-#define TOKEN_VOID     10
-#define TOKEN_STRING   11
-#define TOKEN_FLOAT    12
-#define TOKEN_VECTOR   13
-#define TOKEN_ENTITY   14
+#define TOKEN_TYPEDEF  9   // extension
+#define TOKEN_INT      10  // extension
+#define TOKEN_VOID     11
+#define TOKEN_STRING   12
+#define TOKEN_FLOAT    13
+#define TOKEN_VECTOR   14
+#define TOKEN_ENTITY   15
 
 /*
  * Lexer state constants, these are numbers for where exactly in
@@ -200,10 +201,11 @@ int cpp  (struct lex_file *);
 
 /* typedef.c */
 typedef struct typedef_node_t {
-       struct typedef_node_t *next;
-       char                  *name; /* name of actual type */
+       char      *name; /* name of actual type */
 } typedef_node;
+
 void          typedef_init();
 typedef_node *typedef_find(const char *);
+int           typedef_add (const char *, const char *);
 
 #endif
diff --git a/lex.c b/lex.c
index 2d453d45bd00c9bde35838716f9309420deeceed..48d01c49db4adee40308f55d5a11172e166e7436 100644 (file)
--- a/lex.c
+++ b/lex.c
@@ -34,7 +34,7 @@
 static const char *const lex_keywords[] = {
        "do",    "else",     "if",     "while",
        "break", "continue", "return", "goto",
-       "for",
+       "for",   "typedef",
        
        /* types */
        "int",
diff --git a/parse.c b/parse.c
index f2566d64f70c98cf9acf2465cd4f232013374f1a..4ec25695aebc4de1cd703d489365123698c62eda 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -22,6 +22,7 @@
  */
 #include <limits.h>
 #include <stdlib.h>
+#include <string.h>
 #include "gmqcc.h"
 
 /*
@@ -213,6 +214,22 @@ int parse(struct lex_file *file) {
                                printf("FOO: %s\n", file->lastok);
                                break;
                                
+                       case TOKEN_TYPEDEF: {
+                               char *f = NULL;
+                               char *t = NULL;
+                               token = lex_token(file); 
+                               token = lex_token(file); f = strdup(file->lastok);
+                               token = lex_token(file); 
+                               token = lex_token(file); t = strdup(file->lastok);
+                               
+                               typedef_add(f, t);
+                               
+                               /* free new strings */
+                               mem_d(f);
+                               mem_d(t);
+                               break;
+                       }
+                               
                                
                        case TOKEN_DO:        PARSE_TODO(PARSE_TYPE_DO);
                        case TOKEN_WHILE:     PARSE_TODO(PARSE_TYPE_WHILE);
index 9994e551f11f3d84889ef308ae779f7df7d83914..fcd2b18a176d93eafa4de4719c97265fec90a35d 100644 (file)
--- a/typedef.c
+++ b/typedef.c
@@ -22,6 +22,7 @@
  */
 #include <string.h>
 #include <stdint.h> /* replace if stdint.h doesn't exist! */
+#include <limits.h>
 #include "gmqcc.h"
 
 /*
@@ -158,3 +159,34 @@ typedef_node *typedef_find(const char *s) {
        typedef_node *find = typedef_table[hash];
        return find;
 }
+
+int typedef_add(const char *from, const char *to) {
+       unsigned int  hash = typedef_hash(to);
+       typedef_node *find = typedef_table[hash];
+       if (find)
+               return error(ERROR_PARSE, "typedef for %s already exists\n", to);
+       
+       /* check if the type exists first */
+       if (strncmp(from, "void",   sizeof("void"))   == 0 ||
+               strncmp(from, "string", sizeof("string")) == 0 ||
+               strncmp(from, "float",  sizeof("float"))  == 0 ||
+               strncmp(from, "vector", sizeof("vector")) == 0 ||
+               strncmp(from, "entity", sizeof("entity")) == 0) {
+               
+               typedef_table[hash]       = mem_a(sizeof(typedef_node));
+               typedef_table[hash]->name = 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 = strdup(find->name);
+                       return -100;
+               }
+       }
+       return error(ERROR_PARSE, "cannot typedef %s (not a type)\n", from);
+}
+       
+               
+