From: Dale Weiler Date: Sat, 28 Apr 2012 07:26:40 +0000 (-0400) Subject: assembler can parse internal functions. Wrote all internal functions (that are not... X-Git-Tag: 0.1-rc1~578^2~2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=07c6aea7dc81edd914869b70db9223e4f78d6f9f;p=xonotic%2Fgmqcc.git assembler can parse internal functions. Wrote all internal functions (that are not extensions) to test.qs --- diff --git a/asm.c b/asm.c index 58a4ff9..0e18280 100644 --- a/asm.c +++ b/asm.c @@ -22,18 +22,25 @@ */ #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 80d6c3b..3f7ae5a 100644 --- 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++; + } } } diff --git a/data/test.qs b/data/test.qs index c5ad894..b26b4ef 100644 --- a/data/test.qs +++ b/data/test.qs @@ -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 4b6dfc8..6e66325 100644 --- 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 62d58ff..daf4b87 100644 --- 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;