int is_err(unsigned char first, unsigned char second) { if (isdigit(first)) { if (isdigit(second) || isoper(second) || ('(' == second) || (')' == second)) { return(0); } else { return(1); } } else if (isoper(first)) { if ('(' == second || isdigit(second)) { return(0); } else { return(1); } } else if ('(' == first) { if (isdigit(second) || '(' == second) { return(0); } else { return(1); } } else if (')' == first) { if (isoper(second) || ')' == second) { return(0); } else { return(1); } } else { return(1); } }
/* * Evalutate the expression in reverse polish notation */ int evalpfexp(char *expr) { Stack *stackp; int i = -1; int x, y; expr[ (int)strlen(expr) + 1 ] = '\0'; while( expr[++i] != '\0' ) { if( isdigit((int)expr[i]) ) { x = y = 1; /* set y */ for( ; isdigit((int)expr[i + x]) && expr[i + x] != '\0'; ++x, y *= 10) ; /* empty body */ for(x = 0; isdigit((int)expr[i]) && expr[i] != '\0'; y /= 10, i++) { x += (expr[i] - '0') * y; } push(&stackp, x); } else if( isoper(expr[i]) ) { x = pop(&stackp); y = pop(&stackp); push(&stackp, calculate(y, x, expr[i])); } } return pop(&stackp); } /* eof evalpfexp() */
int oper_associativity(int oper) { if (!isoper(oper)) return -1; if (oper == '^') return ASSOC_RIGHT; return ASSOC_LEFT; }
int postfixeval( char* in, mpfr_t out, int base){ if( in[0] == '\0'){ EMPTIN; } mpfr_t *stack; stack = calloc( sizeof(mpfr_t), 10); ALLOCCHECK( stack); int stack_size = 10; int j = 0; char *number; number = calloc( sizeof(char), 10); ALLOCCHECK( number); int number_size = 10; char *alnumToc; alnumToc = calloc( sizeof(char), 5); ALLOCCHECK( alnumToc); int alnumToc_size = 5; mpfr_t num; mpfr_init( num); for( int i = 0; in[i] != '\0'; i++){ if( isoper(in[i])){ if( in[i] == '+'){ mpfr_add( num, stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 2); } else if( in[i] == '-'){ mpfr_sub( num, stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 2); } else if( in[i] == '*'){ mpfr_mul( num, stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 2); } else if( in[i] == '/'){ mpfr_div( num, stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 2); } else if( in[i] == '^'){ mpfr_pow( num, stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 2); } j--; } else if( isalnum(in[i]) || in[i] == '$'){ int iAlnum; for( iAlnum = 0; isalnum(in[i]) || in[i] == '$'; i++){ ARR_APPEND( alnumToc, in[i], iAlnum, alnumToc_size); } alnumToc[iAlnum] = '\0'; Function *funct; if( in[i] == '('){ if( (funct = getfunct( alnumToc)) != NULL){ if( funct->argnum == 1){ ARGNUMCHECK( in, 1); funct->function.fn1( num, stack[j-1], MPFR_RNDN); CPYRES( 1); } else if( funct->argnum == 2){ ARGNUMCHECK( in, 2); funct->function.fn2( num, stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 2); j--; } else{ ARGNUMCHECK( in, 3); funct->function.fn3( num, stack[j-2], stack[j-2], stack[j-1], MPFR_RNDN); CPYRES( 3); j-=2; } }else{ int argc; sscanf( &in[i], "(%d)", &argc); for( ; in[i] != ')'; i++); if( evaluFunct( alnumToc, &j, stack, &stack_size, 10, argc)){ FREE; return 1; } } } else if( alnumToc[0] == '$'){ if( getvar(&alnumToc[1], &num)){ FREE; return 1; } mpfr_init( stack[j]); mpfr_set( stack[j], num, MPFR_RNDN); j++; ARR_CHECK( stack, j, stack_size); } else{ mpfr_init( stack[j]); mpfr_set_str( stack[j], alnumToc, base, MPFR_RNDN); j++; ARR_CHECK( stack, j, stack_size); } } } mpfr_set( out, stack[0], MPFR_RNDN); FREE; return 0; }
// sets token and token_type to reflect next occuring token int get_token() { char test[3]; register char *temp; int x; lasttype = token_type; token_type = 0; temp = token; for (x=0; x<TOKEN_LEN; x++) token[x] = '\0'; while(iswhite(*prog)) { tokenpos++; prog++; } if(*prog == '?') { prog++; tokenpos++; *temp++ = 'P'; *temp++ = 'R'; *temp++ = 'I'; *temp++ = 'N'; *temp++ = 'T'; return(token_type = TOK_COMMAND); } if((*prog == '\'') && (lasttype == 1)) { prog++; tokenpos++; *temp++ = 'E'; *temp++ = 'D'; *temp++ = 'I'; *temp++ = 'T'; return(token_type = TOK_COMMAND); } /* if((*prog == '.') && (lasttype == 1)) { prog++; tokenpos++; *temp++ = 'P'; *temp++ = 'B'; *temp++ = 'S'; *temp++ = 'T'; *temp++ = 'E'; *temp++ = 'P'; return(token_type = TOK_COMMAND); }*/ if(strchr("\n", *prog)) { *temp = 0; return(token_type = TOK_DONE); } if(*prog == '\'') { prog++; tokenpos++; while (*prog != '\'' && *prog != '\r') { if (strchr("\n", *prog)) return (token_type = TOK_ERROR); *temp++ = *prog++; } prog++; tokenpos++; *temp = 0; return (token_type = TOK_MNEMONIC); } if(*prog == '\"') { prog++; tokenpos++; while (*prog != '\"' && *prog != '\r') { if (strchr("\n", *prog)) return (token_type = TOK_ERROR); *temp++ = *prog++; } prog++; tokenpos++; *temp = 0; return(token_type = TOK_STRING); } if(isoper(*prog)) { if (*prog == ',') { prog++; *temp = 0; return(token_type = TOK_COMMA); } if (*prog == ':') { prog++; *temp = 0; return(token_type = TOK_COLON); } if (*prog == ';') { prog++; *temp = 0; return(token_type = TOK_SEMICOLON); } if (strchr("*<>=", *prog)) { *temp = *prog; prog++; temp++; if (strchr("*<>=", *prog)) { *temp = *prog; prog++; temp++; if (!strcmp(token, "<<") || !strcmp(token, ">>") || !strcmp(token, "*<") || !strcmp(token, "*>") || !strcmp(token, "*=") || !strcmp(token, "<*") || !strcmp(token, ">*") || !strcmp(token, "=*") || !strcmp(token, "==")) { return (token_type = TOK_ERROR); } } *temp = 0; } else { *temp = *prog; prog++; temp++; *temp = 0; } return(token_type = TOK_OPERATOR); } if(isdigit(*prog) || *prog == '.') { while(!isoper(*prog) && !iswhite(*prog)) *temp++ = *prog++; *temp = 0; return(token_type = TOK_NUMBER); } while(!isoper(*prog) && !iswhite(*prog) && *prog != '"' && *prog != '\'') *temp++ = *prog++; if (islongoper(token) && get_fnc(token)) { while (iswhite(*prog)) *temp++ = *prog++; if (*prog == '(') { while (iswhite(*prog)) *temp++ = *prog++; prog++; if (isdigit(*prog)) goto blah; else if ((*prog == '"') || (*prog == '$')) { for (x=strlen(token); x>=3; x--) prog--; for (x=3; x<strlen(token)+1; x++) token[x] = '\0'; return (token_type = TOK_FUNCTION); } else if (isalpha(*prog)) { while (isalpha(*prog)) *temp++ = *prog++; if (*prog == '$') { for (x=strlen(token); x>=3; x--) prog--; for (x=3; x<strlen(token)+1; x++) token[x] = '\0'; return (token_type = TOK_FUNCTION); } else if (*prog == '(') { // test if valid function or sysvar // if succeeded, test function/sysvar return type for strings test[0] = toupper(token[strlen(token)-3]); test[1] = toupper(token[strlen(token)-2]); test[2] = toupper(token[strlen(token)-1]); test[3] = '\0'; if (get_fnc(test) || get_sysvar(test)) { for (x=strlen(token); x>=3; x--) prog--; for (x=3; x<strlen(token)+1; x++) token[x] = '\0'; return (token_type = TOK_FUNCTION); } else goto blah; } else goto blah; } else goto blah; } else { blah: for (x=0; !iswhite(token[x]); x++) ; for (x=x; x<strlen(token)+1; x++) token[x] = '\0'; return (token_type = TOK_OPERATOR); } } else { // !!HACK!! // will decide if this is a sysvar or operator the next time // gettoken is run. if next token is '=' then it's an operator // if so it will change the metacode for this run. if (!strcmp(token, "ERR")) { checkerr = 2; return(token_type = TOK_VARIABLE); //SYSVAR); } if (islongoper(token)) return(token_type = TOK_OPERATOR); if (isreserved(token)) return(token_type = TOK_RESERVED); if (((token[0] == 'F') || (token[0] == 'f')) && ((token[1] == 'N') || (token[1] == 'n'))) return (token_type = TOK_USERFUNCTION); if (get_opcode(token)) return(token_type = TOK_COMMAND); if (get_fnc(token)) return (token_type = TOK_FUNCTION); else return(token_type = TOK_VARIABLE); } return 0; }