bool User_Program::Math (void) { int l1, l2; double f1, f2; const char *math_types [] = {"Plus", "Minus", "Multiply", "Divide", "Modulo", "Power", "Negative"}; if (cmd_ptr->token == NEGATIVE) { if (s->type == STRUCT_DATA || s->type == STRING_DATA) goto error; //---- reverse the sign ---- if (s->type == INT_DATA) { s->lvalue = -(s->lvalue); } else if (s->type == FLOAT_DATA) { s->fvalue = -(s->fvalue); } else { goto error; } return (true); } if (s->type == STRUCT_DATA || s1->type == STRUCT_DATA) goto error; //---- process the data types ---- if (s->type == STRING_DATA || s1->type == STRING_DATA) { //---- string contatination ---- if (cmd_ptr->token != PLUS || s->type != STRING_DATA || s1->type != STRING_DATA) goto error; *(s1->str_ptr) += *(s->str_ptr); } else if (s1->type == FLOAT_DATA || s->type == FLOAT_DATA) { //---- floating point math ---- if (s1->type == FLOAT_DATA) { f1 = s1->fvalue; } else { f1 = s1->lvalue; } if (s->type == FLOAT_DATA) { f2 = s->fvalue; } else { f2 = s->lvalue; } switch (cmd_ptr->token) { case PLUS: f1 += f2; break; case MINUS: f1 -= f2; break; case MULTIPLY: f1 *= f2; break; case DIVIDE: if (f2) { f1 /= f2; } break; case MODULO: if (f2) { f1 = (f1 / f2) - 1.0; } break; case POWER: f1 = pow (f1, f2); break; case FMIN: if (f2 < f1) f1 = f2; break; case FMAX: if (f2 > f1) f1 = f2; break; default: goto token_error; break; } s1->type = FLOAT_DATA; s1->fvalue = f1; } else { l1 = s1->lvalue; l2 = s->lvalue; switch (cmd_ptr->token) { case PLUS: l1 += l2; break; case MINUS: l1 -= l2; break; case MULTIPLY: l1 *= l2; break; case DIVIDE: if (l2) { l1 /= l2; } break; case MODULO: if (l2) { l1 %= l2; } break; case POWER: l1 = (int) pow ((double) l1, (double) l2); break; case FMIN: if (l2 < l1) l1 = l2; break; case FMAX: if (l2 > l1) l1 = l2; break; default: goto token_error; break; } s1->type = INT_DATA; s1->lvalue = l1; } s = &stack [--sindex]; return (true); error: if (cmd_ptr->token == FMIN || cmd_ptr->token == FMAX) { exe->Error (String ("Function \"%s\" does not support %s Data") % Token_Name (FUNCTION, cmd_ptr->token) % Data_Type (s->type)); } else { exe->Error (String ("%s Operator does not support %s Data") % math_types [cmd_ptr->token - PLUS] % Data_Type (s->type)); } return (false); token_error: exe->Error (String ("Unrecognized Math Token = %d") % cmd_ptr->token); return (false); }
bool User_Program::Convert (void) { String *str_ptr; //--- sub string function ---- if (cmd_ptr->token == SUBSTR) { int i1, i2, len; if (sindex <= 2) goto string_error; Stack_Data *s2 = &stack [sindex - 2]; if (s2->type != STRING_DATA || s1->type != INT_DATA || s->type != INT_DATA) goto string_error; i1 = s1->lvalue; i2 = s->lvalue; str_ptr = s2->str_ptr; len = (int) str_ptr->length (); if (i1 < 0) i1 = 0; if (i2 < i1) i2 = i1; if (i2 > len) { i2 = len; if (i1 > i2) i1 = i2; } len = i2 - i1 + 1; (*str_ptr) = str_ptr->substr (i1, len); sindex -= 2; s = s2; s->str_ptr = str_ptr; return (true); } else if (cmd_ptr->token == TRIM) { if (s->type != STRING_DATA) { exe->Error ("Illegal TRIM Function Syntax"); return (false); } s->str_ptr->Trim (); return (true); } //---- type conversion functions ---- if (s->type == STRUCT_DATA) goto error; if (cmd_ptr->token != ATOI && cmd_ptr->token != ATOF) { if (s->type == STRING_DATA) goto error; } else { if (s->type != STRING_DATA) goto error; } switch (cmd_ptr->token) { case FINT: if (s->type == FLOAT_DATA) { s->type = INT_DATA; s->lvalue = (int) s->fvalue; } break; case FFLOAT: if (s->type == INT_DATA) { s->type = FLOAT_DATA; s->fvalue = (double) s->lvalue; } break; case ROUND: if (s->type == FLOAT_DATA) { s->type = INT_DATA; s->lvalue = (int) (s->fvalue + 0.5); } break; case ATOI: s->type = INT_DATA; s->lvalue = s->str_ptr->Integer (); break; case ATOF: s->type = FLOAT_DATA; s->fvalue = s->str_ptr->Double (); break; case ITOA: if (s->type == FLOAT_DATA) { s->lvalue = (int) s->fvalue; } str_ptr = &svalue [0]; (*str_ptr)("%d") % s->lvalue; s->type = STRING_DATA; s->str_ptr = str_ptr; break; case FTOA: if (s->type == INT_DATA) { s->fvalue = s->lvalue; } str_ptr = &svalue [0]; (*str_ptr)("%lf") % s->fvalue; s->type = STRING_DATA; s->str_ptr = str_ptr; break; case TTOI: if (s->type == FLOAT_DATA) { s->lvalue = (int) s->fvalue; } s->type = INT_DATA; s->lvalue /= 10; break; case TTOF: if (s->type == INT_DATA) { s->fvalue = s->lvalue; } s->type = FLOAT_DATA; s->fvalue /= 10.0; break; case ITOT: if (s->type == FLOAT_DATA) { s->lvalue = (int) s->fvalue; } s->type = INT_DATA; s->lvalue *= 10; break; case FTOT: if (s->type == INT_DATA) { s->fvalue = s->lvalue; } s->type = FLOAT_DATA; s->fvalue *= 10.0; break; default: goto token_error; break; } return (true); error: exe->Error (String ("Conversion \"%s\" does not support %s Data") % Token_Name (CONVERT, cmd_ptr->token) % Data_Type (s->type)); return (false); token_error: exe->Error (String ("Conversion Token %d was Unrecognized") % cmd_ptr->token); return (false); string_error: exe->Error ("Illegal SUBSTR Function Syntax"); return (false); }