示例#1
0
文件: Math.cpp 项目: qingswu/Transim
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);
}
示例#2
0
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);
}