void proto_init(struct bot *b) { bot = b; Link *invite_link = hashmap_get("INVITE", b->handlers); if (!invite_link) { invite_link = calloc(1, sizeof(Link)); hashmap_set("INVITE", invite_link, b->handlers); } push_val(invite_link, (void*)irc_invite); Link *chanjoin_link = hashmap_get("332", b->handlers); if (!chanjoin_link) { chanjoin_link = calloc(1, sizeof(Link)); hashmap_set("332", chanjoin_link, b->handlers); } push_val(chanjoin_link, (void*)irc_chan_join); Link *privmsg_link = hashmap_get("PRIVMSG", b->handlers); if (!privmsg_link) { privmsg_link = calloc(1, sizeof(Link)); hashmap_set("PRIVMSG", privmsg_link, b->handlers); } push_val(privmsg_link, (void*)irc_privmsg); }
static int do_expr( void ) { long arg1; long arg2; int op; if( not_ok == pop_op( &op ) ) { return( not_ok ); } if( not_ok == pop_val( &arg1 ) ) { return( not_ok ); } pop_val( &arg2 ); switch( op ) { case '+': push_val( arg2 + arg1 ); break; case '-': push_val( arg2 - arg1 ); break; case '*': push_val( arg2 * arg1 ); break; case '/': if( 0 == arg1 ) { return( not_ok ); } push_val( arg2 / arg1 ); break; case '(': cvalue += 2; break; default: return( not_ok ); } if( 1 > cvalue ) { return( not_ok ); } else { return( op ); } }
void init(struct bot *bot) { mkfifo("status", 0644); if (!isfifo("status")) { printf("[fifo\tfail] Error initializing status FIFO: %s\n", strerror(errno)); } else { push_val(bot->tick_functions, fifo_tick); } }
static char * get_exp( char * str ) { char *ptr = str; char *tptr = tokbuf; struct operator *op; while( *ptr ) { if( *ptr == ' ' ) { if( ignore_blanks ) { ptr++; continue; } else { break; } } op = get_op( ptr ); if (NULL != op ) { if( ('-' == *ptr) || ('+' == *ptr) ) { if( ('-' == *(ptr+1)) || ('+' == *(ptr+1)) ) { return( NULL ); } if( str != ptr ) break; if( str == ptr && !isdigit( ptr[1] ) && '.' != *(ptr+1) ) { push_val(0); *tptr++ = *ptr++; break; } } else if (str == ptr) { *tptr++ = *ptr++; break; } else break; } *tptr++ = *ptr++; } *tptr = NULC; return tokbuf; }
static int evaluate( char * * line, long *val ) { long arg; char * ptr; char * str; char * endptr; int ercode; operator * op; int expr_oper; // looking for term or operator expr_oper = 0; coper = 0; cvalue = 0; nparens = 0; ptr = *line; while( *ptr ) { if( *ptr == ' ' ) { if( ignore_blanks ) { ptr++; continue; } else { break; } } switch( expr_oper ) { case 0: // look for term str = get_exp( ptr ); if( str == NULL ) { // nothing is error return( not_ok ); } op = get_op( str ); if( *(str +1) == NULC ) { if( NULL != op ) { push_op( op->operc ); ptr++; break; } if( (*str == '-' ) || (*str == '+' ) ) { push_op(*str); ++ptr; break; } } arg = strtol( str, &endptr, 10 ); if( (((arg == LONG_MIN) || (arg == LONG_MAX)) && errno == ERANGE) || (str == endptr) ) { return( not_ok ); } push_val( arg ); ptr += endptr - str; // to the next unprocessed char expr_oper = 1; // look for operator next break; case 1: // look for operator op = get_op( ptr ); if( NULL == op ) { return( not_ok ); } if( ')' == *ptr ) { ercode = do_paren(); if( ok > ercode ) { return( ercode ); } } else { while( coper && op->priority <= get_prio_m1() ) { do_expr(); } push_op( op->operc ); expr_oper = 0; // look for term next } ptr++; break; } } while( 1 < cvalue ) { ercode = do_expr(); if( ok > ercode ) return ercode; } if( !coper ) { *line = ptr; // next scan position return( pop_val( val ) ); // no operations left return result } else { return( not_ok ); } }
int evaluate(int *ip, char last_char) { int end, level; int op, type; int arg; int i; unsigned char c; end = 0; level = 0; undef = 0; op_idx = 0; val_idx = 0; value = 0; val_stack[0] = 0; need_operator = 0; expr_lablptr = NULL; expr_lablcnt = 0; op = OP_START; func_idx = 0; /* array index to pointer */ expr = &prlnbuf[*ip]; /* skip spaces */ cont: while (isspace(*expr)) expr++; /* search for a continuation char */ if (*expr == '\\') { /* skip spaces */ i = 1; while (isspace(expr[i])) i++; /* check if end of line */ if (expr[i] == ';' || expr[i] == '\0') { /* output */ if (!continued_line) { /* replace '\' with three dots */ strcpy(expr, "..."); /* store the current line */ strcpy(tmplnbuf, prlnbuf); } /* ok */ continued_line++; /* read a new line */ if (readline() == -1) return (0); /* rewind line pointer and continue */ expr = &prlnbuf[SFIELD]; goto cont; } } /* parser main loop */ while (!end) { c = *expr; /* number */ if (isdigit(c)) { if (need_operator) goto error; if (!push_val(T_DECIMAL)) return (0); } /* symbol */ else if (isalpha(c) || c == '_' || c == '.') { if (need_operator) goto error; if (!push_val(T_SYMBOL)) return (0); } /* operators */ else { switch (c) { /* function arg */ case '\\': if (func_idx == 0) { error("Syntax error in expression!"); return (0); } expr++; c = *expr++; if (c < '1' || c > '9') { error("Invalid function argument index!"); return (0); } arg = c - '1'; expr_stack[func_idx++] = expr; expr = func_arg[func_idx - 2][arg]; break; /* hexa prefix */ case '$': if (need_operator) goto error; if (!push_val(T_HEXA)) return (0); break; /* character prefix */ case '\'': if (need_operator) goto error; if (!push_val(T_CHAR)) return (0); break; /* round brackets */ case '(': if (need_operator) goto error; if (!push_op(OP_OPEN)) return (0); level++; expr++; break; case ')': if (!need_operator) goto error; if (level == 0) goto error; while (op_stack[op_idx] != OP_OPEN) { if (!do_op()) return (0); } op_idx--; level--; expr++; break; /* not equal, left shift, lower, lower or equal */ case '<': if (!need_operator) goto error; expr++; switch (*expr) { case '>': op = OP_NOT_EQUAL; expr++; break; case '<': op = OP_SHL; expr++; break; case '=': op = OP_LOWER_EQUAL; expr++; break; default: op = OP_LOWER; break; } if (!push_op(op)) return (0); break; /* right shift, higher, higher or equal */ case '>': if (!need_operator) goto error; expr++; switch (*expr) { case '>': op = OP_SHR; expr++; break; case '=': op = OP_HIGHER_EQUAL; expr++; break; default: op = OP_HIGHER; break; } if (!push_op(op)) return (0); break; /* equal */ case '=': if (!need_operator) goto error; if (!push_op(OP_EQUAL)) return (0); expr++; break; /* one complement */ case '~': if (need_operator) goto error; if (!push_op(OP_COM)) return (0); expr++; break; /* sub, neg */ case '-': if (need_operator) op = OP_SUB; else op = OP_NEG; if (!push_op(op)) return (0); expr++; break; /* not, not equal */ case '!': if (!need_operator) op = OP_NOT; else { op = OP_NOT_EQUAL; expr++; if (*expr != '=') goto error; } if (!push_op(op)) return (0); expr++; break; /* binary prefix, current PC */ case '%': case '*': if (!need_operator) { if (c == '%') type = T_BINARY; else type = T_PC; if (!push_val(type)) return (0); break; } /* modulo, mul, add, div, and, xor, or */ case '+': case '/': case '&': case '^': case '|': if (!need_operator) goto error; switch (c) { case '%': op = OP_MOD; break; case '*': op = OP_MUL; break; case '+': op = OP_ADD; break; case '/': op = OP_DIV; break; case '&': op = OP_AND; break; case '^': op = OP_XOR; break; case '|': op = OP_OR; break; } if (!push_op(op)) return (0); expr++; break; /* skip immediate operand prefix if in macro */ case '#': if (expand_macro) expr++; else end = 3; break; /* space or tab */ case ' ': case '\t': expr++; break; /* end of line */ case '\0': if (func_idx) { func_idx--; expr = expr_stack[func_idx]; break; } case ';': end = 1; break; case ',': end = 2; break; default: end = 3; break; } } } if (!need_operator) goto error; if (level != 0) goto error; while (op_stack[op_idx] != OP_START) { if (!do_op()) return (0); } /* get the expression value */ value = val_stack[val_idx]; /* any undefined symbols? trap that if in the last pass */ if (undef) { if (pass == LAST_PASS) error("Undefined symbol in operand field!"); } /* check if the last char is what the user asked for */ switch (last_char) { case ';': if (end != 1) goto error; expr++; break; case ',': if (end != 2) { error("Argument missing!"); return (0); } expr++; break; } /* convert back the pointer to an array index */ *ip = expr - prlnbuf; /* ok */ return (1); /* syntax error */ error: error("Syntax error in expression!"); return (0); }
LFUNC bool duel_eval_sbin(tnode *n,tvalue *v) { tval_list *vl = &n->eval.vlist ; tvalue y,*v1= &n->eval.v1, *v2= &n->eval.v2 ; tnode *kid0 = n->kids[0], *kid1 = n->kids[1] ; int vi ; bool ok ; #define lev n->eval.level duel_assert(n->node_kind==NK_OP && n->op_kind==OPK_SBIN); switch(n->op) { case OP_DECL: duel_assert(kid0->node_kind==NK_NAME && kid1->node_kind==NK_CTYPE); if(kid1->ctype->size<=0) duel_gen_error("illegal type size",0); v->val_kind=VK_LVALUE ; v->ctype=kid1->ctype ; v->u.lvalue=duel_alloc_target_space(kid1->ctype->size); strcpy(v->symb_val,kid0->name); duel_set_alias(kid0->name,v); break ; case OP_DEF: if(kid0->node_kind!=NK_NAME) duel_gen_error("left side of := must be a simple var",0); if(!duel_eval(kid1,v)) return FALSE ; duel_set_alias(kid0->name,v); return TRUE ; case ',': if(lev==1 && duel_eval(kid0,v)) return TRUE ; lev=2 ; return duel_eval(kid1,v); case ';': /*note: (x;) is not allowed in syntax, but is allowed here and *means eval x, return nothing. used by parser, e.g. terminating ';' *produces no side effects */ if(lev==1) while(duel_eval(kid0,v)) ; /* eval all left size */ lev=2 ; return duel_eval(kid1,v); break ; case OP_IMP: /* a=>b for each _=eval(a) return eval(b) (with _ set) */ if(lev>1) goto im2 ; for(;;) { if(!duel_eval(kid0,v1)) return FALSE ; lev=2 ; im2: push_dot_stack(v1,0); ok=duel_eval(kid1,v); pop_dot_stack(); if(ok) return TRUE ; } case OP_IF: /* if(a) b return eval(b) for each eval(a)!=0 */ if(lev>1) goto if2 ; for(;;) { if(!duel_eval(kid0,v)) return FALSE ; if(!duel_mk_logical(v,"if(x)y")) continue ; lev=2 ; if2: if(duel_eval(kid1,v)) return TRUE ; } case OP_OR: /* a||b normal 'C' logical or */ if(lev>1) goto or2 ; for(;;) { if(!duel_eval(kid0,v)) return FALSE ; if(duel_mk_logical(v,"x||y")) {lev=1 ; return TRUE ;} or2: if(duel_eval(kid1,v)) { lev=2 ; duel_mk_logical(v,"y||x"); return TRUE ; } } case OP_AND: /* a&&b normal 'C' logical and */ if(lev>1) goto an2 ; for(;;) { if(!duel_eval(kid0,v)) return FALSE ; if(!duel_mk_logical(v,"x&&y")) {lev=1 ; return TRUE ;} an2: if(duel_eval(kid1,v)) { lev=2 ; duel_mk_logical(v,"y&&x"); return TRUE ; } } case '.': if(lev>1) goto dt2 ; for(;;) { if(!duel_eval(kid0,v1)) return FALSE ; *v2 = * v1 ; /* copy value for the lookup */ if(ctype_kind_func_ptr_like(v1->ctype)) /* func.x */ duel_find_func_frame(v2,"x.y"); else if(v1->val_kind!=VK_FVALUE) /* type check frame or struct*/ duel_get_struct_val(v1,"x.y"); lev=2 ; dt2: if(!eval_dot(kid1,v,".",v1,v2)) continue ; if(v->ctype!=v1->ctype || v->val_kind!=v1->val_kind || v->u.lvalue != v1->u.lvalue || strcmp(v->symb_val,v1->symb_val)!=0) /* check for x._ */ duel_set_symb_val(v,"%s.%s",v1,v); return TRUE ; } case OP_ARR: if(lev>1) goto ar2 ; for(;;) { if(!duel_eval(kid0,v1)) return FALSE ; *v2 = *v1 ; /* copy value for dereferencing */ duel_get_struct_ptr_val(v2,"x->y"); lev=2 ; ar2: if(!eval_dot(kid1,v,"->",v1,v2)) continue ; if(v->ctype!=v1->ctype || v->val_kind!=v1->val_kind || v->u.lvalue != v1->u.lvalue || strcmp(v->symb_val,v1->symb_val)!=0) /* check for x->_ */ duel_set_symb_val(v,"%s->%s",v1,v); return TRUE ; } case OP_TO: /* a..b Is it legal to have 1..(5,6) sure! */ if(lev>1) goto to2 ; do { if(kid0 && !duel_eval(kid0,v1)) break ; do { if(kid1 && !duel_eval(kid1,v2)) break ; to2: if(duel_do_op_to(kid0? v1:0,kid1? v2:0,++lev-2,v)) return TRUE; } while(kid1); } while(kid0) ; /* either one (kid0 null) or infinite iterations*/ break ; case OP_SEL: /* x[[y]] */ if(lev==1) { lev=2 ; n->eval.counter= -1 ; } if(!duel_eval(kid1,v1)) { stop_eval(kid0); return FALSE ; } vi=duel_get_posint_val(v1,"y[[x]]"); if(vi<=n->eval.counter) { /* v is smaller than previous v value, so reset x and * start over. Example: \x[1,5,3] after \x[1], * we continue to get [5]. but to get [3] we reset * Alternatively, we could have kept a list of old * generated values. */ stop_eval(kid0) ; n->eval.counter= -1 ; } for( ; n->eval.counter<vi ; n->eval.counter++) if(!duel_eval(kid0,v)) duel_op_error("operator x of y[[x]] too large",0,v1,0); return TRUE ; /* value is the last (v) computed */ break ; case '@': /* x@y - generate x stops when y true */ if(!duel_eval(kid0,v)) return FALSE ; if(kid1->node_kind==NK_CONST) { /* special case y constant */ *v2=kid1->cnst ; *v1= *v ; /* because 'apply_bin_op' destroy its args */ duel_apply_bin_op(OP_EQ,v1,v2,&y); if(y.u.rval_int) { stop_eval(kid0); return FALSE ; } return TRUE ; } *v1 = *v ; /* allow fields in y of x@y for x struct ptr */ if(ctype_kind_ptr_like(v->ctype) && ctype_kind_struct_like(v->ctype->u.kid)) duel_get_struct_ptr_val(v1,"x@y"); while(eval_dot(kid1,v2,"@",v,v1)) /* check &&/y */ if(!duel_mk_logical(v2,"y@x")) { /* y==0, so dont stop x */ stop_eval(kid1); return TRUE ; } stop_eval(kid0); break ; case '#': /* x#i define variable i as counter for gen. x*/ if(kid1->node_kind!=NK_NAME) duel_gen_error("x#y 2rd operand must be a name",0); if(!duel_eval(kid0,v)) return FALSE ; if(lev==1) { lev=2 ; n->eval.counter= -1 ; } /* first time */ y.val_kind=VK_RVALUE ; y.ctype=ctype_int ; y.u.rval_int= ++n->eval.counter ; sprintf(y.symb_val,"%d",n->eval.counter); duel_set_alias(kid1->name,&y); return TRUE ; break ; case OP_DFS: /* x-->y */ if(lev>1) goto df2 ; for(;;) { if(!duel_eval(kid0,v)) return FALSE ; duel_free_val_list(vl); push_val(vl,v); lev=2 ; df2: if(get_next_dfs_val(vl,kid1,v)) return TRUE ; } break ; case OP_WHILE: /* while(a) b */ if(lev==2) goto wh2 ; for(;;) { while(duel_eval(kid0,v)) /* check &&/a */ if(!duel_mk_logical(v,"while(x)y")) { stop_eval(kid0); return FALSE ; } lev=2 ; wh2: if(duel_eval(kid1,v)) return TRUE ; } default: duel_assert(0); } return FALSE ; #undef lev }
/* Calcola e restituisce il risultato di un'espressione in forma infissa */ double EvalInfix(const char *strExpression, char * strError) { Token tok; Token tok_temp; double left, right; double dblRet; strcpy(strError, ""); tok_temp.Type = EOL; tok_temp.str[0] = '@'; tok_temp.str[1] = '\0'; push_op(tok_temp, strError); if ( strError[0] != '\0' ) return 0.0; left = right = 0.0; while ( (PreviousTokenType = GetNextToken(strExpression, &tok, TRUE)) != EOL ) { if ( tok.Type == UNKNOWN ) { sprintf(strError, "Error: invalid token: %s\n", tok.str); return 0.0; } else if ( tok.Type == VALUE ) { push_val(tok.Value, strError); if ( strError[0] != '\0' ) return 0.0; } else if ( tok.Type == OPAREN || tok.Type == UMINUS || tok.Type == UPLUS ) { push_op(tok, strError); if ( strError[0] != '\0' ) return 0.0; } else if ( tok.Type == CPAREN ) { while ( top_op(strError).Type != OPAREN ) { if ( strError[0] != '\0' ) return 0.0; tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; if ( (tok_temp.Type == EOL) || (is_empty_op()) ) { sprintf(strError, "Error: unbalanced brackets.\n"); return 0.0; } right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; if ( tok_temp.Type != UMINUS ) { left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { push_val( -1 * right, strError ); if ( strError[0] != '\0' ) return 0.0; } } pop_op(strError); if ( strError[0] != '\0' ) return 0.0; } else { while ( PREC_TABLE[ top_op(strError).Type ].topOfStack >= PREC_TABLE[ tok.Type ].inputSymbol ) { if ( strError[0] != '\0' ) return 0.0; if ( top_op(strError).Type != UMINUS && top_op(strError).Type != UPLUS ) { if ( strError[0] != '\0' ) return 0.0; right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { if ( top_op(strError).Type == UMINUS ) { if ( strError[0] != '\0' ) return 0.0; right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; pop_op(strError); if ( strError[0] != '\0' ) return 0.0; push_val(-1 * right, strError); if ( strError[0] != '\0' ) return 0.0; } else { pop_op(strError); if ( strError[0] != '\0' ) return 0.0; } } } if ( tok.Type != EOL ) { push_op(tok, strError); if ( strError[0] != '\0' ) return 0.0; } } } while ( 1 ) { tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; if ( tok_temp.Type == EOL ) break; if ( tok_temp.Type != UPLUS ) { right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; } if ( tok_temp.Type != UMINUS && tok_temp.Type != UPLUS ) { left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { push_val( -1 * right, strError ); if ( strError[0] != '\0' ) return 0.0; } } dblRet = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; if ( is_empty_val() ) { return dblRet; } else { sprintf(strError, "Error: malformed expression.\n"); return 0.0; } }