]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
assembler can parse internal functions. Wrote all internal functions (that are not...
authorDale Weiler <killfieldengine@gmail.com>
Sat, 28 Apr 2012 07:26:40 +0000 (03:26 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Sat, 28 Apr 2012 07:26:40 +0000 (03:26 -0400)
asm.c
code.c
data/test.qs
gmqcc.h
util.c

diff --git a/asm.c b/asm.c
index 58a4ff9fb00478b80de8ede26ec7fd567d3f670b..0e1828059d2b61dfb626cf2293963864dbe2dca9 100644 (file)
--- a/asm.c
+++ b/asm.c
  */
 #include "gmqcc.h"
 /*
- * Some assembler keywords not part of the opcodes above: these are
- * for creating functions, or constants.
+ * Following parse states:
+ *     ASM_FUNCTION -- in a function accepting input statements
+ *     ....
  */
-const char *const asm_keys[] = {
-    "FLOAT"    , /* define float  */
-    "VECTOR"   , /* define vector */
-    "ENTITY"   , /* define ent    */
-    "FIELD"    , /* define field  */
-    "STRING"   , /* define string */
-    "FUNCTION"
-};
+typedef enum {
+    ASM_NULL,
+    ASM_FUNCTION
+} asm_state;
 
+typedef struct {
+    char *name;   /* name of constant    */
+    int   offset; /* location in globals */
+} globals;
+VECTOR_MAKE(globals, assembly_constants);
+
+/*
+ * Assembly text processing: this handles the internal collection
+ * of text to allow parsing and assemblation.
+ */
 static char *const asm_getline(size_t *byte, FILE *fp) {
     char   *line = NULL;
     ssize_t read = util_getline(&line, byte, fp);
@@ -45,32 +52,18 @@ static char *const asm_getline(size_t *byte, FILE *fp) {
     return line;
 }
 
+/*
+ * Entire external interface for main.c - to perform actual assemblation
+ * of assembly files.
+ */
 void asm_init(const char *file, FILE **fp) {
     *fp = fopen(file, "r");
     code_init();
 }
-
 void asm_close(FILE *fp) {
     fclose(fp);
     code_write();
 }
-
-/*
- * Following parse states:
- *     ASM_FUNCTION -- in a function accepting input statements
- *     ....
- */
-typedef enum {
-    ASM_NULL,
-    ASM_FUNCTION
-} asm_state;
-
-typedef struct {
-    char *name;   /* name of constant    */
-    int   offset; /* location in globals */
-} globals;
-VECTOR_MAKE(globals, assembly_constants);
-
 void asm_clear() {
     size_t i = 0;
     for (; i < assembly_constants_elements; i++)
@@ -114,14 +107,54 @@ static inline bool asm_parse_func(const char *skip, size_t line, asm_state *stat
             return false;
         }
         /* TODO: failure system, invalid name */
-        if (!isalpha(*name) || isupper(*name)) {
+        if (!isalpha(*name) || util_strupper(name)) {
             printf("invalid identifer for function name\n");
             mem_d(copy);
             mem_d(name);
             return false;
         }
 
-        printf("NAME: %s\n", name);
+        /*
+         * Function could be internal function, look for $
+         * to determine this.
+         */
+        if (strchr(name, ',')) {
+            char *find = strchr(name, ',') + 1;
+            
+            /* skip whitespace */
+            while (*find == ' ' || *find == '\t')
+                find++;
+            
+            if (*find != '$') {
+                printf("expected $ for internal function selection, got %s instead\n", find);
+                mem_d(copy);
+                mem_d(name);
+                return false;
+            }
+            find ++;
+            if (!isdigit(*find)) {
+                printf("invalid internal identifier, expected valid number\n");
+                mem_d(copy);
+                mem_d(name);
+                return false;
+            }
+            /* reassign name */
+            mem_d(name);
+            name = util_strchp(name, strchr(name, ','));
+
+            /* add internal function */
+            code_functions_add((prog_section_function){
+                -atoi(find), /* needs to be negated */
+                 0, 0, 0,
+                .name = code_chars_elements,
+                 0, 0,{0}
+            });
+            /* add name to string table */
+            code_chars_put(name, strlen(name));
+            code_chars_add('\0');
+            
+            printf("found internal function %s, -%d\n", name, atoi(find));
+        }
 
         mem_d(copy);
         mem_d(name);
diff --git a/code.c b/code.c
index 80d6c3b33fb41616d188f35b1bf2eda990e57d45..3f7ae5a041a5cafef0be6cb95719bb3b8721e09f 100644 (file)
--- a/code.c
+++ b/code.c
@@ -205,18 +205,21 @@ void code_write() {
             *((int32_t*)&code_functions_data[i].argsize)
         );
         util_debug("GEN", "    NAME: %s\n", &code_chars_data[code_functions_data[i].name]);
-        util_debug("GEN", "    CODE:\n");
-        for (;;) {
-            if (code_statements_data[j].opcode != INSTR_DONE &&
-                code_statements_data[j].opcode != INSTR_RETURN)
-                util_debug("GEN", "        %s {0x%05d,0x%05d,0x%05d}\n",
-                    asm_instr[code_statements_data[j].opcode].m,
-                    code_statements_data[j].s1,
-                    code_statements_data[j].s2,
-                    code_statements_data[j].s3
-                );
-            else break;
-            j++;
+        /* Internal functions have no code */
+        if (code_functions_data[i].entry >= 0) {
+            util_debug("GEN", "    CODE:\n");
+            for (;;) {
+                if (code_statements_data[j].opcode != INSTR_DONE &&
+                    code_statements_data[j].opcode != INSTR_RETURN)
+                    util_debug("GEN", "        %s {0x%05d,0x%05d,0x%05d}\n",
+                        asm_instr[code_statements_data[j].opcode].m,
+                        code_statements_data[j].s1,
+                        code_statements_data[j].s2,
+                        code_statements_data[j].s3
+                    );
+                else break;
+                j++;
+            }
         }
     }
     
index c5ad8941389bdfdf6b35c68979004de5f30efcb0..b26b4efb9d10036173548146395b1240c4ef4220 100644 (file)
@@ -1,11 +1,85 @@
-FLOAT: f 1;
-FLOAT: f 2;
-FLOAT: f 3;
-STRING: bar "hello world"
-
 ; these are builtin functions
-FUNCTION: foo
+FUNCTION: makevectors,    $1
+FUNCTION: setorigin,      $2
+FUNCTION: setmodel,       $3
+FUNCTION: setsize,        $4
+
+FUNCTION: break,          $6
+FUNCTION: random,         $7
+FUNCTION: sound,          $8
+FUNCTION: normalize,      $9
+FUNCTION: error,          $10
+FUNCTION: objerror,       $11
+FUNCTION: vlen,           $12
+FUNCTION: vectoyaw,       $13
+FUNCTION: spawn,          $14
+FUNCTION: remove,         $15
+FUNCTION: traceline,      $16
+
+FUNCTION: find,           $18
+FUNCTION: precache_sound, $19
+FUNCTION: precache_model, $20
+
+FUNCTION: findradius,     $22
+
+FUNCTION: dprint,         $25
+FUNCTION: ftos,           $26
+FUNCTION: vtos,           $27
+FUNCTION: coredump,       $28
+FUNCTION: traceon,        $29
+FUNCTION: traceoff,       $30
+FUNCTION: eprint,         $31
+FUNCTION: walkmove,       $32
+
+FUNCTION: droptofloor,    $34
+FUNCTION: lightstyle,     $35
+FUNCTION: rint,           $36
+FUNCTION: floor,          $37
+FUNCTION: ceil,           $38
+
+FUNCTION: checkbottom,    $40
+FUNCTION: pointcontents,  $41
+
+FUNCTION: fabs,           $43
+              
+FUNCTION: cvar,           $45
+FUNCTION: localcmd,       $46
+FUNCTION: nextent,        $47
+FUNCTION: particle,       $48
+FUNCTION: ChangeYaw,      $49
+
+FUNCTION: vectoangles,    $51
+FUNCTION: vectoangles2,   $51
+
+FUNCTION: sin,            $60
+FUNCTION: cos,            $61
+FUNCTION: sqrt,           $62
+FUNCTION: changepitch,    $63
+FUNCTION: tracetoss,      $64
+FUNCTION: etos,           $65
+
+FUNCTION: precache_file,  $68
+FUNCTION: makestatic,     $69
+
+FUNCTION: cvar_set,       $72
+
+FUNCTION: ambientsound,   $74
+FUNCTION: precache_model2,$75
+FUNCTION: precache_sound2,$76
+FUNCTION: precache_file2, $77
+
+FUNCTION: stof,           $81
+
+FUNCTION: tracebox,       $90
+FUNCTION: randomvec,      $91
+FUNCTION: getlight,       $92
+FUNCTION: getlight2,      $92
+FUNCTION: registercvar,   $93
+FUNCTION: min,            $94
+FUNCTION: max,            $95
+FUNCTION: bound,          $96
+FUNCTION: pow,            $97
+FUNCTION: findfloat,      $98
+FUNCTION: checkextension, $99
 
-FUNCTION: foo
-       ADD_F 200.4f, 300.3, OFS_RETURN
-       DONE
+; todo support other crap
diff --git a/gmqcc.h b/gmqcc.h
index 4b6dfc85947cc3653c205f21850c0b61cb68efc3..6e66325e00469c61e9113713b7c37096a6fb2e40 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -194,6 +194,7 @@ void *util_memory_a      (unsigned int, unsigned int, const char *);
 void  util_memory_d      (void       *, unsigned int, const char *);
 void  util_meminfo       ();
 
+bool  util_strupper      (const char *);
 char *util_strdup        (const char *);
 char *util_strrq         (char *);
 char *util_strrnl        (char *);
diff --git a/util.c b/util.c
index 62d58fff3e5fca7ab893d2a443ef929257bb0d5e..daf4b87a99a7b204934fa5b6818b844d3cf07009 100644 (file)
--- a/util.c
+++ b/util.c
@@ -166,6 +166,19 @@ char *util_strsws(const char *skip) {
     return util_strdup(skip-size);
 }
 
+/*
+ * Returns true if string is all uppercase, otherwise
+ * it returns false.
+ */
+bool util_strupper(const char *str) {
+    while (*str) {
+        if(!isupper(*str))
+            return false;
+        str++;
+    }
+    return true;
+}
+
 void util_debug(const char *area, const char *ms, ...) {
     if (!opts_debug)
         return;