assembler can parse internal functions. Wrote all internal functions (that are not extensions) to test.qs

This commit is contained in:
Dale Weiler 2012-04-28 03:26:40 -04:00
parent 403901d6ee
commit 07c6aea7dc
5 changed files with 181 additions and 57 deletions

105
asm.c
View file

@ -21,40 +21,6 @@
* SOFTWARE.
*/
#include "gmqcc.h"
/*
* Some assembler keywords not part of the opcodes above: these are
* for creating functions, or constants.
*/
const char *const asm_keys[] = {
"FLOAT" , /* define float */
"VECTOR" , /* define vector */
"ENTITY" , /* define ent */
"FIELD" , /* define field */
"STRING" , /* define string */
"FUNCTION"
};
static char *const asm_getline(size_t *byte, FILE *fp) {
char *line = NULL;
ssize_t read = util_getline(&line, byte, fp);
*byte = read;
if (read == -1) {
mem_d (line);
return NULL;
}
return line;
}
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
@ -71,6 +37,33 @@ typedef struct {
} 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);
*byte = read;
if (read == -1) {
mem_d (line);
return NULL;
}
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();
}
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);

27
code.c
View file

@ -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++;
}
}
}

View 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: foo
ADD_F 200.4f, 300.3, OFS_RETURN
DONE
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
; todo support other crap

View file

@ -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 *);

13
util.c
View file

@ -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;