1 /****************************************************************************
2  * Copyright (C) 2009 by Matteo Franchin                                    *
3  *                                                                          *
4  * This file is part of Box.                                                *
5  *                                                                          *
6  *   Box is free software: you can redistribute it and/or modify it         *
7  *   under the terms of the GNU Lesser General Public License as published  *
8  *   by the Free Software Foundation, either version 3 of the License, or   *
9  *   (at your option) any later version.                                    *
10  *                                                                          *
11  *   Box is distributed in the hope that it will be useful,                 *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
14  *   GNU Lesser General Public License for more details.                    *
15  *                                                                          *
16  *   You should have received a copy of the GNU Lesser General Public       *
17  *   License along with Box.  If not, see <http://www.gnu.org/licenses/>.   *
18  ****************************************************************************/
19 
20 #include <assert.h>
21 #include <stdio.h>
22 
23 #include "mem.h"
24 #include "ast.h"
25 #include "print.h"
26 #include "srcpos.h"
27 
28 /** Used for generic parsing of tree
29  * (to destroy or print the tree, for example)
30  */
ASTNode_Get_Subnodes(ASTNode * node,ASTNode ** subnodes[AST_MAX_NUM_SUBNODES])31 int ASTNode_Get_Subnodes(ASTNode *node, ASTNode **subnodes[AST_MAX_NUM_SUBNODES]) {
32   switch(node->type) {
33   case ASTNODETYPE_ERROR:
34     return 0;
35   case ASTNODETYPE_TYPENAME:
36     subnodes[0] = & node->attr.typenm.scope;
37     return 1;
38   case ASTNODETYPE_TYPETAG:
39     return 0;
40   case ASTNODETYPE_SUBTYPE:
41     subnodes[0] = & node->attr.subtype.parent;
42     return 1;
43   case ASTNODETYPE_INSTANCE:
44     subnodes[0] = & node->attr.instance.type;
45     return 1;
46   case ASTNODETYPE_BOX:
47     subnodes[0] = & node->attr.box.parent;
48     subnodes[1] = & node->attr.box.first_statement;
49     return 2;
50   case ASTNODETYPE_STATEMENT:
51     subnodes[0] = & node->attr.statement.target;
52     subnodes[1] = & node->attr.statement.next_statement;
53     return 2;
54   case ASTNODETYPE_CONST:
55     return 0;
56   case ASTNODETYPE_STRING:
57     return 0;
58   case ASTNODETYPE_VAR:
59     subnodes[0] = & node->attr.var.scope;
60     return 1;
61   case ASTNODETYPE_IGNORE:
62     subnodes[0] = & node->attr.ignore.expr;
63     return 1;
64   case ASTNODETYPE_UNOP:
65     subnodes[0] = & node->attr.un_op.expr;
66     return 1;
67   case ASTNODETYPE_BINOP:
68     subnodes[0] = & node->attr.bin_op.left;
69     subnodes[1] = & node->attr.bin_op.right;
70     return 2;
71   case ASTNODETYPE_MEMBER:
72     subnodes[0] = & node->attr.member.expr;
73     subnodes[1] = & node->attr.member.next;
74     return 2;
75   case ASTNODETYPE_STRUC:
76     subnodes[0] = & node->attr.struc.first_member;
77     return 1;
78   case ASTNODETYPE_ARRAYGET:
79     subnodes[0] = & node->attr.array_get.array;
80     subnodes[1] = & node->attr.array_get.index;
81     return 2;
82   case ASTNODETYPE_MEMBERGET:
83     subnodes[0] = & node->attr.member_get.struc;
84     return 1;
85   case ASTNODETYPE_RAISE:
86     subnodes[0] = & node->attr.raise.expr;
87     return 1;
88   case ASTNODETYPE_SUBTYPEBLD:
89     subnodes[0] = & node->attr.subtype_bld.parent;
90     return 1;
91   case ASTNODETYPE_SELFGET:
92     return 0;
93   case ASTNODETYPE_PROCDEF:
94     subnodes[0] = & node->attr.proc_def.child_type;
95     subnodes[1] = & node->attr.proc_def.parent_type;
96     subnodes[2] = & node->attr.proc_def.c_name;
97     subnodes[3] = & node->attr.proc_def.implem;
98     return 4;
99   case ASTNODETYPE_TYPEDEF:
100     subnodes[0] = & node->attr.type_def.name;
101     subnodes[1] = & node->attr.type_def.src_type;
102     return 2;
103   case ASTNODETYPE_STRUCTYPE:
104     subnodes[0] = & node->attr.struc_type.first_member;
105     return 1;
106   case ASTNODETYPE_MEMBERTYPE:
107     subnodes[0] = & node->attr.member_type.type;
108     subnodes[1] = & node->attr.member_type.next;
109     return 2;
110   case ASTNODETYPE_RAISETYPE:
111     subnodes[0] = & node->attr.raise_type.type;
112     return 1;
113   case ASTNODETYPE_SPECTYPE:
114     subnodes[0] = & node->attr.spec_type.first_member;
115     return 1;
116   }
117   assert(0); /* Should never happen! */
118   return 0;
119 }
120 
ASTNodeType_To_Str(ASTNodeType t)121 const char *ASTNodeType_To_Str(ASTNodeType t) {
122   switch(t) {
123   case ASTNODETYPE_ERROR:      return "Error";
124   case ASTNODETYPE_TYPENAME:   return "TypeName";
125   case ASTNODETYPE_TYPETAG:    return "TypeTag";
126   case ASTNODETYPE_SUBTYPE:    return "SubType";
127   case ASTNODETYPE_INSTANCE:   return "Instance";
128   case ASTNODETYPE_BOX:        return "Box";
129   case ASTNODETYPE_STATEMENT:  return "Statement";
130   case ASTNODETYPE_CONST:      return "Const";
131   case ASTNODETYPE_STRING:     return "String";
132   case ASTNODETYPE_VAR:        return "Var";
133   case ASTNODETYPE_IGNORE:     return "Ignore";
134   case ASTNODETYPE_UNOP:       return "UnOp";
135   case ASTNODETYPE_BINOP:      return "BinOp";
136   case ASTNODETYPE_MEMBER:     return "Member";
137   case ASTNODETYPE_STRUC:      return "Struc";
138   case ASTNODETYPE_ARRAYGET:   return "ArrayGet";
139   case ASTNODETYPE_MEMBERGET:  return "MemberGet";
140   case ASTNODETYPE_SUBTYPEBLD: return "SubtypeBld";
141   case ASTNODETYPE_SELFGET:    return "SelfGet";
142   case ASTNODETYPE_TYPEDEF:    return "TypeDef";
143   default:                     return "UnknownNode";
144   }
145   return "???";
146 }
147 
ASTUnOp_To_String(ASTUnOp op)148 const char *ASTUnOp_To_String(ASTUnOp op) {
149   switch(op) {
150   case ASTUNOP_PLUS: return "+";
151   case ASTUNOP_NEG: return "-";
152   case ASTUNOP_LINC: return "++";
153   case ASTUNOP_LDEC: return "--";
154   case ASTUNOP_RINC: return "++";
155   case ASTUNOP_RDEC: return "--";
156   case ASTUNOP_NOT: return "!";
157   case ASTUNOP_BNOT: return "~";
158   }
159   return "?";
160 }
161 
ASTUnOp_Is_Right(ASTUnOp op)162 int ASTUnOp_Is_Right(ASTUnOp op) {
163  switch(op) {
164  case ASTUNOP_RINC:
165  case ASTUNOP_RDEC:
166    return 1;
167  default:
168    return 0;
169  }
170   return 0;
171 }
172 
ASTBinOp_To_String(ASTBinOp op)173 const char *ASTBinOp_To_String(ASTBinOp op) {
174   switch(op) {
175   case ASTBINOP_ADD: return "+";
176   case ASTBINOP_SUB: return "-";
177   case ASTBINOP_MUL: return "*";
178   case ASTBINOP_DIV: return "/";
179   case ASTBINOP_REM: return "%";
180   case ASTBINOP_POW: return "**";
181   case ASTBINOP_SHL: return "<<";
182   case ASTBINOP_SHR: return ">>";
183   case ASTBINOP_EQ: return "==";
184   case ASTBINOP_NE: return "!=";
185   case ASTBINOP_LT: return "<";
186   case ASTBINOP_LE: return "<=";
187   case ASTBINOP_GT: return ">";
188   case ASTBINOP_GE: return ">=";
189   case ASTBINOP_BAND: return "&";
190   case ASTBINOP_BXOR: return "^";
191   case ASTBINOP_BOR: return "|";
192   case ASTBINOP_LAND: return "&&";
193   case ASTBINOP_LOR: return "||";
194   case ASTBINOP_ASSIGN: return "=";
195   case ASTBINOP_APLUS: return "+=";
196   case ASTBINOP_AMINUS: return "-=";
197   case ASTBINOP_ATIMES: return "*=";
198   case ASTBINOP_AREM: return "%=";
199   case ASTBINOP_ADIV: return "/=";
200   case ASTBINOP_ASHL: return "<<=";
201   case ASTBINOP_ASHR: return ">>=";
202   case ASTBINOP_ABAND: return "&=";
203   case ASTBINOP_ABXOR: return "^=";
204   case ASTBINOP_ABOR: return "|=";
205   }
206   return "?";
207 }
208 
ASTNode_New(ASTNodeType t)209 ASTNode *ASTNode_New(ASTNodeType t) {
210   ASTNode *node,
211           **subnode[AST_MAX_NUM_SUBNODES];
212   int i, num_subnodes;
213 
214   node = Box_Mem_Alloc(sizeof(ASTNode));
215   assert(node != NULL);
216 
217   node->type = t;
218   node->finaliser = NULL;
219   num_subnodes = ASTNode_Get_Subnodes(node, subnode);
220   assert(num_subnodes <= AST_MAX_NUM_SUBNODES);
221   for(i = 0; i < num_subnodes; i++)
222     *subnode[i] = NULL;
223 
224   BoxSrc_Init(& node->src);
225   return node;
226 }
227 
ASTNode_Destroy(ASTNode * node)228 void ASTNode_Destroy(ASTNode *node) {
229   if (node == NULL)
230     return;
231 
232   else {
233     ASTNode **subnode[AST_MAX_NUM_SUBNODES];
234     int i, num_subnodes;
235 
236     /* First destroy children */
237     num_subnodes = ASTNode_Get_Subnodes(node, subnode);
238     for(i = 0; i < num_subnodes; i++) {
239       ASTNode *child = *subnode[i];
240       ASTNode_Destroy(child);
241     }
242 
243     if (node->finaliser != NULL)
244       node->finaliser(node);
245 
246     Box_Mem_Free(node);
247   }
248 }
249 
ASTNode_Set_Error(ASTNode * node)250 void ASTNode_Set_Error(ASTNode *node) {
251 }
252 
253 /* Used to draw a tree using the characters | \ and - */
254 typedef struct __IndentStr {
255   const char *this;
256   struct __IndentStr *next;
257 } IndentStr;
258 
Indent_Push(IndentStr * indent,IndentStr * next)259 static void Indent_Push(IndentStr *indent, IndentStr *next) {
260   for(; indent->next != NULL; indent = indent->next);
261   indent->next = next;
262   next->next = NULL;
263 }
264 
Indent_Pop(IndentStr * indent)265 static void Indent_Pop(IndentStr *indent) {
266   if (indent->next != NULL) {
267     IndentStr *next = indent->next;
268     for(; next->next != NULL;) {
269       indent = next;
270       next = next->next;
271     }
272     indent->next = NULL;
273   }
274 }
275 
276 static const char *branch_sep  = "--";
277 static const char *branch_down = " |";
278 static const char *branch_last = " \\";
279 static const char *branch_end  = "  ";
280 
Indent_Print(FILE * out,IndentStr * indent)281 static void Indent_Print(FILE *out, IndentStr *indent) {
282   for(; indent != NULL; indent = indent->next) {
283     fprintf(out, "%s", indent->this);
284     if (indent->this == branch_last)
285       indent->this = branch_end;
286   }
287 }
288 
My_Node_Print(FILE * out,ASTNode * node,IndentStr * indent)289 static void My_Node_Print(FILE *out, ASTNode *node, IndentStr *indent) {
290   ASTNode **subnode[AST_MAX_NUM_SUBNODES];
291   int i, num_subnodes;
292 
293   if (node == NULL) {
294     Indent_Print(out, indent);
295     fprintf(out, "%sEMPTY NODE\n", branch_sep);
296     return;
297   }
298 
299   /* Get subnodes */
300   num_subnodes = ASTNode_Get_Subnodes(node, subnode);
301 
302   Indent_Print(out, indent);
303   fprintf(out, "%s%s(num_subnodes=%d)\n",
304           branch_sep, ASTNodeType_To_Str(node->type), num_subnodes);
305 
306   if (num_subnodes > 0) {
307     IndentStr new_indent;
308     new_indent.this = branch_down;
309     Indent_Push(indent, & new_indent);
310 
311     for(i = 0; i < num_subnodes; i++) {
312       ASTNode *child = *subnode[i];
313       if (i == num_subnodes - 1)
314         new_indent.this = branch_last;
315       My_Node_Print(out, child, indent);
316     }
317 
318     Indent_Pop(indent);
319   }
320 }
321 
ASTNode_Print(FILE * out,ASTNode * node)322 void ASTNode_Print(FILE *out, ASTNode *node) {
323   IndentStr indent;
324   indent.this = "";
325   indent.next = NULL;
326   My_Node_Print(out, node, & indent);
327 }
328 
ASTNodeError_New(void)329 ASTNode *ASTNodeError_New(void) {
330   return ASTNode_New(ASTNODETYPE_ERROR);
331 }
332 
ASTNodeTypeName_Finaliser(ASTNode * node)333 static void ASTNodeTypeName_Finaliser(ASTNode *node) {
334   assert(node->type == ASTNODETYPE_TYPENAME);
335   Box_Mem_Free(node->attr.typenm.name);
336 }
337 
ASTNodeTypeName_New(const char * name,size_t name_len)338 ASTNode *ASTNodeTypeName_New(const char *name, size_t name_len) {
339   ASTNode *node = ASTNode_New(ASTNODETYPE_TYPENAME);
340   node->attr.typenm.name =
341     (name_len > 0) ? Box_Mem_Strndup(name, name_len) : Box_Mem_Strdup(name);
342   node->attr.typenm.scope = NULL;
343   node->finaliser = ASTNodeTypeName_Finaliser;
344   return node;
345 }
346 
ASTNodeTypeTag_New(BoxTypeId value)347 ASTNode *ASTNodeTypeTag_New(BoxTypeId value) {
348   ASTNode *node = ASTNode_New(ASTNODETYPE_TYPETAG);
349   node->attr.typetag.type = value;
350   return node;
351 }
352 
ASTNodeSubtype_Finaliser(ASTNode * node)353 static void ASTNodeSubtype_Finaliser(ASTNode *node) {
354   assert(node->type == ASTNODETYPE_SUBTYPE);
355   Box_Mem_Free(node->attr.subtype.name);
356 }
357 
ASTNodeSubtype_New(ASTNode * parent_type,const char * name)358 ASTNode *ASTNodeSubtype_New(ASTNode *parent_type, const char *name) {
359   ASTNode *node = ASTNode_New(ASTNODETYPE_SUBTYPE);
360   node->attr.subtype.name = Box_Mem_Strdup(name);
361   node->attr.subtype.parent = parent_type;
362   node->finaliser = ASTNodeSubtype_Finaliser;
363   return node;
364 }
365 
ASTNodeStatement_New(ASTNode * target)366 ASTNode *ASTNodeStatement_New(ASTNode *target) {
367   ASTNode *node = ASTNode_New(ASTNODETYPE_STATEMENT);
368   node->attr.statement.target = target;
369   node->attr.statement.sep = ASTSEP_VOID;
370   return node;
371 }
372 
ASTNodeSep_New(ASTSep sep)373 ASTNode *ASTNodeSep_New(ASTSep sep) {
374   ASTNode *node = ASTNode_New(ASTNODETYPE_STATEMENT);
375   node->attr.statement.sep = sep;
376   return node;
377 }
378 
ASTNodeInstance_New(ASTNode * type)379 ASTNode *ASTNodeInstance_New(ASTNode *type) {
380   ASTNode *node = ASTNode_New(ASTNODETYPE_INSTANCE);
381   node->attr.instance.type = type;
382   return node;
383 }
384 
ASTNodeBox_Finaliser(ASTNode * node)385 static void ASTNodeBox_Finaliser(ASTNode *node) {
386   assert(node->type == ASTNODETYPE_BOX);
387   BoxSrcName *srcname = node->attr.box.file_names;
388   if (srcname != NULL)
389     BoxSrcName_Destroy(srcname);
390 }
391 
ASTNodeBox_New(ASTNode * parent,ASTNode * first_statement)392 ASTNode *ASTNodeBox_New(ASTNode *parent, ASTNode *first_statement) {
393   ASTNode *node = ASTNode_New(ASTNODETYPE_BOX);
394   node->attr.box.first_statement = first_statement;
395   node->attr.box.last_statement = first_statement;
396   node->attr.box.parent = parent;
397   node->attr.box.file_names = NULL;
398   node->finaliser = ASTNodeBox_Finaliser;
399   return node;
400 }
401 
ASTNodeBox_Add_Statement(ASTNode * box,ASTNode * statement)402 ASTNode *ASTNodeBox_Add_Statement(ASTNode *box, ASTNode *statement) {
403   assert(box->type == ASTNODETYPE_BOX);
404 
405   if (statement == NULL) {
406     return box;
407 
408   } else {
409     ASTNode *last_statement = box->attr.box.last_statement;
410 
411     assert(statement->type == ASTNODETYPE_STATEMENT);
412 
413     if (last_statement == NULL) {
414       assert(box->attr.box.first_statement == NULL);
415       box->attr.box.first_statement = box->attr.box.last_statement = statement;
416 
417     } else {
418       last_statement->attr.statement.next_statement = statement;
419       box->attr.box.last_statement = statement;
420     }
421     return box;
422   }
423 }
424 
ASTNodeBox_Add_Sep(ASTNode * box,ASTSep sep)425 ASTNode *ASTNodeBox_Add_Sep(ASTNode *box, ASTSep sep) {
426   if (sep == ASTSEP_VOID)
427     return box;
428   else {
429     ASTNode *sep_node = ASTNodeSep_New(sep);
430     return ASTNodeBox_Add_Statement(box, sep_node);
431   }
432 }
433 
ASTNodeBox_Set_Parent(ASTNode * box,ASTNode * parent)434 ASTNode *ASTNodeBox_Set_Parent(ASTNode *box, ASTNode *parent) {
435   assert(box->type == ASTNODETYPE_BOX);
436   box->attr.box.parent = parent;
437   return box;
438 }
439 
ASTNodeConst_New(ASTConstType t,ASTConst c)440 ASTNode *ASTNodeConst_New(ASTConstType t, ASTConst c) {
441   ASTNode *node = ASTNode_New(ASTNODETYPE_CONST);
442   node->attr.constant.type = t;
443   node->attr.constant.value = c;
444   return node;
445 }
446 
ASTNodeString_Finaliser(ASTNode * node)447 static void ASTNodeString_Finaliser(ASTNode *node) {
448   assert(node->type == ASTNODETYPE_STRING);
449   Box_Mem_Free(node->attr.string.str);
450 }
451 
ASTNodeString_New(const char * str,size_t str_len)452 ASTNode *ASTNodeString_New(const char *str, size_t str_len) {
453   ASTNode *node = ASTNode_New(ASTNODETYPE_STRING);
454   node->attr.string.str =
455     Box_Mem_Str_Merge_With_Len(str, str_len, NULL, 0);
456   node->finaliser = ASTNodeString_Finaliser;
457   return node;
458 }
459 
ASTNodeString_Concat(ASTNode * str1,ASTNode * str2)460 ASTNode *ASTNodeString_Concat(ASTNode *str1, ASTNode *str2) {
461   assert(str1->type == ASTNODETYPE_STRING &&
462          str2->type == ASTNODETYPE_STRING);
463   char *old_str = str1->attr.string.str;
464   str1->attr.string.str = Box_Mem_Str_Merge(old_str, str2->attr.string.str);
465   Box_Mem_Free(old_str);
466   ASTNode_Destroy(str2);
467   return str1;
468 }
469 
ASTNodeVar_Finaliser(ASTNode * node)470 static void ASTNodeVar_Finaliser(ASTNode *node) {
471   assert(node->type == ASTNODETYPE_VAR);
472   Box_Mem_Free(node->attr.var.name);
473 }
474 
ASTNodeVar_New(const char * name,size_t name_len)475 ASTNode *ASTNodeVar_New(const char *name, size_t name_len) {
476   ASTNode *node = ASTNode_New(ASTNODETYPE_VAR);
477   node->attr.var.name = (name_len > 0) ?
478                         Box_Mem_Strndup(name, name_len) : Box_Mem_Strdup(name);
479   node->attr.var.scope = NULL;
480   node->finaliser = ASTNodeVar_Finaliser;
481   return node;
482 }
483 
ASTNodeIgnore_New(ASTNode * expr,int do_ignore)484 ASTNode *ASTNodeIgnore_New(ASTNode *expr, int do_ignore) {
485   ASTNode *node = ASTNode_New(ASTNODETYPE_IGNORE);
486   node->attr.ignore.expr = expr;
487   node->attr.ignore.ignore = do_ignore;
488   return node;
489 }
490 
ASTNodeUnOp_New(ASTUnOp op,ASTNode * expr)491 ASTNode *ASTNodeUnOp_New(ASTUnOp op, ASTNode *expr) {
492   ASTNode *node = ASTNode_New(ASTNODETYPE_UNOP);
493   node->attr.un_op.operation = op;
494   node->attr.un_op.expr = expr;
495   return node;
496 }
497 
ASTNodeBinOp_New(ASTBinOp op,ASTNode * left,ASTNode * right)498 ASTNode *ASTNodeBinOp_New(ASTBinOp op, ASTNode *left, ASTNode *right) {
499   ASTNode *node = ASTNode_New(ASTNODETYPE_BINOP);
500   node->attr.bin_op.operation = op;
501   node->attr.bin_op.left = left;
502   node->attr.bin_op.right = right;
503   return node;
504 }
505 
My_ASTNodeMember_Finaliser(ASTNode * node)506 static void My_ASTNodeMember_Finaliser(ASTNode *node) {
507   assert(node->type == ASTNODETYPE_MEMBER);
508   Box_Mem_Free(node->attr.member.name);
509 }
510 
ASTNodeMember_New(const char * name,ASTNode * expr)511 ASTNode *ASTNodeMember_New(const char *name, ASTNode *expr) {
512   ASTNode *node = ASTNode_New(ASTNODETYPE_MEMBER);
513   node->attr.member.name = (name == NULL) ? NULL : Box_Mem_Strdup(name);
514   node->attr.member.expr = expr;
515   node->attr.member.next = NULL;
516   node->finaliser = My_ASTNodeMember_Finaliser;
517   return node;
518 }
519 
ASTNodeRaise_New(ASTNode * expr)520 ASTNode *ASTNodeRaise_New(ASTNode *expr) {
521   ASTNode *node = ASTNode_New(ASTNODETYPE_RAISE);
522   node->attr.raise.expr = expr;
523   return node;
524 }
525 
ASTNodeStruc_New(const char * first_name,ASTNode * first_expr)526 ASTNode *ASTNodeStruc_New(const char *first_name, ASTNode *first_expr) {
527   ASTNode *first_member = NULL, *node;
528   assert(!(first_name != NULL && first_expr == NULL));
529   if (first_expr != NULL)
530     first_member = ASTNodeMember_New(first_name, first_expr);
531 
532   node = ASTNode_New(ASTNODETYPE_STRUC);
533   node->attr.struc.first_member = first_member;
534   node->attr.struc.last_member = first_member;
535   return node;
536 }
537 
ASTNodeStruc_Add_Member(ASTNode * struc,const char * this_name,ASTNode * this_expr)538 ASTNode *ASTNodeStruc_Add_Member(ASTNode *struc,
539                                  const char *this_name, ASTNode *this_expr) {
540   ASTNode *this_member = NULL;
541   assert(struc->type == ASTNODETYPE_STRUC);
542   assert(!(this_name != NULL && this_expr == NULL));
543   if (this_expr == NULL) return struc;
544 
545   this_member = ASTNodeMember_New(this_name, this_expr);
546   if (struc->attr.struc.last_member == NULL) {
547     assert(struc->attr.struc.first_member == NULL);
548     struc->attr.struc.first_member = this_member;
549     struc->attr.struc.last_member = this_member;
550     return struc;
551 
552   } else {
553     ASTNode *last_member = struc->attr.struc.last_member;
554     last_member->attr.member.next = this_member;
555     struc->attr.struc.last_member = this_member;
556   }
557   return struc;
558 }
559 
ASTNodeArrayGet_New(ASTNode * array,ASTNode * index)560 ASTNode *ASTNodeArrayGet_New(ASTNode *array, ASTNode *index) {
561   ASTNode *node = ASTNode_New(ASTNODETYPE_ARRAYGET);
562   node->attr.array_get.array = array;
563   node->attr.array_get.index = index;
564   return node;
565 }
566 
ASTNodeMemberGet_Finaliser(ASTNode * node)567 static void ASTNodeMemberGet_Finaliser(ASTNode *node) {
568   assert(node->type == ASTNODETYPE_MEMBERGET);
569   Box_Mem_Free(node->attr.member_get.member);
570 }
571 
ASTNodeMemberGet_New(ASTNode * struc,const char * member,int member_len)572 ASTNode *ASTNodeMemberGet_New(ASTNode *struc,
573                               const char *member, int member_len) {
574   ASTNode *node = ASTNode_New(ASTNODETYPE_MEMBERGET);
575   node->attr.member_get.struc = struc;
576   node->attr.member_get.member = (member_len > 0) ?
577                                   Box_Mem_Strndup(member, member_len) :
578                                   Box_Mem_Strdup(member);
579   node->finaliser = ASTNodeMemberGet_Finaliser;
580   return node;
581 }
582 
ASTNodeSubtype_Build_Finaliser(ASTNode * node)583 static void ASTNodeSubtype_Build_Finaliser(ASTNode *node) {
584   assert(node->type == ASTNODETYPE_SUBTYPEBLD);
585   Box_Mem_Free(node->attr.subtype_bld.subtype);
586 }
587 
ASTNodeSubtype_Build(ASTNode * parent,const char * subtype)588 ASTNode *ASTNodeSubtype_Build(ASTNode *parent, const char *subtype) {
589   ASTNode *node = ASTNode_New(ASTNODETYPE_SUBTYPEBLD);
590   node->attr.subtype_bld.parent = parent;
591   node->attr.subtype_bld.subtype = Box_Mem_Strdup(subtype);
592   node->finaliser = ASTNodeSubtype_Build_Finaliser;
593   return node;
594 }
595 
ASTNodeSelfGet_New(BoxInt level)596 ASTNode *ASTNodeSelfGet_New(BoxInt level) {
597   ASTNode *node = ASTNode_New(ASTNODETYPE_SELFGET);
598   node->attr.self_get.level = level;
599   return node;
600 }
601 
ASTNodeProcDef_New(ASTNode * child_type,BoxCombType combine,ASTNode * parent_type)602 ASTNode *ASTNodeProcDef_New(ASTNode *child_type, BoxCombType combine,
603                             ASTNode *parent_type) {
604   ASTNode *node = ASTNode_New(ASTNODETYPE_PROCDEF);
605   node->attr.proc_def.child_type = child_type;
606   node->attr.proc_def.parent_type = parent_type;
607   node->attr.proc_def.combine = combine;
608   return node;
609 }
610 
ASTNodeProcDef_Set(ASTNode * proc_def,ASTNode * c_name,ASTNode * implem)611 ASTNode *ASTNodeProcDef_Set(ASTNode *proc_def, ASTNode *c_name,
612                             ASTNode *implem) {
613   assert(proc_def->type == ASTNODETYPE_PROCDEF);
614   if (c_name != NULL)
615     proc_def->attr.proc_def.c_name = c_name;
616   if (implem != NULL)
617     proc_def->attr.proc_def.implem = implem;
618   return proc_def;
619 }
620 
ASTNodeTypeDef_New(ASTNode * name,ASTNode * src_type)621 ASTNode *ASTNodeTypeDef_New(ASTNode *name, ASTNode *src_type) {
622   ASTNode *node = ASTNode_New(ASTNODETYPE_TYPEDEF);
623   node->attr.type_def.name = name;
624   node->attr.type_def.src_type = src_type;
625   return node;
626 }
627 
My_ASTNodeMemberType_Finaliser(ASTNode * node)628 static void My_ASTNodeMemberType_Finaliser(ASTNode *node) {
629   assert(node->type == ASTNODETYPE_MEMBERTYPE);
630   Box_Mem_Free(node->attr.member_type.name);
631 }
632 
ASTNodeMemberType_New(ASTTypeMemb * m)633 ASTNode *ASTNodeMemberType_New(ASTTypeMemb *m) {
634   ASTNode *node = ASTNode_New(ASTNODETYPE_MEMBERTYPE);
635   node->attr.member_type.name = (m->name == NULL) ?
636                                 NULL : Box_Mem_Strdup(m->name);
637   node->attr.member_type.type = m->type;
638   node->attr.member_type.next = NULL;
639   node->finaliser = My_ASTNodeMemberType_Finaliser;
640   return node;
641 }
642 
ASTNodeStrucType_New(ASTTypeMemb * first_member)643 ASTNode *ASTNodeStrucType_New(ASTTypeMemb *first_member) {
644   ASTNode *member = NULL, *node;
645   assert(first_member->type != NULL);
646   if (first_member != NULL)
647     member = ASTNodeMemberType_New(first_member);
648 
649   node = ASTNode_New(ASTNODETYPE_STRUCTYPE);
650   node->attr.struc_type.first_member = member;
651   node->attr.struc_type.last_member = member;
652   return node;
653 }
654 
ASTNodeStrucType_Add_Member(ASTNode * struc_type,ASTTypeMemb * member)655 ASTNode *ASTNodeStrucType_Add_Member(ASTNode *struc_type,
656                                      ASTTypeMemb *member) {
657   ASTNode *this_member = NULL;
658   assert(struc_type->type == ASTNODETYPE_STRUCTYPE);
659   assert(member != NULL);
660   assert(!(member->type == NULL && member->name == NULL));
661 
662   this_member = ASTNodeMemberType_New(member);
663   if (struc_type->attr.struc_type.last_member == NULL) {
664     assert(struc_type->attr.struc_type.first_member == NULL);
665     struc_type->attr.struc_type.first_member = this_member;
666     struc_type->attr.struc_type.last_member = this_member;
667     return struc_type;
668 
669   } else {
670     ASTNode *last_member = struc_type->attr.struc_type.last_member;
671     last_member->attr.member_type.next = this_member;
672     struc_type->attr.struc_type.last_member = this_member;
673   }
674   return struc_type;
675 }
676 
ASTNodeSpecType_New(ASTNode * first_type,ASTNode * second_type)677 ASTNode *ASTNodeSpecType_New(ASTNode *first_type, ASTNode *second_type) {
678   ASTNode *node;
679   node = ASTNode_New(ASTNODETYPE_SPECTYPE);
680   node->attr.spec_type.first_member = NULL;
681   node->attr.spec_type.last_member = NULL;
682   node = ASTNodeSpecType_Add_Member(node, first_type);
683   node = ASTNodeSpecType_Add_Member(node, second_type);
684   return node;
685 }
686 
ASTNodeSpecType_Add_Member(ASTNode * spec_type,ASTNode * type)687 ASTNode *ASTNodeSpecType_Add_Member(ASTNode *spec_type, ASTNode *type) {
688   ASTNode *memb_node;
689   ASTTypeMemb type_memb;
690 
691   assert(spec_type->type == ASTNODETYPE_SPECTYPE);
692 
693   type_memb.type = type;
694   type_memb.name = NULL;
695   memb_node = ASTNodeMemberType_New(& type_memb);
696   if (spec_type->attr.spec_type.last_member == NULL) {
697     assert(spec_type->attr.spec_type.first_member == NULL);
698     spec_type->attr.spec_type.first_member =
699       spec_type->attr.spec_type.last_member = memb_node;
700     return spec_type;
701 
702   } else {
703     ASTNode *last_member = spec_type->attr.struc_type.last_member;
704     last_member->attr.member_type.next = memb_node;
705     spec_type->attr.struc_type.last_member = memb_node;
706   }
707 
708   return spec_type;
709 }
710 
ASTNodeRaiseType_New(ASTNode * type)711 ASTNode *ASTNodeRaiseType_New(ASTNode *type) {
712   ASTNode *node;
713   node = ASTNode_New(ASTNODETYPE_RAISETYPE);
714   node->attr.raise_type.type = type;
715   return node;
716 }
717