ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
tree.c
Go to the documentation of this file.
1 
12 #include "tree.h"
13 #include "ceptr_error.h"
14 #include "hashfn.h"
15 #include "def.h"
16 
17 #include "receptor.h"
18 #include "scape.h"
19 #include "util.h"
20 #include "debug.h"
21 
22 /***************** Node creation */
23 void __t_append_child(T *t,T *c) {
24  if (t->structure.child_count == 0) {
25  t->structure.children = malloc(sizeof(T *)*TREE_CHILDREN_BLOCK);
26  } else if (!(t->structure.child_count % TREE_CHILDREN_BLOCK)){
27  int b = t->structure.child_count/TREE_CHILDREN_BLOCK + 1;
28  t->structure.children = realloc(t->structure.children,sizeof(T *)*(TREE_CHILDREN_BLOCK*b));
29  }
30 
31  t->structure.children[t->structure.child_count++] = c;
32 }
33 
34 T * __t_init(T *parent,Symbol symbol,bool is_run_node) {
35  T *t = malloc(is_run_node ? sizeof(rT) : sizeof(T));
36  t->structure.child_count = 0;
37  t->structure.parent = parent;
38  t->contents.symbol = symbol;
39  t->context.flags = 0;
40  if (is_run_node) {
41  ((rT *)t)->cur_child = RUN_TREE_NOT_EVAULATED;
42  t->context.flags |= TFLAG_RUN_NODE;
43  }
44  if (parent != NULL) {
45  __t_append_child(parent,t);
46  }
47  return t;
48 }
49 
59 T * __t_new(T *parent,Symbol symbol,void *surface,size_t size,bool is_run_node) {
60  T *t = __t_init(parent,symbol,is_run_node);
61  if (is_run_node) t->context.flags |= TFLAG_RUN_NODE;
62  if (size && surface) {
63  void *dst;
64  if (size <= sizeof(void *)) {
65  dst = &t->contents.surface;
66  }
67  else {
68  t->context.flags |= TFLAG_ALLOCATED;
69  dst = t->contents.surface = malloc(size);
70  }
71  memcpy(dst,surface,size);
72  }
73  t->contents.size = size;
74  return t;
75 }
76 
85 T * __t_newc(T *parent,Symbol symbol,char surface,bool is_run_node) {
86  return __t_new(parent,symbol,&surface,sizeof(char),is_run_node);
87 }
88 
97 T * __t_newi(T *parent,Symbol symbol,int surface,bool is_run_node) {
98  return __t_new(parent,symbol,&surface,sizeof(int),is_run_node);
99 }
100 
109 T * __t_newi64(T *parent,Symbol symbol,long surface,bool is_run_node) {
110  return __t_new(parent,symbol,&surface,sizeof(long),is_run_node);
111 }
112 
121 T *__t_news(T *parent,Symbol symbol,SemanticID surface,bool is_run_node){
122  return __t_new(parent,symbol,&surface,sizeof(SemanticID),is_run_node);
123 }
124 
133 T * _t_newt(T *parent,Symbol symbol,T *surface) {
134  T *t = __t_init(parent,symbol,false);
135  *((T **)&t->contents.surface) = surface;
136  t->contents.size = sizeof(T *);
137 
138  t->context.flags |= TFLAG_SURFACE_IS_TREE;
139  return t;
140 }
141 
150 T * __t_new_str(T *parent,Symbol symbol,char *surface,bool is_run_node) {
151  return __t_new(parent,symbol,surface,strlen(surface)+1,is_run_node);
152 }
153 
160 T *_t_new_root(Symbol symbol) {
161  return _t_new(0,symbol,0,0);
162 }
163 
171 T *__t_newr(T *parent,Symbol symbol,bool is_run_node) {
172  return __t_new(parent,symbol,0,0,is_run_node);
173 }
174 
175 /* create tree node whose surface is a specially allocated c structure,
176  i.e. a receptor, scape, or stream, these nodes get cloned as references
177  so the c-structure isn't double freed
178 */
179 T *__t_new_special(T *parent,Symbol symbol,void *s,int flag,bool is_run_node) {
180  T *t = __t_init(parent,symbol,is_run_node);
181  t->contents.surface = s;
182  t->contents.size = sizeof(void *);
183 
184  t->context.flags |= flag;
185  if (is_run_node) t->context.flags |= TFLAG_RUN_NODE;
186  return t;
187 }
188 
204 T *_t_new_receptor(T *parent,Symbol symbol,Receptor *r) {
205  T *t = __t_new_special(parent,symbol,r,TFLAG_SURFACE_IS_TREE+TFLAG_SURFACE_IS_RECEPTOR,0);
206  return t;
207 }
208 
222 T *_t_new_scape(T *parent,Symbol symbol,Scape *s) {
223  return __t_new_special(parent,symbol,s,TFLAG_SURFACE_IS_SCAPE,0);
224 }
225 
239 T *_t_new_cptr(T *parent,Symbol symbol,void *s) {
240  return __t_new_special(parent,symbol,s,TFLAG_SURFACE_IS_CPTR+TFLAG_REFERENCE,0);
241 }
242 
251 T * _t_newp(T *parent,Symbol symbol,Process surface) {
252  return _t_news(parent,symbol,surface);
253 }
254 
261 void _t_add(T *t,T *c) {
262  root_check(c);
263  c->structure.parent = t;
264  __t_append_child(t,c);
265 }
266 
278 T *_t_detach_by_idx(T *t,int i) {
279  T *x = _t_child(t,i);
280  _t_detach_by_ptr(t,x);
281  return x;
282 }
283 
291 void _t_detach_by_ptr(T *t,T *c) {
292  // search for the child to be removed
293  DO_KIDS(t,
294  if (_t_child(t,i) == c) {
295  // if found remove it by decreasing the child count and shift all the other children down
296  t->structure.child_count--;
297  if (t->structure.child_count == 0) {
298  free(t->structure.children);
299  }
300  for(;i<_c;i++) {
301  t->structure.children[i-1] = t->structure.children[i];
302  }
303  break;
304  }
305  );
306 
307  if (c) c->structure.parent = 0;
308 }
309 
325 void __t_morph(T *t,Symbol s,void *surface,size_t size,int allocate) {
326  t->contents.size = size;
327  if (t->context.flags & TFLAG_ALLOCATED) {
328  free(t->contents.surface);
329  }
330 
331  if (allocate) {
332  t->contents.surface = malloc(size);
333  memcpy(t->contents.surface,surface,size);
334  t->context.flags = TFLAG_ALLOCATED;
335  }
336  else {
337  if (surface)
338  memcpy(&t->contents.surface,surface,size);
339  t->context.flags = 0;
340  }
341 
342  t->contents.symbol = s;
343 }
344 
357 void _t_morph(T *dst,T *src) {
358  __t_morph(dst,_t_symbol(src),_t_surface(src),_t_size(src),src->context.flags & TFLAG_ALLOCATED);
359 }
360 
372 void _t_replace(T *t,int i,T *r) {
373  T *c = _t_child(t,i);
374  if (!c) {raise_error("tree doesn't have child %d",i);}
375  _t_free(c);
376  t->structure.children[i-1] = r;
377  r->structure.parent = t;
378 }
379 
391 void _t_replace_node(T *t,T *r) {
392  root_check(r);
393  if ((t->context.flags & TFLAG_RUN_NODE) != (r->context.flags & TFLAG_RUN_NODE)) {
394  raise_error("runnode mismatch");
395  }
396  __t_free(t);
397  t->contents = r->contents;
398  t->structure.child_count = r->structure.child_count;
399  t->structure.children = r->structure.children;
400  t->context = r->context;
401  free(r);
402  // fix the childrens' parent pointer
403  DO_KIDS(t,_t_child(t,i)->structure.parent = t);
404 }
405 
418 T *_t_swap(T *t,int i,T *r) {
419  root_check(r);
420  T *c = _t_child(t,i);
421  if (!c) {raise_error("tree doesn't have child %d",i);}
422  t->structure.children[i-1] = r;
423  r->structure.parent = t;
424  c->structure.parent = NULL;
425  return c;
426 }
427 
438 void _t_insert_at(T *t, int *path, T *i) {
439  T *c = _t_get(t,path);
440  int d = _t_path_depth(path)-1;
441  if (c) {
442  T *p = _t_parent(c);
443  if (!p) {
444  raise_error("Can't insert into the root!");
445  }
446 
447  // first insert the new tree at the end just to use the code we
448  // already have for mallocing children, etc,
449  _t_add(p,i);
450 
451  // then shift the other children over
452  int j,l = _t_children(p);
453  j = l - path[d];
454  T **tp = &p->structure.children[l-1];
455  while(j--) {
456  *tp = *(tp-1);
457  tp--;
458  }
459  // and put the new tree where it belongs
460  *tp = i;
461  }
462  else {
463  // if path points to one beyond last child, we can simply add it.
464  if (path[d]>1) {
465  path[d]--;
466  c = _t_get(t,path);
467  if (c) {
468  T *p = _t_parent(c);
469  if (!p) {
470  raise_error("Can't insert into the root!");
471  }
472  _t_add(p,i);
473  path[d]++;
474  return;
475  }
476  }
477  else if (d==0) { // special case to insert into first child of empty root
478  _t_add(t,i);
479  return;
480  }
481  raise_error("Path must lead to an existing node or one after last child.");
482  }
483 }
484 
485 /***************** Node deletion */
486 
487 void __t_free_children(T *t) {
488  int c = t->structure.child_count;
489  if (c > 0) {
490  while(--c>=0) {
491  _t_free(t->structure.children[c]);
492  }
493  free(t->structure.children);
494  }
495  t->structure.child_count = 0;
496 }
497 
498 // free everything except the node itself
499 void __t_free(T *t) {
500  __t_free_children(t);
501  if (!(t->context.flags & TFLAG_REFERENCE)) {
502  if (t->context.flags & TFLAG_ALLOCATED)
503  free(t->contents.surface);
504  else if (t->context.flags & TFLAG_SURFACE_IS_TREE) {
505  if (t->context.flags & TFLAG_SURFACE_IS_RECEPTOR)
506  _r_free((Receptor *)t->contents.surface);
507  else
508  _t_free((T *)t->contents.surface);
509  }
510  else if (t->context.flags & TFLAG_SURFACE_IS_SCAPE)
511  _s_free((Scape *)t->contents.surface);
512  else if (t->context.flags & TFLAG_SURFACE_IS_CPTR) {
513  raise_error("WHAAA!");
514  }
515  }
516 }
517 
526 void _t_free(T *t) {
527  __t_free(t);
528  free(t);
529 }
530 
531 T *__t_clone(T *t,T *p) {
532  T *nt;
533  uint32_t flags = t->context.flags;
534 
535  // if the tree points to a type that has an allocated c structure as its surface
536  // the clone must be marked as a reference, otherwise it would get freed twice
537  if (flags & (TFLAG_SURFACE_IS_RECEPTOR+TFLAG_SURFACE_IS_SCAPE+TFLAG_SURFACE_IS_CPTR)) {
538  nt = __t_new_special(p,_t_symbol(t),_t_surface(t),flags,0);
539  nt->context.flags |= TFLAG_REFERENCE;
540  }
541  else if (flags & TFLAG_SURFACE_IS_TREE) {
542  nt = _t_newt(p,_t_symbol(t),__t_clone((T *)_t_surface(t),0));
543  }
544  else if(_t_size(t) == 0)
545  nt = _t_newr(p,_t_symbol(t));
546  else
547  nt = _t_new(p,_t_symbol(t),_t_surface(t),_t_size(t));
548  DO_KIDS(t,__t_clone(_t_child(t,i),nt));
549 
550 
551  return nt;
552 }
553 
554 T *__t_rclone(T *t,T *p) {
555  T *nt;
556  uint32_t flags = t->context.flags;
557  if (flags & TFLAG_SURFACE_IS_RECEPTOR) {
558  raise_error("can't rclone receptors");
559  }
560  // if the tree points to a type that has an allocated c structure as its surface
561  // the clone must be marked as a reference, otherwise it would get freed twice
562  else if (flags & (TFLAG_SURFACE_IS_RECEPTOR+TFLAG_SURFACE_IS_SCAPE+TFLAG_SURFACE_IS_CPTR)) {
563  nt = __t_new_special(p,_t_symbol(t),_t_surface(t),flags,1);
564  nt->context.flags |= TFLAG_REFERENCE;
565  }
566  else if (flags & TFLAG_SURFACE_IS_TREE) {
567  nt = _t_newt(p,_t_symbol(t),__t_rclone((T *)_t_surface(t),0));
568  }
569  else if(_t_size(t) == 0)
570  nt = __t_new(p,_t_symbol(t),0,0,1);
571  else
572  nt = __t_new(p,_t_symbol(t),_t_surface(t),_t_size(t),1);
573  ((rT *)nt)->cur_child = RUN_TREE_NOT_EVAULATED;
574  DO_KIDS(t,__t_rclone(_t_child(t,i),nt));
575  return nt;
576 }
577 
589 T *_t_clone(T *t) {
590  return __t_clone(t,0);
591 }
592 
593 T *_t_rclone(T *t) {
594  return __t_rclone(t,0);
595 }
596 
597 SemanticID _getBuildType(SemTable *sem,SemanticID param,Structure *stP,T **defP) {
598  if (is_process(param)) {
599  *defP = _sem_get_def(sem,param);
600  return PROCESS_SIGNATURE;
601  }
602  /* if (is_protocol(param)) { */
603  /* *defP = _sem_get_def(sem,param); */
604  /* return PROTOCOL_SEMANTICS; */
605  /* } */
606  Structure st = _sem_get_symbol_structure(sem,param);
607  *stP = st;
608  if (semeq(st,NULL_STRUCTURE)) {
609  *defP = NULL;
610  return st;
611  }
612  T *st_def = _sem_get_def(sem,st);
613  T *def = _t_child(st_def,2);
614  *defP = def;
615  Symbol stsym = _t_symbol(def);
616  return stsym;
617 }
618 /* // check the symbol set to see if param is legal: */
619 /* int i,c = _t_children(def); */
620 /* for (i=1;i<=c;i++) { */
621 /* if (semeq(*(Symbol *)_t_surface(_t_child(def,i)),param)) break; */
622 /* } */
623 /* if (i > c) raise_error("got %s but expecting symbol in set: %s",_sem_get_name(sem,param),_t2s(sem,def)); */
624 enum buildStates {bReadSymbol,bPop,bAddRoot,bReadBase};
635 T *_t_build(SemTable *sem,T *parent,...) {
636  va_list ap;
637  va_start (ap, parent);
638  Symbol param,type;
639  T *t = parent;
640  bool done = false;
641  Structure st = NULL_STRUCTURE;
642  char *stn;
643  T *def,*p;
644  int state = bReadSymbol;
645  // Symbol expecting[100];
646  // T* expecting_def[100];
647  int level = 0;
648  while(!done) {
649  switch(state) {
650  case bReadSymbol:
651  param = va_arg(ap,Symbol);
652  if (semeq(param,NULL_SYMBOL)) {debug(D_TREE,"read NULL_SYMBOL\n");state=bPop;break;}
653  //expecting[level]
654  type = _getBuildType(sem,param,&st,&def);
655  //expectig_def[level] = def;
656  debug(D_TREE,"reading %s of type: %s with def:%s\n",_sem_get_name(sem,param),_sem_get_name(sem,type),_t2s(sem,def));
657  if (semeq(type,PROCESS_SIGNATURE)) {
658  state = bAddRoot;
659  }
660  else if (semeq(type,STRUCTURE_SYMBOL)) {
661  if (semeq(*(Symbol *)_t_surface(def),NULL_SYMBOL)) {
662  state = bReadBase;
663  }
664  else {
665  state = bAddRoot;
666  }
667  }
668  else if (semeq(type,NULL_STRUCTURE)) {
669  // null structure literal so just add it and pop
670  _t_newr(t,param);
671  state = bPop;
672  }
673  else if (semeq(type,STRUCTURE_OR)) {
674  state = bAddRoot;
675  }
676  else if (semeq(type,STRUCTURE_ZERO_OR_MORE) || semeq(type,STRUCTURE_ANYTHING) || semeq(type,STRUCTURE_SEQUENCE) || semeq(type,STRUCTURE_ONE_OR_MORE)) {
677  state = bAddRoot;
678  }
679  else {
680  debug(D_TREE,"type:%s \n",_sem_get_name(sem,type));
681  raise_error("type: %s unimplemented in bReadSymbol",_sem_get_name(sem,type));
682  }
683  break;
684  case bReadBase:
685  // these are all the system defined structures
686  debug(D_TREE,"building sys structure %s\n",_sem_get_name(sem,st));
687  if (semeq(st,PROCESS) || semeq(st,SYMBOL) || semeq(st,STRUCTURE) || semeq(st,PROTOCOL)) {
688  t = _t_news(t,param,va_arg(ap,SemanticID));
689  // execption for SEMTREX_GROUP which has children...
690  if (semeq(param,SEMTREX_GROUP)) {
691  state = bReadSymbol;
692  break;
693  }
694  }
695  else if (semeq(st,INTEGER) || semeq(st,BIT)) {
696  t = _t_newi(t,param,va_arg(ap,int));
697  }
698  else if (semeq(st,CSTRING)) {
699  t = _t_new_str(t,param,va_arg(ap,char *));
700  }
701  else if (semeq(st,CHAR)) {
702  int i = va_arg(ap,int);
703  t = _t_newc(t,param,i);
704  }
705  else if (semeq(st,FLOAT)) {
706  double d = va_arg(ap,double); // because vararg floats get promoted to doubles
707  float f = d;
708  t = _t_new(t,param,&f,sizeof(float));
709  }
710  else if (semeq(st,TREE_PATH)) {
711  int path[100];
712  int j = 0;
713  while((path[j]=va_arg(ap,int)) != TREE_PATH_TERMINATOR) {
714  j++;
715  if (j==100) raise_error("path too deep!");
716  }
717  t = _t_new(t,param,path,sizeof(int)*(j+1));
718  }
719  else {
720  raise_error("unimplemented surface type:%s",_sem_get_name(sem,st));
721  }
722  state = bPop;
723  break;
724  case bPop:
725  p = _t_parent(t);
726  if (p == parent) {done = true;break;}
727  t = p;
728  param = _t_symbol(t);
729  type = _getBuildType(sem,param,&st,&def);
730  debug(D_TREE,"popping to %s of type %s\n",_sem_get_name(sem,param),_sem_get_name(sem,type));
731  if (semeq(type,STRUCTURE_ZERO_OR_MORE) || semeq(type,STRUCTURE_ANYTHING) || semeq(type,STRUCTURE_SEQUENCE) || semeq(type,STRUCTURE_ONE_OR_MORE)) {
732  state = bReadSymbol;
733  }
734  else if (semeq(type,PROCESS_SIGNATURE)) {
735  state = bReadSymbol;
736  }
737  else if (semeq(type,STRUCTURE_OR)) {
738  state = bPop; //gotta pop right away because we only expect one item
739  }
740  else if (semeq(type,STRUCTURE_SYMBOL)) {
741  // this should only happen when popping back from a SEMTREX_GROUP
742  // so just pop again
743  state = bPop; //gotta pop right away because we only expect one item
744  }
745  else {
746  debug(D_TREE,"type:%s \n",_sem_get_name(sem,type));
747  raise_error("type: %s unimplemented in bPop",_sem_get_name(sem,type));
748  }
749  break;
750  case bAddRoot:
751  debug(D_TREE,"adding node %s\n",_sem_get_name(sem,param));
752  t = _t_newr(t,param);
753  state = bReadSymbol;
754  break;
755  }
756  }
757  va_end(ap);
758  return t;
759 }
760 
771 T *_t_build2(SemTable *sem,T *parent,...) {
772  va_list ap;
773  va_start (ap, parent);
774  Symbol param,type,node;
775  T *t = parent;
776  bool done = false;
777  Structure st = NULL_STRUCTURE;
778  char *stn;
779  T *def;
780  while(!done) {
781  param = va_arg(ap,Symbol);
782  if (semeq(param,STX_OP)) {
783  node = va_arg(ap,Symbol);
784  type = NULL_SYMBOL;
785  if (!semeq(node,NULL_SYMBOL)) type = _getBuildType(sem,node,&st,&def);
786  if (semeq(type,STRUCTURE_SYMBOL) && semeq(*(Symbol *)_t_surface(def),NULL_SYMBOL)) {
787  debug(D_TREE,"building sys structure %s\n",_sem_get_name(sem,st));
788  if (semeq(st,PROCESS) || semeq(st,SYMBOL) || semeq(st,STRUCTURE) || semeq(st,PROTOCOL)) {
789  t = _t_news(t,node,va_arg(ap,SemanticID));
790  }
791  else if (semeq(st,INTEGER) || semeq(st,BIT)) {
792  t = _t_newi(t,node,va_arg(ap,int));
793  }
794  else if (semeq(st,CSTRING)) {
795  t = _t_new_str(t,node,va_arg(ap,char *));
796  }
797  else if (semeq(st,CHAR)) {
798  int x = va_arg(ap,int);
799  t = _t_newc(t,node,x);
800  }
801  else if (semeq(st,TREE_PATH)) {
802  int path[100];
803  int j = 0;
804  while((path[j]=va_arg(ap,int)) != TREE_PATH_TERMINATOR) {
805  j++;
806  if (j==100) raise_error("path too deep!");
807  }
808  t = _t_new(t,node,path,sizeof(int)*(j+1));
809  }
810  else {
811  raise_error("unimplemented surface type:%s",_sem_get_name(sem,st));
812  }
813  }
814  else {
815  t = _t_newr(t,node);
816  }
817  }
818  else if (semeq(param,STX_CP)) {
819  T *p = _t_parent(t);
820  if (p == parent) {done = true;break;}
821  t = p;
822  }
823  else {
824  raise_error("expecting open or close! got: %s",_sem_get_name(sem,param));
825  }
826  }
827  va_end(ap);
828  return t;
829 }
830 #define test_buffer_overrun if (i == 999) raise_error("buf overrun\n");
831 
832 T *__t_tokenize(char *s) {
833  T *t = _t_new_root(P_TOKENS);
834  char buf[1000];
835  while(*s) {
836  int c = *s;
837  if (isspace(c)) {s++;continue;}
838  if (c == '(') _t_newr(t,P_OP);
839  else if (c == ')') _t_newr(t,P_CP);
840  else if (c == ':') _t_newr(t,P_COLON);
841  else if (c == '%') _t_newr(t,P_INTERPOLATE);
842  else if (c == '\'') {
843  c = *++s;
844  if (!c) raise_error("expecting char value, got end of string");
845  int x = *++s;
846  if (!x) raise_error("expecting ', got end of string");
847  if (x != '\'') raise_error("expecting ' got %c\n",x);
848  _t_newc(t,P_VAL_C,c);
849  }
850  else if (c == '"') {
851  int i = 0;
852  while((c=buf[i]=*++s) && c != '"' && i<999) i++;
853  test_buffer_overrun;
854  if (!c) raise_error("no closing quote found");
855  buf[i]=0;
856  _t_new_str(t,P_VAL_S,buf);
857  }
858  else if (isdigit(c) || c == '.') {
859  bool is_float = false;
860  int i = 0;
861  while((c=buf[i]=*s) && (isdigit(c) || (c =='.' && !is_float)) && i<999) {
862  if (c=='.') is_float = true;
863  i++; s++;
864  }
865  buf[i]=0;
866  if (is_float) {
867  float f = atof(buf);
868  _t_new(t,P_VAL_F,&f,sizeof(float));
869  }
870  else _t_newi(t,P_VAL_I,atoi(buf));
871  test_buffer_overrun;
872  if (c=='.') raise_error("unexpected . in number\n");
873  s--;
874 
875  }
876  else if (c == '/') {
877  int j = 0;
878  int path[100];
879  while(c=='/') {
880  int i = 0;
881  s++;
882  while((c=buf[i]=*s) && isdigit(c) && i<999) {
883  i++; s++;
884  }
885  test_buffer_overrun;
886  if (i==0 && c!=')') raise_error("expecting a number");
887  if (i) {
888  buf[i]=0;
889  path[j++] = atoi(buf);
890  if (j==99) raise_error("path too deep in parse");
891  }
892  }
893  path[j++]=TREE_PATH_TERMINATOR;
894  _t_new(t,P_VAL_PATH,path,sizeof(int)*j);
895  s--;
896  }
897  else {
898  int i = 0;
899  while((c=buf[i]=*s) && (isalnum(c) || c =='_') && i<999) {i++; s++;}
900  test_buffer_overrun;
901  buf[i]=0;
902  _t_new_str(t,P_LABEL,buf);
903  s--;
904  }
905  s++;
906  }
907  return t;
908 }
909 
919 T *_t_parse(SemTable *sem,T *parent,char *s,...) {
920  T *tokens = __t_tokenize(s);
921  T *t = parent;
922  int idx = 1;
923  T *tok;
924  va_list ap;
925  va_start (ap, s);
926  while ((tok = _t_child(tokens,idx++))) {
927  if (semeq(P_INTERPOLATE,_t_symbol(tok))) {
928  _t_add(t,va_arg(ap,T *));
929  }
930  // if we are opening a new tree node
931  else if (semeq(P_OP,_t_symbol(tok))) {
932  tok = _t_child(tokens,idx++);
933  if (!tok) raise_error("unexpected end of tokens!");
934  if (!semeq(P_LABEL,_t_symbol(tok)))
935  raise_error("expecting symbol LABEL");
936  char *label = (char *)_t_surface(tok);
937  SemanticID node;
938  if (!_sem_get_by_label(sem,label,&node)) {
939  raise_error("unknown semantic id:%s",label);
940  }
941 
942  T *def;
943  Structure st;
944  Symbol type = NULL_SYMBOL;
945 
946  if (!semeq(node,NULL_SYMBOL)) type = _getBuildType(sem,node,&st,&def);
947  // if the symbol is a structure type or has a NULL_SYMBOL as it's definitional
948  // surface then we know that we have a simple structure to build
949  if (semeq(type,STRUCTURE_SYMBOL) && semeq(*(Symbol *)_t_surface(def),NULL_SYMBOL)) {
950  tok = _t_child(tokens,idx++);
951  if (!tok) raise_error("unexpected end of tokens! expecting P_COLON");
952  if (!semeq(P_COLON,_t_symbol(tok)))
953  raise_error("expecting P_COLON got %s",_t2s(sem,tok));
954  tok = _t_child(tokens,idx++);
955  if (!tok) raise_error("unexpected end of tokens! expecting a value token");
956  Symbol v = _t_symbol(tok);
957  if (!(semeq(v,P_VAL_S)||semeq(v,P_VAL_C)||semeq(v,P_VAL_I)||semeq(v,P_VAL_F)||semeq(v,P_VAL_PATH)||semeq(v,P_LABEL) )) raise_error("expecting value symbol got: %s",_t2s(sem,tok));
958 
959  if (semeq(st,PROCESS) || semeq(st,SYMBOL) || semeq(st,STRUCTURE) || semeq(st,PROTOCOL)) {
960  if (!semeq(v,P_LABEL)) raise_error("expecting a label for the value of a SemanticID");
961  label = (char *)_t_surface(tok);
962  if (!_sem_get_by_label(sem,label,&v)) {
963  raise_error("unknown semantic id:%s",label);
964  }
965  t = _t_news(t,node,v);
966  }
967  else if (semeq(st,INTEGER) || semeq(st,BIT)) {
968  if (!semeq(v,P_VAL_I)) raise_error("expecting a P_VAL_I got %s",_t2s(sem,tok));
969  t = _t_newi(t,node,*(int *)_t_surface(tok));
970  }
971  else if (semeq(st,FLOAT)) {
972  if (!semeq(v,P_VAL_F)) raise_error("expecting a P_VAL_F got %s",_t2s(sem,tok));
973  t = _t_new(t,node,(float *)_t_surface(tok),sizeof(float));
974  }
975  else if (semeq(st,CSTRING)) {
976  if (!semeq(v,P_VAL_S)) raise_error("expecting a P_VAL_S got %s",_t2s(sem,tok));
977  t = _t_new_str(t,node,(char *)_t_surface(tok));
978  }
979  else if (semeq(st,CHAR)) {
980  if (!semeq(v,P_VAL_C)) raise_error("expecting a P_VAL_C got %s",_t2s(sem,tok));
981  int x = *(int *)_t_surface(tok);
982  t = _t_newc(t,node,x);
983  }
984  else if (semeq(st,TREE_PATH)) {
985  if (!semeq(v,P_VAL_PATH)) raise_error("expecting a P_VAL_PATH got %s",_t2s(sem,tok));
986  t = _t_new(t,node,_t_surface(tok),_t_size(tok));
987  }
988  else {
989  raise_error("unimplemented surface type:%s",_sem_get_name(sem,st));
990  }
991  }
992  else {
993  t = _t_newr(t,node);
994  }
995  }
996  else if (semeq(P_CP,_t_symbol(tok))) {
997  T *p = _t_parent(t);
998  if (p == parent) {break;}
999  t = p;
1000  }
1001  else {
1002  raise_error("expecting open or close paren! got: %s\n",_t2s(sem,tok));
1003  }
1004  }
1005  if (idx < _t_children(tokens)) raise_error("found ending close paren but some tokens still remain: %s",_t2s(sem,tokens));
1006  _t_free(tokens);
1007  va_end(ap);
1008  return t;
1009 }
1010 
1011 
1012 #include "semtrex.h"
1013 // used to resolve a semantic link that links kind to kind.
1014 T *__t_find_actual(T *sem_map,Symbol actual_kind,T *replacement_kind) {
1015  T *result = NULL;
1016  T *stx = _t_new_root(SEMTREX_WALK);
1017  T *l = _sl(stx,SEMANTIC_LINK);
1018  T *seq = _t_newr(l,SEMTREX_SEQUENCE);
1019  T *x = _t_newr(seq,SEMTREX_VALUE_LITERAL);
1020  T *k = _t_clone(replacement_kind);
1021  _t_add(x,k);
1022  x = _sl(seq,REPLACEMENT_VALUE);
1023  T *g = _t_news(x,SEMTREX_GROUP,actual_kind);
1024  x = _sl(g,actual_kind);
1025  T *mr;
1026  debug(D_TREE," trying to find a %s in sem_map\n",t2s(replacement_kind));
1027  if (_t_matchr(stx,sem_map,&mr)) {
1028  result = _stx_get_matched_node(actual_kind,mr,sem_map,NULL);
1029  debug(D_TREE," re-mapping %s ->",t2s(replacement_kind));
1030  debug(D_TREE,"%s\n",t2s(result));
1031  _t_free(mr);
1032  } else {debug(D_TREE," failed!\n");}
1033  _t_free(stx);
1034  return result;
1035 };
1036 
1049 bool __t_fill_template(T *template, T *sem_map,bool as_run_node) {
1050  if (!template) return false;
1051  debug(D_TREE,"filling template:\n%s\n",__t2s(G_sem,template,INDENT));
1052  debug(D_TREE,"from sem_map:\n%s\n\n",__t2s(G_sem,sem_map,INDENT));
1053 
1054  bool is_run_node = (template->context.flags |= TFLAG_RUN_NODE) || as_run_node;
1055  if (semeq(_t_symbol(template),SLOT)) {
1056  T *t = _t_child(template,SlotSemanticRefIdx);
1057  Symbol sym = _t_symbol(t);
1058  Symbol valsym = *(Symbol *)_t_surface(t);
1059  T *v = _t_child(template,SlotValueOfIdx);
1060  Symbol valof;
1061  T *children = NULL;
1062  if (v) {
1063  Symbol vsym = _t_symbol(v);
1064  if (semeq(vsym,SLOT_IS_VALUE_OF))
1065  valof = *(Symbol *)_t_surface(v);
1066  else if (semeq(vsym,SLOT_CHILDREN)) {
1067  __t_fill_template(v,sem_map,as_run_node);
1068  _t_detach_by_ptr(template,v);
1069  children = v;
1070  v = NULL;
1071  }
1072  else {
1073  raise_error("expecting SLOT_IS_VALUE_OF or SLOT_CHILDREN, got %s",_sem_get_name(G_sem,vsym));
1074  }
1075  }
1076  debug(D_TREE,"replacing %s\n",t2s(template));
1077  // scan all the sem_map for semantic refs that match this slot.
1078  // @todo convert this to a hashtable based implementation, probably on the treehash of the semantic ref
1079  int i,c = _t_children(sem_map);
1080  for(i=1;i<=c;i++) {
1081  T *m = _t_child(sem_map,i);
1082  T *ref = _t_child(m,SemanticMapSemanticRefIdx);
1083  debug(D_TREE,"(checking to see if sym:%s == _t_symbol(ref):%s\n",_sem_get_name(G_sem,sym),_sem_get_name(G_sem,_t_symbol(ref)));
1084  debug(D_TREE," and that valsym:%s == _t_surface(ref):%s\n",_sem_get_name(G_sem,valsym),_sem_get_name(G_sem,*(Symbol *)_t_surface(ref)));
1085  if (semeq(sym,_t_symbol(ref)) && semeq(valsym,*(Symbol *)_t_surface(ref))) {
1086  debug(D_TREE," yes!)\n");
1087  debug(D_TREE,"with %s\n",t2s(m));
1088  T *r = NULL;
1089  T *replacement_value = _t_child(_t_child(m,SemanticMapReplacementValIdx),1);
1090  if (semeq(sym,GOAL) && !v) { // treat a VALUE_OF slot as a symbol not a process
1091  SemanticID p = _t_symbol(replacement_value);
1092  if (!is_process(p)) {
1093  if (semeq(ACTUAL_PROCESS,p)) {
1094  p = *(Process *)_t_surface(replacement_value);
1095  }
1096  else if (semeq(GOAL,p)) {
1097  // if the replacement value is a goal, we need to look for
1098  // it's actual process symbol in the map
1099  T *x = __t_find_actual(sem_map,ACTUAL_PROCESS,replacement_value);
1100  if (!x)
1101  raise_error("unable to find actual for %s",t2s(m));
1102  p = *(Process *)_t_surface(x);
1103  }
1104  else {
1105  raise_error("expecting GOAL or ACTUAL_PROCESS for replacement values. got: %s",t2s(m));
1106  }
1107  }
1108  r = __t_new(0,p,0,0,is_run_node);
1109  if (is_run_node)
1110  ((rT *)r)->cur_child = RUN_TREE_NOT_EVAULATED;
1111  }
1112  else {
1113  SemanticID rsid = _t_symbol(replacement_value);
1114  debug(D_TREE,"replacement value: %s\n",t2s(replacement_value));
1115  // if the replacement value is a kind try to re-resolve from the map
1116  if (semeq(rsid,ROLE)) {
1117  T *x = __t_find_actual(sem_map,ACTUAL_RECEPTOR,replacement_value);
1118  if (x) replacement_value = x;
1119  }
1120  else if (semeq(rsid,USAGE)) {
1121  T *x = __t_find_actual(sem_map,ACTUAL_SYMBOL,replacement_value);
1122  if (x) replacement_value = x;
1123  }
1124  if (v) {
1125  // in the value_of case the replacement node is of the type specified in the template
1126  // and the "value" is either the surface of the "ACTUAL_X" or its children
1127  if (_t_children(replacement_value)) {
1128  if (is_run_node)
1129  r = _t_rclone(replacement_value);
1130  else
1131  r = _t_clone(replacement_value);
1132  r->contents.symbol = valof;
1133  }
1134  else {
1135  r = __t_new(0,valof,_t_surface(replacement_value),_t_size(t),is_run_node);
1136  }
1137  }
1138  else {
1139  // in the structure case: first, check to see if the replacement node is an "ACTUAL_SYMBOL" in which case we try to find an actual value for that symbol in the semantic map, and if that fails, simply assume that the symbol value is the actual value.
1140  T *temp = NULL;
1141  if (semeq(rsid,ACTUAL_SYMBOL)) {
1142  Symbol acsym = *(Symbol *)_t_surface(replacement_value);
1143  T *ac = _t_news(0,ACTUAL_SYMBOL,acsym);
1144  T *x = __t_find_actual(sem_map,ACTUAL_VALUE,ac);
1145  _t_free(ac);
1146  if (x) {
1147  replacement_value = _t_child(x,1);
1148  }
1149  else replacement_value = temp = _t_new_root(acsym);
1150  }
1151  else if (semeq(rsid,ACTUAL_VALUE)) {
1152  replacement_value = _t_child(replacement_value,1);
1153  }
1154  if (semeq(NULL_SYMBOL,_t_symbol(replacement_value))) {
1155  replacement_value = NULL;
1156  }
1157  if (replacement_value) {
1158  if (is_run_node)
1159  r = _t_rclone(replacement_value);
1160  else
1161  r = _t_clone(replacement_value);
1162  }
1163  else r = NULL;
1164  if (temp) _t_free(temp);
1165  }
1166  }
1167  if (children) {
1168  T *t;
1169  while(t = _t_detach_by_idx(children,1))
1170  _t_add(r,t);
1171  _t_free(children);
1172  }
1173  if (r) _t_replace_node(template,r);
1174  else {
1175  T *p = _t_parent(template);
1176  if (!p) raise_error("not expecting a root node!");
1177  _t_detach_by_ptr(p,template);
1178  _t_free(template);
1179  template = NULL;
1180  }
1181  break;
1182  }
1183  else { debug(D_TREE," nope)\n");}
1184  }
1185  }
1186  else {
1187  int i;
1188  for(i=1;i<=_t_children(template);i++) {
1189  T *t = _t_child(template,i);
1190  // if the fill resulted in deletion we need to decrease the count to not skip a child
1191  if (_t_fill_template(t,sem_map)) i--;
1192  }
1193  }
1194  debug(D_TREE,"results in:\n%s\n\n",template ? __t2s(G_sem,template,INDENT) : "<nothing>");
1195  return template == NULL;
1196 }
1197 
1198 /******************** Node data accessors */
1205 int _t_children(T *t) {
1206  return t->structure.child_count;
1207 }
1208 
1215 void * _t_surface(T *t) {
1216  if (t->context.flags & (TFLAG_ALLOCATED|TFLAG_SURFACE_IS_TREE|TFLAG_SURFACE_IS_SCAPE|TFLAG_SURFACE_IS_CPTR))
1217  return t->contents.surface;
1218  else
1219  return &t->contents.surface;
1220 }
1221 
1229  return t->contents.symbol;
1230 }
1231 
1238 size_t _t_size(T *t) {
1239  return t->contents.size;
1240 }
1241 
1242 /***************** Tree navigation */
1243 
1251 T *_t_child(T *t,int i) {
1252  if (i>t->structure.child_count || i < 1) return 0;
1253  return t->structure.children[i-1];
1254 }
1255 
1262 T * _t_parent(T *t) {
1263  return t->structure.parent;
1264 }
1265 
1272 T * _t_root(T *t) {
1273  T *p;
1274  while ((p = _t_parent(t)) != 0) t = p;
1275  return t;
1276 }
1277 
1284 int _t_node_index(T *t) {
1285  int c;
1286  int i;
1287  T *p = _t_parent(t);
1288  if (p==0) return 0;
1289  c = _t_children(p);
1290  for(i=0;i<c;i++) {
1291  if (p->structure.children[i] == t) {
1292  return i+1;
1293  }
1294  }
1295  return 0;
1296 }
1297 
1307  int c;
1308  int i;
1309  T *p = _t_parent(t);
1310  if (p==0) return 0;
1311  c = _t_children(p);
1312  for(i=0;i<c;i++) {
1313  if (p->structure.children[i] == t) {
1314  i++;
1315  return i<c ? p->structure.children[i] : 0;
1316  }
1317  }
1318  return 0;
1319 }
1320 
1328 T *__t_find(T *t,SemanticID sym,int start_child) {
1329  T *p;
1330  int i;
1331  int c = _t_children(t);
1332  for(i = start_child;i<=c;i++) {
1333  if (semeq(_t_symbol(p=_t_child(t,i)),sym)) return p;
1334  }
1335  return NULL;
1336 }
1337 
1338 
1339 /***************** Tree path based accesses */
1350 int _t_path_equal(int *p1,int *p2){
1351  while(*p1 != TREE_PATH_TERMINATOR && *p2 != TREE_PATH_TERMINATOR)
1352  if (*(p1++) != *(p2++)) return 0;
1353  return *p1 == TREE_PATH_TERMINATOR && *p2 == TREE_PATH_TERMINATOR;
1354 }
1355 
1365 int _t_path_depth(int *p) {
1366  int i=0;
1367  while(*p++ != TREE_PATH_TERMINATOR) i++;
1368  return i;
1369 }
1370 
1384 int * _t_get_path(T *t) {
1385  if (!t) return NULL;
1386  T *n;
1387  // allocate an array to hold the
1388  int s = sizeof(int)*20; // assume most trees are shallower than 10 nodes to prevent realloc
1389  int *p = malloc(s);
1390  int j,k,l,i=0,temp;
1391 
1392  // store the children's path index values into the array as we walk back up the tree to the root
1393  for(n=t;n;) {
1394  p[i] = _t_node_index(n);
1395  n =_t_parent(n);
1396  if (++i >= s) {
1397  s*=2;p=realloc(p,s);} // realloc array if tree too deep
1398  }
1399  if (i > 2) {
1400  // reverse the list by swapping elements going from the outside to the center
1401  i-=2;
1402  l = i+1;
1403  k = i/2+1;
1404  for(j=0;j<k;j++) {
1405  temp = p[j];
1406  p[j] = p[i];
1407  p[i--] = temp;
1408  }
1409  }
1410  else l = i-1;
1411  p[l]= TREE_PATH_TERMINATOR;
1412  return p;
1413 }
1414 
1424 void _t_pathcpy(int *dst_p,int *src_p) {
1425  while(*src_p != TREE_PATH_TERMINATOR) {
1426  *dst_p++ = *src_p++;
1427  }
1428  *dst_p = TREE_PATH_TERMINATOR;
1429 }
1430 
1441 T * _t_get(T *t,int *p) {
1442  int i = *p++;
1443  T *c;
1444  if (i == TREE_PATH_TERMINATOR)
1445  return t;
1446  else if (i == 0) {
1447  if (!(t->context.flags & TFLAG_SURFACE_IS_TREE)) {
1448  raise_error("surface is not a tree!");
1449  }
1450  c = (T *)(_t_surface(t));
1451  }
1452  else
1453  c = _t_child(t,i);
1454  if (c == NULL ) return NULL;
1455  if (*p == TREE_PATH_TERMINATOR) return c;
1456  return _t_get(c,p);
1457 }
1458 
1470 T * _t_getv(T *t,...) {
1471  int p[100];
1472  va_list ap;
1473  va_start (ap, t);
1474  int i = 0;
1475  while((p[i] = va_arg(ap,int)) != TREE_PATH_TERMINATOR) {
1476  if (i++ == 100) raise_error("tree path to deep");
1477  }
1478  va_end(ap);
1479  return _t_get(t,p);
1480 }
1481 
1492 void * _t_get_surface(T *t,int *p) {
1493  T *c = _t_get(t,p);
1494  if (c == NULL) return NULL;
1495  return _t_surface(c);
1496 }
1497 
1508 char * _t_sprint_path(int *fp,char *buf) {
1509  char *b = buf;
1510  int d=_t_path_depth(fp);
1511  if (d > 0) {
1512  int i;
1513  for(i=0;i<d;i++) {
1514  sprintf(b,"/%d",fp[i]);
1515  b += strlen(b);
1516  }
1517  }
1518  else {
1519  buf[0] = '/';
1520  buf[1] = 0;
1521  }
1522 
1523  return buf;
1524 }
1525 
1543 T *_t_path_walk(T *t,int **pathP,int *lenP ) {
1544  int *p,i;
1545 
1546  if (*pathP == NULL) {
1547 
1548  // if the pathP is NULL then this is the first call, so we can descend the left branch
1549  // and malloc our path buffer based on how far we had to descend.
1550  int d = 0;
1551  while (_t_children(t)) {
1552  t = _t_child(t,1);
1553  d++;
1554  }
1555  *lenP = sizeof(int)*(d+1);
1556  *pathP = p = malloc(*lenP);
1557  for(i=0;i<d;i++) {p[i]=1;}
1558  p[d]=TREE_PATH_TERMINATOR;
1559  return t;
1560  }
1561  else {
1562  // otherwise, figure out what we need to do by the context.
1563  p = *pathP;
1564  int d = _t_path_depth(p);
1565 
1566  // if the current path is the root, then simply remain at the root because we are already done
1567  // @todo how to signal this as an error?
1568  if (d == 0) return NULL;
1569 
1570  T *x = _t_get(t,p);
1571  // the next node is always either the left descend of the current node's next sibling, or
1572  // if it has no next sibling, then the parent
1573  int cur_idx = p[d-1];
1574  T* parent = _t_parent(x);
1575  if (_t_children(parent) > cur_idx) {
1576  // current node does have next siblings so next will be the left descend of the sibling
1577  i = ++p[d-1]; // first adjust the path to be the next sibling
1578  x = _t_child(parent,i); // get the next sibling node
1579  i = 0;
1580  while (_t_children(x)) { // and do the left descend
1581  x = _t_child(x,1);
1582  i++;
1583  }
1584  // now check if we need to realloc
1585  int new_depth_size = (i+d+1)*sizeof(int);
1586  if ( new_depth_size > *lenP) {
1587  *pathP = p = realloc(*pathP,*lenP=new_depth_size);
1588  }
1589  while(i--) p[d++]=1;
1590  p[d]=TREE_PATH_TERMINATOR;
1591  return x;
1592  }
1593  else {
1594  // no next sibling so the next node is the parent
1595  p[d-1] = TREE_PATH_TERMINATOR;
1596  return parent;
1597  }
1598  }
1599 }
1600 
1601 /***************** Tree hashing utilities */
1602 
1614 TreeHash _t_hash(SemTable *sem,T *t) {
1615  int i,c = _t_children(t);
1616  TreeHash result;
1617  if (c == 0) {
1618  struct {Symbol s;TreeHash h;} h;
1619  void *surface = _t_surface(t);
1620  h.s = _t_symbol(t);
1621  //@todo fix this so we don't have keep doing this on the recursive calls...
1622  size_t l = _d_get_symbol_size(sem,h.s,surface);
1623  if (l > 0)
1624  h.h = hashfn((char *)surface,l);
1625  else
1626  h.h = 0;
1627  result = hashfn((char *)&h,sizeof(h));
1628  }
1629  else {
1630  size_t l = sizeof(TreeHash)*c+sizeof(Symbol);
1631  TreeHash *h,*hashes = malloc(l);
1632  h = hashes;
1633  for(i=1;i<=c;i++) {
1634  *(h++) = _t_hash(sem,_t_child(t,i));
1635  }
1636  (*(Symbol *)h) = _t_symbol(t);
1637  result = hashfn((char *)hashes,l);
1638  free(hashes);
1639  }
1640  return result;
1641 }
1642 
1649 int _t_hash_equal(TreeHash h1,TreeHash h2) {
1650  return h1 == h2;
1651 }
1652 
1653 // scaffolding for uuid generator
1654 // for now we just use the current time
1655 UUIDt __uuid_gen() {
1656  UUIDt u;
1657  struct timespec c;
1658  clock_gettime(CLOCK_MONOTONIC, &c);
1659  u.time = ((c.tv_sec * (1000000)) + (c.tv_nsec / 1000));
1660  u.data = 0;
1661  return u;
1662 }
1663 
1664 int __uuid_equal(UUIDt *u1,UUIDt *u2) {
1665  return memcmp(u1,u2,sizeof(UUIDt))==0;
1666 };
1667 /***************** Tree serialization */
1668 
1670 #define SWRITE(type,value) type * type##P = (type *)(*bufferP +offset); *type##P=value;offset += sizeof(type);
1671 
1686 size_t __t_serialize(SemTable *sem,T *t,void **bufferP,size_t offset,size_t current_size,int compact){
1687  size_t cl =0,l = _t_size(t);
1688  int i, c = _t_children(t);
1689 
1690  // printf("\ncurrent_size:%ld offset:%ld size:%ld symbol:%s",current_size,offset,l,_sem_get_name(sem,_t_symbol(t)));
1691  while ((offset+l+sizeof(Symbol)) > current_size) {
1692  current_size*=2;
1693  *bufferP = realloc(*bufferP,current_size);
1694  }
1695  if (!compact) {
1696  Symbol s = _t_symbol(t);
1697  SWRITE(Symbol,s);
1698  SWRITE(int,c);
1699  }
1700  if (l) {
1701  memcpy(*bufferP+offset,_t_surface(t),l);
1702  offset += l;
1703  }
1704 
1705  for(i=1;i<=c;i++) {
1706  offset = __t_serialize(sem,_t_child(t,i),bufferP,offset,current_size,compact);
1707  }
1708  return offset;
1709 }
1710 
1711 
1723 void _t_serialize(SemTable *sem,T *t,void **surfaceP,size_t *lengthP) {
1724  size_t buf_size = 1000;
1725  *surfaceP = malloc(buf_size);
1726  *lengthP = __t_serialize(sem,t,surfaceP,0,buf_size,0);
1727  *surfaceP = realloc(*surfaceP,*lengthP);
1728 }
1729 
1731 #define SREAD(type,var_name) type var_name = *(type *)*surfaceP;*lengthP -= sizeof(type);*surfaceP += sizeof(type);
1732 #define _SREAD(type,var_name) var_name = *(type *)*surfaceP;*lengthP -= sizeof(type);*surfaceP += sizeof(type);
1734 
1735 T * _t_unserialize(SemTable *sem,void **surfaceP,size_t *lengthP,T *t) {
1736  size_t size;
1737 
1738  SREAD(Symbol,s);
1739  // printf("\nSymbol:%s",_sem_get_name(sem,s));
1740 
1741  SREAD(int,c);
1742 
1743  Structure st = _sem_get_symbol_structure(sem,s);
1744 
1745  if (is_sys_structure(st)) {
1746  size = _sys_structure_size(st.id,*surfaceP);
1747  if (size == -1) {raise_error("BANG!");}
1748  }
1749  else size = 0;
1750  if (size > 0) {
1751  // printf(" reading: %ld bytes\n",size);
1752  if (semeq(st,INTEGER))
1753  t = _t_newi(t,s,*(int *)*surfaceP);
1754  else
1755  t = _t_new(t,s,*surfaceP,size);
1756  *lengthP -= size;
1757  *surfaceP += size;
1758  }
1759  else {
1760  t = _t_newr(t,s);
1761  }
1762 
1763  int i;
1764  for(i=1;i<=c;i++) {
1765  _t_unserialize(sem,surfaceP,lengthP,t);
1766  }
1767  return t;
1768 }
1769 
1770 
1771 #define _add_char2buf(c,buf) *buf=c;buf++;*buf=0
1772 
1773 #define _add_sem(buf,s) sprintf(buf,"{ \"ctx\":%d,\"type\":%d,\"id\":%d }",s.context,s.semtype,s.id);
1774 
1785 char * _t2rawjson(SemTable *sem,T *t,int level,char *buf) {
1786  char *result = buf;
1787  if (!t) return "";
1788  Symbol s = _t_symbol(t);
1789  char b[255];
1790  char tbuf[2000];
1791  int i;
1792  char *c,cr;
1793  Xaddr x;
1794  buf = _indent_line(level,buf);
1795 
1796  sprintf(buf,"{\"sem\":");
1797  buf+= strlen(buf);
1798  _add_sem(buf,s);
1799  buf+= strlen(buf);
1800  if (is_symbol(s) && !semeq(s,NULL_SYMBOL)) {
1801  Structure st = _sem_get_symbol_structure(sem,s);
1802 
1803  if (is_sys_structure(st)) {
1804  switch(st.id) {
1805  case ENUM_ID: // for now enum surfaces are just strings so we can see the text value
1806  case CSTRING_ID:
1807  //@todo add escaping of quotes, carriage returns, etc...
1808  sprintf(buf,",\"surface\":\"\%s\"",(char *)_t_surface(t));
1809  break;
1810  case CHAR_ID:
1811  cr = *(char *)_t_surface(t);
1812  if (cr == '"') {
1813  sprintf(buf,",\"surface\":\"\\\"\"");
1814  } else {
1815  sprintf(buf,",\"surface\":\"%c\"",cr);
1816  }
1817  break;
1818  case BIT_ID:
1819  sprintf(buf,",\"surface\":%s",(*(int *)_t_surface(t)) ? "1" : "0");
1820  break;
1821  case BLOB_ID:
1822  raise_error("not implemented");
1823  break;
1824  case INTEGER_ID:
1825  sprintf(buf,",\"surface\":%d",*(int *)_t_surface(t));
1826  break;
1827  case INTEGER64_ID:
1828  sprintf(buf,",\"surface\":%ld",*(uint64_t *)_t_surface(t));
1829  break;
1830  case FLOAT_ID:
1831  sprintf(buf,",\"surface\":%f",*(float *)_t_surface(t));
1832  break;
1833  case SYMBOL_ID:
1834  case STRUCTURE_ID:
1835  case PROCESS_ID:
1836  case PROTOCOL_ID:
1837  case RECEPTOR_ID:
1838  {
1839  SemanticID sem =*(SemanticID *)_t_surface(t);
1840  sprintf(buf,",\"surface\":");
1841  buf+= strlen(buf);
1842  _add_sem(buf,sem);
1843  }
1844  break;
1845  case TREE_PATH_ID:
1846  sprintf(buf,",\"surface\":\"%s\"",_t_sprint_path((int *)_t_surface(t),b));
1847  break;
1848  case XADDR_ID:
1849  x = *(Xaddr *)_t_surface(t);
1850  sprintf(buf,",\"surface\":{ \"symbol\":\"%s\",\"addr\":%d }",_sem_get_name(sem,x.symbol),x.addr);
1851  break;
1852  case CPOINTER_ID:
1853  sprintf(buf,",\"surface\":\"%p\"",_t_surface(t));
1854  break;
1855  case TREE_ID:
1856  if (t->context.flags & TFLAG_SURFACE_IS_TREE) {
1857  c = _t2rawjson(sem,(T *)_t_surface(t),0,tbuf);
1858  sprintf(buf,",\"surface\":%s",c);
1859  break;
1860  }
1861  case RECEPTOR_SURFACE_ID:
1862  if (t->context.flags & (TFLAG_SURFACE_IS_TREE+TFLAG_SURFACE_IS_RECEPTOR)) {
1863  c = _t2rawjson(sem,((Receptor *)_t_surface(t))->root,0,tbuf);
1864  sprintf(buf,",\"surface\":%s",c);
1865  break;
1866  }
1867  case SCAPE_ID:
1868  if (t->context.flags & TFLAG_SURFACE_IS_SCAPE) {
1869  Scape *sc = (Scape *)_t_surface(t);
1870  //TODO: fixme!
1871  raise_error("not-implemented");
1872  sprintf(buf,"(key %s,data %s",_sem_get_name(sem,sc->key_source),_sem_get_name(sem,sc->data_source));
1873  break;
1874  }
1875  default:
1876  // other structures are composed so work automatically
1877  if (st.id > _t_children(__sem_get_defs(sem,SEM_TYPE_STRUCTURE,st.context)))
1878  raise_error("don't know how to convert surface of %s, structure id %d seems invalid",_sem_get_name(sem,s),st.id);
1879 
1880  }
1881  }
1882  }
1883  buf += strlen(buf);
1884  int _c = _t_children(t);
1885  if ( _c > 0) {
1886  sprintf(buf,",\"children\":[");
1887  buf += strlen(buf);
1888  for(i=1;i<=_c;i++){
1889  _t2rawjson(sem,_t_child(t,i),level < 0 ? level-1 : level+1,buf);
1890  buf += strlen(buf);
1891  if (i<_c) {
1892  _add_char2buf(',',buf);
1893  }
1894  }
1895  _add_char2buf(']',buf);
1896  }
1897  _add_char2buf('}',buf);
1898  return result;
1899 }
1900 
1912 char * _t2json(SemTable *sem,T *t,int level,char *buf) {
1913  char *result = buf;
1914  if (!t) return "";
1915  Symbol s = _t_symbol(t);
1916  char b[255];
1917  char tbuf[2000];
1918  int i;
1919  char *c,cr;
1920  Xaddr x;
1921  buf = _indent_line(level,buf);
1922 
1923  if (is_process(s)) {
1924  sprintf(buf,"{ \"type\":\"process\",\"name\" :\"%s\"",_sem_get_name(sem,s));
1925  }
1926  else {
1927  char *n = _sem_get_name(sem,s);
1928  Structure st = _sem_get_symbol_structure(sem,s);
1929  sprintf(buf,"{ \"symbol\":{ \"context\":%d,\"id\":%d },",s.context,s.id);
1930  buf+= strlen(buf);
1931 
1932  if (!is_sys_structure(st)) {
1933  // if it's not a system structure, it's composed, so all we need to do is
1934  // print out the symbol name, and the reset will take care of itself
1935  sprintf(buf,"\"type\":\"%s\",\"name\":\"%s\"",_sem_get_name(sem,st),n);
1936  }
1937  else {
1938 
1939  switch(st.id) {
1940  case ENUM_ID: // for now enum surfaces are just strings so we can see the text value
1941  case CSTRING_ID:
1942  //@todo add escaping of quotes, carriage returns, etc...
1943  sprintf(buf,"\"type\":\"CSTRING\",\"name\":\"%s\",\"surface\":\"\%s\"",n,(char *)_t_surface(t));
1944  break;
1945  case CHAR_ID:
1946  cr = *(char *)_t_surface(t);
1947  if (cr == '"') {
1948  sprintf(buf,"\"type\":\"CHAR\",\"name\":\"%s\",\"surface\":\"\\\"\"",n);
1949  } else {
1950  sprintf(buf,"\"type\":\"CHAR\",\"name\":\"%s\",\"surface\":\"%c\"",n,cr);
1951  }
1952  break;
1953  case BIT_ID:
1954  sprintf(buf,"\"type\":\"BIT\",\"name\":\"%s\",\"surface\":%s",n,(*(int *)_t_surface(t)) ? "1" : "0");
1955  break;
1956  case BLOB_ID:
1957  raise_error("not implemented");
1958  break;
1959  case INTEGER_ID:
1960  sprintf(buf,"\"type\":\"INTEGER\",\"name\":\"%s\",\"surface\":%d",n,*(int *)_t_surface(t));
1961  break;
1962  case INTEGER64_ID:
1963  sprintf(buf,"\"type\":\"INTEGER64\",\"name\":\"%s\",\"surface\":%ld",n,*(uint64_t*)_t_surface(t));
1964  break;
1965  case FLOAT_ID:
1966  sprintf(buf,"\"type\":\"FLOAT\",\"name\":\"%s\",\"surface\":%f",n,*(float *)_t_surface(t));
1967  break;
1968  case SYMBOL_ID:
1969  c = _sem_get_name(sem,*(Symbol *)_t_surface(t));
1970  sprintf(buf,"\"type\":\"SYMBOL\",\"name\":\"%s\",\"surface\":\"%s\"",n,c?c:"<unknown>");
1971  break;
1972  case STRUCTURE_ID:
1973  c = _sem_get_name(sem,*(Structure *)_t_surface(t));
1974  sprintf(buf,"\"type\":\"STRUCTURE\",\"name\":\"%s\",\"surface\":\"%s\"",n,c?c:"<unknown>");
1975  break;
1976  case PROCESS_ID:
1977  c = _sem_get_name(sem,*(Process *)_t_surface(t));
1978  sprintf(buf,"\"type\":\"PROCESS\",\"name\":\"%s\",\"surface\":\"%s\"",n,c?c:"<unknown>");
1979  break;
1980  case PROTOCOL_ID:
1981  c = _sem_get_name(sem,*(Protocol *)_t_surface(t));
1982  sprintf(buf,"\"type\":\"PROTOCOL\",\"name\":\"%s\",\"surface\":\"%s\"",n,c?c:"<unknown>");
1983  break;
1984  case RECEPTOR_ID:
1985  c = _sem_get_name(sem,*(SemanticID *)_t_surface(t));
1986  sprintf(buf,"\"type\":\"RECEPTOR\",\"name\":\"%s\",\"surface\":\"%s\"",n,c?c:"<unknown>");
1987  break;
1988  case TREE_PATH_ID:
1989  sprintf(buf,"\"type\":\"TREE_PATH\",\"name\":\"%s\",\"surface\":\"%s\"",n,_t_sprint_path((int *)_t_surface(t),b));
1990  break;
1991  case XADDR_ID:
1992  x = *(Xaddr *)_t_surface(t);
1993  sprintf(buf,"\"type\":\"XADDR\",\"name\":\"%s\",\"surface\":{ \"symbol\":\"%s\",\"addr\":%d }",n,_sem_get_name(sem,x.symbol),x.addr);
1994  break;
1995  case CPOINTER_ID:
1996  sprintf(buf,"\"type\":\"CPOINTER\",\"name\":\"%s\",\"surface\":\"%p\"",n,_t_surface(t));
1997  break;
1998  case TREE_ID:
1999  if (t->context.flags & TFLAG_SURFACE_IS_TREE) {
2000  c = _t2json(sem,(T *)_t_surface(t),0,tbuf);
2001  sprintf(buf,"\"type\":\"TREE\",\"name\":\"%s\",\"surface\":%s",n,c);
2002  break;
2003  }
2004  case RECEPTOR_SURFACE_ID:
2005  if (t->context.flags & (TFLAG_SURFACE_IS_TREE+TFLAG_SURFACE_IS_RECEPTOR)) {
2006  c = _t2json(sem,((Receptor *)_t_surface(t))->root,0,tbuf);
2007  sprintf(buf,"\"type\":\"RECEPTOR\",\"name\":\"%s\",\"surface\":%s",n,c);
2008  break;
2009  }
2010  case SCAPE_ID:
2011  if (t->context.flags & TFLAG_SURFACE_IS_SCAPE) {
2012  Scape *sc = (Scape *)_t_surface(t);
2013  //TODO: fixme!
2014  sprintf(buf,"(%s:key %s,data %s",n,_sem_get_name(sem,sc->key_source),_sem_get_name(sem,sc->data_source));
2015  break;
2016  }
2017  default:
2018  if (semeq(s,SEMTREX_MATCH_CURSOR)) {
2019  c = _t2json(sem,*(T **)_t_surface(t),0,tbuf);
2020  //c = "null";
2021  sprintf(buf,"(%s:{%s}",n,c);
2022  break;
2023  }
2024  if (n == 0)
2025  sprintf(buf,"(<unknown:%d.%d.%d>",s.context,s.semtype,s.id);
2026  else {
2027  c = _sem_get_name(sem,st);
2028  sprintf(buf,"\"type\":\"%s\",\"name\":\"%s\"",c,n);
2029  }
2030  }
2031  }
2032  }
2033  buf += strlen(buf);
2034  int _c = _t_children(t);
2035  if ( _c > 0) {
2036  sprintf(buf,",\"children\":[");
2037  buf += strlen(buf);
2038  for(i=1;i<=_c;i++){
2039  _t2json(sem,_t_child(t,i),level < 0 ? level-1 : level+1,buf);
2040  buf += strlen(buf);
2041  if (i<_c) {
2042  _add_char2buf(',',buf);
2043  }
2044  }
2045  _add_char2buf(']',buf);
2046  }
2047  _add_char2buf('}',buf);
2048  return result;
2049 }
2050 
2051 // assumes that t is a CSTRING structured tree
2052 int __t_writeln(T *t,Stream *stream) {
2053  int err = 0;
2054  char *str = _t_surface(t);
2055  return _st_writeln(stream,str);
2056 }
2057 
2066 int _t_write(SemTable *sem,T *t,Stream *stream) {
2067  int err;
2068  Symbol sym = _t_symbol(t);
2069  if (semeq(sym,LINE)) {
2070  err = __t_writeln(t,stream);
2071  }
2072  else if (semeq(sym,LINES)) {
2073  DO_KIDS(t,
2074  err = __t_writeln(_t_child(t,i),stream);
2075  if (err == 0) return 0;
2076  );
2077  }
2078  else {
2079  char *str;
2080  Structure struc = _sem_get_symbol_structure(sem,sym);
2081  if (semeq(struc,CSTRING)) {
2082  str = _t_surface(t);
2083  }
2084  else {
2085  str = _t2s(sem,t);
2086  }
2087  err = _st_write(stream,str,strlen(str));
2088  }
2089  return err;
2090 }
2091 
T * _t_new_root(Symbol symbol)
Definition: tree.c:160
char * _sem_get_name(SemTable *sem, SemanticID s)
Definition: semtable.c:85
Definition: ceptr_types.h:114
T * _t_next_sibling(T *t)
Definition: tree.c:1306
T * _t_new_scape(T *parent, Symbol symbol, Scape *s)
Definition: tree.c:222
int _st_write(Stream *st, char *buf, size_t len)
Definition: stream.c:534
void _t_morph(T *dst, T *src)
Definition: tree.c:357
T * _t_build2(SemTable *sem, T *parent,...)
Definition: tree.c:771
Definition: stream.h:30
T * __t_newi(T *parent, Symbol symbol, int surface, bool is_run_node)
Definition: tree.c:97
T * _t_get(T *t, int *p)
Definition: tree.c:1441
int _t_write(SemTable *sem, T *t, Stream *stream)
Definition: tree.c:2066
T * _t_path_walk(T *t, int **pathP, int *lenP)
Definition: tree.c:1543
bool __t_fill_template(T *template, T *sem_map, bool as_run_node)
Definition: tree.c:1049
int _t_hash_equal(TreeHash h1, TreeHash h2)
Definition: tree.c:1649
T * _t_detach_by_idx(T *t, int i)
Definition: tree.c:278
header file for symbol and structure definition functions
int _t_path_depth(int *p)
Definition: tree.c:1365
int _t_node_index(T *t)
Definition: tree.c:1284
Semantic tree regular expression header file.
T * _t_new_receptor(T *parent, Symbol symbol, Receptor *r)
Definition: tree.c:204
TreeHash _t_hash(SemTable *sem, T *t)
Definition: tree.c:1614
int * _t_get_path(T *t)
Definition: tree.c:1384
T * _t_clone(T *t)
Definition: tree.c:589
void _r_free(Receptor *r)
Definition: receptor.c:186
semantic trees header file
T * __t_newr(T *parent, Symbol symbol, bool is_run_node)
Definition: tree.c:171
void _s_free(Scape *s)
Definition: scape.c:43
T * _t_root(T *t)
Definition: tree.c:1272
void _t_serialize(SemTable *sem, T *t, void **surfaceP, size_t *lengthP)
Definition: tree.c:1723
T * __t_new(T *parent, Symbol symbol, void *surface, size_t size, bool is_run_node)
Definition: tree.c:59
Symbol _t_symbol(T *t)
Definition: tree.c:1228
T * _t_child(T *t, int i)
Definition: tree.c:1251
T * _t_newp(T *parent, Symbol symbol, Process surface)
Definition: tree.c:251
T * _t_swap(T *t, int i, T *r)
Definition: tree.c:418
void _t_pathcpy(int *dst_p, int *src_p)
Definition: tree.c:1424
void _t_insert_at(T *t, int *path, T *i)
Definition: tree.c:438
size_t __t_serialize(SemTable *sem, T *t, void **bufferP, size_t offset, size_t current_size, int compact)
Definition: tree.c:1686
receptor implementation header file
size_t _d_get_symbol_size(SemTable *sem, Symbol s, void *surface)
Definition: def.c:178
void * _t_surface(T *t)
Definition: tree.c:1215
T * __t_new_str(T *parent, Symbol symbol, char *surface, bool is_run_node)
Definition: tree.c:150
T * _t_newt(T *parent, Symbol symbol, T *surface)
Definition: tree.c:133
void _t_replace_node(T *t, T *r)
Definition: tree.c:391
SState * state(StateType type, int *statesP, int level)
Definition: semtrex.c:103
T * _t_parent(T *t)
Definition: tree.c:1262
char * _t2rawjson(SemTable *sem, T *t, int level, char *buf)
Definition: tree.c:1785
#define SREAD(type, var_name)
macro to read typed date from the surface and update length and surface values
Definition: tree.c:1731
#define SWRITE(type, value)
macro to write data by type into *bufferP and increment offset by the size of the type ...
Definition: tree.c:1670
int _t_matchr(T *semtrex, T *t, T **rP)
Definition: semtrex.c:798
scape header files
void * _t_get_surface(T *t, int *p)
Definition: tree.c:1492
T * __t_find(T *t, SemanticID sym, int start_child)
Definition: tree.c:1328
#define _sl(t, s)
macro to add a single symbol literal to semtrex tree
Definition: semtrex.h:122
char * __t2s(SemTable *sem, T *t, int indent)
Definition: def.c:518
T * __t_newi64(T *parent, Symbol symbol, long surface, bool is_run_node)
Definition: tree.c:109
T * _t_parse(SemTable *sem, T *parent, char *s,...)
Definition: tree.c:919
int _t_path_equal(int *p1, int *p2)
Definition: tree.c:1350
void _t_add(T *t, T *c)
Definition: tree.c:261
char * _t2json(SemTable *sem, T *t, int level, char *buf)
Definition: tree.c:1912
void __t_morph(T *t, Symbol s, void *surface, size_t size, int allocate)
Definition: tree.c:325
int _t_children(T *t)
Definition: tree.c:1205
void _t_replace(T *t, int i, T *r)
Definition: tree.c:372
void _t_detach_by_ptr(T *t, T *c)
Definition: tree.c:291
void _t_free(T *t)
Definition: tree.c:526
T * __t_news(T *parent, Symbol symbol, SemanticID surface, bool is_run_node)
Definition: tree.c:121
int _st_writeln(Stream *stream, char *str)
Definition: stream.c:563
T * _t_build(SemTable *sem, T *parent,...)
Definition: tree.c:635
T * _t_getv(T *t,...)
Definition: tree.c:1470
size_t _t_size(T *t)
Definition: tree.c:1238
T * __t_newc(T *parent, Symbol symbol, char surface, bool is_run_node)
Definition: tree.c:85
T * _t_new_cptr(T *parent, Symbol symbol, void *s)
Definition: tree.c:239
char * _t_sprint_path(int *fp, char *buf)
Definition: tree.c:1508