]> de.git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
More assembly work
authorDale Weiler <killfieldengine@gmail.com>
Sat, 28 Apr 2012 06:34:39 +0000 (02:34 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Sat, 28 Apr 2012 06:34:39 +0000 (02:34 -0400)
asm.c
data/test.qs
gmqcc.h
util.c

diff --git a/asm.c b/asm.c
index ae50a0520013d26df7ca107d0087f2a092bb9127..58a4ff9fb00478b80de8ede26ec7fd567d3f670b 100644 (file)
--- a/asm.c
+++ b/asm.c
@@ -103,8 +103,28 @@ static inline bool asm_parse_func(const char *skip, size_t line, asm_state *stat
         return false;
 
     if (strstr(skip, "FUNCTION:") == &skip[0]) {
-        *state = ASM_FUNCTION; /* update state */
-        /* TODO */
+        char  *copy = util_strsws(skip+10);
+        char  *name = util_strchp(copy, strchr(copy, '\0'));
+
+        /* TODO: failure system, missing name */
+        if (!name) {
+            printf("expected name on function\n");
+            mem_d(copy);
+            mem_d(name);
+            return false;
+        }
+        /* TODO: failure system, invalid name */
+        if (!isalpha(*name) || isupper(*name)) {
+            printf("invalid identifer for function name\n");
+            mem_d(copy);
+            mem_d(name);
+            return false;
+        }
+
+        printf("NAME: %s\n", name);
+
+        mem_d(copy);
+        mem_d(name);
         return true;
     }
     return false;
@@ -117,19 +137,32 @@ void asm_parse(FILE *fp) {
     size_t    size  = 0; /* size of line */
     asm_state state = ASM_NULL;
 
-    #define asm_end(x) do { mem_d(data); line++; printf(x); } while (0); continue
+    #define asm_end(x)            \
+        do {                      \
+            mem_d(data);          \
+            mem_d(copy);          \
+            line++;               \
+            util_debug("ASM", x); \
+        } while (0); continue
     
     while ((data = asm_getline (&size, fp)) != NULL) {
-        data = util_strsws(data,&skip); /* skip   whitespace */
-        data = util_strrnl(data);       /* delete newline    */
+        char *copy = util_strsws(data); /* skip   whitespace */
+              skip = util_strrnl(copy); /* delete newline    */
 
         /* parse type */
-        if(asm_parse_type(skip, line, &state)){ asm_end(""); }
+        if(asm_parse_type(skip, line, &state)){ asm_end("asm_parse_type\n"); }
         /* parse func */
-        if(asm_parse_func(skip, line, &state)){ asm_end(""); }
+        if(asm_parse_func(skip, line, &state)){ asm_end("asm_parse_func\n"); }
+
+        /* statement closure */
+        if (state == ASM_FUNCTION && (
+            (strstr(skip, "DONE")   == &skip[0])||
+            (strstr(skip, "RETURN") == &skip[0]))) state = ASM_NULL;
         
         /* TODO: everything */
         (void)state;
+        asm_end("asm_parse_end\n");
     }
+    #undef asm_end
        asm_clear();
 }
index 5c5134a52c2b57db0d5de51963e9e7fac1a960df..c5ad8941389bdfdf6b35c68979004de5f30efcb0 100644 (file)
@@ -3,6 +3,9 @@ FLOAT: f 2;
 FLOAT: f 3;
 STRING: bar "hello world"
 
+; these are builtin functions
+FUNCTION: foo
+
 FUNCTION: foo
        ADD_F 200.4f, 300.3, OFS_RETURN
        DONE
diff --git a/gmqcc.h b/gmqcc.h
index 0cf779761500e27a09cf27f2d0278fadf95e9e64..4b6dfc85947cc3653c205f21850c0b61cb68efc3 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -197,7 +197,8 @@ void  util_meminfo       ();
 char *util_strdup        (const char *);
 char *util_strrq         (char *);
 char *util_strrnl        (char *);
-char *util_strsws        (char *, char **);
+char *util_strsws        (const char *);
+char *util_strchp        (const char *, const char *);
 void  util_debug         (const char *, const char *, ...);
 int   util_getline       (char **, size_t *, FILE *);
 void  util_endianswap    (void *,  int, int);
diff --git a/util.c b/util.c
index 2b59537c69ba45f5b32289ffcb54b89f20e925b7..62d58fff3e5fca7ab893d2a443ef929257bb0d5e 100644 (file)
--- a/util.c
+++ b/util.c
@@ -33,7 +33,7 @@ struct memblock_t {
     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 *info = malloc(sizeof(struct memblock_t) + byte);
@@ -46,6 +46,7 @@ void *util_memory_a(unsigned int byte, unsigned int line, const char *file) {
     util_debug("MEM", "allocation: % 8u (bytes) address 0x%08X @ %s:%u\n", byte, data, file, line);
     mem_at++;
     mem_ab += info->byte;
+
     return data;
 }
 
@@ -57,6 +58,7 @@ void util_memory_d(void *ptrn, unsigned int line, const char *file) {
     util_debug("MEM", "released:   % 8u (bytes) address 0x%08X @ %s:%u\n", info->byte, data, file, line);
     mem_db += info->byte;
     mem_dt++;
+
     free(data);
 }
 
@@ -117,6 +119,23 @@ char *util_strrq(char *s) {
     return dst;
 }
 
+/*
+ * Chops a substring from an existing string by creating a
+ * copy of it and null terminating it at the required position.
+ */
+char *util_strchp(const char *s, const char *e) {
+    if (!s || !e)
+        return NULL;
+        
+    size_t m  = 0;
+    char  *c  = util_strdup(s);
+    while (s != e)
+        s++,c++,m++;
+         
+    *c = '\0';
+    return c-m;
+}
+
 /*
  * Remove newline from a string (if it exists).  This is
  * done pointer wise instead of strlen(), and an array
@@ -137,15 +156,14 @@ char *util_strrnl(char *src) {
  * skipping past it, and stroing the skip distance, so
  * the string can later be freed (if it was allocated)
  */
-char *util_strsws(char *skip, char **move) {
+char *util_strsws(const char *skip) {
     size_t size = 0;
     if (!skip)
         return NULL;
     
     while (*skip == ' ' || *skip == '\t')
         skip++,size++;
-    *move = skip;
-    return skip-size;
+    return util_strdup(skip-size);
 }
 
 void util_debug(const char *area, const char *ms, ...) {