]> git.sur5r.net Git - cc65/blob - src/cc65/exprnode.c
Added .dbg statement generation for the assembler
[cc65] / src / cc65 / exprnode.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                exprnode.c                                 */
4 /*                                                                           */
5 /*             Expression node structure for the cc65 C compiler             */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2000      Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@musoftware.de                                            */
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 /* common */
37 #include "check.h"
38
39 /* cc65 */
40 #include "error.h"
41 #include "exprnode.h"
42
43
44
45 /*****************************************************************************/
46 /*                                   Code                                    */
47 /*****************************************************************************/
48
49
50
51 ExprNode* InitExprNode (ExprNode* E, nodetype_t NT, type* Type,
52                         int LValue, struct ExprHeap* Owner)
53 /* Initialize a new expression node */
54 {
55     /* Intialize basic data */
56     E->MData.Owner = Owner;
57     E->NT          = NT;
58     E->Type        = Type;
59     E->LValue      = LValue;
60     E->IVal        = 0;
61     E->FVal        = 0.0;
62
63     /* Initialize the expression list in the node */
64     InitCollection (&E->List);
65
66     /* Return the node just initialized */
67     return E;
68 }
69
70
71
72 void* GetItem (ExprNode* N, unsigned Index)
73 /* Return one of the items from the nodes item list */
74 {
75     return CollAt (&N->List, Index);
76 }
77
78
79
80 void AppendItem (ExprNode* N, void* Item)
81 /* Append an item to the nodes item list */
82 {
83     CollAppend (&N->List, Item);
84 }
85
86
87
88 void SetItem (ExprNode* N, void* Item, unsigned Index)
89 /* Set a specific node item. The item list is filled with null pointers as
90  * needed.
91  */
92 {
93     if (Index >= CollCount (&N->List)) {
94         /* Fill up with NULL pointers */
95         while (Index >= CollCount (&N->List) < Index) {
96             CollAppend (&N->List, 0);
97         }
98         /* Append the new item */
99         CollAppend (&N->List, Item);
100     } else {
101         /* There is an item with this index, replace it */
102         CollReplace (&N->List, Item, Index);
103     }
104 }
105
106
107
108 ExprNode* GetNode (ExprNode* N, unsigned Index)
109 /* Get one of the sub-nodes from the list */
110 {
111     return GetNode (N, Index);
112 }
113
114
115
116 ExprNode* GetLeftNode (ExprNode* N)
117 /* Get the left sub-node from the list */
118 {
119     return GetNode (N, IDX_LEFT);
120 }
121
122
123
124 void SetLeftNode (ExprNode* Root, ExprNode* Left)
125 /* Set the left node in Root */
126 {
127     SetItem (Root, Left, IDX_LEFT);
128 }
129
130
131
132 ExprNode* GetRightNode (ExprNode* N)
133 /* Get the right sub-node from the list */
134 {
135     return GetNode (N, IDX_RIGHT);
136 }
137
138
139
140 void SetRightNode (ExprNode* Root, ExprNode* Right)
141 /* Set the right node in Root */
142 {
143     SetItem (Root, Right, IDX_RIGHT);
144 }
145
146
147
148 struct SymEntry* GetNodeSym (ExprNode* N)
149 /* Get the symbol entry for a NT_SYM node */
150 {
151     return (struct SymEntry*) GetItem (N, IDX_SYM);
152 }
153
154
155
156 void SetNodeSym (ExprNode* N, struct SymEntry* Sym)
157 /* Set the symbol entry in a NT_SYM node */
158 {
159     SetItem (N, Sym, IDX_SYM);
160 }
161
162
163
164 int IsLeafNode (const ExprNode* E)
165 /* Return true if this is a leaf node */
166 {
167     return (E->NT & NT_MASK_LEAF) == NT_LEAF;
168 }
169
170
171
172 int IsBranchNode (const ExprNode* E)
173 /* Return true if this is a branch node */
174 {
175     return (E->NT & NT_MASK_LEAF) == NT_BRANCH;
176 }
177
178
179
180 void DumpExpr (FILE* F, const ExprNode* E)
181 /* Dump an expression in UPN notation to the given file */
182 {
183     if (IsLeafNode (E)) {
184
185         /* Operand */
186         switch (E->NT) {
187
188             case NT_SYM:
189                 /* Symbol */
190                 fprintf (F, "SYM ");
191                 break;
192
193             case NT_CONST:
194                 /* A constant of some sort */
195                 if (IsClassInt (E->Type)) {
196                     fprintf (F, "%0*lX ", SizeOf (E->Type), E->IVal);
197                 } else if (IsClassFloat (E->Type)) {
198                     fprintf (F, "%f ", E->FVal);
199                 } else {
200                     Internal ("Unknown type for NT_CONST");
201                 }
202                 break;
203
204             case NT_ASM:
205                 /* Inline assembler */
206                 fprintf (F, "ASM ");
207                 break;
208
209             case NT_REG_A:
210                 /* A register */
211                 fprintf (F, "REG_A ");
212                 break;
213
214             case NT_REG_X:
215                 /* X register */
216                 fprintf (F, "REG_X ");
217                 break;
218
219             case NT_REG_Y:
220                 /* Y register */
221                 fprintf (F, "REG_Y ");
222                 break;
223
224             case NT_REG_AX:
225                 /* AX register */
226                 fprintf (F, "REG_AX ");
227                 break;
228
229             case NT_REG_EAX:
230                 /* EAX register */
231                 fprintf (F, "REG_EAX ");
232                 break;
233
234             default:
235                 Internal ("Unknown node type: %04X", E->NT);
236                 break;
237
238         }
239
240     } else {
241
242         unsigned I, Count;
243
244         /* Dump the operands */
245         switch (E->NT & NT_MASK_LIST) {
246
247             case NT_LIST_EXPR:
248                 Count = CollCount (&E->List);
249                 for (I = 0; I < Count; ++I) {
250                     DumpExpr (F, (const ExprNode*) CollConstAt (&E->List, I));
251                 }
252                 break;
253
254             default:
255                 Internal ("Operator with LIST != NT_LIST_EXPR");
256
257         }
258
259         /* Dump the operator */
260         switch (E->NT) {
261
262             case NT_ARRAY_SUBSCRIPT:
263                 /* Array subscript */
264                 fprintf (F, "[] ");
265                 break;
266
267             case NT_STRUCT_ACCESS:
268                 /* Access of a struct field */
269                 fprintf (F, ". ");
270                 break;
271
272             case NT_STRUCTPTR_ACCESS:
273                 /* Access via struct ptr */
274                 fprintf (F, "-> ");
275                 break;
276
277             case NT_FUNCTION_CALL:
278                 /* Call a function */
279                 fprintf (F, "CALL ");
280                 break;
281
282             case NT_TYPECAST:
283                 /* A cast */
284                 fprintf (F, "CAST ");
285                 break;
286
287             case NT_ADDRESS:
288                 /* Address operator (&) */
289                 fprintf (F, "ADDR ");
290                 break;
291
292             case NT_INDIRECT:
293                 /* Indirection operator (*) */
294                 fprintf (F, "FETCH ");
295                 break;
296
297             case NT_UNARY_MINUS:
298                 /* - */
299                 fprintf (F, "NEG ");
300                 break;
301
302             case NT_COMPLEMENT:
303                 /* ~ */
304                 fprintf (F, "~ ");
305                 break;
306
307             case NT_BOOL_NOT:
308                 /* ! */
309                 fprintf (F, "! ");
310                 break;
311
312             case NT_PLUS:
313                 /* + */
314                 fprintf (F, "+ ");
315                 break;
316
317             case NT_MINUS:
318                 /* - */
319                 fprintf (F, "- ");
320                 break;
321
322             case NT_MUL:
323                 /* * */
324                 fprintf (F, "* ");
325                 break;
326
327             case NT_DIV:
328                 /* / */
329                 fprintf (F, "/ ");
330                 break;
331
332             case NT_SHL:
333                 /* << */
334                 fprintf (F, "<< ");
335                 break;
336
337             case NT_SHR:
338                 /* >> */
339                 fprintf (F, ">> ");
340                 break;
341
342             case NT_AND:
343                 /* & */
344                 fprintf (F, "& ");
345                 break;
346
347             case NT_OR:
348                 /* | */
349                 fprintf (F, "| ");
350                 break;
351
352             case NT_XOR:
353                 /* ^ */
354                 fprintf (F, "^ ");
355                 break;
356
357             case NT_TERNARY:
358                 /* ?: */
359                 fprintf (F, "?: ");
360                 break;
361
362             case NT_ASSIGN:
363                 /* = */
364                 fprintf (F, "= ");
365                 break;
366
367             case NT_PLUS_ASSIGN:
368                 /* += */
369                 fprintf (F, "+= ");
370                 break;
371
372             case NT_MINUS_ASSIGN:
373                 /* -= */
374                 fprintf (F, "-= ");
375                 break;
376
377             case NT_MUL_ASSIGN:
378                 /* *= */
379                 fprintf (F, "*= ");
380                 break;
381
382             case NT_DIV_ASSIGN:
383                 /* /= */
384                 fprintf (F, "/= ");
385                 break;
386
387             case NT_SHL_ASSIGN:
388                 /* <<= */
389                 fprintf (F, "<<= ");
390                 break;
391
392             case NT_SHR_ASSIGN:
393                 /* >>= */
394                 fprintf (F, ">>= ");
395                 break;
396
397             case NT_AND_ASSIGN:
398                 /* &= */
399                 fprintf (F, "&= ");
400                 break;
401
402             case NT_OR_ASSIGN:
403                 /* |= */
404                 fprintf (F, "|= ");
405                 break;
406
407             case NT_XOR_ASSIGN:
408                 /* ^= */
409                 fprintf (F, "^= ");
410                 break;
411
412             case NT_PRE_DEC:
413                 /* -- */
414                 fprintf (F, "<-- ");
415                 break;
416
417             case NT_POST_DEC:
418                 /* -- */
419                 fprintf (F, "--> ");
420                 break;
421
422             case NT_PRE_INC:
423                 /* ++ */
424                 fprintf (F, "<++ ");
425                 break;
426
427             case NT_POST_INC:
428                 /* ++ */
429                 fprintf (F, "++> ");
430                 break;
431
432             case NT_BOOL_OR:
433                 /* || */
434                 fprintf (F, "|| ");
435                 break;
436
437             case NT_BOOL_AND:
438                 /* && */
439                 fprintf (F, "&& ");
440                 break;
441
442             case NT_EQ:
443                 /* == */
444                 fprintf (F, "== ");
445                 break;
446
447             case NT_NE:
448                 /* != */
449                 fprintf (F, "!= ");
450                 break;
451
452             case NT_LT:
453                 /* < */
454                 fprintf (F, "< ");
455                 break;
456
457             case NT_LE:
458                 /* <= */
459                 fprintf (F, "<= ");
460                 break;
461
462             case NT_GT:
463                 /* > */
464                 fprintf (F, "> ");
465                 break;
466
467             case NT_GE:
468                 /* >= */
469                 fprintf (F, ">= ");
470                 break;
471
472             default:
473                 Internal ("Unknown node type: %04X", E->NT);
474                 break;
475
476         }
477     }
478 }
479
480
481