|
|
@ -1,28 +1,31 @@ |
|
|
|
#include <math.h> |
|
|
|
#include <math.h> |
|
|
|
#include "object.h" |
|
|
|
#include "object.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Val |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
double v; |
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
Val() = delete; |
|
|
|
|
|
|
|
Val(Val&&) = delete; |
|
|
|
|
|
|
|
Val(Val&) = delete; |
|
|
|
|
|
|
|
Val(const OBType<ObjectInt>& i, const OBType<ObjectReal>& r) {v=r?r->Value():i->Value();} |
|
|
|
|
|
|
|
Val(const OBType<ObjectReal>& r, const OBType<ObjectInt>& i) {v=r?r->Value():i->Value();} |
|
|
|
|
|
|
|
operator double() const {return v;} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
ObjectBase* Arifm_Add(const ObjectList* input) |
|
|
|
ObjectBase* Arifm_Add(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); |
|
|
|
OBType<ObjectInt> i1(arg1), i2(arg2); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r1(arg1), r2(arg2); |
|
|
|
|
|
|
|
|
|
|
|
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; |
|
|
|
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// Integer arifmetic
|
|
|
|
// Integer arifmetic
|
|
|
|
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(arg1)->Value() + dynamic_cast<const ObjectInt*>(arg2)->Value()); |
|
|
|
if(i1 && i2) return new ObjectInt(i1->Value()+i2->Value()); |
|
|
|
|
|
|
|
|
|
|
|
// Real arifmetic
|
|
|
|
// Real arifmetic
|
|
|
|
double r1,r2; |
|
|
|
return new ObjectReal(Val(i1,r1)+Val(i2,r2)); |
|
|
|
|
|
|
|
|
|
|
|
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value(); |
|
|
|
|
|
|
|
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value(); |
|
|
|
|
|
|
|
else r2=dynamic_cast<const ObjectInt*>(arg2)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new ObjectReal(r1+r2); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -30,24 +33,15 @@ ObjectBase* Arifm_Sub(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); |
|
|
|
OBType<ObjectInt> i1(arg1), i2(arg2); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r1(arg1), r2(arg2); |
|
|
|
|
|
|
|
|
|
|
|
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; |
|
|
|
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// Integer arifmetic
|
|
|
|
// Integer arifmetic
|
|
|
|
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(arg1)->Value() - dynamic_cast<const ObjectInt*>(arg2)->Value()); |
|
|
|
if(i1 && i2) return new ObjectInt(i1->Value()-i2->Value()); |
|
|
|
|
|
|
|
|
|
|
|
// Real arifmetic
|
|
|
|
// Real arifmetic
|
|
|
|
double r1,r2; |
|
|
|
return new ObjectReal(Val(i1,r1)-Val(i2,r2)); |
|
|
|
|
|
|
|
|
|
|
|
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value(); |
|
|
|
|
|
|
|
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value(); |
|
|
|
|
|
|
|
else r2=dynamic_cast<const ObjectInt*>(arg2)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new ObjectReal(r1-r2); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -55,24 +49,15 @@ ObjectBase* Arifm_Mul(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); |
|
|
|
OBType<ObjectInt> i1(arg1), i2(arg2); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r1(arg1), r2(arg2); |
|
|
|
|
|
|
|
|
|
|
|
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; |
|
|
|
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// Integer arifmetic
|
|
|
|
// Integer arifmetic
|
|
|
|
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(arg1)->Value() * dynamic_cast<const ObjectInt*>(arg2)->Value()); |
|
|
|
if(i1 && i2) return new ObjectInt(i1->Value()*i2->Value()); |
|
|
|
|
|
|
|
|
|
|
|
// Real arifmetic
|
|
|
|
// Real arifmetic
|
|
|
|
double r1,r2; |
|
|
|
return new ObjectReal(Val(i1,r1)*Val(i2,r2)); |
|
|
|
|
|
|
|
|
|
|
|
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value(); |
|
|
|
|
|
|
|
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value(); |
|
|
|
|
|
|
|
else r2=dynamic_cast<const ObjectInt*>(arg2)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new ObjectReal(r1*r2); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -80,24 +65,15 @@ ObjectBase* Arifm_Div(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); |
|
|
|
OBType<ObjectInt> i1(arg1), i2(arg2); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r1(arg1), r2(arg2); |
|
|
|
|
|
|
|
|
|
|
|
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; |
|
|
|
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// Integer arifmetic
|
|
|
|
// Integer arifmetic
|
|
|
|
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(arg1)->Value() / dynamic_cast<const ObjectInt*>(arg2)->Value()); |
|
|
|
if(i1 && i2) return new ObjectInt(i1->Value()/i2->Value()); |
|
|
|
|
|
|
|
|
|
|
|
// Real arifmetic
|
|
|
|
// Real arifmetic
|
|
|
|
double r1,r2; |
|
|
|
return new ObjectReal(Val(i1,r1)/Val(i2,r2)); |
|
|
|
|
|
|
|
|
|
|
|
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value(); |
|
|
|
|
|
|
|
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value(); |
|
|
|
|
|
|
|
else r2=dynamic_cast<const ObjectInt*>(arg2)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new ObjectReal(r1/r2); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -105,21 +81,13 @@ ObjectBase* Arifm_Pow(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
if(input->Size()!=2) return 0; |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
|
|
|
std::type_index t1(typeid(*arg1)),t2(typeid(*arg2)); |
|
|
|
OBType<ObjectInt> i1(arg1), i2(arg2); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r1(arg1), r2(arg2); |
|
|
|
|
|
|
|
|
|
|
|
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0; |
|
|
|
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
|
|
|
|
|
|
|
|
|
|
|
// Only real arifmetic
|
|
|
|
// Only real arifmetic
|
|
|
|
double r1,r2; |
|
|
|
return new ObjectReal(pow(Val(i1,r1),Val(i2,r2))); |
|
|
|
|
|
|
|
|
|
|
|
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(arg1)->Value(); |
|
|
|
|
|
|
|
else r1=dynamic_cast<const ObjectInt*>(arg1)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(arg2)->Value(); |
|
|
|
|
|
|
|
else r2=dynamic_cast<const ObjectInt*>(arg2)->Value(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new ObjectReal(pow(r1,r2)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -127,13 +95,13 @@ ObjectBase* Arifm_Neg(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=1) return 0; |
|
|
|
if(input->Size()!=1) return 0; |
|
|
|
const ObjectBase *arg=input->At(0); |
|
|
|
const ObjectBase *arg=input->At(0); |
|
|
|
std::type_index t(typeid(*arg)); |
|
|
|
OBType<ObjectInt> i(arg); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r(arg); |
|
|
|
|
|
|
|
|
|
|
|
// Integer arifmetic
|
|
|
|
// Integer arifmetic
|
|
|
|
if(t==ti) return new ObjectInt(-dynamic_cast<const ObjectInt*>(arg)->Value()); |
|
|
|
if(i) return new ObjectInt(-i->Value()); |
|
|
|
// Real arifmetic
|
|
|
|
// Real arifmetic
|
|
|
|
if(t==tr) return new ObjectReal(-dynamic_cast<const ObjectReal*>(arg)->Value()); |
|
|
|
if(r) return new ObjectReal(-r->Value()); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
@ -143,13 +111,13 @@ ObjectBase* Arifm_Pos(const ObjectList* input) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(input->Size()!=1) return 0; |
|
|
|
if(input->Size()!=1) return 0; |
|
|
|
const ObjectBase *arg=input->At(0); |
|
|
|
const ObjectBase *arg=input->At(0); |
|
|
|
std::type_index t(typeid(*arg)); |
|
|
|
OBType<ObjectInt> i(arg); |
|
|
|
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt)); |
|
|
|
OBType<ObjectReal> r(arg); |
|
|
|
|
|
|
|
|
|
|
|
// Integer arifmetic
|
|
|
|
// Integer arifmetic
|
|
|
|
if(t==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(arg)->Value()); |
|
|
|
if(i) return new ObjectInt(i->Value()); |
|
|
|
// Real arifmetic
|
|
|
|
// Real arifmetic
|
|
|
|
if(t==tr) return new ObjectReal(dynamic_cast<const ObjectReal*>(arg)->Value()); |
|
|
|
if(r) return new ObjectReal(r->Value()); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|