]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Function parsing for the assembler now works, and adds the function to the function...
authorDale Weiler <killfieldengine@gmail.com>
Tue, 1 May 2012 20:42:11 +0000 (16:42 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Tue, 1 May 2012 20:42:11 +0000 (16:42 -0400)
asm.c
code.c
data/test.qs
lex.c

diff --git a/asm.c b/asm.c
index ad47b5785f89877c25705f78f9784f4aebb01808..6539e16a07cb168088efd8cc50cc860f377aee3b 100644 (file)
--- a/asm.c
+++ b/asm.c
@@ -161,6 +161,7 @@ static GMQCC_INLINE bool asm_parse_type(const char *skip, size_t line, asm_state
                 BUILD_ELEMENT(1, val2);
                 BUILD_ELEMENT(2, val3);
                 #undef  BUILD_ELEMENT
+                mem_d(name);
             } else {
                 /* TODO global not constant */
             }
@@ -261,6 +262,8 @@ static GMQCC_INLINE bool asm_parse_func(const char *skip, size_t line, asm_state
             code_globals_add  (code_chars_elements);
             code_chars_put    (name, strlen(name));
             code_chars_add    ('\0');
+            
+            util_debug("ASM", "added internal function %s to function table\n", name);
 
             /*
              * Sanatize the numerical constant used to select the
@@ -274,9 +277,81 @@ static GMQCC_INLINE bool asm_parse_func(const char *skip, size_t line, asm_state
                 printf("invalid internal function identifier, must be all numeric\n");
 
         } else {
-            printf("Found function %s\n", name);
-        }
+            /*
+             * The function isn't an internal one. Determine the name and
+             * amount of arguments the function accepts by searching for
+             * the `#` (pound sign).
+             */
+            int   args = 0;
+            char *find = strchr(name, '#');
+            char *peek = find;
+            
+            /*
+             * Code structures for filling after determining the correct
+             * information to add to the code write system.
+             */
+            prog_section_function function;
+            prog_section_def      def;
+            if (find) {
+                find ++;
+
+                /* skip whitespace */
+                if (*find == ' ' || *find == '\t')
+                    find++;
+
+                /*
+                 * If the input is larger than eight, it's considered
+                 * invalid and shouldn't be allowed.  The QuakeC VM only
+                 * allows a maximum of eight arguments.
+                 */
+                if (strlen(find) > 1 || *find == '9') {
+                    printf("invalid number of arguments, must be a valid number from 0-8\n");
+                    mem_d(copy);
+                    mem_d(name);
+                    return false;
+                }
+
+                if (*find != '0') {
+                    /*
+                     * if we made it this far we have a valid number for the
+                     * argument count, so fall through a switch statement and
+                     * do it.
+                     */
+                    switch (*find) {
+                        case '8': args++; case '7': args++;
+                        case '6': args++; case '5': args++;
+                        case '4': args++; case '3': args++;
+                        case '2': args++; case '1': args++;
+                    }
+                }
+            } else {
+                printf("missing number of argument count in function %s\n", name);
+            }
+            /* terminate name inspot */
+            *--peek='\0';
 
+            /*
+             * We got valid function structure information now. Lets add
+             * the function to the code writer function table.
+             */
+            function.entry      = code_statements_elements;
+            function.firstlocal = 0;
+            function.profile    = 0;
+            function.name       = code_chars_elements;
+            function.file       = 0;
+            function.nargs      = args;
+            def.type            = TYPE_FUNCTION;
+            def.offset          = code_globals_elements;
+            def.name            = code_chars_elements;
+            code_functions_add(function);
+            code_defs_add     (def);
+            code_globals_add  (code_chars_elements);
+            code_chars_put    (name, strlen(name));
+            code_chars_add    ('\0');
+            
+            util_debug("ASM", "added context function %s to function table\n", name);
+        }
+        
         mem_d(copy);
         mem_d(name);
         return true;
@@ -318,6 +393,6 @@ void asm_parse(FILE *fp) {
         asm_end("asm_parse_end\n");
     }
     #undef asm_end
-        asm_dumps();
+    asm_dumps();
     asm_clear();
 }
diff --git a/code.c b/code.c
index 616a3a994c8868a11d9690d95318bab1500c067e..8f2bac917c57a307759037777161a9f1cda63abe 100644 (file)
--- a/code.c
+++ b/code.c
@@ -147,14 +147,14 @@ void code_test() {
 
 void code_write() {
     prog_header  code_header  = {0};
-    prog_section statements;
-    prog_section defs;
-    prog_section fields;
-    prog_section functions;
-    prog_section globals;
-    prog_section strings;
-    FILE        *fp        = NULL;
-    size_t       it        = 1;
+    prog_section statements   = {0};
+    prog_section defs         = {0};
+    prog_section fields       = {0};
+    prog_section functions    = {0};
+    prog_section globals      = {0};
+    prog_section strings      = {0};
+    FILE        *fp           = NULL;
+    size_t       it           = 1;
 
     /* see proposal.txt */
     if (opts_omit_nullcode) {
index 50a541dccde2676950875875d54a4587d88f21b9..26b0aeb69f63ee8605b9412108f05ce7884d212f 100644 (file)
@@ -86,3 +86,6 @@ FUNCTION: checkextension, $99
 VECTOR: dude1, -1,  +2, 38865.444
 FLOAT:  dude2, 1
 STRING: "hello world"
+
+FUNCTION: foo #1
+
diff --git a/lex.c b/lex.c
index 5a908b8e7d2406520ac8ca1b6e628b7495ea32e3..a7949eaf092c8fa212831055d5b65315df665a9b 100644 (file)
--- a/lex.c
+++ b/lex.c
@@ -318,7 +318,7 @@ int lex_token(lex_file *file) {
         #undef TEST_TYPE
         return LEX_IDENT;
     }
-    return ch;
+    return (ch != ' ') ? ch : lex_token(file);
 }
 
 void lex_reset(lex_file *file) {