From 888192a9eaf8772841c3ffc2bef2e40336b49445 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 17 Mar 2020 01:42:46 +0900 Subject: [PATCH] [qfcc] Resurrect ex_def expression type It turns out to be useful still as using symbol expressions isn't always appropriate and the workarounds were getting nasty. --- tools/qfcc/include/expr.h | 8 ++++++++ tools/qfcc/source/dot_expr.c | 11 +++++++++++ tools/qfcc/source/expr.c | 21 +++++++++++++++++++++ tools/qfcc/source/expr_assign.c | 2 ++ tools/qfcc/source/statements.c | 9 +++++++++ 5 files changed, 51 insertions(+) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 836ec864d..dc3a84f63 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -49,6 +49,7 @@ typedef enum { ex_block, ///< statement block expression (::ex_block_t) ex_expr, ///< binary expression (::ex_expr_t) ex_uexpr, ///< unary expression (::ex_expr_t) + ex_def, ///< non-temporary variable (::def_t) ex_symbol, ///< non-temporary variable (::symbol_t) ex_temp, ///< temporary variable (::ex_temp_t) ex_vector, ///< "vector" expression (::ex_vector_t) @@ -230,6 +231,7 @@ typedef struct expr_s { ex_bool_t bool; ///< boolean logic expression ex_block_t block; ///< statement block expression ex_expr_t expr; ///< binary or unary expression + struct def_s *def; ///< def reference expression struct symbol_s *symbol; ///< symbol reference expression ex_temp_t temp; ///< temporary variable expression ex_vector_t vector; ///< vector expression list @@ -411,6 +413,12 @@ expr_t *new_binary_expr (int op, expr_t *e1, expr_t *e2); */ expr_t *new_unary_expr (int op, expr_t *e1); +/** Create a new def reference (non-temporary variable) expression node. + + \return The new def reference expression node (::def_t). +*/ +expr_t *new_def_expr (struct def_s *def); + /** Create a new symbol reference (non-temporary variable) expression node. \return The new symbol reference expression node (::symbol_t). diff --git a/tools/qfcc/source/dot_expr.c b/tools/qfcc/source/dot_expr.c index 76bd21089..27d535845 100644 --- a/tools/qfcc/source/dot_expr.c +++ b/tools/qfcc/source/dot_expr.c @@ -62,6 +62,7 @@ const char *expr_names[] = "block", "expr", "uexpr", + "def", "symbol", "temp", "vector", @@ -354,6 +355,15 @@ print_uexpr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next) dstring_delete (typestr); } +static void +print_def (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next) +{ + int indent = level * 2 + 2; + + dasprintf (dstr, "%*se_%p [label=\"d %s\\n%d\"];\n", indent, "", e, + e->e.def->name, e->line); +} + static void print_symbol (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next) { @@ -542,6 +552,7 @@ _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next) print_block, print_subexpr, print_uexpr, + print_def, print_symbol, print_temp, print_vector, diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 2cd64dc13..8eeea76c1 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -239,6 +239,8 @@ get_type (expr_t *e) case ex_expr: case ex_uexpr: return e->e.expr.type; + case ex_def: + return e->e.def->type; case ex_symbol: return e->e.symbol->type; case ex_temp: @@ -342,6 +344,7 @@ copy_expr (expr_t *e) return 0; switch (e->type) { case ex_error: + case ex_def: case ex_symbol: case ex_nil: case ex_value: @@ -610,6 +613,15 @@ new_unary_expr (int op, expr_t *e1) return e; } +expr_t * +new_def_expr (def_t *def) +{ + expr_t *e = new_expr (); + e->type = ex_def; + e->e.def = def; + return e; +} + expr_t * new_symbol_expr (symbol_t *symbol) { @@ -1542,6 +1554,13 @@ unary_expr (int op, expr_t *e) n->e.expr.type = e->e.expr.type; return n; } + case ex_def: + { + expr_t *n = new_unary_expr (op, e); + + n->e.expr.type = e->e.def->type; + return n; + } case ex_symbol: { expr_t *n = new_unary_expr (op, e); @@ -1602,6 +1621,7 @@ unary_expr (int op, expr_t *e) return error (e, "invalid type for unary !"); case ex_uexpr: case ex_expr: + case ex_def: case ex_symbol: case ex_temp: case ex_vector: @@ -1671,6 +1691,7 @@ unary_expr (int op, expr_t *e) goto bitnot_expr; case ex_expr: case ex_bool: + case ex_def: case ex_symbol: case ex_temp: case ex_vector: diff --git a/tools/qfcc/source/expr_assign.c b/tools/qfcc/source/expr_assign.c index 88d45ad7b..7d1f1aab9 100644 --- a/tools/qfcc/source/expr_assign.c +++ b/tools/qfcc/source/expr_assign.c @@ -85,6 +85,8 @@ int is_lvalue (const expr_t *expr) { switch (expr->type) { + case ex_def: + return !expr->e.def->constant; case ex_symbol: switch (expr->e.symbol->sy_type) { case sy_name: diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 1733700fd..a950842e5 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -1267,6 +1267,13 @@ expr_uexpr (sblock_t *sblock, expr_t *e, operand_t **op) return sblock; } +static sblock_t * +expr_def (sblock_t *sblock, expr_t *e, operand_t **op) +{ + *op = def_operand (e->e.def, e->e.def->type, e); + return sblock; +} + static sblock_t * expr_symbol (sblock_t *sblock, expr_t *e, operand_t **op) { @@ -1398,6 +1405,7 @@ statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op) expr_block, // ex_block expr_expr, expr_uexpr, + expr_def, expr_symbol, expr_temp, expr_vector_e, // ex_vector @@ -1715,6 +1723,7 @@ statement_slist (sblock_t *sblock, expr_t *e) statement_block, statement_expr, statement_uexpr, + statement_nonexec, // ex_def statement_nonexec, // ex_symbol statement_nonexec, // ex_temp statement_nonexec, // ex_vector