Mercurial > hg > index.cgi
changeset 399:6153cb49403c
Initial commit of pragma newsource
pragma newsource enables a source code variant as follows:
1. no line numbers
2. no implied comments at the end of lines
3. all comments must be introduced by a comment character
4. spaces are allowed in operands
(4) is not quite complete. This commit handles "operandless" instructions
(anything where the parser calls skip_operand()) and expression parsing.
author | William Astle <lost@l-w.ca> |
---|---|
date | Tue, 13 Oct 2015 23:38:02 -0600 |
parents | 4cf907aa634c |
children | bbe5401a9bf3 |
files | lwasm/lwasm.c lwasm/lwasm.h lwasm/pass1.c lwasm/pragma.c lwlib/lw_expr.c lwlib/lw_expr.h |
diffstat | 6 files changed, 89 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/lwasm/lwasm.c Sun Oct 11 09:31:06 2015 -0600 +++ b/lwasm/lwasm.c Tue Oct 13 23:38:02 2015 -0600 @@ -32,6 +32,15 @@ #include "lwasm.h" #include "instab.h" +void lwasm_skip_to_next_token(line_t *cl, char **p) +{ + if (CURPRAGMA(cl, PRAGMA_NEWSOURCE)) + { + for (; **p && isspace(**p); (*p)++) + /* do nothing */ ; + } +} + int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr) { return 0; @@ -869,13 +878,20 @@ if (as->exprwidth != 16) { lw_expr_setwidth(as->exprwidth); - e = lw_expr_parse(p, as); + if (CURPRAGMA(as -> cl, PRAGMA_NEWSOURCE)) + e = lw_expr_parse(p, as); + else + e = lw_expr_parse_compact(p, as); lw_expr_setwidth(0); } else { - e = lw_expr_parse(p, as); + if (CURPRAGMA(as -> cl, PRAGMA_NEWSOURCE)) + e = lw_expr_parse(p, as); + else + e = lw_expr_parse_compact(p, as); } + lwasm_skip_to_next_token(as -> cl, p); return e; } @@ -921,8 +937,10 @@ return NULL; } -void skip_operand(char **p) +void skip_operand_real(line_t *cl, char **p) { + if (CURPRAGMA(cl, PRAGMA_NEWSOURCE)) + return; for (; **p && !isspace(**p); (*p)++) /* do nothing */ ; }
--- a/lwasm/lwasm.h Sun Oct 11 09:31:06 2015 -0600 +++ b/lwasm/lwasm.h Tue Oct 13 23:38:02 2015 -0600 @@ -102,6 +102,7 @@ PRAGMA_M80EXT = 1 << 21, // enable Macro-80C assembler extensions PRAGMA_6809CONV = 1 << 22, // enable 6809 convenience ops PRAGMA_6309CONV = 1 << 23, // enable 6309 convenience ops + PRAGMA_NEWSOURCE = 1 << 24, // don't use compatibility source format PRAGMA_CLEARBIT = 1 << 31 // reserved to indicate negated pragma flag status }; @@ -444,7 +445,9 @@ lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p); int lwasm_emitexpr(line_t *cl, lw_expr_t expr, int s); -void skip_operand(char **p); +void skip_operand_real(line_t *l, char **p); +/* this macro can only be used where "l" is the current line pointer */ +#define skip_operand(p) skip_operand_real(l, p) int lwasm_lookupreg2(const char *rlist, char **p); int lwasm_lookupreg3(const char *rlist, char **p); @@ -472,4 +475,8 @@ #define OPLEN(op) (((op)>0xFF)?2:1) #define CURPRAGMA(l,p) (((l) && ((l)->pragmas & (p))) ? 1 : 0) +/* some functions for parsing */ +/* skip to the start of the next token if the current parsing mode allows it */ +void lwasm_skip_to_next_token(line_t *cl, char **p); + #endif /* ___lwasm_h_seen___ */
--- a/lwasm/pass1.c Sun Oct 11 09:31:06 2015 -0600 +++ b/lwasm/pass1.c Tue Oct 13 23:38:02 2015 -0600 @@ -38,7 +38,7 @@ /* pass 1: parse the lines -line format: +line format if PRAGMA_NEWSOURCE is not in force: [<symbol>] <opcode> <operand>[ <comment>] @@ -48,6 +48,14 @@ white space and must be followed by a single whitespace character. After that whitespace character, the line is parsed as if it had no line number. +Also, no spaces are permitted within <operand>. + +With PRAGMA_NEWSOURCE in effect, line numbers are not allowed and there +is no automatic comment at the end of each line. All comments must be +introduced with the comment character. This allows the parser to handle +spaces in operands unambiguously so in this mode, spaces are permitted +within operands. + */ void do_pass1(asmstate_t *as) { @@ -174,12 +182,12 @@ } // skip comments - // commends do not create a context break + // comments do not create a context break if (*line == '*' || *line == ';' || *line == '#') goto nextline; p1 = line; - if (isdigit(*p1)) + if (isdigit(*p1) && !CURPRAGMA(cl, PRAGMA_NEWSOURCE)) { // skip line number while (*p1 && isdigit(*p1)) @@ -212,8 +220,6 @@ else stspace = 0; -// if (*p1 == '*' || *p1 == ';' || *p1 == '#') -// goto nextline; if (!*p1) { // nothing but whitespace - context break @@ -235,7 +241,7 @@ p1++; for (; *p1 && isspace(*p1); p1++) /* do nothing */ ; - + if (*p1 == '=') { tok = p1++; @@ -263,12 +269,12 @@ } if (*tok) { - if (CURPRAGMA(cl, PRAGMA_TESTMODE)) - { - /* in test mode, terminate the line here so we don't affect the parsers */ - /* (cl -> ltext retains the full, unmodified string) */ - char *t = strstr(p1, ";."); - if (t) *t = 0; + if (CURPRAGMA(cl, PRAGMA_TESTMODE)) + { + /* in test mode, terminate the line here so we don't affect the parsers */ + /* (cl -> ltext retains the full, unmodified string) */ + char *t = strstr(p1, ";."); + if (t) *t = 0; } // look up operation code @@ -371,10 +377,23 @@ else cl -> dlen = cl -> len; } - if (*p1 && !isspace(*p1) && !(cl -> err)) + if (!CURPRAGMA(cl, PRAGMA_NEWSOURCE)) { - // flag bad operand error - lwasm_register_error2(as, cl, E_OPERAND_BAD, "(%s)", p1); + if (*p1 && !isspace(*p1) && !(cl -> err)) + { + // flag bad operand error + lwasm_register_error2(as, cl, E_OPERAND_BAD, "(%s)", p1); + } + } + else + { + lwasm_skip_to_next_token(cl, &p1); + /* if we did not hit the end of the line and we aren't at a comment character, error out */ + if (*p1 && *p1 != ';' && *p1 != '#' && *p1 != ';') + { + // flag bad operand error + lwasm_register_error2(as, cl, E_OPERAND_BAD, "%s", p1); + } } /* do a reduction on the line expressions to avoid carrying excessive expression baggage if not needed */
--- a/lwasm/pragma.c Sun Oct 11 09:31:06 2015 -0600 +++ b/lwasm/pragma.c Tue Oct 13 23:38:02 2015 -0600 @@ -72,6 +72,8 @@ { "m80ext", "nom80ext", PRAGMA_M80EXT }, { "6809conv", "no6809conv", PRAGMA_6809CONV }, { "6309conv", "no6309conv", PRAGMA_6309CONV }, + { "newsource", "nonewsource", PRAGMA_NEWSOURCE }, + { "nooldsource", "oldsource", PRAGMA_NEWSOURCE }, { 0, 0, 0 } };
--- a/lwlib/lw_expr.c Sun Oct 11 09:31:06 2015 -0600 +++ b/lwlib/lw_expr.c Tue Oct 13 23:38:02 2015 -0600 @@ -36,6 +36,7 @@ /* Q&D to break out of infinite recursion */ static int level = 0; static int bailing = 0; +static int parse_compact = 0; static void (*divzero)(void *priv) = NULL; @@ -1141,7 +1142,7 @@ following conditions: 1. a NUL character -2. a whitespace character +2. a whitespace character (if parse mode is "COMPACT") 3. a ) 4. a , 5. any character that is not recognized as a term @@ -1155,19 +1156,29 @@ lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec); +static void lw_expr_parse_next_tok(char **p) +{ + if (parse_compact) + return; + for (; **p && isspace(**p); (*p)++) + /* do nothing */ ; +} + lw_expr_t lw_expr_parse_term(char **p, void *priv) { lw_expr_t term, term2; eval_next: + lw_expr_parse_next_tok(p); + if (!**p || isspace(**p) || **p == ')' || **p == ']') return NULL; - // parentheses if (**p == '(') { (*p)++; term = lw_expr_parse_expr(p, priv, 0); + lw_expr_parse_next_tok(p); if (**p != ')') { lw_expr_destroy(term); @@ -1247,6 +1258,7 @@ int opern, i; lw_expr_t term1, term2, term3; + lw_expr_parse_next_tok(p); if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';') return NULL; @@ -1255,6 +1267,7 @@ return NULL; eval_next: + lw_expr_parse_next_tok(p); if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';') return term1; @@ -1312,9 +1325,17 @@ lw_expr_t lw_expr_parse(char **p, void *priv) { + parse_compact = 0; return lw_expr_parse_expr(p, priv, 0); } +lw_expr_t lw_expr_parse_compact(char **p, void *priv) +{ + parse_compact = 1; + return lw_expr_parse_expr(p, priv, 0); +} + + int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv) { struct lw_expr_opers *o;
--- a/lwlib/lw_expr.h Sun Oct 11 09:31:06 2015 -0600 +++ b/lwlib/lw_expr.h Tue Oct 13 23:38:02 2015 -0600 @@ -90,6 +90,7 @@ void lw_expr_set_term_parser(lw_expr_fn3_t *fn); lw_expr_t lw_expr_parse(char **p, void *priv); +lw_expr_t lw_expr_parse_compact(char **p, void *priv); int lw_expr_istype(lw_expr_t e, int t); int lw_expr_intval(lw_expr_t e); int lw_expr_specint(lw_expr_t e);