*/
#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);
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++)
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);
*((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++;
+ }
}
}
-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
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 *);
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;