# HG changeset patch # User William Astle # Date 1436844030 21600 # Node ID 6ee9c67a0f8d1fc11cb23ad735be1ce25a84b134 # Parent 04e11f6faead04c77f8ffab332e1e59c96cc06cb Add conditional for testing if a pragma is in effect An obvious addition that took someone else to notice... Thanks to Erik G for the patch. diff -r 04e11f6faead -r 6ee9c67a0f8d lwasm/instab.c --- a/lwasm/instab.c Mon Jul 13 21:19:38 2015 -0600 +++ b/lwasm/instab.c Mon Jul 13 21:20:30 2015 -0600 @@ -244,6 +244,10 @@ #define pseudo_resolve_ifndef NULL #define pseudo_emit_ifndef NULL +PARSEFUNC(pseudo_parse_ifpragma); +#define pseudo_resolve_ifpragma NULL +#define pseudo_emit_ifpragma NULL + PARSEFUNC(pseudo_parse_ifstr); #define pseudo_resolve_ifstr NULL #define pseudo_emit_ifstr NULL @@ -657,6 +661,8 @@ { "else", { -1, -1, -1, -1}, pseudo_parse_else, pseudo_resolve_else, pseudo_emit_else, lwasm_insn_cond}, { "ifdef", { -1, -1, -1, -1}, pseudo_parse_ifdef, pseudo_resolve_ifdef, pseudo_emit_ifdef, lwasm_insn_cond}, { "ifndef", { -1, -1, -1, -1}, pseudo_parse_ifndef, pseudo_resolve_ifndef, pseudo_emit_ifndef, lwasm_insn_cond}, + { "ifpragma", { -1, -1, -1, -1}, pseudo_parse_ifpragma, pseudo_resolve_ifpragma, pseudo_emit_ifpragma, lwasm_insn_cond}, + { "ifopt", { -1, -1, -1, -1}, pseudo_parse_ifpragma, pseudo_resolve_ifpragma, pseudo_emit_ifpragma, lwasm_insn_cond}, // string operations, mostly useful in macros { "ifstr", { -1, -1, -1, -1}, pseudo_parse_ifstr, pseudo_resolve_ifstr, pseudo_emit_ifstr, lwasm_insn_cond}, diff -r 04e11f6faead -r 6ee9c67a0f8d lwasm/lwasm.h --- a/lwasm/lwasm.h Mon Jul 13 21:19:38 2015 -0600 +++ b/lwasm/lwasm.h Mon Jul 13 21:20:30 2015 -0600 @@ -99,7 +99,8 @@ PRAGMA_CT = 1 << 18, // enable cycle count running total PRAGMA_CC = 1 << 19, // clear cycle count running total PRAGMA_QRTS = 1 << 20, // enable BRA ?RTS support - PRAGMA_M80EXT = 1 << 21 // enable Macro-80C assembler extensions + PRAGMA_M80EXT = 1 << 21, // enable Macro-80C assembler extensions + PRAGMA_CLEARBIT = 1 << 31 // reserved to indicate negated pragma flag status }; enum @@ -419,6 +420,8 @@ struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags); struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym); +int parse_pragma_helper(char *p); + int lwasm_cycle_calc_ind(line_t *cl); int lwasm_cycle_calc_rlist(line_t *cl); void lwasm_cycle_update_count(line_t *cl, int opc); diff -r 04e11f6faead -r 6ee9c67a0f8d lwasm/pragma.c --- a/lwasm/pragma.c Mon Jul 13 21:19:38 2015 -0600 +++ b/lwasm/pragma.c Mon Jul 13 21:20:30 2015 -0600 @@ -73,40 +73,48 @@ { 0, 0, 0 } }; +int parse_pragma_helper(char *p) +{ + int i; + + for (i = 0; set_pragmas[i].setstr; i++) + { + if (!strcasecmp(p, set_pragmas[i].setstr)) + { + return set_pragmas[i].flag; + return 1; + } + if (!strcasecmp(p, set_pragmas[i].resetstr)) + { + return set_pragmas[i].flag | PRAGMA_CLEARBIT; + return 2; + } + } + + return 0; +} + int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr) { char *p; - int i; const char *np = str; - int pragmas = as -> pragmas; + int pragma; while (np) { p = lw_token(np, ',', &np); - debug_message(as, 200, "Setting pragma %s", p); - for (i = 0; set_pragmas[i].setstr; i++) - { - if (!strcasecmp(p, set_pragmas[i].setstr)) - { - pragmas |= set_pragmas[i].flag; - goto out; - } - if (!strcasecmp(p, set_pragmas[i].resetstr)) - { - pragmas &= ~(set_pragmas[i].flag); - goto out; - } - } - /* unrecognized pragma here */ - if (!ignoreerr) - { - lw_free(p); + debug_message(as, 200, "Setting/resetting pragma %s", p); + pragma = parse_pragma_helper(p); + lw_free(p); + + if (pragma == 0 && !ignoreerr) return 0; - } - out: - lw_free(p); + + if (pragma & PRAGMA_CLEARBIT) + as->pragmas &= ~pragma; + else + as->pragmas |= pragma; } - as -> pragmas = pragmas; return 1; } diff -r 04e11f6faead -r 6ee9c67a0f8d lwasm/pseudo.c --- a/lwasm/pseudo.c Mon Jul 13 21:19:38 2015 -0600 +++ b/lwasm/pseudo.c Mon Jul 13 21:20:30 2015 -0600 @@ -1369,6 +1369,58 @@ } } +PARSEFUNC(pseudo_parse_ifpragma) +{ + char *pstr; + int i; + int pragma; + int compare; + + l -> len = 0; + l -> hideline = 1; + + if (as -> skipcond && !(as -> skipmacro)) + { + as -> skipcount++; + skip_operand(p); + return; + } + +again: + for (i = 0; (*p)[i] && !isspace((*p)[i]) && (*p)[i] != '|' && (*p)[i] != '&'; i++) + /* do nothing */; + + pstr = lw_strndup(*p, i); + (*p) += i; + + pragma = parse_pragma_helper(pstr); + if (!pragma) lwasm_register_error(as, l, E_PRAGMA_UNRECOGNIZED); + + lw_free(pstr); + + if (pragma & PRAGMA_CLEARBIT) + { + pragma &= ~PRAGMA_CLEARBIT; /* strip off flag bit */ + compare = l -> pragmas & pragma ? 0 : 1; + } + else + { + compare = l -> pragmas & pragma; + } + + if (!compare) + { + if (**p == '|') + { + (*p)++; + goto again; + } + as -> skipcond = 1; + as -> skipcount = 1; + } + skip_operand(p); +} + PARSEFUNC(pseudo_parse_error) { lwasm_register_error2(as, l, E_USER_SPECIFIED, "%s", *p);