]> git.sur5r.net Git - cc65/blob - src/ca65/expr.c
b0eb0503c9ad351238be66bad8319d9312f72351
[cc65] / src / ca65 / expr.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                  expr.c                                   */
4 /*                                                                           */
5 /*             Expression evaluation for the ca65 macroassembler             */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
10 /*               Römerstraße 52                                              */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <string.h>
37 #include <time.h>
38
39 /* common */
40 #include "check.h"
41 #include "cpu.h"
42 #include "exprdefs.h"
43 #include "print.h"
44 #include "shift.h"
45 #include "tgttrans.h"
46 #include "version.h"
47 #include "xmalloc.h"
48
49 /* ca65 */
50 #include "error.h"
51 #include "expr.h"
52 #include "global.h"
53 #include "instr.h"
54 #include "nexttok.h"
55 #include "objfile.h"
56 #include "segment.h"
57 #include "symbol.h"
58 #include "symtab.h"
59 #include "toklist.h"
60 #include "ulabel.h"
61
62
63
64 /*****************************************************************************/
65 /*                                   Data                                    */
66 /*****************************************************************************/
67
68
69
70 /* Since all expressions are first packed into expression trees, and each
71  * expression tree node is allocated on the heap, we add some type of special
72  * purpose memory allocation here: Instead of freeing the nodes, we save some
73  * number of freed nodes for later and remember them in a single linked list
74  * using the Left link.
75  */
76 #define MAX_FREE_NODES  64
77 static ExprNode*        FreeExprNodes = 0;
78 static unsigned         FreeNodeCount = 0;
79
80 /* Structure for parsing expression trees */
81 typedef struct ExprDesc ExprDesc;
82 struct ExprDesc {
83     long        Val;            /* The offset value */
84     long        Left;           /* Left value for StudyBinaryExpr */
85     int         TooComplex;     /* Expression is too complex to evaluate */
86     long        SymCount;       /* Symbol reference count */
87     long        SecCount;       /* Section reference count */
88     SymEntry*   SymRef;         /* Symbol reference if any */
89     unsigned    SecRef;         /* Section reference if any */
90 };
91
92
93
94
95 /*****************************************************************************/
96 /*                                 Forwards                                  */
97 /*****************************************************************************/
98
99
100
101 static void StudyExpr (ExprNode* Expr, ExprDesc* D, int Sign);
102 /* Study an expression tree and place the contents into D */
103
104
105
106 /*****************************************************************************/
107 /*                                  Helpers                                  */
108 /*****************************************************************************/
109
110
111
112 static ExprDesc* InitExprDesc (ExprDesc* ED)
113 /* Initialize an ExprDesc structure for use with StudyExpr */
114 {
115     ED->Val        = 0;
116     ED->TooComplex = 0;
117     ED->SymCount   = 0;
118     ED->SecCount   = 0;
119     return ED;
120 }
121
122
123
124 static int ExprDescIsConst (const ExprDesc* ED)
125 /* Return true if the expression is constant */
126 {
127     return (ED->TooComplex == 0 && ED->SymCount == 0 && ED->SecCount == 0);
128 }
129
130
131
132 static ExprNode* NewExprNode (unsigned Op)
133 /* Create a new expression node */
134 {
135     ExprNode* N;
136
137     /* Do we have some nodes in the list already? */
138     if (FreeExprNodes) {
139         /* Use first node from list */
140         N = FreeExprNodes;
141         FreeExprNodes = N->Left;
142     } else {
143         /* Allocate fresh memory */
144         N = xmalloc (sizeof (ExprNode));
145     }
146     N->Op = Op;
147     N->Left = N->Right = 0;
148     N->Obj = 0;
149
150     return N;
151 }
152
153
154
155 static void FreeExprNode (ExprNode* E)
156 /* Free a node */
157 {
158     if (E) {
159         if (E->Op == EXPR_SYMBOL) {
160             /* Remove the symbol reference */
161             SymDelExprRef (E->V.Sym, E);
162         }
163         /* Place the symbol into the free nodes list if possible */
164         if (FreeNodeCount < MAX_FREE_NODES) {
165             /* Remember this node for later */
166             E->Left = FreeExprNodes;
167             FreeExprNodes = E;
168         } else {
169             /* Free the memory */
170             xfree (E);
171         }
172     }
173 }
174
175
176
177 /*****************************************************************************/
178 /*                                   Code                                    */
179 /*****************************************************************************/
180
181
182
183 static ExprNode* Expr0 (void);
184
185
186
187 int IsByteRange (long Val)
188 /* Return true if this is a byte value */
189 {
190     return (Val & ~0xFFL) == 0;
191 }
192
193
194
195 int IsWordRange (long Val)
196 /* Return true if this is a word value */
197 {
198     return (Val & ~0xFFFF) == 0;
199 }
200
201
202
203 static int IsEasyConst (const ExprNode* E, long* Val)
204 /* Do some light checking if the given node is a constant. Don't care if E is
205  * a complex expression. If E is a constant, return true and place its value
206  * into Val, provided that Val is not NULL.
207  */
208 {
209     /* Resolve symbols, follow symbol chains */
210     while (E->Op == EXPR_SYMBOL) {
211         E = SymResolve (E->V.Sym);
212         if (E == 0) {
213             /* Could not resolve */
214             return 0;
215         }
216     }
217
218     /* Symbols resolved, check for a literal */
219     if (E->Op == EXPR_LITERAL) {
220         if (Val) {
221             *Val = E->V.Val;
222         }
223         return 1;
224     }
225
226     /* Not found to be a const according to our tests */
227     return 0;
228 }
229
230
231
232 static int FuncBlank (void)
233 /* Handle the .BLANK builtin function */
234 {
235     /* Assume no tokens if the closing brace follows (this is not correct in
236      * all cases, since the token may be the closing brace, but this will
237      * give a syntax error anyway and may not be handled by .BLANK.
238      */
239     if (Tok == TOK_RPAREN) {
240         /* No tokens */
241         return 1;
242     } else {
243         /* Skip any tokens */
244         int Braces = 0;
245         while (!TokIsSep (Tok)) {
246             if (Tok == TOK_LPAREN) {
247                 ++Braces;
248             } else if (Tok == TOK_RPAREN) {
249                 if (Braces == 0) {
250                     /* Done */
251                     break;
252                 } else {
253                     --Braces;
254                 }
255             }
256             NextTok ();
257         }
258         return 0;
259     }
260 }
261
262
263
264 static int FuncConst (void)
265 /* Handle the .CONST builtin function */
266 {
267     /* Read an expression */
268     ExprNode* Expr = Expression ();
269
270     /* Check the constness of the expression */
271     int Result = IsConstExpr (Expr, 0);
272
273     /* Free the expression */
274     FreeExpr (Expr);
275
276     /* Done */
277     return Result;
278 }
279
280
281
282 static int FuncDefined (void)
283 /* Handle the .DEFINED builtin function */
284 {
285     /* Parse the symbol name and search for the symbol */
286     SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
287
288     /* Check if the symbol is defined */
289     return (Sym != 0 && SymIsDef (Sym));
290 }
291
292
293
294 static int DoMatch (enum TC EqualityLevel)
295 /* Handle the .MATCH and .XMATCH builtin functions */
296 {
297     int Result;
298     TokNode* Root = 0;
299     TokNode* Last = 0;
300     TokNode* Node = 0;
301
302     /* A list of tokens follows. Read this list and remember it building a
303      * single linked list of tokens including attributes. The list is
304      * terminated by a comma.
305      */
306     while (Tok != TOK_COMMA) {
307
308         /* We may not end-of-line of end-of-file here */
309         if (TokIsSep (Tok)) {
310             Error ("Unexpected end of line");
311             return 0;
312         }
313
314         /* Get a node with this token */
315         Node = NewTokNode ();
316
317         /* Insert the node into the list */
318         if (Last == 0) {
319             Root = Node;
320         } else {
321             Last->Next = Node;
322         }
323         Last = Node;
324
325         /* Skip the token */
326         NextTok ();
327     }
328
329     /* Skip the comma */
330     NextTok ();
331
332     /* Read the second list which is terminated by the right parenthesis and
333      * compare each token against the one in the first list.
334      */
335     Result = 1;
336     Node = Root;
337     while (Tok != TOK_RPAREN) {
338
339         /* We may not end-of-line of end-of-file here */
340         if (TokIsSep (Tok)) {
341             Error ("Unexpected end of line");
342             return 0;
343         }
344
345         /* Compare the tokens if the result is not already known */
346         if (Result != 0) {
347             if (Node == 0) {
348                 /* The second list is larger than the first one */
349                 Result = 0;
350             } else if (TokCmp (Node) < EqualityLevel) {
351                 /* Tokens do not match */
352                 Result = 0;
353             }
354         }
355
356         /* Next token in first list */
357         if (Node) {
358             Node = Node->Next;
359         }
360
361         /* Next token in current list */
362         NextTok ();
363     }
364
365     /* Check if there are remaining tokens in the first list */
366     if (Node != 0) {
367         Result = 0;
368     }
369
370     /* Free the token list */
371     while (Root) {
372         Node = Root;
373         Root = Root->Next;
374         FreeTokNode (Node);
375     }
376
377     /* Done, return the result */
378     return Result;
379 }
380
381
382
383 static int FuncMatch (void)
384 /* Handle the .MATCH function */
385 {
386     return DoMatch (tcSameToken);
387 }
388
389
390
391 static int FuncReferenced (void)
392 /* Handle the .REFERENCED builtin function */
393 {
394     /* Parse the symbol name and search for the symbol */
395     SymEntry* Sym = ParseScopedSymName (SYM_FIND_EXISTING);
396
397     /* Check if the symbol is referenced */
398     return (Sym != 0 && SymIsRef (Sym));
399 }
400
401
402
403 static int FuncStrAt (void)
404 /* Handle the .STRAT function */
405 {
406     char Str [sizeof(SVal)];
407     long Index;
408
409     /* String constant expected */
410     if (Tok != TOK_STRCON) {
411         Error ("String constant expected");
412         NextTok ();
413         return 0;
414
415     }
416
417     /* Remember the string and skip it */
418     strcpy (Str, SVal);
419     NextTok ();
420
421     /* Comma must follow */
422     ConsumeComma ();
423
424     /* Expression expected */
425     Index = ConstExpression ();
426
427     /* Must be a valid index */
428     if (Index >= (long) strlen (Str)) {
429         Error ("Range error");
430         return 0;
431     }
432
433     /* Return the char, handle as unsigned. Be sure to translate it into
434      * the target character set.
435      */
436     return (unsigned char) TgtTranslateChar (Str [(size_t)Index]);
437 }
438
439
440
441 static int FuncStrLen (void)
442 /* Handle the .STRLEN function */
443 {
444     /* String constant expected */
445     if (Tok != TOK_STRCON) {
446
447         Error ("String constant expected");
448         /* Smart error recovery */
449         if (Tok != TOK_RPAREN) {
450             NextTok ();
451         }
452         return 0;
453
454     } else {
455
456         /* Get the length of the string */
457         int Len = strlen (SVal);
458
459         /* Skip the string */
460         NextTok ();
461
462         /* Return the length */
463         return Len;
464
465     }
466 }
467
468
469
470 static int FuncTCount (void)
471 /* Handle the .TCOUNT function */
472 {
473     /* We have a list of tokens that ends with the closing paren. Skip
474      * the tokens, handling nested braces and count them.
475      */
476     int      Count  = 0;
477     unsigned Parens = 0;
478     while (Parens != 0 || Tok != TOK_RPAREN) {
479
480         /* Check for end of line or end of input. Since the calling function
481          * will check for the closing paren, we don't need to print an error
482          * here, just bail out.
483          */
484         if (TokIsSep (Tok)) {
485             break;
486         }
487
488         /* One more token */
489         ++Count;
490
491         /* Keep track of the nesting level */
492         switch (Tok) {
493             case TOK_LPAREN:    ++Parens;       break;
494             case TOK_RPAREN:    --Parens;       break;
495             default:                            break;
496         }
497
498         /* Skip the token */
499         NextTok ();
500     }
501
502     /* Return the number of tokens */
503     return Count;
504 }
505
506
507
508 static int FuncXMatch (void)
509 /* Handle the .XMATCH function */
510 {
511     return DoMatch (tcIdentical);
512 }
513
514
515
516 static ExprNode* Function (int (*F) (void))
517 /* Handle builtin functions */
518 {
519     long Result;
520
521     /* Skip the keyword */
522     NextTok ();
523
524     /* Expression must be enclosed in braces */
525     if (Tok != TOK_LPAREN) {
526         Error ("'(' expected");
527         SkipUntilSep ();
528         return GenLiteralExpr (0);
529     }
530     NextTok ();
531
532     /* Call the function itself */
533     Result = F ();
534
535     /* Closing brace must follow */
536     ConsumeRParen ();
537
538     /* Return an expression node with the boolean code */
539     return GenLiteralExpr (Result);
540 }
541
542
543
544 static ExprNode* Factor (void)
545 {
546     ExprNode* L;
547     ExprNode* N;
548     SymEntry* S;
549     long      Val;
550
551     switch (Tok) {
552
553         case TOK_INTCON:
554             N = GenLiteralExpr (IVal);
555             NextTok ();
556             break;
557
558         case TOK_CHARCON:
559             N = GenLiteralExpr (TgtTranslateChar (IVal));
560             NextTok ();
561             break;
562
563         case TOK_NAMESPACE:
564         case TOK_IDENT:
565             /* Search for the symbol */
566             S = ParseScopedSymName (SYM_ALLOC_NEW);
567             if (S == 0) {
568                 /* Some weird error happened before */
569                 N = GenLiteralExpr (0);
570             } else {
571                 /* Mark the symbol as referenced */
572                 SymRef (S);
573                 /* Remove the symbol if possible */
574                 if (SymHasExpr (S)) {
575                     N = CloneExpr (GetSymExpr (S));
576                 } else {
577                     /* Create symbol node */
578                     N = GenSymExpr (S);
579                 }
580             }
581             break;
582
583         case TOK_ULABEL:
584             N = ULabRef (IVal);
585             NextTok ();
586             break;
587
588         case TOK_MINUS:
589             NextTok ();
590             L = Factor ();
591             if (IsEasyConst (L, &Val)) {
592                 FreeExpr (L);
593                 N = GenLiteralExpr (-Val);
594             } else {
595                 N = NewExprNode (EXPR_UNARY_MINUS);
596                 N->Left = L;
597             }
598             break;
599
600         case TOK_NOT:
601             NextTok ();
602             L = Factor ();
603             if (IsEasyConst (L, &Val)) {
604                 FreeExpr (L);
605                 N = GenLiteralExpr (~Val);
606             } else {
607                 N = NewExprNode (EXPR_NOT);
608                 N->Left = L;
609             }
610             break;
611
612         case TOK_STAR:
613         case TOK_PC:
614             NextTok ();
615             N = GenCurrentPC ();
616             break;
617
618         case TOK_LT:
619             NextTok ();
620             L = Factor ();
621             if (IsEasyConst (L, &Val)) {
622                 FreeExpr (L);
623                 N = GenLiteralExpr (Val & 0xFF);
624             } else {
625                 N = NewExprNode (EXPR_BYTE0);
626                 N->Left = L;
627             }
628             break;
629
630         case TOK_GT:
631             NextTok ();
632             L = Factor ();
633             if (IsEasyConst (L, &Val)) {
634                 FreeExpr (L);
635                 N = GenLiteralExpr ((Val >> 8) & 0xFF);
636             } else {
637                 N = NewExprNode (EXPR_BYTE1);
638                 N->Left = L;
639             }
640             break;
641
642         case TOK_BANK:
643             NextTok ();
644             L = Factor ();
645             if (IsEasyConst (L, &Val)) {
646                 FreeExpr (L);
647                 N = GenLiteralExpr ((Val >> 16) & 0xFF);
648             } else {
649                 N = NewExprNode (EXPR_BYTE2);
650                 N->Left = L;
651             }
652             break;
653
654         case TOK_LPAREN:
655             NextTok ();
656             N = Expr0 ();
657             ConsumeRParen ();
658             break;
659
660         case TOK_BLANK:
661             N = Function (FuncBlank);
662             break;
663
664         case TOK_CONST:
665             N = Function (FuncConst);
666             break;
667
668         case TOK_CPU:
669             N = GenLiteralExpr (CPUIsets[CPU]);
670             NextTok ();
671             break;
672
673         case TOK_DEFINED:
674             N = Function (FuncDefined);
675             break;
676
677         case TOK_MATCH:
678             N = Function (FuncMatch);
679             break;
680
681         case TOK_REFERENCED:
682             N = Function (FuncReferenced);
683             break;
684
685         case TOK_STRAT:
686             N = Function (FuncStrAt);
687             break;
688
689         case TOK_STRLEN:
690             N = Function (FuncStrLen);
691             break;
692
693         case TOK_TCOUNT:
694             N = Function (FuncTCount);
695             break;
696
697         case TOK_TIME:
698             N = GenLiteralExpr (time (0));
699             NextTok ();
700             break;
701
702         case TOK_VERSION:
703             N = GenLiteralExpr (VERSION);
704             NextTok ();
705             break;
706
707         case TOK_XMATCH:
708             N = Function (FuncXMatch);
709             break;
710
711         default:
712             if (LooseCharTerm && Tok == TOK_STRCON && strlen(SVal) == 1) {
713                 /* A character constant */
714                 N = GenLiteralExpr (TgtTranslateChar (SVal[0]));
715             } else {
716                 N = GenLiteralExpr (0); /* Dummy */
717                 Error ("Syntax error");
718             }
719             NextTok ();
720             break;
721     }
722     return N;
723 }
724
725
726
727 static ExprNode* Term (void)
728 {
729     /* Read left hand side */
730     ExprNode* Root = Factor ();
731
732     /* Handle multiplicative operations */
733     while (Tok == TOK_MUL || Tok == TOK_DIV || Tok == TOK_MOD ||
734            Tok == TOK_AND || Tok == TOK_XOR || Tok == TOK_SHL ||
735            Tok == TOK_SHR) {
736
737         long LVal, RVal, Val;
738         ExprNode* Left;
739         ExprNode* Right;
740
741         /* Remember the token and skip it */
742         enum Token T = Tok;
743         NextTok ();
744
745         /* Move root to left side and read the right side */
746         Left  = Root;
747         Right = Factor ();
748
749         /* If both expressions are constant, we can evaluate the term */
750         if (IsEasyConst (Left, &LVal) && IsEasyConst (Right, &RVal)) {
751
752             switch (T) {
753                 case TOK_MUL:
754                     Val = LVal * RVal;
755                     break;
756
757                 case TOK_DIV:
758                     if (RVal == 0) {
759                         Error ("Division by zero");
760                         Val = 1;
761                     } else {
762                         Val = LVal / RVal;
763                     }
764                     break;
765
766                 case TOK_MOD:
767                     if (RVal == 0) {
768                         Error ("Modulo operation with zero");
769                         Val = 1;
770                     } else {
771                         Val = LVal % RVal;
772                     }
773                     break;
774
775                 case TOK_AND:
776                     Val = LVal & RVal;
777                     break;
778
779                 case TOK_XOR:
780                     Val = LVal ^ RVal;
781                     break;
782
783                 case TOK_SHL:
784                     Val = shl_l (LVal, RVal);
785                     break;
786
787                 case TOK_SHR:
788                     Val = shr_l (LVal, RVal);
789                     break;
790
791                 default:
792                     Internal ("Invalid token");
793             }
794
795             /* Generate a literal expression and delete the old left and
796              * right sides.
797              */
798             FreeExpr (Left);
799             FreeExpr (Right);
800             Root = GenLiteralExpr (Val);
801
802         } else {
803
804             /* Generate an expression tree */
805             unsigned char Op;
806             switch (T) {
807                 case TOK_MUL:   Op = EXPR_MUL;  break;
808                 case TOK_DIV:   Op = EXPR_DIV;  break;
809                 case TOK_MOD:   Op = EXPR_MOD;  break;
810                 case TOK_AND:   Op = EXPR_AND;  break;
811                 case TOK_XOR:   Op = EXPR_XOR;  break;
812                 case TOK_SHL:   Op = EXPR_SHL;  break;
813                 case TOK_SHR:   Op = EXPR_SHR;  break;
814                 default:        Internal ("Invalid token");
815             }
816             Root        = NewExprNode (Op);
817             Root->Left  = Left;
818             Root->Right = Right;
819
820         }
821
822     }
823
824     /* Return the expression tree we've created */
825     return Root;
826 }
827
828
829
830 static ExprNode* SimpleExpr (void)
831 {
832     /* Read left hand side */
833     ExprNode* Root = Term ();
834
835     /* Handle additive operations */
836     while (Tok == TOK_PLUS || Tok == TOK_MINUS || Tok == TOK_OR) {
837
838         long LVal, RVal, Val;
839         ExprNode* Left;
840         ExprNode* Right;
841
842         /* Remember the token and skip it */
843         enum Token T = Tok;
844         NextTok ();
845
846         /* Move root to left side and read the right side */
847         Left  = Root;
848         Right = Term ();
849
850         /* If both expressions are constant, we can evaluate the term */
851         if (IsEasyConst (Left, &LVal) && IsEasyConst (Right, &RVal)) {
852
853             switch (T) {
854                 case TOK_PLUS:  Val = LVal + RVal;      break;
855                 case TOK_MINUS: Val = LVal - RVal;      break;
856                 case TOK_OR:    Val = LVal | RVal;      break;
857                 default:        Internal ("Invalid token");
858             }
859
860             /* Generate a literal expression and delete the old left and
861              * right sides.
862              */
863             FreeExpr (Left);
864             FreeExpr (Right);
865             Root = GenLiteralExpr (Val);
866
867         } else {
868
869             /* Generate an expression tree */
870             unsigned char Op;
871             switch (T) {
872                 case TOK_PLUS:  Op = EXPR_PLUS;  break;
873                 case TOK_MINUS: Op = EXPR_MINUS; break;
874                 case TOK_OR:    Op = EXPR_OR;    break;
875                 default:        Internal ("Invalid token");
876             }
877             Root        = NewExprNode (Op);
878             Root->Left  = Left;
879             Root->Right = Right;
880
881         }
882     }
883
884     /* Return the expression tree we've created */
885     return Root;
886 }
887
888
889
890 static ExprNode* BoolExpr (void)
891 /* Evaluate a boolean expression */
892 {
893     /* Read left hand side */
894     ExprNode* Root = SimpleExpr ();
895
896     /* Handle booleans */
897     while (Tok == TOK_EQ || Tok == TOK_NE || Tok == TOK_LT ||
898            Tok == TOK_GT || Tok == TOK_LE || Tok == TOK_GE) {
899
900         long LVal, RVal, Val;
901         ExprNode* Left;
902         ExprNode* Right;
903
904         /* Remember the token and skip it */
905         enum Token T = Tok;
906         NextTok ();
907
908         /* Move root to left side and read the right side */
909         Left  = Root;
910         Right = SimpleExpr ();
911
912         /* If both expressions are constant, we can evaluate the term */
913         if (IsEasyConst (Left, &LVal) && IsEasyConst (Right, &RVal)) {
914
915             switch (T) {
916                 case TOK_EQ:    Val = (LVal == RVal);   break;
917                 case TOK_NE:    Val = (LVal != RVal);   break;
918                 case TOK_LT:    Val = (LVal < RVal);    break;
919                 case TOK_GT:    Val = (LVal > RVal);    break;
920                 case TOK_LE:    Val = (LVal <= RVal);   break;
921                 case TOK_GE:    Val = (LVal >= RVal);   break;
922                 default:        Internal ("Invalid token");
923             }
924
925             /* Generate a literal expression and delete the old left and
926              * right sides.
927              */
928             FreeExpr (Left);
929             FreeExpr (Right);
930             Root = GenLiteralExpr (Val);
931
932         } else {
933
934             /* Generate an expression tree */
935             unsigned char Op;
936             switch (T) {
937                 case TOK_EQ:    Op = EXPR_EQ;   break;
938                 case TOK_NE:    Op = EXPR_NE;   break;
939                 case TOK_LT:    Op = EXPR_LT;   break;
940                 case TOK_GT:    Op = EXPR_GT;   break;
941                 case TOK_LE:    Op = EXPR_LE;   break;
942                 case TOK_GE:    Op = EXPR_GE;   break;
943                 default:        Internal ("Invalid token");
944             }
945             Root        = NewExprNode (Op);
946             Root->Left  = Left;
947             Root->Right = Right;
948
949         }
950     }
951
952     /* Return the expression tree we've created */
953     return Root;
954 }
955
956
957
958 static ExprNode* Expr2 (void)
959 /* Boolean operators: AND and XOR */
960 {
961     /* Read left hand side */
962     ExprNode* Root = BoolExpr ();
963
964     /* Handle booleans */
965     while (Tok == TOK_BOOLAND || Tok == TOK_BOOLXOR) {
966
967         long LVal, RVal, Val;
968         ExprNode* Left;
969         ExprNode* Right;
970
971         /* Remember the token and skip it */
972         enum Token T = Tok;
973         NextTok ();
974
975         /* Move root to left side and read the right side */
976         Left  = Root;
977         Right = BoolExpr ();
978
979         /* If both expressions are constant, we can evaluate the term */
980         if (IsEasyConst (Left, &LVal) && IsEasyConst (Right, &RVal)) {
981
982             switch (T) {
983                 case TOK_BOOLAND:   Val = ((LVal != 0) && (RVal != 0)); break;
984                 case TOK_BOOLXOR:   Val = ((LVal != 0) ^  (RVal != 0)); break;
985                 default:        Internal ("Invalid token");
986             }
987
988             /* Generate a literal expression and delete the old left and
989              * right sides.
990              */
991             FreeExpr (Left);
992             FreeExpr (Right);
993             Root = GenLiteralExpr (Val);
994
995         } else {
996
997             /* Generate an expression tree */
998             unsigned char Op;
999             switch (T) {
1000                 case TOK_BOOLAND:   Op = EXPR_BOOLAND; break;
1001                 case TOK_BOOLXOR:   Op = EXPR_BOOLXOR; break;
1002                 default:            Internal ("Invalid token");
1003             }
1004             Root        = NewExprNode (Op);
1005             Root->Left  = Left;
1006             Root->Right = Right;
1007
1008         }
1009     }
1010
1011     /* Return the expression tree we've created */
1012     return Root;
1013 }
1014
1015
1016
1017 static ExprNode* Expr1 (void)
1018 /* Boolean operators: OR */
1019 {
1020     /* Read left hand side */
1021     ExprNode* Root = Expr2 ();
1022
1023     /* Handle booleans */
1024     while (Tok == TOK_BOOLOR) {
1025
1026         long LVal, RVal, Val;
1027         ExprNode* Left;
1028         ExprNode* Right;
1029
1030         /* Remember the token and skip it */
1031         enum Token T = Tok;
1032         NextTok ();
1033
1034         /* Move root to left side and read the right side */
1035         Left  = Root;
1036         Right = Expr2 ();
1037
1038         /* If both expressions are constant, we can evaluate the term */
1039         if (IsEasyConst (Left, &LVal) && IsEasyConst (Right, &RVal)) {
1040
1041             switch (T) {
1042                 case TOK_BOOLOR:    Val = ((LVal != 0) || (RVal != 0)); break;
1043                 default:        Internal ("Invalid token");
1044             }
1045
1046             /* Generate a literal expression and delete the old left and
1047              * right sides.
1048              */
1049             FreeExpr (Left);
1050             FreeExpr (Right);
1051             Root = GenLiteralExpr (Val);
1052
1053         } else {
1054
1055             /* Generate an expression tree */
1056             unsigned char Op;
1057             switch (T) {
1058                 case TOK_BOOLOR:    Op = EXPR_BOOLOR;  break;
1059                 default:            Internal ("Invalid token");
1060             }
1061             Root        = NewExprNode (Op);
1062             Root->Left  = Left;
1063             Root->Right = Right;
1064
1065         }
1066     }
1067
1068     /* Return the expression tree we've created */
1069     return Root;
1070 }
1071
1072
1073
1074 static ExprNode* Expr0 (void)
1075 /* Boolean operators: NOT */
1076 {
1077     ExprNode* Root;
1078
1079     /* Handle booleans */
1080     if (Tok == TOK_BOOLNOT) {
1081
1082         long Val;
1083         ExprNode* Left;
1084
1085         /* Skip the operator token */
1086         NextTok ();
1087
1088         /* Read the argument */
1089         Left = Expr0 ();
1090
1091         /* If the argument is const, evaluate it directly */
1092         if (IsEasyConst (Left, &Val)) {
1093             FreeExpr (Left);
1094             Root = GenLiteralExpr (!Val);
1095         } else {
1096             Root = NewExprNode (EXPR_BOOLNOT);
1097             Root->Left = Left;
1098         }
1099
1100     } else {
1101
1102         /* Read left hand side */
1103         Root = Expr1 ();
1104
1105     }
1106
1107     /* Return the expression tree we've created */
1108     return Root;
1109 }
1110
1111
1112
1113 static void StudyBinaryExpr (ExprNode* Expr, ExprDesc* D)
1114 /* Study a binary expression subtree. Helper function for StudyExpr. */
1115 {
1116     StudyExpr (Expr->Left, D, 1);
1117     if (ExprDescIsConst (D)) {
1118         D->Left = D->Val;
1119         D->Val = 0;
1120         StudyExpr (Expr->Right, D, 1);
1121         if (!ExprDescIsConst (D)) {
1122             D->TooComplex = 1;
1123         }
1124     } else {
1125         D->TooComplex = 1;
1126     }
1127 }
1128
1129
1130
1131 static void StudyExpr (ExprNode* Expr, ExprDesc* D, int Sign)
1132 /* Study an expression tree and place the contents into D */
1133 {
1134     SymEntry* Sym;
1135     unsigned  Sec;
1136     ExprDesc  SD;
1137     ExprDesc  SD1;
1138
1139     /* Initialize SD. This is not needed in all cases, but it's rather cheap
1140      * and simplifies the code below.
1141      */
1142     InitExprDesc (&SD);
1143
1144     /* Study this expression node */
1145     switch (Expr->Op) {
1146
1147         case EXPR_LITERAL:
1148             D->Val += (Sign * Expr->V.Val);
1149             break;
1150
1151         case EXPR_SYMBOL:
1152             Sym = Expr->V.Sym;
1153             if (SymIsImport (Sym)) {
1154                 if (D->SymCount == 0) {
1155                     D->SymCount += Sign;
1156                     D->SymRef = Sym;
1157                 } else if (D->SymRef == Sym) {
1158                     /* Same symbol */
1159                     D->SymCount += Sign;
1160                 } else {
1161                     /* More than one import */
1162                     D->TooComplex = 1;
1163                 }
1164             } else if (SymHasExpr (Sym)) {
1165                 if (SymHasUserMark (Sym)) {
1166                     if (Verbosity > 0) {
1167                         DumpExpr (Expr, SymResolve);
1168                     }
1169                     PError (GetSymPos (Sym),
1170                             "Circular reference in definition of symbol `%s'",
1171                             GetSymName (Sym));
1172                     D->TooComplex = 1;
1173                 } else {
1174                     SymMarkUser (Sym);
1175                     StudyExpr (GetSymExpr (Sym), D, Sign);
1176                     SymUnmarkUser (Sym);
1177                 }
1178             } else {
1179                 D->TooComplex = 1;
1180             }
1181             break;
1182
1183         case EXPR_SECTION:
1184             Sec = Expr->V.SegNum;
1185             if (D->SecCount == 0) {
1186                 D->SecCount += Sign;
1187                 D->SecRef = Sec;
1188             } else if (D->SecRef == Sec) {
1189                 /* Same section */
1190                 D->SecCount += Sign;
1191             } else {
1192                 /* More than one section */
1193                 D->TooComplex = 1;
1194             }
1195             break;
1196
1197         case EXPR_ULABEL:
1198             if (ULabCanResolve ()) {
1199                 /* We can resolve the label */
1200                 StudyExpr (ULabResolve (Expr->V.Val), D, Sign);
1201             } else {
1202                 D->TooComplex = 1;
1203             }
1204             break;
1205
1206         case EXPR_PLUS:
1207             StudyExpr (Expr->Left, D, Sign);
1208             StudyExpr (Expr->Right, D, Sign);
1209             break;
1210
1211         case EXPR_MINUS:
1212             StudyExpr (Expr->Left, D, Sign);
1213             StudyExpr (Expr->Right, D, -Sign);
1214             break;
1215
1216         case EXPR_MUL:
1217             InitExprDesc (&SD1);
1218             StudyExpr (Expr->Left, &SD, 1);
1219             StudyExpr (Expr->Right, &SD1, 1);
1220             if (SD.TooComplex == 0 && SD1.TooComplex == 0) {
1221                 /* First calculate SD = SD*SD1 if possible */
1222                 if (ExprDescIsConst (&SD)) {
1223                     /* Left is a constant */
1224                     SD1.Val      *= SD.Val;
1225                     SD1.SymCount *= SD.Val;
1226                     SD1.SecCount *= SD.Val;
1227                     SD = SD1;
1228                 } else if (ExprDescIsConst (&SD1)) {
1229                     /* Right is constant */
1230                     SD.Val      *= SD1.Val;
1231                     SD.SymCount *= SD1.Val;
1232                     SD.SecCount *= SD1.Val;
1233                 } else {
1234                     D->TooComplex = 1;
1235                 }
1236                 /* Now calculate D * Sign * SD */
1237                 if (!D->TooComplex) {
1238                     if ((D->SymCount == 0 || SD.SymCount == 0 || D->SymRef == SD.SymRef) &&
1239                         (D->SecCount == 0 || SD.SecCount == 0 || D->SecRef == SD.SecRef)) {
1240                         D->Val      += (Sign * SD.Val);
1241                         if (D->SymCount == 0) {
1242                             D->SymRef = SD.SymRef;
1243                         }
1244                         D->SymCount += (Sign * SD.SymCount);
1245                         if (D->SecCount == 0) {
1246                             D->SecRef = SD.SecRef;
1247                         }
1248                         D->SecCount += (Sign * SD.SecCount);
1249                     }
1250                 } else {
1251                     D->TooComplex = 1;
1252                 }
1253             } else {
1254                 D->TooComplex = 1;
1255             }
1256             break;
1257
1258         case EXPR_DIV:
1259             StudyBinaryExpr (Expr, &SD);
1260             if (!SD.TooComplex) {
1261                 if (SD.Val == 0) {
1262                     Error ("Division by zero");
1263                     D->TooComplex = 1;
1264                 } else {
1265                     D->Val += Sign * (SD.Left / SD.Val);
1266                 }
1267             } else {
1268                 D->TooComplex = 1;
1269             }
1270             break;
1271
1272         case EXPR_MOD:
1273             StudyBinaryExpr (Expr, &SD);
1274             if (!SD.TooComplex) {
1275                 if (SD.Val == 0) {
1276                     Error ("Modulo operation with zero");
1277                     D->TooComplex = 1;
1278                 } else {
1279                     D->Val += Sign * (SD.Left % SD.Val);
1280                 }
1281             } else {
1282                 D->TooComplex = 1;
1283             }
1284             break;
1285
1286         case EXPR_OR:
1287             StudyBinaryExpr (Expr, &SD);
1288             if (!SD.TooComplex) {
1289                 D->Val += Sign * (SD.Left | SD.Val);
1290             } else {
1291                 D->TooComplex = 1;
1292             }
1293             break;
1294
1295         case EXPR_XOR:
1296             StudyBinaryExpr (Expr, &SD);
1297             if (!SD.TooComplex) {
1298                 D->Val += Sign * (SD.Left ^ SD.Val);
1299             } else {
1300                 D->TooComplex = 1;
1301             }
1302             break;
1303
1304         case EXPR_AND:
1305             StudyBinaryExpr (Expr, &SD);
1306             if (!SD.TooComplex) {
1307                 D->Val += Sign * (SD.Left & SD.Val);
1308             } else {
1309                 D->TooComplex = 1;
1310             }
1311             break;
1312
1313         case EXPR_SHL:
1314             StudyBinaryExpr (Expr, &SD);
1315             if (!SD.TooComplex) {
1316                 D->Val += (Sign * shl_l (SD.Left, (unsigned) SD.Val));
1317             } else {
1318                 D->TooComplex = 1;
1319             }
1320             break;
1321
1322         case EXPR_SHR:
1323             StudyBinaryExpr (Expr, &SD);
1324             if (!SD.TooComplex) {
1325                 D->Val += (Sign * shr_l (SD.Left, (unsigned) SD.Val));
1326             } else {
1327                 D->TooComplex = 1;
1328             }
1329             break;
1330
1331         case EXPR_EQ:
1332             StudyBinaryExpr (Expr, &SD);
1333             if (!SD.TooComplex) {
1334                 D->Val += Sign * (SD.Left == SD.Val);
1335             } else {
1336                 D->TooComplex = 1;
1337             }
1338             break;
1339
1340         case EXPR_NE:
1341             StudyBinaryExpr (Expr, &SD);
1342             if (!SD.TooComplex) {
1343                 D->Val += Sign * (SD.Left != SD.Val);
1344             } else {
1345                 D->TooComplex = 1;
1346             }
1347             break;
1348
1349         case EXPR_LT:
1350             StudyBinaryExpr (Expr, &SD);
1351             if (!SD.TooComplex) {
1352                 D->Val += Sign * (SD.Left < SD.Val);
1353             } else {
1354                 D->TooComplex = 1;
1355             }
1356             break;
1357
1358         case EXPR_GT:
1359             StudyBinaryExpr (Expr, &SD);
1360             if (!SD.TooComplex) {
1361                 D->Val += Sign * (SD.Left > SD.Val);
1362             } else {
1363                 D->TooComplex = 1;
1364             }
1365             break;
1366
1367         case EXPR_LE:
1368             StudyBinaryExpr (Expr, &SD);
1369             if (!SD.TooComplex) {
1370                 D->Val += Sign * (SD.Left <= SD.Val);
1371             } else {
1372                 D->TooComplex = 1;
1373             }
1374             break;
1375
1376         case EXPR_GE:
1377             StudyBinaryExpr (Expr, &SD);
1378             if (!SD.TooComplex) {
1379                 D->Val += Sign * (SD.Left >= SD.Val);
1380             } else {
1381                 D->TooComplex = 1;
1382             }
1383             break;
1384
1385         case EXPR_BOOLAND:
1386             StudyExpr (Expr->Left, &SD, 1);
1387             if (ExprDescIsConst (&SD)) {
1388                 if (SD.Val != 0) {   /* Shortcut op */
1389                     SD.Val = 0;
1390                     StudyExpr (Expr->Right, &SD, 1);
1391                     if (ExprDescIsConst (&SD)) {
1392                         D->Val += Sign * (SD.Val != 0);
1393                     } else {
1394                         D->TooComplex = 1;
1395                     }
1396                 }
1397             } else {
1398                 D->TooComplex = 1;
1399             }
1400             break;
1401
1402         case EXPR_BOOLOR:
1403             StudyExpr (Expr->Left, &SD, 1);
1404             if (ExprDescIsConst (&SD)) {
1405                 if (SD.Val == 0) {   /* Shortcut op */
1406                     StudyExpr (Expr->Right, &SD, 1);
1407                     if (ExprDescIsConst (&SD)) {
1408                         D->Val += Sign * (SD.Val != 0);
1409                     } else {
1410                         D->TooComplex = 1;
1411                     }
1412                 } else {
1413                     D->Val += Sign;
1414                 }
1415             } else {
1416                 D->TooComplex = 1;
1417             }
1418             break;
1419
1420         case EXPR_BOOLXOR:
1421             StudyBinaryExpr (Expr, &SD);
1422             if (!SD.TooComplex) {
1423                 D->Val += Sign * ((SD.Left != 0) ^ (SD.Val != 0));
1424             }
1425             break;
1426
1427         case EXPR_UNARY_MINUS:
1428             StudyExpr (Expr->Left, D, -Sign);
1429             break;
1430
1431         case EXPR_NOT:
1432             StudyExpr (Expr->Left, &SD, 1);
1433             if (ExprDescIsConst (&SD)) {
1434                 D->Val += (Sign * ~SD.Val);
1435             } else {
1436                 D->TooComplex = 1;
1437             }
1438             break;
1439
1440         case EXPR_SWAP:
1441             StudyExpr (Expr->Left, &SD, 1);
1442             if (ExprDescIsConst (&SD)) {
1443                 D->Val += Sign * (((SD.Val >> 8) & 0x00FF) | ((SD.Val << 8) & 0xFF00));
1444             } else {
1445                 D->TooComplex = 1;
1446             }
1447             break;
1448
1449         case EXPR_BOOLNOT:
1450             StudyExpr (Expr->Left, &SD, 1);
1451             if (ExprDescIsConst (&SD)) {
1452                 D->Val += Sign * (SD.Val != 0);
1453             } else {
1454                 D->TooComplex = 1;
1455             }
1456             break;
1457
1458         case EXPR_FORCEWORD:
1459         case EXPR_FORCEFAR:
1460             /* Ignore */
1461             StudyExpr (Expr->Left, D, Sign);
1462             break;
1463
1464         case EXPR_BYTE0:
1465             StudyExpr (Expr->Left, &SD, 1);
1466             if (ExprDescIsConst (&SD)) {
1467                 D->Val += Sign * (SD.Val & 0xFF);
1468             } else {
1469                 D->TooComplex = 1;
1470             }
1471             break;
1472
1473         case EXPR_BYTE1:
1474             StudyExpr (Expr->Left, &SD, 1);
1475             if (ExprDescIsConst (&SD)) {
1476                 D->Val += Sign * ((SD.Val >> 8) & 0xFF);
1477             } else {
1478                 D->TooComplex = 1;
1479             }
1480             break;
1481
1482         case EXPR_BYTE2:
1483             StudyExpr (Expr->Left, &SD, 1);
1484             if (ExprDescIsConst (&SD)) {
1485                 D->Val += Sign * ((SD.Val >> 16) & 0xFF);
1486             } else {
1487                 D->TooComplex = 1;
1488             }
1489             break;
1490
1491         case EXPR_BYTE3:
1492             StudyExpr (Expr->Left, &SD, 1);
1493             if (ExprDescIsConst (&SD)) {
1494                 D->Val += Sign * ((SD.Val >> 24) & 0xFF);
1495             } else {
1496                 D->TooComplex = 1;
1497             }
1498             break;
1499
1500         case EXPR_WORD0:
1501             StudyExpr (Expr->Left, &SD, 1);
1502             if (ExprDescIsConst (&SD)) {
1503                 D->Val += Sign * (SD.Val & 0xFFFF);
1504             } else {
1505                 D->TooComplex = 1;
1506             }
1507             break;
1508
1509         case EXPR_WORD1:
1510             StudyExpr (Expr->Left, &SD, 1);
1511             if (ExprDescIsConst (&SD)) {
1512                 D->Val += Sign * ((SD.Val >> 16) & 0xFFFF);
1513             } else {
1514                 D->TooComplex = 1;
1515             }
1516             break;
1517
1518         default:
1519             Internal ("Unknown Op type: %u", Expr->Op);
1520             break;
1521     }
1522 }
1523
1524
1525
1526 static ExprNode* SimplifyExpr (ExprNode* Expr)
1527 /* Try to simplify the given expression tree */
1528 {
1529     if (Expr && Expr->Op != EXPR_LITERAL) {
1530
1531         /* Create an expression description and initialize it */
1532         ExprDesc D;
1533         InitExprDesc (&D);
1534
1535         /* Study the expression */
1536         StudyExpr (Expr, &D, 1);
1537
1538         /* Now check if we can generate a literal value */
1539         if (ExprDescIsConst (&D)) {
1540             /* No external references */
1541             FreeExpr (Expr);
1542             Expr = GenLiteralExpr (D.Val);
1543         }
1544     }
1545     return Expr;
1546 }
1547
1548
1549
1550 ExprNode* Expression (void)
1551 /* Evaluate an expression, build the expression tree on the heap and return
1552  * a pointer to the root of the tree.
1553  */
1554 {
1555 #if 1
1556     return SimplifyExpr (Expr0 ());
1557 #else
1558     /* Test code */
1559     ExprNode* Expr = Expr0 ();
1560     printf ("Before: "); DumpExpr (Expr, SymResolve);
1561     Expr = SimplifyExpr (Expr);
1562     printf ("After:  "); DumpExpr (Expr, SymResolve);
1563     return Expr;
1564 #endif
1565 }
1566
1567
1568
1569 long ConstExpression (void)
1570 /* Parse an expression. Check if the expression is const, and print an error
1571  * message if not. Return the value of the expression, or a dummy, if it is
1572  * not constant.
1573  */
1574 {
1575 #if 1
1576     /* Read the expression */
1577     ExprNode* Expr = Expr0 ();
1578 #else
1579     /* Test code */
1580     ExprNode* Expr = Expression ();
1581 #endif
1582
1583     /* Study the expression */
1584     ExprDesc D;
1585     InitExprDesc (&D);
1586     StudyExpr (Expr, &D, 1);
1587
1588     /* Check if the expression is constant */
1589     if (!ExprDescIsConst (&D)) {
1590         Error ("Constant expression expected");
1591         D.Val = 0;
1592     }
1593
1594     /* Free the expression tree and return the value */
1595     FreeExpr (Expr);
1596     return D.Val;
1597 }
1598
1599
1600
1601 void FreeExpr (ExprNode* Root)
1602 /* Free the expression, Root is pointing to. */
1603 {
1604     if (Root) {
1605         FreeExpr (Root->Left);
1606         FreeExpr (Root->Right);
1607         FreeExprNode (Root);
1608     }
1609 }
1610
1611
1612
1613 ExprNode* GenLiteralExpr (long Val)
1614 /* Return an expression tree that encodes the given literal value */
1615 {
1616     ExprNode* Expr = NewExprNode (EXPR_LITERAL);
1617     Expr->V.Val = Val;
1618     return Expr;
1619 }
1620
1621
1622
1623 ExprNode* GenSymExpr (SymEntry* Sym)
1624 /* Return an expression node that encodes the given symbol */
1625 {
1626     ExprNode* Expr = NewExprNode (EXPR_SYMBOL);
1627     Expr->V.Sym = Sym;
1628     SymAddExprRef (Sym, Expr);
1629     return Expr;
1630 }
1631
1632
1633
1634 static ExprNode* GenSectionExpr (unsigned SegNum)
1635 /* Return an expression node for the given section */
1636 {
1637     ExprNode* Expr = NewExprNode (EXPR_SECTION);
1638     Expr->V.SegNum = SegNum;
1639     return Expr;
1640 }
1641
1642
1643
1644 ExprNode* GenAddExpr (ExprNode* Left, ExprNode* Right)
1645 /* Generate an addition from the two operands */
1646 {
1647     ExprNode* Root = NewExprNode (EXPR_PLUS);
1648     Root->Left = Left;
1649     Root->Right = Right;
1650     return Root;
1651 }
1652
1653
1654
1655 ExprNode* GenCurrentPC (void)
1656 /* Return the current program counter as expression */
1657 {
1658     ExprNode* Root;
1659
1660     if (RelocMode) {
1661         /* Create SegmentBase + Offset */
1662         Root = GenAddExpr (GenSectionExpr (GetCurrentSegNum ()),
1663                            GenLiteralExpr (GetPC ()));
1664     } else {
1665         /* Absolute mode, just return PC value */
1666         Root = GenLiteralExpr (GetPC ());
1667     }
1668
1669     return Root;
1670 }
1671
1672
1673
1674 ExprNode* GenSwapExpr (ExprNode* Expr)
1675 /* Return an extended expression with lo and hi bytes swapped */
1676 {
1677     ExprNode* N = NewExprNode (EXPR_SWAP);
1678     N->Left = Expr;
1679     return N;
1680 }
1681
1682
1683
1684 ExprNode* GenBranchExpr (unsigned Offs)
1685 /* Return an expression that encodes the difference between current PC plus
1686  * offset and the target expression (that is, Expression() - (*+Offs) ).
1687  */
1688 {
1689     ExprNode* N;
1690     ExprNode* Root;
1691     long      Val;
1692
1693     /* Read Expression() */
1694     N = Expression ();
1695
1696     /* If the expression is a cheap constant, generate a simpler tree */
1697     if (IsEasyConst (N, &Val)) {
1698
1699         /* Free the constant expression tree */
1700         FreeExpr (N);
1701
1702         /* Generate the final expression:
1703          * Val - (* + Offs)
1704          * Val - ((Seg + PC) + Offs)
1705          * Val - Seg - PC - Offs
1706          * (Val - PC - Offs) - Seg
1707          */
1708         Root = GenLiteralExpr (Val - GetPC () - Offs);
1709         if (RelocMode) {
1710             N = Root;
1711             Root = NewExprNode (EXPR_MINUS);
1712             Root->Left  = N;
1713             Root->Right = GenSectionExpr (GetCurrentSegNum ());
1714         }
1715
1716     } else {
1717
1718         /* Generate the expression:
1719          * N - (* + Offs)
1720          * N - ((Seg + PC) + Offs)
1721          * N - Seg - PC - Offs
1722          * N - (PC + Offs) - Seg
1723          */
1724         Root = NewExprNode (EXPR_MINUS);
1725         Root->Left  = N;
1726         Root->Right = GenLiteralExpr (GetPC () + Offs);
1727         if (RelocMode) {
1728             N = Root;
1729             Root = NewExprNode (EXPR_MINUS);
1730             Root->Left  = N;
1731             Root->Right = GenSectionExpr (GetCurrentSegNum ());
1732         }
1733     }
1734
1735     /* Return the result */
1736     return Root;
1737 }
1738
1739
1740
1741 ExprNode* GenULabelExpr (unsigned Num)
1742 /* Return an expression for an unnamed label with the given index */
1743 {
1744     ExprNode* Node = NewExprNode (EXPR_ULABEL);
1745     Node->V.Val = Num;
1746
1747     /* Return the new node */
1748     return Node;
1749 }
1750
1751
1752
1753 ExprNode* GenByteExpr (ExprNode* Expr)
1754 /* Force the given expression into a byte and return the result */
1755 {
1756     /* Use the low byte operator to force the expression into byte size */
1757     ExprNode* Root = NewExprNode (EXPR_BYTE0);
1758     Root->Left  = Expr;
1759
1760     /* Return the result */
1761     return Root;
1762 }
1763
1764
1765
1766 ExprNode* GenWordExpr (ExprNode* Expr)
1767 /* Force the given expression into a word and return the result. */
1768 {
1769     /* AND the expression by $FFFF to force it into word size */
1770     ExprNode* Root = NewExprNode (EXPR_AND);
1771     Root->Left  = Expr;
1772     Root->Right = GenLiteralExpr (0xFFFF);
1773
1774     /* Return the result */
1775     return Root;
1776 }
1777
1778
1779
1780 ExprNode* GenNE (ExprNode* Expr, long Val)
1781 /* Generate an expression that compares Expr and Val for inequality */
1782 {
1783     /* Generate a compare node */
1784     ExprNode* Root = NewExprNode (EXPR_NE);
1785     Root->Left  = Expr;
1786     Root->Right = GenLiteralExpr (Val);
1787
1788     /* Return the result */
1789     return Root;
1790 }
1791
1792
1793
1794 int IsConstExpr (ExprNode* Expr, long* Val)
1795 /* Return true if the given expression is a constant expression, that is, one
1796  * with no references to external symbols. If Val is not NULL and the
1797  * expression is constant, the constant value is stored here.
1798  */
1799 {
1800     /* Study the expression */
1801     ExprDesc D;
1802     InitExprDesc (&D);
1803     StudyExpr (Expr, &D, 1);
1804
1805     /* Check if the expression is constant */
1806     if (ExprDescIsConst (&D)) {
1807         if (Val) {
1808             *Val = D.Val;
1809         }
1810         return 1;
1811     } else {
1812         return 0;
1813     }
1814 }
1815
1816
1817
1818 static void CheckByteExpr (const ExprNode* N, int* IsByte)
1819 /* Internal routine that is recursively called to check if there is a zeropage
1820  * symbol in the expression tree.
1821  */
1822 {
1823     if (N) {
1824         switch (N->Op & EXPR_TYPEMASK) {
1825
1826             case EXPR_LEAFNODE:
1827                 switch (N->Op) {
1828
1829                     case EXPR_SYMBOL:
1830                         if (SymIsZP (N->V.Sym)) {
1831                             *IsByte = 1;
1832                         } else if (SymHasExpr (N->V.Sym)) {
1833                             /* Check if this expression is a byte expression */
1834                             CheckByteExpr (GetSymExpr (N->V.Sym), IsByte);
1835                         }
1836                         break;
1837
1838                     case EXPR_SECTION:
1839                         if (GetSegAddrSize (N->V.SegNum) == ADDR_SIZE_ZP) {
1840                             *IsByte = 1;
1841                         }
1842                         break;
1843
1844                 }
1845                 break;
1846
1847             case EXPR_UNARYNODE:
1848                 CheckByteExpr (N->Left, IsByte);
1849                 break;
1850
1851             case EXPR_BINARYNODE:
1852                 CheckByteExpr (N->Left, IsByte);
1853                 CheckByteExpr (N->Right, IsByte);
1854                 break;
1855
1856             default:
1857                 Internal ("Unknown expression op: %02X", N->Op);
1858         }
1859     }
1860 }
1861
1862
1863
1864 int IsByteExpr (ExprNode* Root)
1865 /* Return true if this is a byte expression */
1866 {
1867     int IsByte;
1868     long Val;
1869
1870     if (IsConstExpr (Root, &Val)) {
1871         IsByte = IsByteRange (Val);
1872     } else if (Root->Op == EXPR_BYTE0 || Root->Op == EXPR_BYTE1 ||
1873                Root->Op == EXPR_BYTE2 || Root->Op == EXPR_BYTE3) {
1874         /* Symbol forced to have byte range */
1875         IsByte = 1;
1876     } else {
1877         /* We have undefined symbols in the expression. Assume that the
1878          * expression is a byte expression if there is at least one symbol
1879          * declared as zeropage in it. Being wrong here is not a very big
1880          * problem since the linker knows about all symbols and detects
1881          * error like mixing absolute and zeropage labels.
1882          */
1883         IsByte = 0;
1884         CheckByteExpr (Root, &IsByte);
1885     }
1886     return IsByte;
1887 }
1888
1889
1890
1891 ExprNode* CloneExpr (ExprNode* Expr)
1892 /* Clone the given expression tree. The function will simply clone symbol
1893  * nodes, it will not resolve them.
1894  */
1895 {
1896     ExprNode* Clone;
1897
1898     /* Accept NULL pointers */
1899     if (Expr == 0) {
1900         return 0;
1901     }
1902
1903     /* Clone the node */
1904     switch (Expr->Op) {
1905
1906         case EXPR_LITERAL:
1907             Clone = GenLiteralExpr (Expr->V.Val);
1908             break;
1909
1910         case EXPR_ULABEL:
1911             Clone = GenULabelExpr (Expr->V.Val);
1912             break;
1913
1914         case EXPR_SYMBOL:
1915             Clone = GenSymExpr (Expr->V.Sym);
1916             break;
1917
1918         case EXPR_SECTION:
1919             Clone = GenSectionExpr (Expr->V.SegNum);
1920             break;
1921
1922         default:
1923             /* Generate a new node */
1924             Clone = NewExprNode (Expr->Op);
1925             /* Clone the tree nodes */
1926             Clone->Left = CloneExpr (Expr->Left);
1927             Clone->Right = CloneExpr (Expr->Right);
1928             break;
1929     }
1930
1931     /* Done */
1932     return Clone;
1933 }
1934
1935
1936
1937 void WriteExpr (ExprNode* Expr)
1938 /* Write the given expression to the object file */
1939 {
1940     /* Null expressions are encoded by a type byte of zero */
1941     if (Expr == 0) {
1942         ObjWrite8 (EXPR_NULL);
1943         return;
1944     }
1945
1946     /* If the is a leafnode, write the expression attribute, otherwise
1947      * write the expression operands.
1948      */
1949     switch (Expr->Op) {
1950
1951         case EXPR_LITERAL:
1952             ObjWrite8 (EXPR_LITERAL);
1953             ObjWrite32 (Expr->V.Val);
1954             break;
1955
1956         case EXPR_SYMBOL:
1957             if (SymIsImport (Expr->V.Sym)) {
1958                 ObjWrite8 (EXPR_SYMBOL);
1959                 ObjWriteVar (GetSymIndex (Expr->V.Sym));
1960             } else {
1961                 WriteExpr (GetSymExpr (Expr->V.Sym));
1962             }
1963             break;
1964
1965         case EXPR_SECTION:
1966             ObjWrite8 (EXPR_SECTION);
1967             ObjWrite8 (Expr->V.SegNum);
1968             break;
1969
1970         case EXPR_ULABEL:
1971             WriteExpr (ULabResolve (Expr->V.Val));
1972             break;
1973
1974         default:
1975             /* Not a leaf node */
1976             ObjWrite8 (Expr->Op);
1977             WriteExpr (Expr->Left);
1978             WriteExpr (Expr->Right);
1979             break;
1980
1981     }
1982 }
1983
1984
1985
1986