]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parse.c
Merging master and adopting its main.c
[xonotic/gmqcc.git] / parse.c
diff --git a/parse.c b/parse.c
index 6423f5daa4b7d14979702843f5541e86e372ee15..c8ff73aee908ac6804a38b9b264d295fa0d15ebe 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 
+ * Copyright (C) 2012
  *     Dale Weiler
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
@@ -48,57 +48,57 @@ void compile_constant_debug() {
  * 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 parse_gen(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);
                 token = lex_token(file); f = util_strdup(file->lastok);
-                token = lex_token(file); 
+                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:;
+            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
@@ -108,23 +108,27 @@ int parse_gen(struct lex_file *file) {
                     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)
-                            });
+                            {
+                                constant c;
+                                c.name     = util_strdup(name),
+                                c.type     = TYPE_STRING,
+                                c.value[0] = 0;
+                                c.value[1] = 0;
+                                c.value[2] = 0;
+                                c.string   = util_strdup(file->lastok);
+                                compile_constants_add(c);
+                            }
                             break;
                         /* TODO: name constant, old qc vec literals, whitespace fixes, name constant */
                         case TOKEN_VECTOR: {
@@ -133,13 +137,13 @@ int parse_gen(struct lex_file *file) {
                             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");    
-                            
+                                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
@@ -188,7 +192,7 @@ int parse_gen(struct lex_file *file) {
                                 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.
@@ -197,46 +201,52 @@ int parse_gen(struct lex_file *file) {
                             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
-                            });
+                            {
+                                constant c;
+
+                                c.name     = util_strdup(name),
+                                c.type     = TYPE_VECTOR,
+                                c.value[0] = compile_calc_x;
+                                c.value[1] = compile_calc_y;
+                                c.value[2] = compile_calc_z;
+                                c.string   = NULL;
+                                compile_constants_add(c);
+                            }
                             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
-                            });
+                            /* constant */
+                            {
+                                constant c;
+                                c.name     = util_strdup(name),
+                                c.type     = TOKEN_FLOAT,
+                                c.value[0] = 0;
+                                c.value[1] = 0;
+                                c.value[2] = 0;
+                                c.string   = NULL;
+                                compile_constants_add(c);
+                            }
                             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
@@ -253,6 +263,8 @@ int parse_gen(struct lex_file *file) {
                  * directives so far are #include.
                  */
                 if (strncmp(file->lastok, "include", sizeof("include")) == 0) {
+                    char     *copy = NULL;
+                    lex_file *next = NULL;
                     /*
                      * We only suport include " ", not <> like in C (why?)
                      * because the latter is silly.
@@ -261,20 +273,25 @@ int parse_gen(struct lex_file *file) {
                         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);
-                    
+
+                    copy = util_strdup(file->lastok);
+                    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
-                    });
+                    /* constant */
+                    {
+                        constant c;
+                        c.name     = "#include",
+                        c.type     = TYPE_VOID,
+                        c.value[0] = 0;
+                        c.value[1] = 0;
+                        c.value[2] = 0;
+                        c.string   = copy;
+                        compile_constants_add(c);
+                    }
                     parse_gen(next);
                     mem_d    (copy);
                     lex_close(next);
@@ -283,7 +300,7 @@ int parse_gen(struct lex_file *file) {
                 while (token != '\n')
                     token = lex_token(file);
                 break;
-                
+
             case LEX_IDENT:
                 token = lex_token(file);
                 break;
@@ -291,5 +308,14 @@ int parse_gen(struct lex_file *file) {
     }
     compile_constant_debug();
     lex_reset(file);
+    /* free constants */
+    {
+        size_t i = 0;
+        for (; i < compile_constants_elements; i++) {
+            mem_d(compile_constants_data[i].name);
+            mem_d(compile_constants_data[i].string);
+        }
+        mem_d(compile_constants_data);
+    }
     return 1;
-}    
+}