ceptr
 All Data Structures Files Functions Variables Typedefs Macros Modules Pages
def.c
Go to the documentation of this file.
1 
12 #include "tree.h"
13 #include "stream.h"
14 #include "def.h"
15 #include "semtrex.h"
16 char __d_extra_buf[100];
17 
18 int semeq(SemanticID s1,SemanticID s2) {
19  return (s1.context == s2.context)&&(s1.semtype == s2.semtype)&&(s1.id==s2.id);
20  // return (memcmp(&s1,&s2,sizeof(SemanticID))==0);
21 }
22 
23 // used to find the semantic address for a def when building a SemanticID
24 // the semantic address is just the child index of the definition
25 SemanticAddr _d_get_def_addr(T *def) {
26  return _t_node_index(def);
27 }
28 
29 SemanticID _d_define(SemTable *sem,T *def,SemanticType semtype,Context c) {
30  T *definitions = __sem_get_defs(sem,semtype,c);
31  _t_add(definitions,def);
32  SemanticID sid = {c,semtype,_d_get_def_addr(def)};
33  return sid;
34 }
35 
36 // internal check to see if a symbol is valid
37 void __d_validate_symbol(SemTable *sem,Symbol s,char *n) {
38  if (!is_symbol(s)) raise_error("Bad symbol in %s def: semantic type not SEM_TYPE_SYMBOL",n);
39  if (is_sys_symbol(s) && (s.id == 0)) return; // NULL_SYMBOL ok
40  T *symbols = _sem_get_defs(sem,s);
41  if (!_t_child(symbols,s.id)) raise_error("Bad symbol in %s def: definition not found in context",n);
42 }
43 
44 // internal check to see if a structure is valid
45 void __d_validate_structure(SemTable *sem,Structure s,char *n) {
46  if (!is_structure(s)) raise_error("Bad structure in %s def: semantic type not SEM_TYPE_STRUCTURE",n);
47  if (is_sys_structure(s) && (s.id == 0)) return; // NULL_STRUCTURE ok
48  T *structures = _sem_get_defs(sem,s);
49  if(s.id && !_t_child(structures,s.id)) {raise_error("Unknown structure <%d.%d.%d> in declaration of %s",s.context,s.semtype,s.id,n);}
50 }
51 
52 // this is used to reset the structure of a symbol that has been pre declared as NULL_SYMBOL
53 // to it's actual value.
54 void __d_set_symbol_structure(T *symbols,Symbol sym,Structure s) {
55  T *t = _t_child(symbols,sym.id);
56  if (!t) raise_error("def not found!");
57  T * structure_def = _t_child(t,SymbolDefStructureIdx);
58  if (!semeq(NULL_STRUCTURE,*(Symbol *)_t_surface(structure_def)))
59  raise_error("Symbol already defined");
60  *(Symbol *)_t_surface(structure_def) = s;
61 }
62 
63 // this is used to set the structure definition of a declared but undefined strcture
64 void __d_set_structure_def(T *structures,Structure s,T *def) {
65  T *d = _t_child(structures,s.id);
66  if (_t_children(d) > 1) raise_error("Structure already defined");
67  _t_add(d,def);
68 }
69 
83 Symbol _d_define_symbol(SemTable *sem,Structure s,char *label,Context c){
84  __d_validate_structure(sem,s,label);
85  T *def = _t_new_root(SYMBOL_DEFINITION);
86  T *l = _t_newr(def,SYMBOL_LABEL);
87  _t_new_str(l,ENGLISH_LABEL,label);
88  _t_news(def,SYMBOL_STRUCTURE,s);
89 
90  return _d_define(sem,def,SEM_TYPE_SYMBOL,c);
91 }
92 
104 Structure _d_define_structure(SemTable *sem,char *label,T *structure_def,Context c) {
105  T *def = _t_new_root(STRUCTURE_DEFINITION);
106  T *l = _t_newr(def,STRUCTURE_LABEL);
107  _t_new_str(l,ENGLISH_LABEL,label);
108  if (structure_def) _t_add(def,structure_def);
109  return _d_define(sem,def,SEM_TYPE_STRUCTURE,c);
110 }
111 
124 Structure _d_define_structure_v(SemTable *sem,char *label,Context c,int num_params,...) {
125  va_list params;
126  va_start(params,num_params);
127  T *def = _d_make_vstruc_def(sem,label,num_params,params);
128  va_end(params);
129  return _d_define_structure(sem,label,def,c);
130 }
131 
132 // build a STRUCTURE_SEQUENCE STRUCTURE_DEF out of va_list
133 T * _d_make_vstruc_def(SemTable *sem,char *label,int num_params,va_list params) {
134  T *p,*seq = 0;
135  if (num_params > 1)
136  seq = _t_newr(0,STRUCTURE_SEQUENCE);
137  int i;
138  for(i=0;i<num_params;i++) {
139  Symbol s = va_arg(params,Symbol);
140  __d_validate_symbol(sem,s,label);
141  p = _t_news(seq,STRUCTURE_SYMBOL,s);
142  }
143  return seq ? seq : p;
144 }
145 
157  T *def = _t_child(symbols,s.id);
158  if (!def) {
159  raise_error("Bad symbol:%d.%d.%d-- only %d symbols in decl list",s.context,s.semtype,s.id,_t_children(symbols));
160  }
161  T *t = _t_child(def,SymbolDefStructureIdx);
162  return *(Structure *)_t_surface(t);
163 }
164 
165 
166 
178 size_t _d_get_symbol_size(SemTable *sem,Symbol s,void *surface) {
179  Structure st = _sem_get_symbol_structure(sem,s);
180  return _d_get_structure_size(sem,st,surface);
181 }
182 
183 size_t _sys_structure_size(int id,void *surface) {
184  switch(id) {
185  case TREE_ID:
186  case NULL_STRUCTURE_ID: return 0;
187  // case SEMTREX: return
188  case PROCESS_ID:
189  case PROTOCOL_ID:
190  case STRUCTURE_ID:
191  case SYMBOL_ID: return sizeof(SemanticID);
192  case BIT_ID:
193  case INTEGER_ID: return sizeof(int);
194  case INTEGER64_ID: return sizeof(uint64_t);
195  case FLOAT_ID: return sizeof(float);
196  case CSTRING_ID: return strlen(surface)+1;
197  case XADDR_ID: return sizeof(Xaddr);
198  case UUID_ID: return sizeof(UUIDt);
199  case CPOINTER_ID:
200  case RECEPTOR_ID:
201  case SCAPE_ID:
202  return sizeof(void *);
203  default: return -1;
204  }
205 }
206 
218 size_t _d_get_structure_size(SemTable *sem,Structure s,void *surface) {
219  size_t size = 0;
220  T *structures = _sem_get_defs(sem,s);
221 
222  if (is_sys_structure(s)) {
223  size = _sys_structure_size(s.id,surface);
224  if (size == -1) {
225  raise_error("DON'T HAVE A SIZE FOR STRUCTURE '%s' (%d)",_sem_get_name(sem,s),s.id);
226  }
227  }
228  else {
229  T *structure = _t_child(structures,s.id);
230  T *parts = _t_child(structure,2);
231  if (semeq(_t_symbol(parts),STRUCTURE_SEQUENCE)) {
232  DO_KIDS(parts,
233  T *p = _t_child(parts,i);
234  if (!semeq(_t_symbol(p),STRUCTURE_SYMBOL)) {
235  raise_error("CAN'T GET SIZE FOR VARIABLE STRUCTURES '%s' (%d)",_sem_get_name(sem,s),s.id);
236  }
237  size += _d_get_symbol_size(sem,*(Symbol *)_t_surface(p),surface +size);
238  );
239  }
240  else if (semeq(_t_symbol(parts),STRUCTURE_SYMBOL)) {
241  size = _d_get_symbol_size(sem,*(Symbol *)_t_surface(parts),surface);
242  }
243  }
244  return size;
245 }
246 
247 #define MAX_HASHES 10
248 // extract the template signature from the code
249 void __d_tsig(SemTable *sem,T *code, T *tsig,TreeHash *hashes) {
250  Symbol sym = _t_symbol(code);
251 
252  // hack to get around falsely adding a TEMPLATE_SIGNATURE see bug #127
253  if (semeq(sym,FILL_FROM_MATCH)) return;
254  if (semeq(sym,SLOT)) {
255  TreeHash h;
256  T *c = NULL;
257  // slot children aren't part of the signature they are part of the
258  // the code that needs to be searched!
259  if (c = _t_find(code,SLOT_CHILDREN)) {
260  int i = _t_node_index(c);
261  c = _t_clone(code);
262  T *sc = _t_detach_by_idx(c,i);
263  __d_tsig(sem,sc,tsig,hashes);
264  _t_free(sc);
265  _t_hash(sem,c);
266  }
267  else h = _t_hash(sem,code);
268  // check for duplicates
269  int i=0;
270  while(hashes[i] && hashes[i]!=h) {
271  i++;
272  if (i == MAX_HASHES) raise_error("whoa! too many slots in code template");
273  }
274  // if its unique then add it.
275  if (!hashes[i]) {
276  hashes[i] = h;
277  if (!c) c = _t_clone(code); // clone it if it wasn't cloned above
278  c->contents.symbol = EXPECTED_SLOT;
279  _t_add(tsig,c);
280  c = NULL;
281  }
282  if (c) _t_free(c);
283  }
284  else {
285  DO_KIDS(code,__d_tsig(sem,_t_child(code,i),tsig,hashes));
286  }
287 }
288 
302 T *_d_make_process_def(T *code,char *name,char *intention,T *signature,T *link) {
303  T *def = _t_new_root(PROCESS_DEFINITION);
304  T *l = _t_newr(def,PROCESS_NAME);
305  _t_new_str(l,ENGLISH_LABEL,name);
306  _t_new(def,PROCESS_INTENTION,intention,strlen(intention)+1);
307  if (!code)
308  code = _t_new_root(NULL_PROCESS); // indicates a system (i.e. non ceptr) defined process
309  _t_add(def,code);
310  if (!signature) {
311  // @todo, we really shouldn't be doing this, but have to for now...
312  signature = _t_new_root(PROCESS_SIGNATURE);
313  }
314  _t_add(def,signature);
315  if (link) {
316  _t_add(def,link);
317  }
318  return def;
319 }
320 
321 
336 Process _d_define_process(SemTable *sem,T *code,char *name,char *intention,T *signature,T *link,Context c) {
337  T *def = _d_make_process_def(code,name,intention,signature,link);
338  if (signature && code) {
339  T *tsig = _t_new_root(TEMPLATE_SIGNATURE);
340  TreeHash h[MAX_HASHES]={0,0,0,0,0,0,0,0,0,0};
341  __d_tsig(sem,code,tsig,h);
342  if (_t_children(tsig)) _t_add(signature,tsig);
343  else _t_free(tsig);
344  }
345  return _d_define(sem,def,SEM_TYPE_PROCESS,c);
346 }
347 
357 Protocol _d_define_protocol(SemTable *sem,T *def,Context c) {
358  //__d_validate_protocol(sem,def); //@todo
359  return _d_define(sem,def,SEM_TYPE_PROTOCOL,c);
360 }
361 
362 T *__d_build_def_semtrex(SemTable *sem,T *def,T *stx) {
363  Symbol def_sym = _t_symbol(def);
364  if (semeq(def_sym,STRUCTURE_SYMBOL)) {
365  Symbol sym = *(Symbol *)_t_surface(def);
366  if (!semeq(NULL_SYMBOL,sym))
367  stx = _d_build_def_semtrex(sem,sym,stx);
368  }
369  else if (semeq(def_sym,STRUCTURE_SEQUENCE)) {
370  int i,c = _t_children(def);
371  if (c > 0) {
372  stx = _t_newr(stx,SEMTREX_SEQUENCE);
373  for(i=1;i<=c;i++) {
374  __d_build_def_semtrex(sem,_t_child(def,i),stx);
375  }
376  }
377  }
378  else if (semeq(def_sym,STRUCTURE_OR)) {
379  int i,c = _t_children(def);
380  if (c == 1) {
381  stx = _t_newr(stx,SEMTREX_ZERO_OR_ONE);
382  __d_build_def_semtrex(sem,_t_child(def,1),stx);
383  }
384  else if (c > 1) {
385  // semtrex OR is binary whereas structure def or is a set,
386  // so we have to build up a binary tree OR structure
387  // so, we build it up from the bottom first, building from the
388  // last child backwards.
389  T *last = __d_build_def_semtrex(sem,_t_child(def,c),NULL);
390  for(i=c-1;i>=1;i--) {
391  T *or = _t_new_root(SEMTREX_OR);
392  __d_build_def_semtrex(sem,_t_child(def,i),or);
393  _t_add(or,last);
394  last = or;
395  }
396  if (stx) _t_add(stx,last);
397  stx = last;
398  }
399  }
400  else if (semeq(def_sym,STRUCTURE_ANYTHING)) {
401  stx = _t_newr(stx,SEMTREX_ZERO_OR_MORE);
402  stx = _t_newr(stx,SEMTREX_SYMBOL_ANY);
403  if (_t_children(def))
404  __d_build_def_semtrex(sem,_t_child(def,1),stx);
405  }
406  else if (semeq(def_sym,STRUCTURE_ZERO_OR_MORE)) {
407  stx = _t_newr(stx,SEMTREX_ZERO_OR_MORE);
408  __d_build_def_semtrex(sem,_t_child(def,1),stx);
409  }
410  else if (semeq(def_sym,STRUCTURE_ONE_OR_MORE)) {
411  stx = _t_newr(stx,SEMTREX_ONE_OR_MORE);
412  __d_build_def_semtrex(sem,_t_child(def,1),stx);
413  }
414  else {
415  raise_error("translation from %s not implemented\n",_sem_get_name(sem,def_sym));
416  }
417  return stx;
418 }
419 
434  T *stx = _sl(parent,s);
435 
436  //printf("building semtrex for %s\n",_sem_get_name(sem,s));
437  Structure st = _sem_get_symbol_structure(sem,s);
438  if (!semeq(st,NULL_STRUCTURE)) {
439  T *structure = _sem_get_def(sem,st);
440  T *def = _t_child(structure,StructureDefDefIdx);
441  __d_build_def_semtrex(sem,def,stx);
442  }
443  return stx;
444 }
445 
457 SemanticID _d_define_receptor(SemTable *sem,char *label,T *definitions,Context c) {
458 
459  T *def = _t_new_root(RECEPTOR_DEFINITION);
460  T *l=_t_newr(def,RECEPTOR_LABEL);
461  _t_new_str(l,ENGLISH_LABEL,label);
462  _t_add(def,definitions);
463 
464  return __d_define_receptor(sem,def,c);
465 }
466 
478 SemanticID __d_define_receptor(SemTable *sem,T *def,Context c) {
479 
480  T *definitions = _t_child(def,ReceptorDefinitionDefsIdx);
481 
482  bool vmhost_special_case = (c == SYS_CONTEXT) && (!sem->contexts);
483  //__d_validate_receptor(sem,def); //@todo
484  // @todo recursively add definitions for any receptors defined in def
485  if (_t_children(_t_child(definitions,SEM_TYPE_RECEPTOR))) {
486  raise_error("recursive receptor definition not yet implemented");
487  }
488  Context new_context = _sem_new_context(sem,definitions);
489 
490  // big trick!! put the context number in the surface of the definition so
491  // we can get later in _d_get_receptor_address
492  (*(int *)_t_surface(def)) = new_context;
493 
494  // account for the one exception where the VMHost is defined inside itself
495  // we can't use _d_define because when it tries to look up the newly added
496  // def with _d_get_def_addr which uses _t_get_path, it will fail on the infinite loop.
497  if (vmhost_special_case) {
498  // this makes the "defined-inside-itself" loop!
499  // _t_add(def,d);
500  SemanticID sid = {c,SEM_TYPE_RECEPTOR,0};
501  return sid;
502  }
503  return _d_define(sem,def,SEM_TYPE_RECEPTOR,c);
504 }
505 
506 // this works because when a receptor gets defined the semantic context get jammed into the definition surface!
507 Context _d_get_receptor_context(SemTable *sem,SemanticID r) {
508  T *def = _sem_get_def(sem,r);
509  return *(int *)_t_surface(def);
510 }
511 
512 /***************** Tree debugging utilities */
513 
518 char * __t2s(SemTable *sem,T *t,int indent) {
519  static char buf[100000];
520  buf[0] = 0;
521  return __t_dump(sem,t,indent,buf);
522 }
523 
524 char *_indent_line(int level,char *buf) {
525  if (level < -1) {
526  int j = (-level - 1)*3;
527  *buf++ = '\n';
528  while(j--) *buf++ = ' ';
529  *buf = 0;
530  }
531  else if (level > 0) {
532  *buf++ = ' ';
533  }
534  return buf;
535 }
536 
537 #include "ansicolor.h"
538 #define MAX_LEVEL 100
539 T *G_cursor = NULL;
540 char * __t_dump(SemTable *sem,T *t,int level,char *buf) {
541  if (!t) return "";
542  Symbol s = _t_symbol(t);
543  char b[255];
544  char tbuf[2000];
545  int i;
546  char *c,*obuf;
547  Xaddr x;
548  buf = _indent_line(level,buf);
549 
550  if (level > MAX_LEVEL) {
551  raise_error("whoa, MAX_LEVEL exceeded!");
552  }
553 
554  // use this to mark all run nodes with a %
555  /* if (t->context.flags & TFLAG_RUN_NODE) { */
556  /* *buf++ = '%'; */
557  /* sprintf(buf,"%d",rt_cur_child(t)); */
558  /* buf += strlen(buf); */
559  /* } */
560 
561  char *n = _sem_get_name(sem,s);
562  obuf = buf;
563  if (t && (t == G_cursor)) {sprintf(buf,KRED);buf += strlen(buf);}
564 
565  if (is_process(s)) {
566  sprintf(buf,"(process:%s",n);
567  }
568  else if (is_receptor(s)) {
569  if (t->context.flags & (TFLAG_SURFACE_IS_TREE+TFLAG_SURFACE_IS_RECEPTOR)) {
570  c = __t_dump(sem,((Receptor *)_t_surface(t))->root,0,tbuf);
571  sprintf(buf,"(%s:{%s}",n,c);
572  }
573  else {
574  raise_error("bad node flags for receptor semtype!");
575  }
576  }
577  else if (semeq(s,NULL_SYMBOL)) {
578  sprintf(buf,"(NULL_SYMBOL");
579  }
580  else {
581  Structure st = _sem_get_symbol_structure(sem,s);
582  if (!is_sys_structure(st)) {
583  // if it's not a system structure, it's composed, so all we need to do is
584  // print out the symbol name, and the reset will take care of itself
585  sprintf(buf,"(%s",n);
586  }
587  else {
588  switch(st.id) {
589  case ENUM_ID: // for now enum surfaces are just strings so we can see the text value
590  case CSTRING_ID:
591  sprintf(buf,"(%s:%s",n,(char *)_t_surface(t));
592  break;
593  case BLOB_ID:
594  sprintf(buf,"(%s:%ld-byte-blob",n,_t_size(t));
595  break;
596  case CHAR_ID:
597  sprintf(buf,"(%s:'%c'",n,*(char *)_t_surface(t));
598  break;
599  case BIT_ID:
600  case INTEGER_ID:
601  sprintf(buf,"(%s:%d",n,*(int *)_t_surface(t));
602  break;
603  case INTEGER64_ID:
604  sprintf(buf,"(%s:%ld",n,*(uint64_t *)_t_surface(t));
605  break;
606  case FLOAT_ID:
607  sprintf(buf,"(%s:%f",n,*(float *)_t_surface(t));
608  break;
609  case SYMBOL_ID:
610  case STRUCTURE_ID:
611  case PROCESS_ID:
612  case PROTOCOL_ID:
613  case RECEPTOR_ID:
614  c = _sem_get_name(sem,*(SemanticID *)_t_surface(t));
615  sprintf(buf,"(%s:%s",n,c?c:"<unknown>");
616  break;
617  case TREE_PATH_ID:
618  sprintf(buf,"(%s:%s",n,_t_sprint_path((int *)_t_surface(t),b));
619  break;
620  case XADDR_ID:
621  x = *(Xaddr *)_t_surface(t);
622  sprintf(buf,"(%s:%s.%d",n,_sem_get_name(sem,x.symbol),x.addr);
623  break;
624  /* case CPOINTER_ID: */
625  /* sprintf(buf,"(%s:%p",n,_t_surface(t)); */
626  /* break; */
627  /* case UUID_ID: */
628  /* { */
629  /* UUIDt x = *(UUIDt *)_t_surface(t); */
630  /* sprintf(buf,"%s:%ld.%ld",n,x.data,x.time); */
631  /* } */
632  /* break; */
633  case TREE_ID:
634  if (t->context.flags & TFLAG_SURFACE_IS_TREE) {
635  c = __t_dump(sem,(T *)_t_surface(t),0,tbuf);
636  sprintf(buf,"(%s:{%s}",n,c);
637  break;
638  }
639  raise_error("TREE struct without TREE node flags");
640  case RECEPTOR_SURFACE_ID:
641  raise_error("boink bad receptor struct");
642  case SCAPE_ID:
643  if (t->context.flags & TFLAG_SURFACE_IS_SCAPE) {
644  Scape *sc = (Scape *)_t_surface(t);
645  sprintf(buf,"(%s:key %s,data %s",n,_sem_get_name(sem,sc->key_source),_sem_get_name(sem,sc->data_source));
646  break;
647  }
648  default:
649  if (semeq(s,SEMTREX_MATCH_CURSOR)) {
650  c = __t_dump(sem,*(T **)_t_surface(t),0,tbuf);
651  //c = "null";
652  sprintf(buf,"(%s:{%s}",n,c);
653  break;
654  }
655  if (n == 0)
656  sprintf(buf,"(<unknown:%d.%d.%d>",s.context,s.semtype,s.id);
657  else
658  sprintf(buf,"(%s",n);
659  }
660  }
661  }
662  if (t&&(t == G_cursor)) {sprintf(buf+strlen(buf),KNRM);}
663 
664  DO_KIDS(t,__t_dump(sem,_t_child(t,i),level < 0 ? level-1 : level+1,buf+strlen(buf)));
665  sprintf(buf+strlen(buf),")");
666  return obuf;
667 }
668 
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
Process _d_define_process(SemTable *sem, T *code, char *name, char *intention, T *signature, T *link, Context c)
Definition: def.c:336
T * _t_detach_by_idx(T *t, int i)
Definition: tree.c:278
header file for symbol and structure definition functions
int _t_node_index(T *t)
Definition: tree.c:1284
Semantic tree regular expression header file.
TreeHash _t_hash(SemTable *sem, T *t)
Definition: tree.c:1614
SemanticID _d_define_receptor(SemTable *sem, char *label, T *definitions, Context c)
Definition: def.c:457
T * _t_clone(T *t)
Definition: tree.c:589
semantic trees header file
Symbol _t_symbol(T *t)
Definition: tree.c:1228
T * _t_child(T *t, int i)
Definition: tree.c:1251
streams abstraction header file
T * _d_build_def_semtrex(SemTable *sem, Symbol s, T *parent)
Definition: def.c:433
Structure _d_define_structure(SemTable *sem, char *label, T *structure_def, Context c)
Definition: def.c:104
size_t _d_get_symbol_size(SemTable *sem, Symbol s, void *surface)
Definition: def.c:178
Structure __d_get_symbol_structure(T *symbols, Symbol s)
Definition: def.c:156
void * _t_surface(T *t)
Definition: tree.c:1215
size_t _d_get_structure_size(SemTable *sem, Structure s, void *surface)
Definition: def.c:218
Symbol _d_define_symbol(SemTable *sem, Structure s, char *label, Context c)
Definition: def.c:83
T * _d_make_process_def(T *code, char *name, char *intention, T *signature, T *link)
Definition: def.c:302
#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
SemanticID __d_define_receptor(SemTable *sem, T *def, Context c)
Definition: def.c:478
Protocol _d_define_protocol(SemTable *sem, T *def, Context c)
Definition: def.c:357
void _t_add(T *t, T *c)
Definition: tree.c:261
int _t_children(T *t)
Definition: tree.c:1205
void _t_free(T *t)
Definition: tree.c:526
Structure _d_define_structure_v(SemTable *sem, char *label, Context c, int num_params,...)
Definition: def.c:124
size_t _t_size(T *t)
Definition: tree.c:1238
char * _t_sprint_path(int *fp, char *buf)
Definition: tree.c:1508