Added "-4" switch that enables C style operator precedence (original work by Bastian Schick)

This commit is contained in:
ggn 2022-05-31 22:42:55 +03:00 committed by Shamus Hammons
parent 9aa8503cdc
commit 3f937a2ab5
3 changed files with 117 additions and 14 deletions

View File

@ -127,7 +127,7 @@ Switch Description
-fx Atari 800 com/exe/xex output object file format.
-i\ *path* Set include-file directory search path.
-l\ *[file[prn]]* Construct and direct assembly listing to the specified file.
-l\ *\*[filename]* Create an output listing file without pagination
-l\ *\*[filename]* Create an output listing file without pagination.
-m\ *cpu* Switch CPU type
`68000 - MC68000`
@ -203,8 +203,9 @@ Switch Description
-s Warn about unoptimized long branches and applied optimisations.
-u Force referenced and undefined symbols global.
-v Verbose mode (print running dialogue).
-x Turn on debugging mode
-x Turn on debugging mode.
-yn Set listing page size to n lines.
-4 Use C style operator precedence.
file\ *[s]* Assemble the specified file.
=================== ===========
@ -296,6 +297,9 @@ the table.
space), sets the number of lines in a page. RMAC will produce *N* lines
before emitting a form-feed. If *N* is missing or less than 10 an error message is
generated.
**-4**
Use C style order of precedence in expressions. See `Order of Evaluation`_ for more
information.
`Using RMAC`_
===============
@ -425,7 +429,8 @@ necessary to make other assemblers' source code assemble.
character codes. Watch out for GEMDOS path names in ASCII constants -
you will have to convert them to double-backslashes.
* Expression evaluation is done left-to-right without operator precedence. Use parentheses to
force the expression evaluation as you wish.
force the expression evaluation as you wish. Alternatively, use the **-4** switch to switch
to C style precedence. For more information refer to `Order of Evaluation`_.
* Mark your segments across files.
Branching to a code segment that could be identified as BSS will cause a "Error: cannot initialize non-storage (BSS) section"
* In 68020+ mode **Zan** and **Zri** (register suppression) is not supported.
@ -746,6 +751,24 @@ true.
Thus the expression "1+2*3" evaluates to 9, not 7. However, precedence may be
forced with parenthesis (**()**) or square-brackets (**[]**).
All the above behavior is the default. However if the command line switch **-4**
is used, then C style of operator precedence is enforced. The following list
shows the order of precedence in this mode, from lowest to highest:
* bitwise XOR ^
* bitwise OR |
* bitwise AND &
* relational = < <= >= > !=
* shifts << >>
* sum + -
* product * /
`Types`_
'''''''''
Expressions belong to one of three classes: undefined, absolute or relocatable. An
@ -842,7 +865,9 @@ Operator Description
=========== ==============================================
* All binary operators have the same precedence:
expressions are evaluated strictly left to right.
expressions are evaluated strictly left to right,
with the exception of the **-4** switch. For more information
refer to `Order of Evaluation`_.
* Division or modulo by zero yields an assembly error.

91
expr.c
View File

@ -93,24 +93,97 @@ void InitExpression(void)
symbolNum = 0;
}
extern int correctMathRules;
int xor(void);
int and(void);
int rel(void);
int shift(void);
int sum(void);
int product(void);
//
// Binary operators (all the same precedence)
// Binary operators (all the same precedence,
// except if -4 is passed to the command line)
//
#define precedence(HIERARCHY_HIGHER, HIERARCHY_CURRENT) \
do \
{ \
if (HIERARCHY_HIGHER() != OK) \
return ERROR; \
while (tokenClass[*tok] == HIERARCHY_CURRENT) \
{ \
TOKEN t = *tok++; \
if (HIERARCHY_HIGHER() != OK) \
return ERROR; \
*evalTokenBuffer.u32++ = t; \
} \
}while (0)
int expr0(void)
{
if (expr1() != OK)
return ERROR;
while (tokenClass[*tok] >= MULT)
if ( correctMathRules == 0 )
{
TOKEN t = *tok++;
if (expr1() != OK)
return ERROR;
*evalTokenBuffer.u32++ = t;
}
while (tokenClass[*tok] >= MULT)
{
TOKEN t = *tok++;
if (expr1() != OK)
return ERROR;
*evalTokenBuffer.u32++ = t;
}
}
else
{
// The order of C precedence (lower to higher):
// bitwise XOR ^
// bitwise OR |
// bitwise AND &
// relational = < <= >= > !=
// shifts << >>
// sum + -
// product * /
precedence(xor, OR);
}
return OK;
}
int xor(void)
{
precedence(and, XOR);
return OK;
}
int and(void)
{
precedence(rel, AND);
return OK;
}
int rel(void)
{
precedence(shift, REL);
return OK;
}
int shift(void)
{
precedence(sum, SHIFT);
return OK;
}
int sum(void)
{
precedence(product, ADD);
return OK;
}
int product(void)
{
precedence(expr1, MULT);
return OK;
}

7
rmac.c
View File

@ -60,6 +60,7 @@ int activecpu = CPU_68000; // Active 68k CPU (68000 by default)
int activefpu = FPU_NONE; // Active FPU (none by default)
int org68k_active = 0; // .org switch for 68k (only with RAW output format)
uint32_t org68k_address; // .org for 68k
int correctMathRules; // 1, use C operator precedence in expressions
//
// Convert a string to uppercase
@ -206,6 +207,7 @@ void DisplayHelp(void)
" -v Set verbose mode\n"
" -x Turn on debugging mode\n"
" -y[pagelen] Set page line length (default: 61)\n"
" -4 Use C style operator precedence\n"
"\n", cmdlnexec);
}
@ -334,7 +336,7 @@ int Process(int argc, char ** argv)
regtab = reg68tab; // Idem
regcheck = reg68check; // Idem
regaccept = reg68accept; // Idem
correctMathRules = 0; // respect operator precedence
// Initialize modules
InitSymbolTable(); // Symbol table
InitTokenizer(); // Tokenizer
@ -353,6 +355,9 @@ int Process(int argc, char ** argv)
{
switch (argv[argno][1])
{
case '4':
correctMathRules = 1;
break;
case 'd': // Define symbol
case 'D':
for(s=argv[argno]+2; *s!=EOS;)