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