//————————————————————–
//
// BNF - <expression> ::= <term> [<addop> <term>]*
//
//————————————————————–
void Compiler::Expression ()
{
Term ();
while ((Look.type == T_SUB) || (Look.type == T_ADD)) {
switch (Look.type) {
case (T_SUB):
Match (T_SUB);
Term ();
code (OP_SUB);
break;
case (T_ADD):
Match (T_ADD);
Term ();
code (OP_ADD);
break;
}
}
}
void VM::op_add (void)
{
Variable right(frame.pop());
Variable left(frame.pop());
frame.push( left + right );
}
Variable Variable::operator+( const Variable &right ) const
{
if (isNumeric() && right.isNumeric()) {
if (Type() == FLT || right.Type() == FLT) {
return Variable(tofloat() + right.tofloat());
} else {
return Variable((int)(tonum() + right.tonum()));
}
} else if (Type() != right.Type() && Type() != LIST)
throw aphrodite_exception(E_TYPE);
else if (Type() == STR && right.Type() == STR) {
String *x = new String(*value().str);
*x += *right.value().str;
return Variable(x);
} else if (Type() == LIST)
return Variable(value().list->setadd(right));
else
throw aphrodite_exception(E_TYPE);
return NULL;
}
I am working on a LPC compiler at present for a mud server and I am curious if anyone had some suggestions for how best to resolve and determine the correct operator to apply for a set of binary operators which are overloaded based on the type of it's arguments. Two simple methods would be to generate a two level switch statement and or a function table however both methods suffer from obvious problems since in general type1 op type2 <—> type2 op type1 are often the same and select the same operator with one argument coerced in some manner and I would redundantly be reserving space or encoding both possibilities adding to code repetition. So the question I have are there better ways than using these rather straightforward methods?
An example of this is the '+' operator in LPC. You have the following variants-
int + int
int + float —> coerce int to float then use float + float
float + int —-> coerce int to float then use float + float
float + float
string + int —-> coerce int to string then use string + string
string + float —-> coerce float to string then use string + string
string + string
array + array
mapping + mapping
Is there a good way to encode this coercion behavior?
Thanks in advance.