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