From: Dale Weiler Date: Tue, 1 May 2012 22:05:11 +0000 (-0400) Subject: Assembly statement parsing X-Git-Tag: 0.1-rc1~514^2~4 X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;ds=sidebyside;h=629f6f1e634a6bdd1f3494505d0c4173c293fadf;p=xonotic%2Fgmqcc.git Assembly statement parsing --- diff --git a/asm.c b/asm.c index 6539e16..24b9e0d 100644 --- a/asm.c +++ b/asm.c @@ -348,7 +348,9 @@ 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'); - + + /* update assembly state */ + *state = ASM_FUNCTION; util_debug("ASM", "added context function %s to function table\n", name); } @@ -359,6 +361,69 @@ static GMQCC_INLINE bool asm_parse_func(const char *skip, size_t line, asm_state return false; } +static GMQCC_INLINE bool asm_parse_stmt(const char *skip, size_t line, asm_state *state) { + /* + * This parses a valid statement in assembly and adds it to the code + * table to be wrote. This needs to handle correct checking of all + * statements to ensure the correct amount of operands are passed to + * the menomic. This must also check for valid function calls (ensure + * the names selected exist in the program scope) and ensure the correct + * CALL* is used (depending on the amount of arguments the function + * is expected to take) + */ + char *c = NULL; + prog_section_statement s; + size_t i = 0; + + for (; i < sizeof(asm_instr)/sizeof(*asm_instr); i++) { + /* + * Iterate all possible instructions and check if the selected + * instructure in the input stream `skip` is actually a valid + * instruction. + */ + if (strstr(skip, asm_instr[i].m) == &skip[0]) { + /* + * Parse the operands for `i` (the instruction). The order + * of asm_instr is in the order of the menomic encoding so + * `i` == menomic encoding. + */ + s.opcode = i; + switch (asm_instr[i].o) { + /* + * Each instruction can have from 0-3 operands; and can + * be used with less or more operands depending on it's + * selected use. + * + * DONE for example can use either 0 operands, or 1 (to + * emulate the effect of RETURN) + */ + default: + skip += asm_instr[i].l+1; + /* skip whitespace */ + while (*skip == ' ' || *skip == '\t') + skip++; + /* + * TODO: parse operands correctly figure out what it is + * that the assembly is trying to do, i.e string table + * lookup, function calls etc. + * + * This needs to have a fall state, we start from the + * end of the string and work backwards. + */ + case '3': + s.o3.s1 = 0; + case '2': + s.o2.s1 = 0; + case '1': + s.o1.s1 = 0; + } + /* add the statement now */ + code_statements_add(s); + } + } + return true; +} + void asm_parse(FILE *fp) { char *data = NULL; char *skip = NULL; @@ -379,9 +444,11 @@ void asm_parse(FILE *fp) { skip = util_strrnl(copy); /* delete newline */ /* parse type */ - if(asm_parse_type(skip, line, &state)){ asm_end("asm_parse_type\n"); } + if (asm_parse_type(skip, line, &state)) { asm_end("asm_parse_type\n"); } /* parse func */ - if(asm_parse_func(skip, line, &state)){ asm_end("asm_parse_func\n"); } + if (asm_parse_func(skip, line, &state)) { asm_end("asm_parse_func\n"); } + /* parse stmt */ + if (asm_parse_stmt(skip, line, &state)) { asm_end("asm_parse_stmt\n"); } /* statement closure */ if (state == ASM_FUNCTION && ( diff --git a/data/test.qs b/data/test.qs index 26b0aeb..5420d75 100644 --- a/data/test.qs +++ b/data/test.qs @@ -84,8 +84,7 @@ FUNCTION: checkextension, $99 ; constants test VECTOR: dude1, -1, +2, 38865.444 -FLOAT: dude2, 1 -STRING: "hello world" - -FUNCTION: foo #1 +FUNCTION: foo #8 + MUL_F dude1, dude1, dude1 + CALL1 print, dude1 diff --git a/gmqcc.h b/gmqcc.h index c88c822..032566a 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -369,13 +369,13 @@ typedef struct { } o1; /* operand 2 */ union { - int16_t s2; /* signed */ - uint16_t u2; /* unsigned */ + int16_t s1; /* signed */ + uint16_t u1; /* unsigned */ } o2; /* operand 3 */ union { - int16_t s3; /* signed */ - uint16_t u3; /* unsigned */ + int16_t s1; /* signed */ + uint16_t u1; /* unsigned */ } o3; /*