]> Shamusworld >> Repos - rmac/commitdiff
Added "-4" switch that enables C style operator precedence (original work by Bastian...
authorggn <ggn@atari.org>
Tue, 31 May 2022 19:42:55 +0000 (22:42 +0300)
committerShamus Hammons <jlhamm@acm.org>
Mon, 27 Jun 2022 16:52:24 +0000 (11:52 -0500)
docs/rmac.rst
expr.c
rmac.c

index 9cddd4b2b9f6f5d0ec4adb5f09a6ec3aaabefbdf..78e2d34cb8fae27ae7f615745a65084666415479 100644 (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.
 
diff --git a/expr.c b/expr.c
index 2361817784d7c0eccab31b9060de867613c1ff7d..5a9155c67832c1ee049d899415a0c924b40b4a07 100644 (file)
--- a/expr.c
+++ b/expr.c
@@ -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;
 }
 
diff --git a/rmac.c b/rmac.c
index 9259d4196aef9b14edf026614d26d38ee0bfeaec..5946105b03b0b68989ec8a19a2979a76aa6071db 100644 (file)
--- a/rmac.c
+++ b/rmac.c
@@ -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;)