1
2
3%{
4#include "wisebase.h"
5
6/*
7 *
8
9 Expr Tree is about the yacc parse tree. Each node in the
10 tree is going to be ExprTree *. The children of each node
11 are in the child array, the number of children are in the
12 nochild field.
13
14 Each node has a type, and this is the critical layout of
15 the node. Each type will layout its children in a particular
16 way:
17
18 ETR_NUMBER - has no children. The number is word
19 ETR_OPERATOR - has no children. The operator character is in word
20 ETR_EXPRESSION - has potentially any number of children, but
21    the yacc parser restricts it to (possible_tag) (operator) (possible_tag).
22    Don't rely on this though. Generally allowed types in possible_tag
23    are NUMBEr, TAG, METHOD or EXPRESSION
24
25 ETR_STATEMENT - is the top level tag. It only has one child which must
26     be an ETR_EXPRESSION
27
28 ETR_NAME  - is for absolute variable names (or method names). It has no
29     children. The actual name is in the word
30
31 ETR_ARRAY - has 2 children. The first must be a "TAG" type and is what
32     is indexed, the second must be an EXPRESSION and is what indexes it.
33
34 ETR_TAG -   has any number of children to build up a TAG from NAMES,
35     ->,. (struct refs) or * (REFERNECES).
36
37 ETR_STRUCTREF -  -> or . constructions. It has 3 children: 1st is the
38     TAG to the left of the STRUCTREF, second holds either . or -> in word
39     and third is the tag to the right.
40
41 ETR_REFERENCE - * or & constructions. It has two children. 1st is * or & in
42     word, the second is the tag which is it is acting on.
43
44 ETR_METHOD - function calls. It has one or two children. The first is a tag (hence
45     could be a pointer to a function, or similar). If it is a void function
46     it has no other children the second is a commalist.
47
48 ETR_COMMALIST - can only be found in methods. Any number of children, each being
49     an argument of the method
50
51*/
52
53
54
55
56
57
58enum types {
59	ETR_NUMBER = 0,
60	ETR_OPERATOR,
61	ETR_EXPRESSION,
62	ETR_STATEMENT,
63	ETR_ARRAY,
64	ETR_NAME,
65	ETR_REFERENCE,
66	ETR_STRUCTREF,
67	ETR_METHOD,
68	ETR_COMMALIST,
69	ETR_DECL_VARIABLE,
70	ETR_DECL_METHOD,
71	ETR_DECL_LIST,
72	ETR_TAG
73	};
74
75#define EXPRTREE_MAXCHILD 128
76
77#define IS_DECLARED 2
78#define IS_TOPLEVEL 4
79
80
81%}
82
83
84struct ExprTree
85struct ExprTree * child[EXPRTREE_MAXCHILD];
86int nochild; !def="0"
87char token;
88char * word;
89int type;
90int attrib; !def="0"
91struct ExprTree * parent;
92int position_in_parent;
93
94
95
96%{
97#include "exprtree.h"
98
99void parentfy_ExprTree(ExprTree * et)
100{
101  int i;
102
103  for(i=0;i<et->nochild;i++) {
104    et->child[i]->parent = et;
105    et->child[i]->position_in_parent = i;
106    parentfy_ExprTree(et->child[i]);
107  }
108
109
110}
111
112void declared_ExprTree(ExprTree * et)
113{
114  fprintf(stderr,"Declaring...");
115
116  et->attrib = et->attrib | IS_DECLARED;
117
118}
119
120
121
122void find_toplevel_name(ExprTree * et)
123{
124  /** et should be an expression or a tag **/
125
126  int i;
127
128  for(i=0;i<et->nochild;i++) {
129    switch(et->child[i]->type) {
130    case ETR_NAME :
131      if( et->position_in_parent == 0 || !(et->parent->type == ETR_REFERENCE || et->parent->type == ETR_STRUCTREF) ) {
132	/*      	printf("Found as a name -> [%d][%d]",et->parent->position_in_parent,et->parent->type);
133	print_ExprTree(et->child[i]);
134	printf("\n");
135	*/
136	et->child[i]->attrib |= IS_TOPLEVEL;
137      } else {
138
139	/*	printf("Ignoring name %d,%d",et->parent->position_in_parent,et->parent->type);
140	print_ExprTree(et->child[i]);
141	printf("\n");
142	*/
143
144	et->child[i]->attrib &= ~IS_TOPLEVEL;
145
146      }
147      break;
148    default :
149/*
150      printf("Going into");
151      print_ExprTree(et->child[i]);
152      printf("\n");
153*/
154      find_toplevel_name(et->child[i]);
155      break;
156    }
157  }
158}
159
160
161void strcat_ExprTree(ExprTree * ExprTree,char * buffer)
162{
163  int i;
164
165  switch(ExprTree->type) {
166  case ETR_NUMBER : strcat(buffer,ExprTree->word); return;
167  case ETR_OPERATOR : strcat(buffer,ExprTree->word); return;
168  case ETR_EXPRESSION : strcat(buffer,"(");
169    for(i=0;i< ExprTree->nochild;i++)
170      strcat_ExprTree(ExprTree->child[i],buffer);
171    strcat(buffer,")");
172    return;
173  case ETR_STATEMENT :
174    for(i=0;i< ExprTree->nochild;i++)
175      strcat_ExprTree(ExprTree->child[i],buffer);
176    return;
177  case ETR_NAME : strcat(buffer,ExprTree->word);
178    return;
179  case ETR_ARRAY :
180    strcat_ExprTree(ExprTree->child[0],buffer);
181    strcat(buffer,"[");
182    strcat_ExprTree(ExprTree->child[1],buffer);
183    strcat(buffer,"]");
184    return;
185  case ETR_TAG :
186    for(i=0;i< ExprTree->nochild;i++)
187      strcat_ExprTree(ExprTree->child[i],buffer);
188    return;
189  case ETR_STRUCTREF :
190    strcat_ExprTree(ExprTree->child[0],buffer);
191    strcat(buffer,ExprTree->child[1]->word);
192    strcat_ExprTree(ExprTree->child[2],buffer);
193    return;
194  case ETR_REFERENCE :
195    strcat(buffer,ExprTree->child[0]->word);
196    strcat_ExprTree(ExprTree->child[1],buffer);
197    return;
198  case ETR_METHOD :
199    fprintf(stderr,"So buffer is now [%s]\n",buffer);
200    strcat_ExprTree(ExprTree->child[0],buffer);
201    strcat(buffer,"(");
202    fprintf(stderr,"So buffer is now [%s]\n",buffer);
203    strcat_ExprTree(ExprTree->child[1],buffer);
204
205    /*    for(i=0;i<ExprTree->child[1]->nochild;i++)
206      strcat_ExprTree(ExprTree->child[1]->child[i],buffer);
207      */
208
209    strcat(buffer,")");
210    return;
211  case ETR_COMMALIST :
212    for(i=0;i<ExprTree->nochild;i++) {
213      strcat_ExprTree(ExprTree->child[i],buffer);
214      if( i != ExprTree->nochild-1)
215	strcat(buffer,",");
216    }
217    return;
218
219  default :
220      warn("In trying to make Expr string, got unobtainable type!");
221  }
222}
223
224void print_ExprTree(ExprTree * ExprTree)
225{
226  int i;
227
228  switch(ExprTree->type) {
229  case ETR_NUMBER : printf("#{%s}",ExprTree->word); return;
230  case ETR_OPERATOR : printf("Op{%s}",ExprTree->word); return;
231  case ETR_EXPRESSION : printf("Expression (");
232    for(i=0;i< ExprTree->nochild;i++)
233      print_ExprTree(ExprTree->child[i]);
234    printf(")");
235    return;
236  case ETR_STATEMENT : printf("Top level:");
237    for(i=0;i< ExprTree->nochild;i++)
238      print_ExprTree(ExprTree->child[i]);
239    printf("\n");
240    return;
241  case ETR_NAME : printf("N{%s}",ExprTree->word);
242    for(i=0;i< ExprTree->nochild;i++)
243      print_ExprTree(ExprTree->child[i]);
244    return;
245  case ETR_ARRAY : printf("{ArrayInto{");
246    print_ExprTree(ExprTree->child[0]);
247    printf("} of [");
248    print_ExprTree(ExprTree->child[1]);
249    printf("]}");
250    return;
251  case ETR_TAG :
252    printf("Tag{");
253    for(i=0;i< ExprTree->nochild;i++)
254      print_ExprTree(ExprTree->child[i]);
255    printf("}");
256    return;
257  case ETR_STRUCTREF :
258    printf("struct{%s}(",ExprTree->child[1]->word);
259    print_ExprTree(ExprTree->child[0]);
260    printf(":");
261    print_ExprTree(ExprTree->child[2]);
262    printf(")");
263    return;
264  case ETR_REFERENCE :
265    printf("Ref{");
266    puts(ExprTree->child[0]->word);
267    print_ExprTree(ExprTree->child[1]);
268    printf("}\n");
269    return;
270  case ETR_METHOD :
271    if( ExprTree->attrib & IS_DECLARED )
272      printf("DEC:");
273
274    printf("Method{");
275    for(i=0;i<ExprTree->child[0]->nochild;i++)
276      print_ExprTree(ExprTree->child[0]->child[i]);
277    if( ExprTree->nochild == 1 )
278      printf("}(void)");
279    else {
280      printf("}(");
281      for(i=0;i<ExprTree->child[1]->nochild;i++)
282	print_ExprTree(ExprTree->child[1]->child[i]);
283      printf(")");
284    }
285    return;
286  case ETR_COMMALIST :
287    printf("List{");
288    for(i=0;i<ExprTree->nochild;i++)
289      print_ExprTree(ExprTree->child[i]);
290    printf("}");
291    return;
292
293  default :
294      printf("Unprintable!");
295  }
296}
297
298
299/*** declarations ***/
300
301ExprTree * new_ExprTree_decl_method(ExprTree * name,ExprTree * list)
302{
303  ExprTree * out;
304
305  out = new_ExprTree();
306
307  out->type = ETR_DECL_METHOD;
308  out->child[0]=name;
309  out->child[1]=list;
310  out->nochild = 2;
311
312  return out;
313}
314
315ExprTree * new_ExprTree_decl_variable(ExprTree * type,ExprTree * name)
316{
317  ExprTree * out;
318
319  out = new_ExprTree();
320
321  out->type = ETR_DECL_VARIABLE;
322  out->child[0]=type;
323  out->child[1]=name;
324  out->nochild = 2;
325
326  return out;
327}
328
329ExprTree * add_to_decl_list_ExprTree(ExprTree * list,ExprTree * add)
330{
331  if( list->type != ETR_DECL_LIST ) {
332    warn("Attempting to add to a non commalist %d",list->type);
333    return list;
334  }
335
336  add_ExprTree(list,add);
337
338  return list;
339}
340
341ExprTree * new_ExprTree_decl_list(ExprTree * start)
342{
343  ExprTree * out;
344
345  out = new_ExprTree();
346
347  out->type = ETR_DECL_LIST;
348  add_ExprTree(out,start);
349
350  return out;
351}
352
353ExprTree * new_ExprTree_struct_ref(ExprTree * left, ExprTree * ref,ExprTree * right)
354{
355  ExprTree * out;
356
357  out = new_ExprTree();
358
359  out->type = ETR_STRUCTREF;
360  out->child[0]=left;
361  out->child[1]=ref;
362  out->child[2]=right;
363  out->nochild = 3;
364
365  return out;
366}
367
368ExprTree * new_ExprTree_ref(char op,ExprTree * right)
369{
370  ExprTree * out;
371
372  out = new_ExprTree();
373
374  out->type = ETR_REFERENCE;
375  out->child[0]=new_ExprTree_token(op);
376  out->child[1]=right;
377  out->nochild = 2;
378
379  return out;
380}
381
382ExprTree * add_to_commalist_ExprTree(ExprTree * list,ExprTree * add)
383{
384  if( list->type != ETR_COMMALIST ) {
385    warn("Attempting to add to a non commalist %d",list->type);
386    return list;
387  }
388
389  add_ExprTree(list,add);
390
391  return list;
392}
393
394ExprTree * new_ExprTree_commalist(ExprTree * start)
395{
396  ExprTree * out;
397
398  out = new_ExprTree();
399
400  out->type = ETR_COMMALIST;
401  add_ExprTree(out,start);
402
403  return out;
404}
405
406ExprTree * new_ExprTree_method(ExprTree * one,ExprTree * other)
407{
408  ExprTree * out;
409
410  out = ExprTree_alloc();
411  out->type = ETR_METHOD;
412
413  /* printf("This one %d\n",one->nochild); */
414
415  add_ExprTree(out,one);
416
417  if(other == NULL) {
418    return out;
419  }
420
421  if(other->type != ETR_COMMALIST ) {
422    warn("Attempting to have a non commalist argument for a method");
423  }
424
425  add_ExprTree(out,other);
426
427  return out;
428}
429
430ExprTree * new_ExprTree_tag_from_name(ExprTree * name)
431{
432
433  ExprTree * out;
434
435  out= new_ExprTree();
436  out->type = ETR_TAG;
437
438  add_ExprTree(out,name);
439
440
441  return out;
442}
443
444ExprTree * new_ExprTree_array(ExprTree * tag,ExprTree * expr)
445{
446  ExprTree * out;
447
448  out = new_ExprTree();
449  out->type = ETR_ARRAY;
450  out->child[0] = tag;
451  out->child[1] = expr;
452  out->nochild = 2;
453  return out;
454}
455
456ExprTree * new_ExprTree_binary_expr(ExprTree * left,char op,ExprTree * rgt)
457{
458  ExprTree * out;
459
460
461  out = new_ExprTree();
462
463  out->type = ETR_EXPRESSION;
464  out->child[0] = left;
465  out->child[1] = new_ExprTree_token(op);
466  out->child[2] = rgt;
467  out->nochild = 3;
468
469  return out;
470}
471
472ExprTree * new_ExprTree_token(char t)
473{
474  ExprTree * out;
475  char buf[2];
476
477  buf[0] = t;
478  buf[1] = '\0';
479
480  out= new_ExprTree();
481  out->type= ETR_OPERATOR;
482  out->token = t;
483  out->word = stringalloc(buf);
484
485  return out;
486}
487
488boolean add_ExprTree(ExprTree * one,ExprTree * child)
489{
490  if( one->nochild+1 > EXPRTREE_MAXCHILD ) {
491    warn("Overflow in ExprTree at %d children",EXPRTREE_MAXCHILD);
492    return FALSE;
493  }
494
495  one->child[one->nochild++] = child;
496  return TRUE;
497}
498
499ExprTree * new_ExprTree(void)
500{
501  int i;
502  ExprTree * out;
503
504  out = ExprTree_alloc();
505  for(i=0;i<128;i++)
506    out->child[i]= NULL;
507
508
509  return out;
510}
511
512
513
514%}
515
516