1 /*****************************************************************************/
5 /* Study an expression tree */
9 /* (C) 2003 Ullrich von Bassewitz */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
47 #include "studyexpr.h"
53 /*****************************************************************************/
55 /*****************************************************************************/
59 ExprDesc* ED_Init (ExprDesc* ED)
60 /* Initialize an ExprDesc structure for use with StudyExpr */
63 ED->AddrSize = ADDR_SIZE_DEFAULT;
76 void ED_Done (ExprDesc* ED)
77 /* Delete allocated memory for an ExprDesc. */
85 int ED_IsConst (const ExprDesc* D)
86 /* Return true if the expression is constant */
90 if (D->Flags & ED_TOO_COMPLEX) {
93 for (I = 0; I < D->SymCount; ++I) {
94 if (D->SymRef[I].Count != 0) {
98 for (I = 0; I < D->SecCount; ++I) {
99 if (D->SecRef[I].Count != 0) {
108 static int ED_IsValid (const ExprDesc* D)
109 /* Return true if the expression is valid, that is, the TOO_COMPLEX flag is
113 return ((D->Flags & ED_TOO_COMPLEX) == 0);
118 static void ED_Invalidate (ExprDesc* D)
119 /* Set the TOO_COMPLEX flag for D */
121 D->Flags |= ED_TOO_COMPLEX;
126 static void ED_UpdateAddrSize (ExprDesc* ED, unsigned char AddrSize)
127 /* Update the address size of the expression */
129 if (ED->AddrSize == ADDR_SIZE_DEFAULT || AddrSize > ED->AddrSize) {
130 ED->AddrSize = AddrSize;
136 static ED_SymRef* ED_FindSymRef (ExprDesc* ED, SymEntry* Sym)
137 /* Find a symbol reference and return it. Return NULL if the reference does
143 for (I = 0, SymRef = ED->SymRef; I < ED->SymCount; ++I, ++SymRef) {
144 if (SymRef->Ref == Sym) {
153 static ED_SecRef* ED_FindSecRef (ExprDesc* ED, unsigned Sec)
154 /* Find a section reference and return it. Return NULL if the reference does
160 for (I = 0, SecRef = ED->SecRef; I < ED->SecCount; ++I, ++SecRef) {
161 if (SecRef->Ref == Sec) {
170 static ED_SymRef* ED_AllocSymRef (ExprDesc* ED, SymEntry* Sym)
171 /* Allocate a new symbol reference and return it. The count of the new
172 * reference will be set to zero, and the reference itself to Sym.
177 /* Make sure we have enough SymRef slots */
178 if (ED->SymCount >= ED->SymLimit) {
180 if (ED->SymLimit == 0) {
183 ED->SymRef = xrealloc (ED->SymRef, ED->SymLimit * sizeof (ED->SymRef[0]));
186 /* Allocate a new slot */
187 SymRef = ED->SymRef + ED->SymCount++;
189 /* Initialize the new struct and return it */
197 static ED_SecRef* ED_AllocSecRef (ExprDesc* ED, unsigned Sec)
198 /* Allocate a new section reference and return it. The count of the new
199 * reference will be set to zero, and the reference itself to Sec.
204 /* Make sure we have enough SecRef slots */
205 if (ED->SecCount >= ED->SecLimit) {
207 if (ED->SecLimit == 0) {
210 ED->SecRef = xrealloc (ED->SecRef, ED->SecLimit * sizeof (ED->SecRef[0]));
213 /* Allocate a new slot */
214 SecRef = ED->SecRef + ED->SecCount++;
216 /* Initialize the new struct and return it */
224 static ED_SymRef* ED_GetSymRef (ExprDesc* ED, SymEntry* Sym)
225 /* Get a symbol reference and return it. If the symbol reference does not
226 * exist, a new one is created and returned.
229 ED_SymRef* SymRef = ED_FindSymRef (ED, Sym);
231 SymRef = ED_AllocSymRef (ED, Sym);
238 static ED_SecRef* ED_GetSecRef (ExprDesc* ED, unsigned Sec)
239 /* Get a section reference and return it. If the section reference does not
240 * exist, a new one is created and returned.
243 ED_SecRef* SecRef = ED_FindSecRef (ED, Sec);
245 SecRef = ED_AllocSecRef (ED, Sec);
252 static void ED_MergeSymRefs (ExprDesc* ED, const ExprDesc* New)
253 /* Merge the symbol references from New into ED */
256 for (I = 0; I < New->SymCount; ++I) {
258 /* Get a pointer to the SymRef entry */
259 const ED_SymRef* NewRef = New->SymRef + I;
261 /* Get the corresponding entry in ED */
262 ED_SymRef* SymRef = ED_GetSymRef (ED, NewRef->Ref);
264 /* Sum up the references */
265 SymRef->Count += NewRef->Count;
271 static void ED_MergeSecRefs (ExprDesc* ED, const ExprDesc* New)
272 /* Merge the section references from New into ED */
275 for (I = 0; I < New->SecCount; ++I) {
277 /* Get a pointer to the SymRef entry */
278 const ED_SecRef* NewRef = New->SecRef + I;
280 /* Get the corresponding entry in ED */
281 ED_SecRef* SecRef = ED_GetSecRef (ED, NewRef->Ref);
283 /* Sum up the references */
284 SecRef->Count += NewRef->Count;
290 static void ED_MergeRefs (ExprDesc* ED, const ExprDesc* New)
291 /* Merge all references from New into ED */
293 ED_MergeSymRefs (ED, New);
294 ED_MergeSecRefs (ED, New);
299 static void ED_Add (ExprDesc* ED, const ExprDesc* Right)
300 /* Calculate ED = ED + Right, update address size in ED */
302 ED->Val += Right->Val;
303 ED_MergeRefs (ED, Right);
304 ED_UpdateAddrSize (ED, Right->AddrSize);
309 static void ED_Mul (ExprDesc* ED, const ExprDesc* Right)
310 /* Calculate ED = ED * Right, update address size in ED */
314 ED->Val *= Right->Val;
315 for (I = 0; I < ED->SymCount; ++I) {
316 ED->SymRef[I].Count *= Right->Val;
318 for (I = 0; I < ED->SecCount; ++I) {
319 ED->SecRef[I].Count *= Right->Val;
321 ED_UpdateAddrSize (ED, Right->AddrSize);
326 static void ED_Neg (ExprDesc* D)
327 /* Negate an expression */
332 for (I = 0; I < D->SymCount; ++I) {
333 D->SymRef[I].Count = -D->SymRef[I].Count;
335 for (I = 0; I < D->SecCount; ++I) {
336 D->SecRef[I].Count = -D->SecRef[I].Count;
342 static void ED_Move (ExprDesc* From, ExprDesc* To)
343 /* Move the data from one ExprDesc to another. Old data is freed, and From
344 * is prepared to that ED_Done may be called safely.
347 /* Delete old data */
359 /*****************************************************************************/
361 /*****************************************************************************/
365 static void StudyExprInternal (ExprNode* Expr, ExprDesc* D);
366 /* Study an expression tree and place the contents into D */
370 static void StudyBinaryExpr (ExprNode* Expr, ExprDesc* D)
371 /* Study a binary expression subtree. This is a helper function for StudyExpr
372 * used for operations that succeed when both operands are known and constant.
373 * It evaluates the two subtrees and checks if they are constant. If they
374 * aren't constant, it will set the TOO_COMPLEX flag, and merge references.
375 * Otherwise the first value is returned in D->Val, the second one in D->Right,
376 * so the actual operation can be done by the caller.
381 /* Study the left side of the expression */
382 StudyExprInternal (Expr->Left, D);
384 /* Study the right side of the expression */
386 StudyExprInternal (Expr->Right, &Right);
388 /* Check if we can handle the operation */
389 if (ED_IsConst (D) && ED_IsConst (&Right)) {
391 /* Remember the constant value from Right */
392 D->Right = Right.Val;
396 /* Cannot evaluate */
399 /* Merge references and update address size */
400 ED_MergeRefs (D, &Right);
401 ED_UpdateAddrSize (D, Right.AddrSize);
411 static void StudyLiteral (ExprNode* Expr, ExprDesc* D)
412 /* Study a literal expression node */
414 /* This one is easy */
415 D->Val = Expr->V.Val;
420 static void StudySymbol (ExprNode* Expr, ExprDesc* D)
421 /* Study a symbol expression node */
423 /* Get the symbol from the expression */
424 SymEntry* Sym = Expr->V.Sym;
426 /* If the symbol is defined somewhere, it has an expression associated.
427 * In this case, just study the expression associated with the symbol,
428 * but mark the symbol so if we encounter it twice, we know that we have
429 * a circular reference.
431 if (SymHasExpr (Sym)) {
432 if (SymHasUserMark (Sym)) {
434 DumpExpr (Expr, SymResolve);
436 PError (GetSymPos (Sym),
437 "Circular reference in definition of symbol `%s'",
442 unsigned char AddrSize;
444 /* Mark the symbol and study its associated expression */
446 StudyExprInternal (GetSymExpr (Sym), D);
449 /* If the symbol has an explicit address size, use it. This may
450 * lead to range errors later (maybe even in the linker stage), if
451 * the user lied about the address size, but for now we trust the
454 AddrSize = GetSymAddrSize (Sym);
455 if (AddrSize != ADDR_SIZE_DEFAULT) {
456 D->AddrSize = AddrSize;
460 /* The symbol is either undefined or an import. In both cases, track
461 * the symbols used and update the address size, but in case of an
462 * undefined symbol also set the "too complex" flag, since we cannot
463 * evaluate the final result.
465 ED_SymRef* SymRef = ED_GetSymRef (D, Sym);
467 ED_UpdateAddrSize (D, GetSymAddrSize (Sym));
468 if (!SymIsImport (Sym)) {
477 static void StudySection (ExprNode* Expr, ExprDesc* D)
478 /* Study a section expression node */
480 /* Get the section reference */
481 ED_SecRef* SecRef = ED_GetSecRef (D, Expr->V.SegNum);
483 /* Update the data and the address size */
485 ED_UpdateAddrSize (D, GetSegAddrSize (SecRef->Ref));
490 static void StudyULabel (ExprNode* Expr, ExprDesc* D)
491 /* Study an unnamed label expression node */
493 /* If we can resolve the label, study the expression associated with it,
494 * otherwise mark the expression as too complex to evaluate.
496 if (ULabCanResolve ()) {
497 /* We can resolve the label */
498 StudyExprInternal (ULabResolve (Expr->V.Val), D);
506 static void StudyPlus (ExprNode* Expr, ExprDesc* D)
507 /* Study an EXPR_PLUS binary expression node */
511 /* Study the left side of the expression */
512 StudyExprInternal (Expr->Left, D);
514 /* Study the right side of the expression */
516 StudyExprInternal (Expr->Right, &Right);
518 /* Check if we can handle the operation */
519 if (ED_IsValid (D) || ED_IsValid (&Right)) {
526 /* Cannot evaluate */
529 /* Merge references and update address size */
530 ED_MergeRefs (D, &Right);
531 ED_UpdateAddrSize (D, Right.AddrSize);
541 static void StudyMinus (ExprNode* Expr, ExprDesc* D)
542 /* Study an EXPR_MINUS binary expression node */
546 /* Study the left side of the expression */
547 StudyExprInternal (Expr->Left, D);
549 /* Study the right side of the expression */
551 StudyExprInternal (Expr->Right, &Right);
553 /* Check if we can handle the operation */
554 if (ED_IsValid (D) || ED_IsValid (&Right)) {
562 /* Cannot evaluate */
565 /* Merge references and update address size */
566 ED_MergeRefs (D, &Right);
567 ED_UpdateAddrSize (D, Right.AddrSize);
577 static void StudyMul (ExprNode* Expr, ExprDesc* D)
578 /* Study an EXPR_MUL binary expression node */
582 /* Study the left side of the expression */
583 StudyExprInternal (Expr->Left, D);
585 /* Study the right side of the expression */
587 StudyExprInternal (Expr->Right, &Right);
589 /* We can handle the operation if at least one of both operands is const
590 * and the other one is valid.
592 if (ED_IsConst (D) && ED_IsValid (&Right)) {
594 /* Multiplicate both, result goes into Right */
597 /* Move result into D */
600 } else if (ED_IsConst (&Right) && ED_IsValid (D)) {
602 /* Multiplicate both */
607 /* Cannot handle this operation */
612 /* If we could not handle the op, merge references and update address size */
613 if (!ED_IsValid (D)) {
614 ED_MergeRefs (D, &Right);
615 ED_UpdateAddrSize (D, Right.AddrSize);
624 static void StudyDiv (ExprNode* Expr, ExprDesc* D)
625 /* Study an EXPR_DIV binary expression node */
627 /* Use helper function */
628 StudyBinaryExpr (Expr, D);
630 /* If the result is valid, apply the operation */
631 if (ED_IsValid (D)) {
633 Error ("Division by zero");
643 static void StudyMod (ExprNode* Expr, ExprDesc* D)
644 /* Study an EXPR_MOD binary expression node */
646 /* Use helper function */
647 StudyBinaryExpr (Expr, D);
649 /* If the result is valid, apply the operation */
650 if (ED_IsValid (D)) {
652 Error ("Modulo operation with zero");
662 static void StudyOr (ExprNode* Expr, ExprDesc* D)
663 /* Study an EXPR_OR binary expression node */
665 /* Use helper function */
666 StudyBinaryExpr (Expr, D);
668 /* If the result is valid, apply the operation */
669 if (ED_IsValid (D)) {
676 static void StudyXor (ExprNode* Expr, ExprDesc* D)
677 /* Study an EXPR_XOR binary expression node */
679 /* Use helper function */
680 StudyBinaryExpr (Expr, D);
682 /* If the result is valid, apply the operation */
683 if (ED_IsValid (D)) {
690 static void StudyAnd (ExprNode* Expr, ExprDesc* D)
691 /* Study an EXPR_AND binary expression node */
693 /* Use helper function */
694 StudyBinaryExpr (Expr, D);
696 /* If the result is valid, apply the operation */
697 if (ED_IsValid (D)) {
704 static void StudyShl (ExprNode* Expr, ExprDesc* D)
705 /* Study an EXPR_SHL binary expression node */
707 /* Use helper function */
708 StudyBinaryExpr (Expr, D);
710 /* If the result is valid, apply the operation */
711 if (ED_IsValid (D)) {
712 D->Val = shl_l (D->Val, D->Right);
718 static void StudyShr (ExprNode* Expr, ExprDesc* D)
719 /* Study an EXPR_SHR binary expression node */
721 /* Use helper function */
722 StudyBinaryExpr (Expr, D);
724 /* If the result is valid, apply the operation */
725 if (ED_IsValid (D)) {
726 D->Val = shr_l (D->Val, D->Right);
732 static void StudyEQ (ExprNode* Expr, ExprDesc* D)
733 /* Study an EXPR_EQ binary expression node */
735 /* Use helper function */
736 StudyBinaryExpr (Expr, D);
738 /* If the result is valid, apply the operation */
739 if (ED_IsValid (D)) {
740 D->Val = (D->Val == D->Right);
743 /* In any case, the result is 0 or 1 */
744 D->AddrSize = ADDR_SIZE_ZP;
749 static void StudyNE (ExprNode* Expr, ExprDesc* D)
750 /* Study an EXPR_NE binary expression node */
752 /* Use helper function */
753 StudyBinaryExpr (Expr, D);
755 /* If the result is valid, apply the operation */
756 if (ED_IsValid (D)) {
757 D->Val = (D->Val != D->Right);
760 /* In any case, the result is 0 or 1 */
761 D->AddrSize = ADDR_SIZE_ZP;
766 static void StudyLT (ExprNode* Expr, ExprDesc* D)
767 /* Study an EXPR_LT binary expression node */
769 /* Use helper function */
770 StudyBinaryExpr (Expr, D);
772 /* If the result is valid, apply the operation */
773 if (ED_IsValid (D)) {
774 D->Val = (D->Val < D->Right);
777 /* In any case, the result is 0 or 1 */
778 D->AddrSize = ADDR_SIZE_ZP;
783 static void StudyGT (ExprNode* Expr, ExprDesc* D)
784 /* Study an EXPR_GT binary expression node */
786 /* Use helper function */
787 StudyBinaryExpr (Expr, D);
789 /* If the result is valid, apply the operation */
790 if (ED_IsValid (D)) {
791 D->Val = (D->Val > D->Right);
794 /* In any case, the result is 0 or 1 */
795 D->AddrSize = ADDR_SIZE_ZP;
800 static void StudyLE (ExprNode* Expr, ExprDesc* D)
801 /* Study an EXPR_LE binary expression node */
803 /* Use helper function */
804 StudyBinaryExpr (Expr, D);
806 /* If the result is valid, apply the operation */
807 if (ED_IsValid (D)) {
808 D->Val = (D->Val <= D->Right);
811 /* In any case, the result is 0 or 1 */
812 D->AddrSize = ADDR_SIZE_ZP;
817 static void StudyGE (ExprNode* Expr, ExprDesc* D)
818 /* Study an EXPR_GE binary expression node */
820 /* Use helper function */
821 StudyBinaryExpr (Expr, D);
823 /* If the result is valid, apply the operation */
824 if (ED_IsValid (D)) {
825 D->Val = (D->Val >= D->Right);
828 /* In any case, the result is 0 or 1 */
829 D->AddrSize = ADDR_SIZE_ZP;
834 static void StudyBoolAnd (ExprNode* Expr, ExprDesc* D)
835 /* Study an EXPR_BOOLAND binary expression node */
837 StudyExprInternal (Expr->Left, D);
838 if (ED_IsConst (D)) {
839 if (D->Val != 0) { /* Shortcut op */
842 StudyExprInternal (Expr->Right, D);
843 if (ED_IsConst (D)) {
844 D->Val = (D->Val != 0);
853 /* In any case, the result is 0 or 1 */
854 D->AddrSize = ADDR_SIZE_ZP;
859 static void StudyBoolOr (ExprNode* Expr, ExprDesc* D)
860 /* Study an EXPR_BOOLOR binary expression node */
862 StudyExprInternal (Expr->Left, D);
863 if (ED_IsConst (D)) {
864 if (D->Val == 0) { /* Shortcut op */
867 StudyExprInternal (Expr->Right, D);
868 if (ED_IsConst (D)) {
869 D->Val = (D->Val != 0);
880 /* In any case, the result is 0 or 1 */
881 D->AddrSize = ADDR_SIZE_ZP;
886 static void StudyBoolXor (ExprNode* Expr, ExprDesc* D)
887 /* Study an EXPR_BOOLXOR binary expression node */
889 /* Use helper function */
890 StudyBinaryExpr (Expr, D);
892 /* If the result is valid, apply the operation */
893 if (ED_IsValid (D)) {
894 D->Val = (D->Val != 0) ^ (D->Right != 0);
897 /* In any case, the result is 0 or 1 */
898 D->AddrSize = ADDR_SIZE_ZP;
903 static void StudyUnaryMinus (ExprNode* Expr, ExprDesc* D)
904 /* Study an EXPR_UNARY_MINUS expression node */
906 /* Study the expression */
907 StudyExprInternal (Expr->Left, D);
909 /* If it is valid, negate it */
910 if (ED_IsValid (D)) {
917 static void StudyNot (ExprNode* Expr, ExprDesc* D)
918 /* Study an EXPR_NOT expression node */
920 /* Study the expression */
921 StudyExprInternal (Expr->Left, D);
923 /* We can handle only const expressions */
924 if (ED_IsConst (D)) {
933 static void StudySwap (ExprNode* Expr, ExprDesc* D)
934 /* Study an EXPR_SWAP expression node */
936 /* Study the expression */
937 StudyExprInternal (Expr->Left, D);
939 /* We can handle only const expressions */
940 if (ED_IsConst (D)) {
941 D->Val = (D->Val & ~0xFFFFUL) | ((D->Val >> 8) & 0xFF) | ((D->Val << 8) & 0xFF00);
949 static void StudyBoolNot (ExprNode* Expr, ExprDesc* D)
950 /* Study an EXPR_BOOLNOT expression node */
952 /* Study the expression */
953 StudyExprInternal (Expr->Left, D);
955 /* We can handle only const expressions */
956 if (ED_IsConst (D)) {
957 D->Val = (D->Val == 0);
962 /* In any case, the result is 0 or 1 */
963 D->AddrSize = ADDR_SIZE_ZP;
968 static void StudyByte0 (ExprNode* Expr, ExprDesc* D)
969 /* Study an EXPR_BYTE0 expression node */
971 /* Study the expression */
972 StudyExprInternal (Expr->Left, D);
974 /* We can handle only const expressions */
975 if (ED_IsConst (D)) {
976 D->Val = (D->Val & 0xFF);
981 /* In any case, the result is a zero page expression */
982 D->AddrSize = ADDR_SIZE_ZP;
987 static void StudyByte1 (ExprNode* Expr, ExprDesc* D)
988 /* Study an EXPR_BYTE1 expression node */
990 /* Study the expression */
991 StudyExprInternal (Expr->Left, D);
993 /* We can handle only const expressions */
994 if (ED_IsConst (D)) {
995 D->Val = (D->Val >> 8) & 0xFF;
1000 /* In any case, the result is a zero page expression */
1001 D->AddrSize = ADDR_SIZE_ZP;
1006 static void StudyByte2 (ExprNode* Expr, ExprDesc* D)
1007 /* Study an EXPR_BYTE2 expression node */
1009 /* Study the expression */
1010 StudyExprInternal (Expr->Left, D);
1012 /* We can handle only const expressions */
1013 if (ED_IsConst (D)) {
1014 D->Val = (D->Val >> 16) & 0xFF;
1019 /* In any case, the result is a zero page expression */
1020 D->AddrSize = ADDR_SIZE_ZP;
1025 static void StudyByte3 (ExprNode* Expr, ExprDesc* D)
1026 /* Study an EXPR_BYTE3 expression node */
1028 /* Study the expression */
1029 StudyExprInternal (Expr->Left, D);
1031 /* We can handle only const expressions */
1032 if (ED_IsConst (D)) {
1033 D->Val = (D->Val >> 24) & 0xFF;
1038 /* In any case, the result is a zero page expression */
1039 D->AddrSize = ADDR_SIZE_ZP;
1044 static void StudyWord0 (ExprNode* Expr, ExprDesc* D)
1045 /* Study an EXPR_WORD0 expression node */
1047 /* Study the expression */
1048 StudyExprInternal (Expr->Left, D);
1050 /* We can handle only const expressions */
1051 if (ED_IsConst (D)) {
1052 D->Val = (D->Val & 0xFFFFL);
1057 /* In any case, the result is an absolute expression */
1058 D->AddrSize = ADDR_SIZE_ABS;
1063 static void StudyWord1 (ExprNode* Expr, ExprDesc* D)
1064 /* Study an EXPR_WORD1 expression node */
1066 /* Study the expression */
1067 StudyExprInternal (Expr->Left, D);
1069 /* We can handle only const expressions */
1070 if (ED_IsConst (D)) {
1071 D->Val = (D->Val >> 16) & 0xFFFFL;
1076 /* In any case, the result is an absolute expression */
1077 D->AddrSize = ADDR_SIZE_ABS;
1082 static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
1083 /* Study an expression tree and place the contents into D */
1085 /* Study this expression node */
1089 StudyLiteral (Expr, D);
1093 StudySymbol (Expr, D);
1097 StudySection (Expr, D);
1101 StudyULabel (Expr, D);
1105 StudyPlus (Expr, D);
1109 StudyMinus (Expr, D);
1169 StudyBoolAnd (Expr, D);
1173 StudyBoolOr (Expr, D);
1177 StudyBoolXor (Expr, D);
1180 case EXPR_UNARY_MINUS:
1181 StudyUnaryMinus (Expr, D);
1189 StudySwap (Expr, D);
1193 StudyBoolNot (Expr, D);
1197 StudyByte0 (Expr, D);
1201 StudyByte1 (Expr, D);
1205 StudyByte2 (Expr, D);
1209 StudyByte3 (Expr, D);
1213 StudyWord0 (Expr, D);
1217 StudyWord1 (Expr, D);
1221 Internal ("Unknown Op type: %u", Expr->Op);
1228 void StudyExpr (ExprNode* Expr, ExprDesc* D)
1229 /* Study an expression tree and place the contents into D */
1233 /* Call the internal function */
1234 StudyExprInternal (Expr, D);
1236 /* Remove symbol references with count zero */
1238 while (I < D->SymCount) {
1239 if (D->SymRef[I].Count == 0) {
1240 /* Delete the entry */
1242 memmove (D->SymRef + I, D->SymRef + I + 1,
1243 (D->SymCount - I) * sizeof (D->SymRef[0]));
1250 /* Remove section references with count zero */
1252 while (I < D->SecCount) {
1253 if (D->SecRef[I].Count == 0) {
1254 /* Delete the entry */
1256 memmove (D->SecRef + I, D->SecRef + I + 1,
1257 (D->SecCount - I) * sizeof (D->SecRef[0]));
1264 /* If we don't have an address size, assign one of the expression is a
1267 if (D->AddrSize == ADDR_SIZE_DEFAULT) {
1268 if (ED_IsConst (D)) {
1269 if ((D->Val & ~0xFFL) == 0) {
1270 D->AddrSize = ADDR_SIZE_ZP;
1271 } else if ((D->Val & ~0xFFFFL) == 0) {
1272 D->AddrSize = ADDR_SIZE_ABS;
1273 } else if ((D->Val & 0xFFFFFFL) == 0) {
1274 D->AddrSize = ADDR_SIZE_FAR;
1276 D->AddrSize = ADDR_SIZE_LONG;
1282 printf ("StudyExpr: "); DumpExpr (Expr, SymResolve);
1283 if (!ED_IsValid (D)) {
1284 printf ("Invalid: %s\n", AddrSizeToStr (D->AddrSize));
1286 printf ("Valid: %s\n", AddrSizeToStr (D->AddrSize));
1287 printf ("%u symbols:\n", D->SymCount);
1288 printf ("%u sections:\n", D->SecCount);