/** * add a symbol definition to a symbol defs tree * * @param[in] sem is the semantic table to which to add the symbol * @param[in] s the structure type for this symbol * @param[in] label a c-string label for this symbol * @param[in] the context in which this symbol is being declared * @returns the new symbol * @todo this is not thread safe! * * <b>Examples (from test suite):</b> * @snippet spec/def_spec.h testDefSymbol */ Symbol _d_define_symbol(SemTable *sem,Structure s,char *label,Context c){ __d_validate_structure(sem,s,label); T *def = _t_new_root(SYMBOL_DEFINITION); T *l = _t_newr(def,SYMBOL_LABEL); _t_new_str(l,ENGLISH_LABEL,label); _t_news(def,SYMBOL_STRUCTURE,s); return _d_define(sem,def,SEM_TYPE_SYMBOL,c); }
/// va_list version of _d_define_structure T * _dv_define_structure(T *structures,char *label,int num_params,va_list params) { T *def = _t_newr(structures,STRUCTURE_DEFINITION); T *l = _t_new(def,STRUCTURE_LABEL,label,strlen(label)+1); T *p = _t_newr(def,STRUCTURE_PARTS); int i; for(i=0;i<num_params;i++) { _t_news(p,STRUCTURE_PART,va_arg(params,Symbol)); } return def; }
// build a STRUCTURE_SEQUENCE STRUCTURE_DEF out of va_list T * _d_make_vstruc_def(SemTable *sem,char *label,int num_params,va_list params) { T *p,*seq = 0; if (num_params > 1) seq = _t_newr(0,STRUCTURE_SEQUENCE); int i; for(i=0;i<num_params;i++) { Symbol s = va_arg(params,Symbol); __d_validate_symbol(sem,s,label); p = _t_news(seq,STRUCTURE_SYMBOL,s); } return seq ? seq : p; }
void addCommand(Receptor *r,ReceptorAddress ox,char *command,char *desc,T *code,T *bindings_handler) { T *expect = _t_new_root(PATTERN); T *s = _t_news(expect,SEMTREX_GROUP,SHELL_COMMAND); T *cm = _sl(s,SHELL_COMMAND); T *vl = _t_newr(cm,SEMTREX_VALUE_LITERAL); T *vls = _t_newr(vl,SEMTREX_VALUE_SET); _t_new_str(vls,VERB,command); T *p = _t_new_root(SAY); __r_make_addr(p,TO_ADDRESS,ox); _t_news(p,ASPECT_IDENT,DEFAULT_ASPECT); _t_news(p,CARRIER,NULL_SYMBOL); // if code is actually an INITIATE then we will have a bindings handler // to which we want to add the SAY command as the ACTUAL_PROCESS // and we will replace the p with code which does the proper protocol // initiation. Kinda weird, I know... if (bindings_handler) { char proc_name[255] = "handle "; strcpy(&proc_name[7],command); int pt1[] = {2,1,TREE_PATH_TERMINATOR}; _t_new(p,PARAM_REF,pt1,sizeof(int)*3); Process proc = _r_define_process(r,p,proc_name,"long desc...",NULL,NULL); _t_news(bindings_handler,ACTUAL_PROCESS,proc); p = code; } else { _t_add(p,code); } Process proc = _r_define_process(r,p,desc,"long desc...",NULL,NULL); T *act = _t_newp(0,ACTION,proc); _r_add_expectation(r,DEFAULT_ASPECT,SHELL_COMMAND,expect,act,0,0,NULL,NULL); }
/** * @brief Creates a new receptor * * allocates all the memory needed in the heap * * @param[in] r semantic ID for this receptor * @returns pointer to a newly allocated Receptor * * <b>Examples (from test suite):</b> * @snippet spec/receptor_spec.h testReceptorCreate */ Receptor *_r_new(SemTable *sem,SemanticID r) { T *t = _t_new_root(RECEPTOR_INSTANCE); _t_news(t,INSTANCE_OF,r); if (semeq(r,SYS_RECEPTOR)) { _t_newi(t,CONTEXT_NUM,0); _t_newi(t,PARENT_CONTEXT_NUM,-1); } else { _t_newi(t,CONTEXT_NUM,_d_get_receptor_context(sem,r)); _t_newi(t,PARENT_CONTEXT_NUM,r.context); } T *state = _r_make_state(); _t_add(t,state); return __r_init(t,sem); }
void makeShell(VMHost *v,FILE *input, FILE *output,Receptor **irp,Receptor **orp,Stream **isp,Stream **osp) { // define and then create the shell receptor Symbol shell = _d_define_receptor(v->r->sem,"shell",__r_make_definitions(),DEV_COMPOSITORY_CONTEXT); Receptor *r = _r_new(v->sem,shell); Xaddr shellx = _v_new_receptor(v,v->r,shell,r); _v_activate(v,shellx); // create stdin/out receptors Stream *output_stream = *osp = _st_new_unix_stream(output,0); Stream *input_stream = *isp = _st_new_unix_stream(input,1); Receptor *i_r = *irp = _r_makeStreamEdgeReceptor(v->sem); _r_addReader(i_r,input_stream,r->addr,DEFAULT_ASPECT,parse_line,LINE,false); Xaddr ix = _v_new_receptor(v,v->r,STREAM_EDGE,i_r); _v_activate(v,ix); Receptor *o_r = *orp = _r_makeStreamEdgeReceptor(v->sem); _r_addWriter(o_r,output_stream,DEFAULT_ASPECT); Xaddr ox = _v_new_receptor(v,v->r,STREAM_EDGE,o_r); _v_activate(v,ox); // set up shell to express the line parsing protocol when it receives LINES from the stream reader Protocol clp; __sem_get_by_label(v->sem,"PARSE_COMMAND_FROM_LINE",&clp,DEV_COMPOSITORY_CONTEXT); T *bindings = _t_new_root(PROTOCOL_BINDINGS); T *res = _t_newr(bindings,RESOLUTION); T *w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,LINE_SENDER); __r_make_addr(w,ACTUAL_RECEPTOR,i_r->addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,COMMAND_RECEIVER); __r_make_addr(w,ACTUAL_RECEPTOR,r->addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_SYMBOL); _t_news(w,USAGE,COMMAND_TYPE); _t_news(w,ACTUAL_SYMBOL,SHELL_COMMAND); _o_express_role(r,clp,COMMAND_RECEIVER,DEFAULT_ASPECT,bindings); _t_free(bindings); // set up shell to use the CLOCK TELL_TIME protocol for the time command Protocol time; __sem_get_by_label(v->sem,"time",&time,CLOCK_CONTEXT); T *code = _t_new_root(INITIATE_PROTOCOL); _t_news(code,PNAME,time); _t_news(code,WHICH_INTERACTION,tell_time); bindings = _t_newr(code,PROTOCOL_BINDINGS); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,TIME_HEARER); __r_make_addr(w,ACTUAL_RECEPTOR,r->addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_RECEPTOR); _t_news(w,ROLE,TIME_TELLER); ReceptorAddress clock_addr = {3}; // @todo bogus!!! fix getting clock address somehow __r_make_addr(w,ACTUAL_RECEPTOR,clock_addr); res = _t_newr(bindings,RESOLUTION); w = _t_newr(res,WHICH_PROCESS); _t_news(w,GOAL,RESPONSE_HANDLER); addCommand(r,o_r->addr,"time","get time",code,w); // (expect (on flux SHELL_COMMAND:receptor) action (send std_out (convert_to_lines (send vmhost receptor-list)))) code = _t_newi(0,MAGIC,MagicReceptors); addCommand(r,o_r->addr,"receptors","get receptor list",code,NULL); // (expect (on flux SHELL_COMMAND:receptor) action (send std_out (convert_to_lines (send vmhost shutdown))) code = _t_newi(0,MAGIC,MagicQuit); addCommand(r,o_r->addr,"quit","shut down the vmhost",code,NULL); // (expect (on flux SHELL_COMMAND:debug) action (send std_out (convert_to_lines (magic toggle debug))) code = _t_newi(0,MAGIC,MagicDebug); addCommand(r,o_r->addr,"debug","toggle debug mode",code,NULL); }
/** * add a symbol definition to a symbol defs tree * * @param[in] symbols a symbol def tree containing symbol definitions * @param[in] s the structure type for this symbol * @param[in] label a c-string label for this symbol * @returns the new symbol def * * <b>Examples (from test suite):</b> * @snippet spec/def_spec.h testDefSymbol */ T *__d_declare_symbol(T *symbols,Structure s,char *label){ T *def = _t_newr(symbols,SYMBOL_DECLARATION); _t_new(def,SYMBOL_LABEL,label,strlen(label)+1); _t_news(def,SYMBOL_STRUCTURE,s); return def; }