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