2 * $Id: astnode.c,v 1.15 2007/08/12 18:58:12 khansen Exp $
4 * Revision 1.15 2007/08/12 18:58:12 khansen
5 * ability to generate pure 6502 binary (--pure-binary switch)
7 * Revision 1.14 2007/08/10 20:21:02 khansen
8 * *** empty log message ***
10 * Revision 1.13 2007/08/09 22:05:49 khansen
11 * general-purpose flags
13 * Revision 1.12 2007/08/07 21:12:16 khansen
16 * Revision 1.11 2007/07/22 13:33:26 khansen
17 * convert tabs to whitespaces
19 * Revision 1.10 2004/12/29 21:44:04 kenth
21 * added create_index()
23 * Revision 1.9 2004/12/19 19:58:23 kenth
26 * Revision 1.8 2004/12/19 09:53:46 kenth
27 * added create_align()
29 * Revision 1.7 2004/12/18 16:56:12 kenth
30 * create_extrn() takes unit id
32 * Revision 1.6 2004/12/16 13:19:07 kenth
33 * astnode_create_label() takes datatype argument
35 * Revision 1.5 2004/12/14 01:48:57 kenth
38 * Revision 1.4 2004/12/11 02:01:10 kenth
39 * added forward/backward branching
41 * Revision 1.3 2004/12/09 11:17:59 kenth
42 * added: warning, error nodes
44 * Revision 1.2 2004/12/06 04:52:05 kenth
45 * Major updates (xorcyst 1.1.0)
47 * Revision 1.1 2004/06/30 07:55:28 kenth
53 * (C) 2004 Kent Hansen
55 * The XORcyst is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
57 * the Free Software Foundation; either version 2 of the License, or
58 * (at your option) any later version.
60 * The XORcyst is distributed in the hope that it will be useful,
61 * but WITHOUT ANY WARRANTY; without even the implied warranty of
62 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 * GNU General Public License for more details.
65 * You should have received a copy of the GNU General Public License
66 * along with The XORcyst; if not, write to the Free Software
67 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
71 * The result of parsing an assembly file is an Abstract Syntax Tree (AST).
72 * Such a tree consists of AST nodes.
73 * This file contains the code to manipulate such nodes.
83 #define SAFE_FREE(a) if (a) { free(a); a = NULL; }
85 /*---------------------------------------------------------------------------*/
86 /* Functions to convert and print astnodes as string.
87 These are useful when debugging syntax trees.
91 * Gets string representation of an addressing mode.
92 * @param am Addressing mode (enumerated type)
93 * @return String representation of am
95 const char *addressing_mode_to_string(addressing_mode am
)
98 case IMPLIED_MODE
: return "IMPLIED_MODE";
99 case ACCUMULATOR_MODE
: return "ACCUMULATOR_MODE";
100 case IMMEDIATE_MODE
: return "IMMEDIATE_MODE";
101 case ZEROPAGE_MODE
: return "ZEROPAGE_MODE";
102 case ZEROPAGE_X_MODE
: return "ZEROPAGE_X_MODE";
103 case ZEROPAGE_Y_MODE
: return "ZEROPAGE_Y_MODE";
104 case ABSOLUTE_MODE
: return "ABSOLUTE_MODE";
105 case ABSOLUTE_X_MODE
: return "ABSOLUTE_X_MODE";
106 case ABSOLUTE_Y_MODE
: return "ABSOLUTE_Y_MODE";
107 case PREINDEXED_INDIRECT_MODE
: return "PREINDEXED_INDIRECT_MODE";
108 case POSTINDEXED_INDIRECT_MODE
: return "POSTINDEXED_INDIRECT_MODE";
109 case INDIRECT_MODE
: return "INDIRECT_MODE";
110 case RELATIVE_MODE
: return "RELATIVE_MODE";
111 case INVALID_MODE
: assert(0); break;
113 return "addressing_mode_to_string: invalid addressing mode";
117 * Gets string representation of an instruction mnemonic.
118 * @param im Instruction mnemonic (enumerated type)
119 * @return String representation of im
121 const char *instr_mnemonic_to_string(instr_mnemonic im
)
124 case ADC_MNEMONIC
: return "ADC_MNEMONIC";
125 case AND_MNEMONIC
: return "AND_MNEMONIC";
126 case ASL_MNEMONIC
: return "ASL_MNEMONIC";
127 case BCC_MNEMONIC
: return "BCC_MNEMONIC";
128 case BCS_MNEMONIC
: return "BCS_MNEMONIC";
129 case BEQ_MNEMONIC
: return "BEQ_MNEMONIC";
130 case BIT_MNEMONIC
: return "BIT_MNEMONIC";
131 case BMI_MNEMONIC
: return "BMI_MNEMONIC";
132 case BNE_MNEMONIC
: return "BNE_MNEMONIC";
133 case BPL_MNEMONIC
: return "BPL_MNEMONIC";
134 case BRK_MNEMONIC
: return "BRK_MNEMONIC";
135 case BVC_MNEMONIC
: return "BVC_MNEMONIC";
136 case BVS_MNEMONIC
: return "BVS_MNEMONIC";
137 case CLC_MNEMONIC
: return "CLC_MNEMONIC";
138 case CLD_MNEMONIC
: return "CLD_MNEMONIC";
139 case CLI_MNEMONIC
: return "CLI_MNEMONIC";
140 case CLV_MNEMONIC
: return "CLV_MNEMONIC";
141 case CMP_MNEMONIC
: return "CMP_MNEMONIC";
142 case CPX_MNEMONIC
: return "CPX_MNEMONIC";
143 case CPY_MNEMONIC
: return "CPY_MNEMONIC";
144 case DEC_MNEMONIC
: return "DEC_MNEMONIC";
145 case DEX_MNEMONIC
: return "DEX_MNEMONIC";
146 case DEY_MNEMONIC
: return "DEY_MNEMONIC";
147 case EOR_MNEMONIC
: return "EOR_MNEMONIC";
148 case INC_MNEMONIC
: return "INC_MNEMONIC";
149 case INX_MNEMONIC
: return "INX_MNEMONIC";
150 case INY_MNEMONIC
: return "INY_MNEMONIC";
151 case JMP_MNEMONIC
: return "JMP_MNEMONIC";
152 case JSR_MNEMONIC
: return "JSR_MNEMONIC";
153 case LDA_MNEMONIC
: return "LDA_MNEMONIC";
154 case LDX_MNEMONIC
: return "LDX_MNEMONIC";
155 case LDY_MNEMONIC
: return "LDY_MNEMONIC";
156 case LSR_MNEMONIC
: return "LSR_MNEMONIC";
157 case NOP_MNEMONIC
: return "NOP_MNEMONIC";
158 case ORA_MNEMONIC
: return "ORA_MNEMONIC";
159 case PHA_MNEMONIC
: return "PHA_MNEMONIC";
160 case PHP_MNEMONIC
: return "PHP_MNEMONIC";
161 case PLA_MNEMONIC
: return "PLA_MNEMONIC";
162 case PLP_MNEMONIC
: return "PLP_MNEMONIC";
163 case ROL_MNEMONIC
: return "ROL_MNEMONIC";
164 case ROR_MNEMONIC
: return "ROR_MNEMONIC";
165 case RTI_MNEMONIC
: return "RTI_MNEMONIC";
166 case RTS_MNEMONIC
: return "RTS_MNEMONIC";
167 case SBC_MNEMONIC
: return "SBC_MNEMONIC";
168 case SEC_MNEMONIC
: return "SEC_MNEMONIC";
169 case SED_MNEMONIC
: return "SED_MNEMONIC";
170 case SEI_MNEMONIC
: return "SEI_MNEMONIC";
171 case STA_MNEMONIC
: return "STA_MNEMONIC";
172 case STX_MNEMONIC
: return "STX_MNEMONIC";
173 case STY_MNEMONIC
: return "STY_MNEMONIC";
174 case TAX_MNEMONIC
: return "TAX_MNEMONIC";
175 case TAY_MNEMONIC
: return "TAY_MNEMONIC";
176 case TSX_MNEMONIC
: return "TSX_MNEMONIC";
177 case TXA_MNEMONIC
: return "TXA_MNEMONIC";
178 case TXS_MNEMONIC
: return "TXS_MNEMONIC";
179 case TYA_MNEMONIC
: return "TYA_MNEMONIC";
181 return "instr_mnemonic_to_string: invalid mnemonic";
185 * Gets string representation of an astnode type.
186 * @param at Node type
187 * @return String representation of at
189 const char *astnode_type_to_string(astnode_type at
) {
191 case NULL_NODE
: return "NULL_NODE";
192 case INTEGER_NODE
: return "INTEGER_NODE";
193 case STRING_NODE
: return "STRING_NODE";
194 case IDENTIFIER_NODE
: return "IDENTIFIER_NODE";
195 case DATA_NODE
: return "DATA_NODE";
196 case STORAGE_NODE
: return "STORAGE_NODE";
197 case MACRO_DECL_NODE
: return "MACRO_DECL_NODE";
198 case MACRO_NODE
: return "MACRO_NODE";
199 case ARITHMETIC_NODE
: return "ARITHMETIC_NODE";
200 case IF_NODE
: return "IF_NODE";
201 case CASE_NODE
: return "CASE_NODE";
202 case DEFAULT_NODE
: return "DEFAULT_NODE";
203 case IFDEF_NODE
: return "IFDEF_NODE";
204 case IFNDEF_NODE
: return "IFNDEF_NODE";
205 case INCSRC_NODE
: return "INCSRC_NODE";
206 case INCBIN_NODE
: return "INCBIN_NODE";
207 case EQU_NODE
: return "EQU_NODE";
208 case ASSIGN_NODE
: return "ASSIGN_NODE";
209 case ALIGN_NODE
: return "ALIGN_NODE";
210 case INSTRUCTION_NODE
: return "INSTRUCTION_NODE";
211 case FILE_PATH_NODE
: return "FILE_PATH_NODE";
212 case CURRENT_PC_NODE
: return "CURRENT_PC_NODE";
213 case LIST_NODE
: return "LIST_NODE";
214 case LABEL_NODE
: return "LABEL_NODE";
215 case LOCAL_LABEL_NODE
: return "LOCAL_LABEL_NODE";
216 case LOCAL_ID_NODE
: return "LOCAL_ID_NODE";
217 case BINARY_NODE
: return "BINARY_NODE";
218 case PUBLIC_NODE
: return "PUBLIC_NODE";
219 case EXTRN_NODE
: return "EXTRN_NODE";
220 case DATASEG_NODE
: return "DATASEG_NODE";
221 case CODESEG_NODE
: return "CODESEG_NODE";
222 case CHARMAP_NODE
: return "CHARMAP_NODE";
223 case STRUC_NODE
: return "STRUC_NODE";
224 case STRUC_DECL_NODE
: return "STRUC_DECL_NODE";
225 case UNION_DECL_NODE
: return "UNION_DECL_NODE";
226 case ENUM_DECL_NODE
: return "ENUM_DECL_NODE";
227 case RECORD_DECL_NODE
: return "RECORD_DECL_NODE";
228 case BITFIELD_DECL_NODE
:return "BITFIELD_DECL_NODE";
229 case DOT_NODE
: return "DOT_NODE";
230 case SIZEOF_NODE
: return "SIZEOF_NODE";
231 case DATATYPE_NODE
: return "DATATYPE_NODE";
232 case VAR_DECL_NODE
: return "VAR_DECL_NODE";
233 case SCOPE_NODE
: return "SCOPE_NODE";
234 case PROC_NODE
: return "PROC_NODE";
235 case REPT_NODE
: return "REPT_NODE";
236 case WHILE_NODE
: return "WHILE_NODE";
237 case MESSAGE_NODE
: return "MESSAGE_NODE";
238 case WARNING_NODE
: return "WARNING_NODE";
239 case ERROR_NODE
: return "ERROR_NODE";
240 case FORWARD_BRANCH_DECL_NODE
: return "FORWARD_BRANCH_DECL_NODE";
241 case BACKWARD_BRANCH_DECL_NODE
: return "BACKWARD_BRANCH_DECL_NODE";
242 case FORWARD_BRANCH_NODE
: return "FORWARD_BRANCH_NODE";
243 case BACKWARD_BRANCH_NODE
: return "BACKWARD_BRANCH_NODE";
244 case MASK_NODE
: return "MASK_NODE";
245 case INDEX_NODE
: return "INDEX_NODE";
246 case ORG_NODE
: return "ORG_NODE";
247 case TOMBSTONE_NODE
: return "TOMBSTONE_NODE";
249 return "astnode_type_to_string: invalid type";
253 * Gets string representation of a datatype.
255 * @return String representation of dt
257 const char *datatype_to_string(const astnode
*dt
)
259 switch (dt
->datatype
) {
260 case BYTE_DATATYPE
: return "BYTE_DATATYPE";
261 case CHAR_DATATYPE
: return "CHAR_DATATYPE";
262 case WORD_DATATYPE
: return "WORD_DATATYPE";
263 case DWORD_DATATYPE
: return "DWORD_DATATYPE";
264 case USER_DATATYPE
: return "USER_DATATYPE"; // astnode_get_child(dt, 0)->ident;
266 return "datatype_to_string: invalid datatype";
270 * Gets string representation of an operator.
272 * @return String representation of op
274 const char *operator_to_string(int op
)
277 case PLUS_OPERATOR
: return "PLUS_OPERATOR";
278 case MINUS_OPERATOR
: return "MINUS_OPERATOR";
279 case MUL_OPERATOR
: return "MUL_OPERATOR";
280 case DIV_OPERATOR
: return "DIV_OPERATOR";
281 case MOD_OPERATOR
: return "MOD_OPERATOR";
282 case AND_OPERATOR
: return "AND_OPERATOR";
283 case OR_OPERATOR
: return "OR_OPERATOR";
284 case XOR_OPERATOR
: return "XOR_OPERATOR";
285 case SHL_OPERATOR
: return "SHL_OPERATOR";
286 case SHR_OPERATOR
: return "SHR_OPERATOR";
287 case LT_OPERATOR
: return "LT_OPERATOR";
288 case GT_OPERATOR
: return "GT_OPERATOR";
289 case EQ_OPERATOR
: return "EQ_OPERATOR";
290 case NE_OPERATOR
: return "NE_OPERATOR";
291 case LE_OPERATOR
: return "LE_OPERATOR";
292 case GE_OPERATOR
: return "GE_OPERATOR";
293 case NEG_OPERATOR
: return "NEG_OPERATOR";
294 case NOT_OPERATOR
: return "NOT_OPERATOR";
295 case LO_OPERATOR
: return "LO_OPERATOR";
296 case HI_OPERATOR
: return "HI_OPERATOR";
297 case UMINUS_OPERATOR
: return "UMINUS_OPERATOR";
298 case BANK_OPERATOR
: return "BANK_OPERATOR";
300 return "operator_to_string: invalid operator";
305 * @param nlevels Levels
307 void indent(int nlevels
)
310 for (i
=0; i
<nlevels
; i
++) {
316 * Prints a node recursively.
317 * @param n Node to print
318 * @param level Level (depth)
320 void astnode_print(const astnode
*n
, int level
)
323 /* Indent so it looks pretty */
325 /* Print the node type */
326 printf(astnode_type_to_string(astnode_get_type(n
)));
327 /* Print attributes for those that have */
328 switch (astnode_get_type(n
)) {
329 case INTEGER_NODE
: printf("(%d)", n
->integer
); break;
330 case STRING_NODE
: printf("(\"%s\")", n
->string
); break;
331 case IDENTIFIER_NODE
: printf("(%s)", n
->ident
); break;
332 case LOCAL_ID_NODE
: printf("(%s)", n
->ident
); break;
333 case FILE_PATH_NODE
: printf("(%s)", n
->file_path
); break;
334 case LABEL_NODE
: printf("(%s)", n
->label
); break;
335 case LOCAL_LABEL_NODE
: printf("(%s)", n
->label
); break;
336 case BINARY_NODE
: printf("(%d)", n
->binary
.size
); break;
338 case ARITHMETIC_NODE
:
341 operator_to_string(n
->oper
)
345 case INSTRUCTION_NODE
:
348 instr_mnemonic_to_string(n
->instr
.mnemonic
),
349 addressing_mode_to_string(n
->instr
.mode
),
357 datatype_to_string(n
)
361 case FORWARD_BRANCH_DECL_NODE
:
362 case BACKWARD_BRANCH_DECL_NODE
:
363 case FORWARD_BRANCH_NODE
:
364 case BACKWARD_BRANCH_NODE
:
365 printf("(%s)", n
->ident
);
371 astnode_type_to_string(n
->param
)
376 /* Has no internal attributes */
380 /* Print the children */
381 for (i
=0; i
<astnode_get_child_count(n
); i
++) {
382 astnode_print(astnode_get_child(n
, i
), level
+1);
386 /*---------------------------------------------------------------------------*/
387 /* Functions for general-purpose node management:
388 Creation, destruction, children etc.
392 * Creates a new node of the given type.
393 * @param type The node's type
394 * @param loc File location
395 * @return The newly created node
397 astnode
*astnode_create(astnode_type type
, location loc
)
399 extern const char *yy_current_filename();
400 if (loc
.file
== NULL
) {
401 loc
.file
= yy_current_filename();
403 /* Allocate memory for node struct */
404 astnode
*n
= (astnode
*)malloc(sizeof(astnode
));
405 /* Fill in struct only if alloc succeeded */
412 n
->parent
= n
->first_child
= n
->prev_sibling
= n
->next_sibling
= NULL
;
419 * Any children of the node are also finalized, recursively.
420 * @param n The node to finalize.
422 void astnode_finalize(astnode
*n
)
424 /* Remove the node from the tree it's in. */
426 /* Finalize all its children recursively. */
427 while (astnode_get_first_child(n
) != NULL
) {
428 astnode_finalize(astnode_remove_child_at(n
, 0));
430 /* Free up memory. */
431 switch (astnode_get_type(n
)) {
432 case LABEL_NODE
: SAFE_FREE(n
->label
); break;
433 case LOCAL_LABEL_NODE
: SAFE_FREE(n
->label
); break;
434 case STRING_NODE
: SAFE_FREE(n
->string
); break;
435 case IDENTIFIER_NODE
: SAFE_FREE(n
->ident
); break;
436 case LOCAL_ID_NODE
: SAFE_FREE(n
->ident
); break;
437 case FILE_PATH_NODE
: SAFE_FREE(n
->file_path
);break;
438 case BINARY_NODE
: SAFE_FREE(n
->binary
.data
); break;
439 case FORWARD_BRANCH_DECL_NODE
:
440 case BACKWARD_BRANCH_DECL_NODE
:
441 case FORWARD_BRANCH_NODE
:
442 case BACKWARD_BRANCH_NODE
:
446 /* Has no internal attributes that are dynamically allocated */
453 * Gets the node's type.
454 * @param n The node whose type to get
455 * @return The node's type (astnode_type)
457 astnode_type
astnode_get_type(const astnode
*n
)
459 return (n
!= NULL
) ? n
->type
: NULL_NODE
;
463 * Sets the parent field of all nodes in c to p.
465 void astnode_set_parent(astnode
*c
, astnode
*p
)
468 for (n
= c
; n
!= NULL
; n
= n
->next_sibling
) {
474 * Replaces a node with another.
476 void astnode_replace(astnode
*old_node
, astnode
*new_node
)
480 /* Get the parent of the node to be replaced */
481 p
= astnode_get_parent(old_node
);
483 /* Call remove_child on parent */
484 i
= astnode_remove_child(p
, old_node
);
485 /* Insert new child at old child's position */
486 astnode_insert_child(p
, new_node
, i
);
491 * Removes a node from a tree.
492 * @param n The node to remove (can't be the root of the tree)
494 void astnode_remove(astnode
*n
)
496 astnode
*p
= astnode_get_parent(n
);
498 astnode_remove_child(p
, n
);
503 * Removes a child node.
504 * @param p Parent node
505 * @param c Child node
506 * @return Index of the removed node
508 int astnode_remove_child(astnode
*p
, astnode
*c
)
511 i
= astnode_get_child_index(p
, c
);
513 /* Remove head of list. */
514 p
->first_child
= c
->next_sibling
;
515 if (p
->first_child
) {
516 p
->first_child
->prev_sibling
= NULL
;
518 c
->parent
= c
->next_sibling
= c
->prev_sibling
= NULL
;
521 c
->prev_sibling
->next_sibling
= c
->next_sibling
;
522 if (c
->next_sibling
) {
523 c
->next_sibling
->prev_sibling
= c
->prev_sibling
;
525 c
->parent
= c
->next_sibling
= c
->prev_sibling
= NULL
;
531 * Removes child node at specified index.
532 * @param p Parent node
533 * @param i Index >= 0
535 astnode
*astnode_remove_child_at(astnode
*p
, int i
)
537 astnode
*c
= astnode_get_child(p
, i
);
538 astnode_remove_child(p
, c
);
543 * Removes all children from a node and returns them as a list.
544 * @param p Parent node whose children to remove
546 astnode
*astnode_remove_children(astnode
*p
)
549 if (p
== NULL
) { return NULL
; }
550 if (p
->first_child
!= NULL
) {
552 p
->first_child
= NULL
;
553 /* Set parent of all siblings to NULL. */
554 astnode_set_parent(c
, NULL
);
555 /* Return the list of children */
559 /* Has no children. */
565 * Inserts a list of nodes as children.
568 void astnode_insert_child(astnode
*p
, astnode
*c
, int i
)
573 x
= astnode_get_child(p
, i
); /* Current child at that position */
575 /* There isn't a node here. Just add to end. */
576 astnode_add_child(p
, c
);
579 n
= astnode_get_last_sibling(c
);
580 /* Make c..n precede x */
581 c
->prev_sibling
= x
->prev_sibling
;
582 if (x
->prev_sibling
) {
583 x
->prev_sibling
->next_sibling
= c
;
589 astnode_set_parent(c
, p
);
598 * Gets the last node in a list.
600 astnode
*astnode_get_last_sibling(const astnode
*n
)
604 for (s
= (astnode
*)n
; s
->next_sibling
!= NULL
; s
= s
->next_sibling
) ;
610 * Gets the parent of a node.
611 * @param n The node whose parent to get
612 * @return The node's parent, or <code>NULL</code> if it has none
614 astnode
*astnode_get_parent(const astnode
*n
)
616 return n
? n
->parent
: NULL
;
620 * Adds child(ren) to a node.
621 * @param n The parent-to-be
622 * @param new_child List of children-to-be
624 void astnode_add_child(astnode
*n
, astnode
*new_child
)
626 if (n
&& new_child
) {
627 if (n
->first_child
== NULL
) {
628 /* This node has no children, add this as the first one */
629 n
->first_child
= new_child
;
630 astnode_set_parent(new_child
, n
);
633 astnode_add_sibling(n
->first_child
, new_child
);
639 * Adds any number of children to a node.
640 * @param n The parent-to-be
642 void astnode_add_children(astnode
*n
, int count
, ...)
649 for (i
=0; i
<count
; i
++) {
650 c
= va_arg(ap
, astnode
*);
651 astnode_add_child(n
, c
);
657 * Adds sibling(s) to a node.
658 * @param brother List of existing siblings
659 * @param sister List of new siblings
661 void astnode_add_sibling(astnode
*brother
, astnode
*sister
)
665 if (brother
&& sister
) {
666 /* Add to end of list */
667 n
= astnode_get_last_sibling(brother
);
668 n
->next_sibling
= sister
;
669 sister
->prev_sibling
= n
;
670 p
= astnode_get_parent(brother
);
671 astnode_set_parent(sister
, p
);
676 * Gets the child node at the specified index.
677 * @param n The parent node
678 * @param index The index of the desired child node
680 astnode
*astnode_get_child(const astnode
*n
, int index
)
686 for (i
= 0; i
!= index
; i
++) {
688 /* No child at that index. */
695 /* Node is NULL, so return NULL */
700 * Gets a node's first child.
703 astnode
*astnode_get_first_child(const astnode
*n
)
705 return (n
== NULL
) ? NULL
: n
->first_child
;
709 * Gets the index of a child node.
710 * @param p Parent node
711 * @param c Child node
712 * @return Index of c >= 0, or -1 if invalid input
714 int astnode_get_child_index(const astnode
*p
, const astnode
*c
)
719 for (i
=0, n
=p
->first_child
; (n
!= c
) && (n
!= NULL
); i
++, n
=n
->next_sibling
);
726 * Gets the number of children a node has.
727 * @param p Node whose children count to get
729 int astnode_get_child_count(const astnode
*p
)
734 for (c
= p
->first_child
; c
!= NULL
; count
++, c
= c
->next_sibling
);
740 * Clones a node and all its children.
741 * @param n The node to clone
742 * @param loc File location
744 astnode
*astnode_clone(const astnode
*n
, location loc
)
748 if (n
== NULL
) { return NULL
; }
750 c
= astnode_create(astnode_get_type(n
), loc
);
751 /* Copy attributes */
752 switch (astnode_get_type(n
)) {
754 c
->integer
= n
->integer
;
758 case IDENTIFIER_NODE
:
761 case LOCAL_LABEL_NODE
:
763 c
->string
= (char *)malloc(strlen(n
->string
)+1);
764 if (c
->string
!= NULL
) {
765 strcpy(c
->string
, n
->string
);
769 case ARITHMETIC_NODE
:
773 case INSTRUCTION_NODE
:
778 c
->binary
= n
->binary
;
782 c
->datatype
= n
->datatype
;
788 /* Clone children (TODO: OPTIMIZE THIS) */
789 for (n_c
=n
->first_child
; n_c
!= NULL
; n_c
=n_c
->next_sibling
) {
790 astnode_add_child(c
, astnode_clone(n_c
, loc
));
792 /* Return the clone */
797 * Tests if two nodes are equal.
799 int astnode_equal(const astnode
*n1
, const astnode
*n2
)
802 /* Verify that types are the same */
803 if (astnode_get_type(n1
) != astnode_get_type(n2
)) {
804 return 0; /* Types don't match -- not equal */
806 /* Verify that internal data is the same */
807 switch (astnode_get_type(n1
)) {
808 case ARITHMETIC_NODE
: if (n1
->oper
!= n2
->oper
) return 0; break;
809 case INTEGER_NODE
: if (n1
->integer
!= n2
->integer
) return 0; break;
810 case STRING_NODE
: if (strcmp(n1
->string
, n2
->string
)) return 0; break;
811 case IDENTIFIER_NODE
: if (strcmp(n1
->ident
, n2
->ident
)) return 0; break;
812 case LOCAL_ID_NODE
: if (strcmp(n1
->ident
, n2
->ident
)) return 0; break;
813 case FILE_PATH_NODE
: if (strcmp(n1
->file_path
, n2
->file_path
)) return 0; break;
814 case LABEL_NODE
: if (strcmp(n1
->label
, n2
->label
)) return 0; break;
815 case LOCAL_LABEL_NODE
: if (strcmp(n1
->label
, n2
->label
)) return 0; break;
816 case BINARY_NODE
: if (n1
->binary
.size
!= n2
->binary
.size
) return 0; break;
817 case DATATYPE_NODE
: if (n1
->datatype
!= n2
->datatype
) return 0; break;
818 case TOMBSTONE_NODE
: if (n1
->param
!= n2
->param
) return 0; break;
819 case INSTRUCTION_NODE
: if ( (n1
->instr
.mnemonic
!= n2
->instr
.mnemonic
) || (n1
->instr
.mode
!= n2
->instr
.mode
) ) return 0; break;
821 /* Has no internal attributes */
824 /* Verify that they have the same number of children */
825 if (astnode_get_child_count(n1
) != astnode_get_child_count(n2
)) {
828 /* Verify that children are equal */
829 for (i
=0; i
<astnode_get_child_count(n1
); i
++) {
830 if (!astnode_equal(astnode_get_child(n1
, i
), astnode_get_child(n2
, i
))) {
839 * Gets the ancestor of a node.
840 * @param n Node whose ancestor to get
841 * @param back How many generations to go back (0=father, 1=grandfather etc.)
843 astnode
*astnode_get_ancestor(const astnode
*n
, int back
)
846 astnode
*a
= astnode_get_parent(n
);
847 for (i
=0; i
<back
; i
++) {
848 a
= astnode_get_parent(a
);
854 * Tests if a node is a descendant of a node of a particular type.
856 * @param type Ancestor's type
857 * @return 0 if no such ancestor, 1 otherwise
859 int astnode_has_ancestor_of_type(const astnode
*n
, astnode_type type
)
862 for (a
= astnode_get_parent(n
); a
!= NULL
; a
= astnode_get_parent(a
) ) {
863 if (astnode_is_type(a
, type
)) {
871 * Gets the next sibling of a node.
874 astnode
*astnode_get_next_sibling(const astnode
*n
)
876 if (n
== NULL
) { return NULL
; }
877 return n
->next_sibling
;
881 * Gets the previous sibling of a node.
884 astnode
*astnode_get_prev_sibling(const astnode
*n
)
886 if (n
== NULL
) { return NULL
; }
887 return n
->prev_sibling
;
891 * Tests if a node is a literal.
892 * @param n Node to test
894 int astnode_is_literal(const astnode
*n
)
896 switch (astnode_get_type(n
)) {
910 /*---------------------------------------------------------------------------*/
911 /* Functions for creating AST nodes of specific type.
912 1:1 correspondence between astnode_create_* and *_INSTRUCTION.
913 Each takes the operands required for that node type,
914 calls astnode_create() and then fills in fields and adds children (if any).
917 astnode
*astnode_create_null(location loc
)
919 /* Create the node */
920 astnode
*n
= astnode_create(NULL_NODE
, loc
);
921 /* Return the newly created node */
926 * Creates a CPU instruction node.
927 * @param mnemonic The instruction mnemonic
928 * @param mode The addressing mode used
929 * @param operand The instruction operand (an expression) (can be <code>NULL</code>)
930 * @param loc File location
932 astnode
*astnode_create_instruction(int mnemonic
, addressing_mode mode
, astnode
*operand
, location loc
)
934 /* Create the node */
935 astnode
*n
= astnode_create(INSTRUCTION_NODE
, loc
);
936 /* Store the mnemonic and addressing mode */
937 n
->instr
.mnemonic
= mnemonic
;
938 n
->instr
.mode
= mode
;
939 /* This node has one child: The operand, which is an expression */
940 astnode_add_child(n
, operand
);
941 /* Return the newly created node */
946 * Creates an identifier node.
947 * @param ident The identifier (a string)
948 * @param loc File location
950 astnode
*astnode_create_identifier(const char *ident
, location loc
)
952 /* Create the node */
953 astnode
*n
= astnode_create(IDENTIFIER_NODE
, loc
);
954 /* Allocate and store text */
955 n
->ident
= (char *)malloc(strlen(ident
)+1);
956 if (n
->ident
!= NULL
) {
957 strcpy(n
->ident
, ident
);
959 /* Return the newly created node */
964 * Creates an integer literal node.
965 * @param value The integer literal
966 * @param loc File location
968 astnode
*astnode_create_integer(int value
, location loc
)
970 /* Create the node */
971 astnode
*n
= astnode_create(INTEGER_NODE
, loc
);
972 /* Store the integer which this node represents */
974 /* Return the newly created node */
979 * Creates a string literal node.
980 * @param value The string literal
981 * @param loc File location
983 astnode
*astnode_create_string(const char *value
, location loc
)
985 /* Create the node */
986 astnode
*n
= astnode_create(STRING_NODE
, loc
);
987 /* Allocate and store text */
988 n
->string
= (char *)malloc(strlen(value
)+1);
989 if (n
->string
!= NULL
) {
990 strcpy(n
->string
, value
);
992 /* Return the newly created node */
997 * Creates an expression node (unary or binary).
998 * @param oper The operator
999 * @param left Left operand
1000 * @param right Right operand (can be <code>NULL</code>)
1001 * @param loc File location
1003 astnode
*astnode_create_arithmetic(arithmetic_operator oper
, astnode
*left
, astnode
*right
, location loc
)
1005 /* Create the node */
1006 astnode
*n
= astnode_create(ARITHMETIC_NODE
, loc
);
1007 /* Store the operator, which describes the type of expression */
1009 /* This node has two children: left-hand side and right-hand side expression */
1010 /* For unary operators right-hand side should be <code>NULL</code> */
1011 astnode_add_children(n
, 2, left
, right
);
1012 /* Return the newly created node */
1017 * Creates an if node.
1018 * @param expr The expression involved in the if
1019 * @param then The statement(s) to assemble when expr is non-zero
1020 * @param elif List of CASE nodes (may be <code>NULL</code>)
1021 * @param els The final else-part (DEFAULT node) (may be <code>NULL</code>)
1022 * @param loc File location
1024 astnode
*astnode_create_if(astnode
*expr
, astnode
*then
, astnode
*elif
, astnode
*els
, location loc
)
1026 /* Create the node */
1027 astnode
*n
= astnode_create(IF_NODE
, loc
);
1028 /* This node has several children: List of CASE nodes, possibly ended by DEFAULT node */
1029 astnode_add_child(n
, astnode_create_case(expr
, then
, loc
) );
1030 astnode_add_child(n
, elif
);
1032 astnode_add_child(n
, astnode_create_default(els
, loc
));
1034 /* Return the newly created node */
1039 * Creates a CASE node.
1040 * @param expr Expression
1041 * @param then List of statement to assemble when expr is non-zero (true)
1042 * @param loc File location
1044 astnode
*astnode_create_case(astnode
*expr
, astnode
*then
, location loc
)
1046 /* Create the node */
1047 astnode
*n
= astnode_create(CASE_NODE
, loc
);
1048 /* This node has two children: expression to test and list of statements. */
1049 astnode_add_children(
1053 astnode_create_list(then
)
1055 /* Return the newly created node */
1060 * Creates a DEFAULT node.
1061 * @param stmts List of statements
1062 * @param loc File location
1064 astnode
*astnode_create_default(astnode
*stmts
, location loc
)
1066 /* Create the node */
1067 astnode
*n
= astnode_create(DEFAULT_NODE
, loc
);
1068 /* This node has list of statements as children. */
1073 /* Return the newly created node */
1078 * Creates an ifdef node.
1079 * @param ident The identifier to check
1080 * @param then The statement(s) to assemble when ident is defined
1081 * @param els The statement(s) to assemble when ident is not defined (can be <code>NULL</code>)
1082 * @param loc File location
1084 astnode
*astnode_create_ifdef(astnode
*ident
, astnode
*then
, astnode
*els
, location loc
)
1086 /* Create the node */
1087 astnode
*n
= astnode_create(IFDEF_NODE
, loc
);
1088 /* This node has three children: identifier to test, then-part, else-part */
1089 astnode_add_children(
1093 astnode_create_list(then
),
1094 astnode_create_list(els
)
1096 /* Return the newly created node */
1101 * Creates an ifndef node.
1102 * @param ident The identifier to check
1103 * @param then The statement(s) to assemble when ident is not defined
1104 * @param els The statement(s) to assemble when ident is defined (can be <code>NULL</code>)
1105 * @param loc File location
1107 astnode
*astnode_create_ifndef(astnode
*ident
, astnode
*then
, astnode
*els
, location loc
)
1109 /* Create the node */
1110 astnode
*n
= astnode_create(IFNDEF_NODE
, loc
);
1111 /* This node has three children: identifier to test, then-part, else-part */
1112 astnode_add_children(
1116 astnode_create_list(then
),
1117 astnode_create_list(els
)
1119 /* Return the newly created node */
1124 * Creates a macro declaration node.
1125 * @param ident Name of macro
1126 * @param params List of parameters (can be <code>NULL</code>)
1127 * @param body Macro body
1128 * @param loc File location
1130 astnode
*astnode_create_macro_decl(astnode
*ident
, astnode
*params
, astnode
*body
, location loc
)
1132 /* Create the node */
1133 astnode
*n
= astnode_create(MACRO_DECL_NODE
, loc
);
1134 /* This node has three children:
1135 1) An identifier, which is the name of the macro
1136 2) List of parameters
1137 3) List of statements, which is the macro body */
1138 astnode_add_children(
1142 astnode_create_list(params
),
1143 astnode_create_list(body
)
1145 /* Return the newly created node */
1150 * Creates a macro node.
1151 * @param ident Name of macro
1152 * @param args List of arguments (can be <code>NULL</code>)
1153 * @param loc File location
1155 astnode
*astnode_create_macro(astnode
*ident
, astnode
*args
, location loc
)
1157 /* Create the node */
1158 astnode
*n
= astnode_create(MACRO_NODE
, loc
);
1159 /* Add the children */
1160 astnode_add_children(
1164 astnode_create_list(args
)
1166 /* Return the newly created node */
1171 * Creates an equ node.
1172 * @param ident Identifier
1173 * @param expr Expression
1174 * @param loc File location
1176 astnode
*astnode_create_equ(astnode
*ident
, astnode
*expr
, location loc
)
1178 /* Create the node */
1179 astnode
*n
= astnode_create(EQU_NODE
, loc
);
1180 /* Add the children */
1181 astnode_add_children(n
, 2, ident
, expr
);
1182 /* Return the newly created node */
1187 * Creates an assign node.
1188 * @param ident Identifier
1189 * @param expr Expression
1190 * @param loc File location
1192 astnode
*astnode_create_assign(astnode
*ident
, astnode
*expr
, location loc
)
1194 /* Create the node */
1195 astnode
*n
= astnode_create(ASSIGN_NODE
, loc
);
1196 /* Add the children */
1197 astnode_add_children(n
, 2, ident
, expr
);
1198 /* Return the newly created node */
1203 * Creates a storage node.
1204 * @param type Type of storage
1205 * @param count Expression with contains count
1206 * @param loc File location
1208 astnode
*astnode_create_storage(astnode
*type
, astnode
*count
, location loc
)
1210 /* Create the node */
1211 astnode
*n
= astnode_create(STORAGE_NODE
, loc
);
1212 /* Add the type of data (enumerated or identifier) */
1213 astnode_add_child(n
, type
);
1214 /* Second child: Count */
1215 if (count
== NULL
) {
1216 /* No count given, default=1 */
1217 count
= astnode_create_integer(1, loc
);
1219 astnode_add_child(n
, count
);
1220 /* Return the newly created node */
1225 * Creates an incsrc node.
1226 * @param file File specifier
1227 * @param loc File location
1229 astnode
*astnode_create_incsrc(astnode
*file
, location loc
)
1231 /* Create the node */
1232 astnode
*n
= astnode_create(INCSRC_NODE
, loc
);
1233 /* One child: Path to file */
1234 astnode_add_child(n
, file
);
1235 /* Return the newly created node */
1240 * Creates an incbin node.
1241 * @param file File specifier
1242 * @param loc File location
1244 astnode
*astnode_create_incbin(astnode
*file
, location loc
)
1246 /* Create the node */
1247 astnode
*n
= astnode_create(INCBIN_NODE
, loc
);
1248 /* One child: Path to file */
1249 astnode_add_child(n
, file
);
1250 /* Return the newly created node */
1255 * Creates a charmap node.
1256 * @param file File specifier
1257 * @param loc File location
1259 astnode
*astnode_create_charmap(astnode
*file
, location loc
)
1261 /* Create the node */
1262 astnode
*n
= astnode_create(CHARMAP_NODE
, loc
);
1263 /* One child: Path to file */
1264 astnode_add_child(n
, file
);
1265 /* Return the newly created node */
1270 * Creates a structure (STRUC) instance node.
1271 * @param vals Values for the structure fields
1272 * @param loc File location
1274 astnode
*astnode_create_struc(astnode
*vals
, location loc
)
1276 /* Create the node */
1277 astnode
*n
= astnode_create(STRUC_NODE
, loc
);
1278 /* Children: value list */
1279 astnode_add_child(n
, vals
);
1280 /* Return the newly created node */
1284 * Creates a structure (STRUC) declaration node.
1285 * @param id Structure identifier
1286 * @param stmts Statements of the structure declaration
1287 * @param loc File location
1289 astnode
*astnode_create_struc_decl(astnode
*id
, astnode
*stmts
, location loc
)
1291 /* Create the node */
1292 astnode
*n
= astnode_create(STRUC_DECL_NODE
, loc
);
1293 /* Two children: Identifier, statement list */
1294 astnode_add_child(n
, id
);
1295 astnode_add_child(n
, stmts
);
1296 /* Return the newly created node */
1301 * Creates a union declaration node.
1302 * @param id Union identifier
1303 * @param stmts Statements of the union declaration
1304 * @param loc File location
1306 astnode
*astnode_create_union_decl(astnode
*id
, astnode
*stmts
, location loc
)
1308 /* Create the node */
1309 astnode
*n
= astnode_create(UNION_DECL_NODE
, loc
);
1310 /* Two children: Identifier, statement list */
1311 astnode_add_child(n
, id
);
1312 astnode_add_child(n
, stmts
);
1313 /* Return the newly created node */
1318 * Creates an enum declaration node.
1319 * @param id Enum identifier
1320 * @param stmts Statements of the enum declaration
1321 * @param loc File location
1323 astnode
*astnode_create_enum_decl(astnode
*id
, astnode
*stmts
, location loc
)
1325 /* Create the node */
1326 astnode
*n
= astnode_create(ENUM_DECL_NODE
, loc
);
1327 /* Two children: Identifier, statement list */
1328 astnode_add_child(n
, id
);
1329 astnode_add_child(n
, stmts
);
1330 /* Return the newly created node */
1335 * Creates a record declaration node.
1336 * @param id Record identifier
1337 * @param fields Fields of the record
1338 * @param loc File location
1340 astnode
*astnode_create_record_decl(astnode
*id
, astnode
*fields
, location loc
)
1342 /* Create the node */
1343 astnode
*n
= astnode_create(RECORD_DECL_NODE
, loc
);
1344 /* Two children: Identifier, field list */
1345 astnode_add_child(n
, id
);
1346 astnode_add_child(n
, fields
);
1347 /* Return the newly created node */
1352 * Creates a bitfield declaration node.
1353 * @param id Identifier
1354 * @param width Width of field
1355 * @param loc Location
1357 astnode
*astnode_create_bitfield_decl(astnode
*id
, astnode
*width
, location loc
)
1359 /* Create the node */
1360 astnode
*n
= astnode_create(BITFIELD_DECL_NODE
, loc
);
1361 /* Two children: Identifier and width */
1362 astnode_add_child(n
, id
);
1363 astnode_add_child(n
, width
);
1364 /* Return the newly created node */
1369 * Creates a public node.
1371 astnode
*astnode_create_public(astnode
*l
, location loc
)
1373 /* Create the node */
1374 astnode
*n
= astnode_create(PUBLIC_NODE
, loc
);
1375 /* Add list of identifiers as child */
1376 astnode_add_child(n
, l
);
1377 /* Return the newly created node */
1382 * Creates an extrn node.
1383 * @param l List of identifiers
1384 * @param t Symbol type specifier
1385 * @param f From unit (identifier, may be <code>NULL</code>)
1387 astnode
*astnode_create_extrn(astnode
*l
, astnode
*t
, astnode
*f
, location loc
)
1389 /* Create the node */
1390 astnode
*n
= astnode_create(EXTRN_NODE
, loc
);
1391 /* Add type specifier as child */
1392 astnode_add_child(n
, t
);
1393 /* Add list of identifiers as child */
1394 astnode_add_child(n
, astnode_create_list(l
));
1395 /* Add from unit identifier */
1396 astnode_add_child(n
, f
);
1397 /* Return the newly created node */
1402 * Creates a dataseg node.
1404 astnode
*astnode_create_dataseg(int modifiers
, location loc
)
1406 /* Create the node */
1407 astnode
*n
= astnode_create(DATASEG_NODE
, loc
);
1409 n
->modifiers
= modifiers
;
1410 /* Return the newly created node */
1415 * Creates a codeseg node.
1417 astnode
*astnode_create_codeseg(location loc
)
1419 /* Create the node */
1420 astnode
*n
= astnode_create(CODESEG_NODE
, loc
);
1421 /* Return the newly created node */
1426 * Creates a data node.
1427 * @param type Type specifier
1428 * @param data List of values
1429 * @param loc File location
1431 astnode
*astnode_create_data(astnode
*type
, astnode
*data
, location loc
)
1433 /* Create the node */
1434 astnode
*n
= astnode_create(DATA_NODE
, loc
);
1435 /* Add the type of data (enumerated or identifier) */
1436 astnode_add_child(n
, type
);
1437 /* Add list of values */
1438 astnode_add_child(n
, data
);
1439 /* Return the newly created node */
1444 * Creates a file path node.
1445 * This is similar to a string literal node, the only difference is semantics.
1446 * A file path node implies that the path can be relative to both current
1447 * directory and any of the directories in the search path.
1448 * @param path The path this node represents
1449 * @param loc File location
1451 astnode
*astnode_create_file_path(const char *path
, location loc
)
1453 /* Create the node */
1454 astnode
*n
= astnode_create(FILE_PATH_NODE
, loc
);
1455 /* Allocate and store text */
1456 n
->file_path
= (char *)malloc(strlen(path
)+1);
1457 if (n
->file_path
!= NULL
) {
1458 strcpy(n
->file_path
, path
);
1460 /* Return the newly created node */
1465 * Creates a (global) label node.
1466 * @param s Name of label
1467 * @param addr Address
1468 * @param type Datatype (may be <code>NULL</code>)
1469 * @param loc Location
1471 astnode
*astnode_create_label(const char *s
, astnode
*addr
, astnode
*type
, location loc
)
1473 /* Create the node */
1474 astnode
*n
= astnode_create(LABEL_NODE
, loc
);
1475 /* Allocate and store text */
1476 n
->label
= (char *)malloc(strlen(s
)+1);
1477 if (n
->label
!= NULL
) {
1478 strcpy(n
->label
, s
);
1480 /* Two children: Datatype and address */
1482 addr
= astnode_create_pc(loc
);
1485 type
= astnode_create_datatype(BYTE_DATATYPE
, NULL
, loc
);
1487 astnode_add_child(n
, type
);
1488 astnode_add_child(n
, addr
);
1489 /* Return the newly created node */
1494 * Creates a local label node.
1495 * @param s Name of label
1496 * @param loc Location
1498 astnode
*astnode_create_local_label(const char *s
, location loc
)
1500 /* Create the node */
1501 astnode
*n
= astnode_create(LOCAL_LABEL_NODE
, loc
);
1502 /* Allocate and store text */
1503 n
->label
= (char *)malloc(strlen(s
)+1);
1504 if (n
->label
!= NULL
) {
1505 strcpy(n
->label
, s
);
1507 /* Return the newly created node */
1512 * Creates a local identifier node.
1513 * @param s Identifier
1514 * @param loc Location
1516 astnode
*astnode_create_local_id(const char *s
, location loc
)
1518 /* Create the node */
1519 astnode
*n
= astnode_create(LOCAL_ID_NODE
, loc
);
1520 /* Allocate and store text */
1521 n
->ident
= (char *)malloc(strlen(s
)+1);
1522 if (n
->ident
!= NULL
) {
1523 strcpy(n
->ident
, s
);
1525 /* Return the newly created node */
1530 * Creates a list node.
1531 * This is a way to group a list of nodes in a parent node.
1532 * @param l List of nodes to group in list node
1534 astnode
*astnode_create_list(astnode
*l
)
1538 /* Create the node */
1540 n
= astnode_create(LIST_NODE
, l
->loc
);
1541 /* Add list of values */
1542 astnode_add_child(n
, l
);
1545 /* Make a node with zero children */
1546 n
= astnode_create(LIST_NODE
, dummyloc
);
1548 /* Return the newly created node (or NULL) */
1553 * Creates a PC node.
1554 * @param loc File location
1556 astnode
*astnode_create_pc(location loc
)
1558 return astnode_create(CURRENT_PC_NODE
, loc
);
1562 * Creates a binary node.
1563 * @param bin Dynamically allocated (malloc() ) data that this node wraps. Will be freed automatically by astnode_finalize()
1564 * @param size Size of bin
1565 * @param loc File location
1567 astnode
*astnode_create_binary(unsigned char *bin
, int size
, location loc
)
1569 /* Create the node */
1570 astnode
*n
= astnode_create(BINARY_NODE
, loc
);
1572 n
->binary
.data
= bin
;
1573 n
->binary
.size
= size
;
1574 /* Return the newly created node */
1579 * Creates a tombstone node, which is a marker node that says that another node
1581 * @param type The type of node that used to live here
1582 * @param loc File location
1584 astnode
*astnode_create_tombstone(astnode_type type
, location loc
)
1586 /* Create the node */
1587 astnode
*n
= astnode_create(TOMBSTONE_NODE
, loc
);
1588 /* Store the type of the old node */
1589 n
->param
= (long)type
;
1590 /* Return the newly created node */
1595 * Creates a dot operator node.
1596 * Represents a structure field access of the form 'before.after'.
1597 * @param before Structure identifier
1598 * @param after Field identifier (can be another dot op, or an identifier)
1600 astnode
*astnode_create_dot(astnode
*before
, astnode
*after
, location loc
)
1602 /* Create the node */
1603 astnode
*n
= astnode_create(DOT_NODE
, loc
);
1604 /* Two children: 'before' . 'after' */
1605 astnode_add_child(n
, before
);
1606 astnode_add_child(n
, after
);
1607 /* Return the newly created node */
1612 * Creates a sizeof operator node.
1613 * @param expr Expression (datatype?)
1614 * @param loc Location
1616 astnode
*astnode_create_sizeof(astnode
*expr
, location loc
)
1618 /* Create the node */
1619 astnode
*n
= astnode_create(SIZEOF_NODE
, loc
);
1620 /* One child: expression */
1621 astnode_add_child(n
, expr
);
1622 /* Return the newly created node */
1627 * Creates a datatype node.
1628 * @param t The datatype this node represents
1629 * @param id If the datatype is a custom one, this is its name
1630 * @param loc Location
1632 astnode
*astnode_create_datatype(datatype t
, astnode
*id
, location loc
)
1634 /* Create the node */
1635 astnode
*n
= astnode_create(DATATYPE_NODE
, loc
);
1636 /* Set the datatype */
1638 /* Possibly one child: identifier */
1640 astnode_add_child(n
, id
);
1642 /* Return the newly created node */
1647 * Creates a variable declaration node.
1648 * @param modifiers PUBLIC_FLAG | ZEROPAGE_FLAG
1649 * @param id Identifier
1650 * @param data Datatype+initializer
1651 * @param loc Location
1653 astnode
*astnode_create_var_decl(int modifiers
, astnode
*id
, astnode
*data
, location loc
)
1655 /* Create the node */
1656 astnode
*n
= astnode_create(VAR_DECL_NODE
, loc
);
1658 n
->modifiers
= modifiers
;
1659 /* Two children: Identifier and datatype+initializer */
1660 astnode_add_child(n
, id
);
1661 astnode_add_child(n
, data
);
1662 /* Return the newly created node */
1669 astnode
*astnode_create_scope(astnode
*left
, astnode
*right
, location loc
)
1671 /* Create the node */
1672 astnode
*n
= astnode_create(SCOPE_NODE
, loc
);
1673 /* Two children: left and right */
1674 astnode_add_child(n
, left
);
1675 astnode_add_child(n
, right
);
1676 /* Return the newly created node */
1681 * Creates a procedure (PROC) node.
1682 * @param ident Name of procedure
1683 * @param stmts Procedure statements
1684 * @param loc File location
1686 astnode
*astnode_create_proc(astnode
*ident
, astnode
*stmts
, location loc
)
1688 /* Create the node */
1689 astnode
*n
= astnode_create(PROC_NODE
, loc
);
1690 /* This node has two children:
1691 1) An identifier, which is the name of the procedure
1692 2) List of statements, which is the procedure body */
1693 astnode_add_children(
1697 astnode_create_list(stmts
)
1699 /* Return the newly created node */
1704 * Creates a REPT node.
1705 * @param expr Number of times to repeat statements
1706 * @param stmts Statement list
1707 * @param loc File location
1709 astnode
*astnode_create_rept(astnode
*expr
, astnode
*stmts
, location loc
)
1711 /* Create the node */
1712 astnode
*n
= astnode_create(REPT_NODE
, loc
);
1713 /* This node has two children:
1714 1) An expression, which is the repeat count
1715 2) List of statements, which is the (anonymous) macro body */
1716 astnode_add_children(
1720 astnode_create_list(stmts
)
1722 /* Return the newly created node */
1727 * Creates a WHILE node.
1728 * @param expr Boolean expression
1729 * @param stmts Statement list
1730 * @param loc File location
1732 astnode
*astnode_create_while(astnode
*expr
, astnode
*stmts
, location loc
)
1734 /* Create the node */
1735 astnode
*n
= astnode_create(WHILE_NODE
, loc
);
1736 /* This node has two children:
1737 1) A boolean expression
1738 2) List of statements, which is the (anonymous) macro body */
1739 astnode_add_children(
1743 astnode_create_list(stmts
)
1745 /* Return the newly created node */
1750 * Creates a MESSAGE node.
1751 * @param expr Message to print.
1752 * @param loc File location
1754 astnode
*astnode_create_message(astnode
*expr
, location loc
)
1756 /* Create the node */
1757 astnode
*n
= astnode_create(MESSAGE_NODE
, loc
);
1758 /* This node has one children: An expression, which is the message to print */
1759 astnode_add_child(n
, expr
);
1760 /* Return the newly created node */
1765 * Creates a WARNING node.
1766 * @param str Warning to print.
1767 * @param loc File location
1769 astnode
*astnode_create_warning(astnode
*str
, location loc
)
1771 /* Create the node */
1772 astnode
*n
= astnode_create(WARNING_NODE
, loc
);
1773 /* This node has one child: A string, which is the warning to print */
1774 astnode_add_child(n
, str
);
1775 /* Return the newly created node */
1780 * Creates an ERROR node.
1781 * @param str Error to print.
1782 * @param loc File location
1784 astnode
*astnode_create_error(astnode
*str
, location loc
)
1786 /* Create the node */
1787 astnode
*n
= astnode_create(ERROR_NODE
, loc
);
1788 /* This node has one child: A string, which is the error to print */
1789 astnode_add_child(n
, str
);
1790 /* Return the newly created node */
1795 * Creates a forward branch declaration node.
1796 * @param ident Branch name
1797 * @param loc File location
1799 astnode
*astnode_create_forward_branch_decl(const char *ident
, location loc
)
1801 /* Create the node */
1802 astnode
*n
= astnode_create(FORWARD_BRANCH_DECL_NODE
, loc
);
1803 /* Allocate and store text */
1804 n
->ident
= (char *)malloc(strlen(ident
)+1);
1805 if (n
->ident
!= NULL
) {
1806 strcpy(n
->ident
, ident
);
1808 /* Return the newly created node */
1813 * Creates a backward branch declaration node.
1814 * @param ident Branch name
1815 * @param loc File location
1817 astnode
*astnode_create_backward_branch_decl(const char *ident
, location loc
)
1819 /* Create the node */
1820 astnode
*n
= astnode_create(BACKWARD_BRANCH_DECL_NODE
, loc
);
1821 /* Allocate and store text */
1822 n
->ident
= (char *)malloc(strlen(ident
)+1);
1823 if (n
->ident
!= NULL
) {
1824 strcpy(n
->ident
, ident
);
1826 /* Return the newly created node */
1831 * Creates a forward branch reference node.
1832 * @param ident Branch name
1833 * @param loc File location
1835 astnode
*astnode_create_forward_branch(const char *ident
, location loc
)
1837 /* Create the node */
1838 astnode
*n
= astnode_create(FORWARD_BRANCH_NODE
, loc
);
1839 /* Allocate and store text */
1840 n
->ident
= (char *)malloc(strlen(ident
)+1);
1841 if (n
->ident
!= NULL
) {
1842 strcpy(n
->ident
, ident
);
1844 /* Return the newly created node */
1849 * Creates a backward branch reference node.
1850 * @param ident Branch name
1851 * @param loc File location
1853 astnode
*astnode_create_backward_branch(const char *ident
, location loc
)
1855 /* Create the node */
1856 astnode
*n
= astnode_create(BACKWARD_BRANCH_NODE
, loc
);
1857 /* Allocate and store text */
1858 n
->ident
= (char *)malloc(strlen(ident
)+1);
1859 if (n
->ident
!= NULL
) {
1860 strcpy(n
->ident
, ident
);
1862 /* Return the newly created node */
1867 * Creates a mask operator node.
1868 * @param expr Expression
1869 * @param loc Location
1871 astnode
*astnode_create_mask(astnode
*expr
, location loc
)
1873 /* Create the node */
1874 astnode
*n
= astnode_create(MASK_NODE
, loc
);
1875 /* One child: expression */
1876 astnode_add_child(n
, expr
);
1877 /* Return the newly created node */
1882 * Creates an ALIGN node.
1883 * @param idents List of identifiers
1884 * @param expr Expression
1885 * @param loc File location
1887 astnode
*astnode_create_align(astnode
*idents
, astnode
*expr
, location loc
)
1889 /* Create the node */
1890 astnode
*n
= astnode_create(ALIGN_NODE
, loc
);
1891 /* This node has two children: List of identifiers and alignment constraint */
1892 astnode_add_child(n
, astnode_create_list(idents
) );
1893 astnode_add_child(n
, expr
);
1894 /* Return the newly created node */
1899 * Creates an INDEX node.
1900 * @param ident Identifier being indexed
1901 * @param expr Index expression
1902 * @param loc File location
1904 astnode
*astnode_create_index(astnode
*ident
, astnode
*expr
, location loc
)
1906 /* Create the node */
1907 astnode
*n
= astnode_create(INDEX_NODE
, loc
);
1908 /* This node has two children: Identifier and expression */
1909 astnode_add_child(n
, ident
);
1910 astnode_add_child(n
, expr
);
1911 /* Return the newly created node */
1916 * Creates an ORG node.
1917 * @param addr Address
1918 * @param loc File location
1920 astnode
*astnode_create_org(astnode
*addr
, location loc
)
1922 /* Create the node */
1923 astnode
*n
= astnode_create(ORG_NODE
, loc
);
1924 /* This node has one child: The address */
1925 astnode_add_child(n
, addr
);
1926 /* Return the newly created node */
1930 /*---------------------------------------------------------------------------*/
1931 /* Functions for (de)serializing a node; probably not complete since it didn't
1932 end up being used by any program.
1935 #define put_byte(f, b) { fputc((unsigned char)(b), f); }
1936 #define put_short(f, w) { put_byte(f, w >> 8); put_byte(f, w); }
1937 #define put_int(f, q) { put_short(f, q >> 16); put_short(f, q); }
1940 * Serializes a node.
1941 * @param n The node to serialize
1942 * @param f The file to write to
1944 void astnode_serialize(const astnode
*n
, FILE *f
)
1947 /* Node type: 1 byte */
1948 put_byte(f
, astnode_get_type(n
));
1949 /* Internal node data */
1950 switch (astnode_get_type(n
)) {
1952 /* Assumes that sizeof(long) is same as for int */
1953 put_int(f
, n
->integer
);
1957 case IDENTIFIER_NODE
:
1959 case FILE_PATH_NODE
:
1961 case LOCAL_LABEL_NODE
:
1962 /* Put length first */
1963 put_int(f
, strlen(n
->string
));
1964 /* Put characters */
1965 for (i
=0; i
<strlen(n
->string
); i
++) {
1966 put_byte(f
, n
->string
[i
]);
1971 /* Datatype: 1 byte */
1972 put_byte(f
, n
->datatype
);
1977 put_int(f
, n
->binary
.size
);
1978 /* Put data bytes */
1979 for (i
=0; i
<n
->binary
.size
; i
++) {
1980 put_byte(f
, n
->binary
.data
[i
]);
1984 case ARITHMETIC_NODE
:
1988 case INSTRUCTION_NODE
:
1993 /* No internal attributes */
1997 put_int(f
, astnode_get_child_count(n
));
1998 /* Serialize children */
1999 for (i
=0; i
<astnode_get_child_count(n
); i
++) {
2000 astnode_serialize(astnode_get_child(n
, i
), f
);
2004 #define get_byte(f) 0
2005 #define get_short(f) 0
2006 #define get_int(f) 0
2009 * Deserializes a node.
2010 * @param f The file to read from
2012 astnode
*astnode_deserialize(FILE *f
)
2019 /* Node type: 1 byte */
2020 t
= (astnode_type
)get_byte(f
);
2021 /* Create the node */
2022 n
= astnode_create(t
, loc
);
2023 /* Internal node data */
2024 switch (astnode_get_type(n
)) {
2026 /* Assumes that sizeof(long) is same as for int */
2027 n
->integer
= get_int(f
);
2031 case IDENTIFIER_NODE
:
2033 case FILE_PATH_NODE
:
2035 case LOCAL_LABEL_NODE
:
2038 /* Create the character array */
2039 n
->string
= malloc(len
+1);
2040 if (n
->string
!= NULL
) {
2041 /* Get characters */
2042 for (i
=0; i
<len
; i
++) {
2043 n
->string
[i
] = get_byte(f
);
2049 /* Datatype: 1 byte */
2050 n
->datatype
= get_byte(f
);
2055 n
->binary
.size
= get_int(f
);
2056 /* Allocate storage */
2057 n
->binary
.data
= (unsigned char *)malloc(n
->binary
.size
);
2058 if (n
->binary
.data
!= NULL
) {
2059 /* Get data bytes */
2060 for (i
=0; i
<n
->param
; i
++) {
2061 n
->binary
.data
[i
] = get_byte(f
);
2066 case ARITHMETIC_NODE
:
2070 case INSTRUCTION_NODE
:
2075 /* No internal attributes */
2080 /* Deserialize children */
2081 for (i
=0; i
<len
; i
++) {
2082 astnode_add_child(n
, astnode_deserialize(f
));
2085 /* Return the deserialized node */