mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-21 10:21:03 +00:00
Function parsing for the assembler now works, and adds the function to the function table for the code writer, quake and darkplaces can see it as well (since a def is also created)
This commit is contained in:
parent
1e0a688bc5
commit
d51718118a
4 changed files with 90 additions and 12 deletions
81
asm.c
81
asm.c
|
@ -161,6 +161,7 @@ static GMQCC_INLINE bool asm_parse_type(const char *skip, size_t line, asm_state
|
|||
BUILD_ELEMENT(1, val2);
|
||||
BUILD_ELEMENT(2, val3);
|
||||
#undef BUILD_ELEMENT
|
||||
mem_d(name);
|
||||
} else {
|
||||
/* TODO global not constant */
|
||||
}
|
||||
|
@ -261,6 +262,8 @@ static GMQCC_INLINE bool asm_parse_func(const char *skip, size_t line, asm_state
|
|||
code_globals_add (code_chars_elements);
|
||||
code_chars_put (name, strlen(name));
|
||||
code_chars_add ('\0');
|
||||
|
||||
util_debug("ASM", "added internal function %s to function table\n", name);
|
||||
|
||||
/*
|
||||
* Sanatize the numerical constant used to select the
|
||||
|
@ -274,9 +277,81 @@ static GMQCC_INLINE bool asm_parse_func(const char *skip, size_t line, asm_state
|
|||
printf("invalid internal function identifier, must be all numeric\n");
|
||||
|
||||
} else {
|
||||
printf("Found function %s\n", name);
|
||||
}
|
||||
/*
|
||||
* The function isn't an internal one. Determine the name and
|
||||
* amount of arguments the function accepts by searching for
|
||||
* the `#` (pound sign).
|
||||
*/
|
||||
int args = 0;
|
||||
char *find = strchr(name, '#');
|
||||
char *peek = find;
|
||||
|
||||
/*
|
||||
* Code structures for filling after determining the correct
|
||||
* information to add to the code write system.
|
||||
*/
|
||||
prog_section_function function;
|
||||
prog_section_def def;
|
||||
if (find) {
|
||||
find ++;
|
||||
|
||||
/* skip whitespace */
|
||||
if (*find == ' ' || *find == '\t')
|
||||
find++;
|
||||
|
||||
/*
|
||||
* If the input is larger than eight, it's considered
|
||||
* invalid and shouldn't be allowed. The QuakeC VM only
|
||||
* allows a maximum of eight arguments.
|
||||
*/
|
||||
if (strlen(find) > 1 || *find == '9') {
|
||||
printf("invalid number of arguments, must be a valid number from 0-8\n");
|
||||
mem_d(copy);
|
||||
mem_d(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*find != '0') {
|
||||
/*
|
||||
* if we made it this far we have a valid number for the
|
||||
* argument count, so fall through a switch statement and
|
||||
* do it.
|
||||
*/
|
||||
switch (*find) {
|
||||
case '8': args++; case '7': args++;
|
||||
case '6': args++; case '5': args++;
|
||||
case '4': args++; case '3': args++;
|
||||
case '2': args++; case '1': args++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("missing number of argument count in function %s\n", name);
|
||||
}
|
||||
/* terminate name inspot */
|
||||
*--peek='\0';
|
||||
|
||||
/*
|
||||
* We got valid function structure information now. Lets add
|
||||
* the function to the code writer function table.
|
||||
*/
|
||||
function.entry = code_statements_elements;
|
||||
function.firstlocal = 0;
|
||||
function.profile = 0;
|
||||
function.name = code_chars_elements;
|
||||
function.file = 0;
|
||||
function.nargs = args;
|
||||
def.type = TYPE_FUNCTION;
|
||||
def.offset = code_globals_elements;
|
||||
def.name = code_chars_elements;
|
||||
code_functions_add(function);
|
||||
code_defs_add (def);
|
||||
code_globals_add (code_chars_elements);
|
||||
code_chars_put (name, strlen(name));
|
||||
code_chars_add ('\0');
|
||||
|
||||
util_debug("ASM", "added context function %s to function table\n", name);
|
||||
}
|
||||
|
||||
mem_d(copy);
|
||||
mem_d(name);
|
||||
return true;
|
||||
|
@ -318,6 +393,6 @@ void asm_parse(FILE *fp) {
|
|||
asm_end("asm_parse_end\n");
|
||||
}
|
||||
#undef asm_end
|
||||
asm_dumps();
|
||||
asm_dumps();
|
||||
asm_clear();
|
||||
}
|
||||
|
|
16
code.c
16
code.c
|
@ -147,14 +147,14 @@ void code_test() {
|
|||
|
||||
void code_write() {
|
||||
prog_header code_header = {0};
|
||||
prog_section statements;
|
||||
prog_section defs;
|
||||
prog_section fields;
|
||||
prog_section functions;
|
||||
prog_section globals;
|
||||
prog_section strings;
|
||||
FILE *fp = NULL;
|
||||
size_t it = 1;
|
||||
prog_section statements = {0};
|
||||
prog_section defs = {0};
|
||||
prog_section fields = {0};
|
||||
prog_section functions = {0};
|
||||
prog_section globals = {0};
|
||||
prog_section strings = {0};
|
||||
FILE *fp = NULL;
|
||||
size_t it = 1;
|
||||
|
||||
/* see proposal.txt */
|
||||
if (opts_omit_nullcode) {
|
||||
|
|
|
@ -86,3 +86,6 @@ FUNCTION: checkextension, $99
|
|||
VECTOR: dude1, -1, +2, 38865.444
|
||||
FLOAT: dude2, 1
|
||||
STRING: "hello world"
|
||||
|
||||
FUNCTION: foo #1
|
||||
|
||||
|
|
2
lex.c
2
lex.c
|
@ -318,7 +318,7 @@ int lex_token(lex_file *file) {
|
|||
#undef TEST_TYPE
|
||||
return LEX_IDENT;
|
||||
}
|
||||
return ch;
|
||||
return (ch != ' ') ? ch : lex_token(file);
|
||||
}
|
||||
|
||||
void lex_reset(lex_file *file) {
|
||||
|
|
Loading…
Reference in a new issue