int calculate_infix(char* finfix, double *result) { int i = 0; char* ptr; double num1, num2; char op; if (result == NULL) return -EINVAL; *result = 0; if (finfix[0] == '\0') return -EINVAL; // evaluate while ( finfix[i] != '\0') { switch (finfix[i]) { case '(': break; case '+': case '-': case '*': case '/': oppush(finfix[i]); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num1 = strtod(&(finfix[i]), &ptr); dpush(num1); while (finfix[i] != *ptr) {i++;} i--; break; case ')': case '\n': case ' ': case '\0': op = oppop(); num1 = dpop(); num2 = dpop(); num1 = _calc_infix(op, num1, num2); dpush(num1); break; default: break; } i++; } while((op = oppop()) > 0) { num1 = dpop(); num2 = dpop(); num1 = _calc_infix(op, num1, num2); dpush(num1); } *result = dpop(); opsptr = 0; dsptr = 0; return 0; }
void simplifylist(char *var, statement *stmt, int start, int end) { int y = 0, channels = 0; char tmp[MAX_STRING_LENGTH], *hex; char *tmp1, *tmp2, *tmp3; char *reorder[32]; int ctr = 0; for (y=start; y<=end; y++) { oppush(0); if (get_sysvarname(stmt->metalist[y].operation)) { sprintf(tmp, "%s", get_sysvarname(stmt->metalist[y].operation)); listpush(tmp); } else if (get_fncname(stmt->metalist[y].operation)) { if ((stmt->metalist[y].operation == OP_AND) || (stmt->metalist[y].operation == OP_OR) || (stmt->metalist[y].operation == OP_XOR)) goto blah; sprintf(tmp, "%s(", get_fncname(stmt->metalist[y].operation)); if (stmt->metalist[y].intarg) { for (ctr=0; ctr<stmt->metalist[y].intarg; ctr++) { reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH); reorder[ctr] = listpop(); } } else { for (ctr=0; ctr<fnctable[get_fnc(get_fncname(stmt->metalist[y]. operation))].numparms; ctr++) { reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH); reorder[ctr] = listpop(); } } for (ctr=ctr-1; ctr>=0; ctr--) { strcat(tmp, reorder[ctr]); if (ctr) strcat(tmp, ","); } strcat(tmp, ")"); listpush(tmp); } else blah: switch(stmt->metalist[y].operation) { case HEXSTRING: hex = SafeMalloc(2+(stmt->metalist[y].intarg*2)); *hex = 0; sprintf(tmp, "$"); for (ctr = 0; ctr < stmt->metalist[y].intarg; ctr++) { sprintf(hex, "%X", stmt->metalist[y].stringarg[ctr]); sprintf(hex, "%c%c", hex[strlen(hex)-2], hex[strlen(hex)-1]); strcat(tmp, hex); } strcat(tmp, "$"); GC_free(hex); listpush(tmp); break; case 0xF5: if (stmt->opcode != CMD_DEFFN) listpush("<BEGINLIST>"); break; case 0xF8: if (stmt->opcode != CMD_DEFFN) { ctr = 0; do { reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH); reorder[ctr] = listpop(); if (!strcmp(reorder[ctr], "<BEGINLIST>")) break; ctr++; } while(1); sprintf(tmp, "%s(", listpop()); for (ctr = ctr-1; ctr >= 0; ctr--) { strcat(tmp, reorder[ctr]); if (ctr) strcat(tmp, ","); } strcat(tmp, ")"); listpush(tmp); } break; case 0x8DC9: listpush(gprog->userfunctions[stmt->metalist[y].shortarg].name); break; case 0xF1: case 0xEC: // workaround, LET handles its own commas if (stmt->opcode != CMD_LET) { sprintf(tmp, "%s,", listpop()); listpush(tmp); for (ctr = 0; ctr < outcount; ctr++) mysprintf(var, "%s", listpop()); } break; case 0xF4F1: if (channels) mysprintf(var, ") "); break; case 0xE1: channels = 1; mysprintf(var, "(%s", listpop()); break; case OP_OPT: case OP_SEP: case OP_SRT: case OP_BNK: case OP_DOM: case OP_END: case OP_IND: case OP_IOL: case OP_ISZ: case OP_KEY: case OP_SIZ: case OP_TBL: case OP_TIM: case OP_ERR: case OP_LEN: case OP_PWD: case OP_ATR: if (channels) mysprintf(var, ", %s=%s", get_symbol(stmt->metalist[y].operation), listpop()); else { sprintf(tmp, "%s, %s=%s", listpop(), get_symbol(stmt->metalist[y].operation), listpop()); listpush(tmp); } break; case LABELREF: sprintf(tmp, "%s", get_labelname(stmt->metalist[y].shortarg)); listpush(tmp); break; case LINEREF: sprintf(tmp, "%.5d", stmt->metalist[y].shortarg); listpush(tmp); break; case MNEMONICREF: sprintf(tmp, "\'%s\'", stmt->metalist[y].stringarg); listpush(tmp); break; case 0xF7: tmp2 = listpop(); sprintf(tmp, "@(%s,%s)", listpop(), tmp2); listpush(tmp); break; case 0xF6: sprintf(tmp, "@(%s)", listpop()); listpush(tmp); break; case FLOAT: sprintf(tmp, "%s", flt2asc(stmt->metalist[y].floatarg)); listpush(tmp); break; case GETVAL_STRINGARRAY: case SETVAL_STRINGARRAY: case GETVAL_STRING: case SETVAL_STRING: ctr = stmt->metalist[y].shortarg; tmp3 = SafeMalloc(MAX_STRING_LENGTH); if (stmt->metalist[y].shortarg & 0x2000) { ctr -= 0x2000; sprintf(tmp3, "(%s)", listpop()); } else if (stmt->metalist[y].shortarg & 0x4000) { ctr -= 0x4000; tmp2 = listpop(); sprintf(tmp3, "(%s,%s)", listpop(), tmp2); } else tmp3 = 0; if (stmt->metalist[y].shortarg & 0x8000) { ctr -= 0x8000; if (stmt->metalist[y].operation == GETVAL_STRINGARRAY || stmt->metalist[y].operation == SETVAL_STRINGARRAY) { tmp1 = listpop(); tmp2 = listpop(); sprintf(tmp, "[%s,%s,%s]", listpop(), tmp2, tmp1); listpush(tmp); } else { sprintf(tmp, "[%s]", listpop()); listpush(tmp); } } else if (stmt->metalist[y].operation == GETVAL_STRINGARRAY || stmt->metalist[y].operation == SETVAL_STRINGARRAY) { tmp1 = listpop(); sprintf(tmp, "[%s,%s]", listpop(), tmp1); listpush(tmp); } else listpush(""); // noarrayref if (tmp3) sprintf(tmp, "%s%s%s", get_symname(ctr), listpop(), tmp3); else sprintf(tmp, "%s%s", get_symname(ctr), listpop()); GC_free(tmp3); if ((stmt->metalist[y].operation == SETVAL_STRING) || (stmt->metalist[y].operation == SETVAL_STRINGARRAY)) { if ((stmt->opcode == CMD_LET) || (stmt->opcode == CMD_FOR)) strcat(tmp, "="); } listpush(tmp); break; case GETVAL_NUMERIC: case SETVAL_NUMERIC: case GETVAL_NUMERICARRAY: case SETVAL_NUMERICARRAY: ctr = stmt->metalist[y].shortarg; if (stmt->metalist[y].shortarg & 0x8000) { ctr -= 0x8000; if (stmt->metalist[y].operation == GETVAL_NUMERICARRAY || stmt->metalist[y].operation == SETVAL_NUMERICARRAY) { tmp1 = listpop(); tmp2 = listpop(); sprintf(tmp, "[%s,%s,%s]", listpop(), tmp2, tmp1); listpush(tmp); } else { sprintf(tmp, "[%s]", listpop()); listpush(tmp); } } else if (stmt->metalist[y].operation == GETVAL_NUMERICARRAY || stmt->metalist[y].operation == SETVAL_NUMERICARRAY) { tmp1 = listpop(); sprintf(tmp, "[%s,%s]", listpop(), tmp1); listpush(tmp); } else listpush(""); // noarrayref sprintf(tmp, "%s%s", get_symname(ctr), listpop()); if (stmt->metalist[y].operation == SETVAL_NUMERIC || stmt->metalist[y].operation == SETVAL_NUMERICARRAY) if ((stmt->opcode == CMD_LET) || (stmt->opcode == CMD_FOR)) strcat(tmp, "="); listpush(tmp); break; case SHORTLITERAL: sprintf(tmp, "\"%s\"", stmt->metalist[y].stringarg); listpush(tmp); break; case OP_NEGATE: sprintf(tmp, "(-%s)", listpop()); listpush(tmp); break; case OP_STRCAT: tmp2 = listpop(); sprintf(tmp, "%s+%s", listpop(), tmp2); listpush(tmp); break; case OP_AND: case OP_XOR: case OP_OR: case OP_LESSTHAN: case OP_GREATTHAN: case OP_NOTEQUAL: case OP_EQUALSCMP: case OP_LTEQ: case OP_GTEQ: case OP_ADD: case OP_SUBTRACT: case OP_MULTIPLY: case OP_DIVIDE: case OP_EXPONENT: oppop(); if (oppop() >= getprec(get_symbol(stmt->metalist[y].operation))) { tmp3 = listpop(); tmp1 = SafeMalloc(strlen(tmp3)+2); sprintf(tmp1, "(%s)", tmp3); } else tmp1 = listpop(); if (oppop() >= getprec(get_symbol(stmt->metalist[y].operation))) { tmp3 = listpop(); tmp2 = SafeMalloc(strlen(tmp3)+2); sprintf(tmp2, "(%s)", tmp3); } else tmp2 = listpop(); oppush(getprec(get_symbol(stmt->metalist[y].operation))); sprintf(tmp, "%s%s%s", tmp2, get_symbol(stmt->metalist[y].operation), tmp1); listpush(tmp); break; } } }