-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`
-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.
=================== ===========
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`_
===============
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.
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
=========== ==============================================
* 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.
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;
}
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
" -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);
}
regtab = reg68tab; // Idem
regcheck = reg68check; // Idem
regaccept = reg68accept; // Idem
-
+ correctMathRules = 0; // respect operator precedence
// Initialize modules
InitSymbolTable(); // Symbol table
InitTokenizer(); // Tokenizer
{
switch (argv[argno][1])
{
+ case '4':
+ correctMathRules = 1;
+ break;
case 'd': // Define symbol
case 'D':
for(s=argv[argno]+2; *s!=EOS;)