Michael Uleysky
9 years ago
3 changed files with 97 additions and 137 deletions
@ -1,9 +1,92 @@
|
||||
#include <cmath> |
||||
#include "object.h" |
||||
|
||||
ObjectBase* Arifm_Add(const ObjectList* input); |
||||
ObjectBase* Arifm_Sub(const ObjectList* input); |
||||
ObjectBase* Arifm_Mul(const ObjectList* input); |
||||
ObjectBase* Arifm_Div(const ObjectList* input); |
||||
ObjectBase* Arifm_Pow(const ObjectList* input); |
||||
ObjectBase* Arifm_Neg(const ObjectList* input); |
||||
ObjectBase* Arifm_Pos(const ObjectList* input); |
||||
template<class O> |
||||
struct Valued |
||||
{ |
||||
double operator ()(const O* q, bool* isok) {return q->Value();} |
||||
}; |
||||
|
||||
template<> |
||||
struct Valued<ObjectString> |
||||
{ |
||||
double operator ()(const ObjectString* q, bool* isok) {double d=0; *isok=str2double(q->Value(),&d); return d;} |
||||
}; |
||||
|
||||
template<class O> |
||||
struct Valuei |
||||
{ |
||||
int64_t operator ()(const O* q, bool* isok) {return q->Value();} |
||||
}; |
||||
|
||||
template<> |
||||
struct Valuei<ObjectString> |
||||
{ |
||||
int64_t operator ()(const ObjectString* q, bool* isok) {int64_t i=0; *isok=str2int(q->Value(),&i); return i;} |
||||
}; |
||||
|
||||
|
||||
template<class T> class OpAdd {public: static T V(T a1, T a2) {return a1+a2;}}; |
||||
template<class T> class OpSub {public: static T V(T a1, T a2) {return a1-a2;}}; |
||||
template<class T> class OpMul {public: static T V(T a1, T a2) {return a1*a2;}}; |
||||
template<class T> class OpDiv {public: static T V(T a1, T a2) {return a1/a2;}}; |
||||
template<class T> class OpPow {public: static T V(T a1, T a2) {return pow(a1,a2);}}; |
||||
template<class T> class OpNeg {public: static T V(T a) {return -a;}}; |
||||
template<class T> class OpPos {public: static T V(T a) {return +a;}}; |
||||
|
||||
template<template<typename> class Op, bool intArifm=true> |
||||
ObjectBase* Arifm2(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=2) return 0; |
||||
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
||||
OBTypeM<Valuei,ObjectInt,ObjectString> i1(arg1), i2(arg2); |
||||
OBTypeM<Valued,ObjectReal,ObjectInt,ObjectString> r1(arg1), r2(arg2); |
||||
bool isok; |
||||
|
||||
// Integer arifmetic
|
||||
isok=true; |
||||
if(i1 && i2 && intArifm) |
||||
{ |
||||
int64_t v1=i1(&isok),v2=i2(&isok); |
||||
if(isok) return new ObjectInt(Op<int64_t>::V(v1,v2)); |
||||
} |
||||
|
||||
// Real arifmetic
|
||||
isok=true; |
||||
if(r1 && r2) |
||||
{ |
||||
double v1=r1(&isok),v2=r2(&isok); |
||||
if(isok) return new ObjectReal(Op<double>::V(v1,v2)); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
template<template<typename> class Op, bool intArifm=true> |
||||
ObjectBase* Arifm1(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=1) return 0; |
||||
const ObjectBase *arg=input->At(0); |
||||
OBTypeM<Valuei,ObjectInt,ObjectString> i(arg); |
||||
OBTypeM<Valued,ObjectReal,ObjectString> r(arg); |
||||
bool isok; |
||||
|
||||
// Integer arifmetic
|
||||
isok=true; |
||||
if(i && intArifm) |
||||
{ |
||||
int64_t v=i(&isok); |
||||
if(isok) return new ObjectInt(Op<int64_t>::V(v)); |
||||
} |
||||
|
||||
// Real arifmetic
|
||||
isok=true; |
||||
if(r) |
||||
{ |
||||
double v=r(&isok); |
||||
if(isok) return new ObjectReal(Op<double>::V(v)); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
@ -1,123 +0,0 @@
|
||||
#include <math.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) |
||||
{ |
||||
if(input->Size()!=2) return 0; |
||||
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
||||
OBType<ObjectInt> i1(arg1), i2(arg2); |
||||
OBType<ObjectReal> r1(arg1), r2(arg2); |
||||
|
||||
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
||||
|
||||
// Integer arifmetic
|
||||
if(i1 && i2) return new ObjectInt(i1->Value()+i2->Value()); |
||||
// Real arifmetic
|
||||
return new ObjectReal(Val(i1,r1)+Val(i2,r2)); |
||||
} |
||||
|
||||
|
||||
ObjectBase* Arifm_Sub(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=2) return 0; |
||||
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
||||
OBType<ObjectInt> i1(arg1), i2(arg2); |
||||
OBType<ObjectReal> r1(arg1), r2(arg2); |
||||
|
||||
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
||||
|
||||
// Integer arifmetic
|
||||
if(i1 && i2) return new ObjectInt(i1->Value()-i2->Value()); |
||||
// Real arifmetic
|
||||
return new ObjectReal(Val(i1,r1)-Val(i2,r2)); |
||||
} |
||||
|
||||
|
||||
ObjectBase* Arifm_Mul(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=2) return 0; |
||||
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
||||
OBType<ObjectInt> i1(arg1), i2(arg2); |
||||
OBType<ObjectReal> r1(arg1), r2(arg2); |
||||
|
||||
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
||||
|
||||
// Integer arifmetic
|
||||
if(i1 && i2) return new ObjectInt(i1->Value()*i2->Value()); |
||||
// Real arifmetic
|
||||
return new ObjectReal(Val(i1,r1)*Val(i2,r2)); |
||||
} |
||||
|
||||
|
||||
ObjectBase* Arifm_Div(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=2) return 0; |
||||
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
||||
OBType<ObjectInt> i1(arg1), i2(arg2); |
||||
OBType<ObjectReal> r1(arg1), r2(arg2); |
||||
|
||||
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
||||
|
||||
// Integer arifmetic
|
||||
if(i1 && i2) return new ObjectInt(i1->Value()/i2->Value()); |
||||
// Real arifmetic
|
||||
return new ObjectReal(Val(i1,r1)/Val(i2,r2)); |
||||
} |
||||
|
||||
|
||||
ObjectBase* Arifm_Pow(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=2) return 0; |
||||
const ObjectBase *arg1=input->At(0),*arg2=input->At(1); |
||||
OBType<ObjectInt> i1(arg1), i2(arg2); |
||||
OBType<ObjectReal> r1(arg1), r2(arg2); |
||||
|
||||
if( !(i1 || r1) || !(i2 || r2) ) return 0; |
||||
|
||||
// Only real arifmetic
|
||||
return new ObjectReal(pow(Val(i1,r1),Val(i2,r2))); |
||||
} |
||||
|
||||
|
||||
ObjectBase* Arifm_Neg(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=1) return 0; |
||||
const ObjectBase *arg=input->At(0); |
||||
OBType<ObjectInt> i(arg); |
||||
OBType<ObjectReal> r(arg); |
||||
|
||||
// Integer arifmetic
|
||||
if(i) return new ObjectInt(-i->Value()); |
||||
// Real arifmetic
|
||||
if(r) return new ObjectReal(-r->Value()); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
ObjectBase* Arifm_Pos(const ObjectList* input) |
||||
{ |
||||
if(input->Size()!=1) return 0; |
||||
const ObjectBase *arg=input->At(0); |
||||
OBType<ObjectInt> i(arg); |
||||
OBType<ObjectReal> r(arg); |
||||
|
||||
// Integer arifmetic
|
||||
if(i) return new ObjectInt(i->Value()); |
||||
// Real arifmetic
|
||||
if(r) return new ObjectReal(r->Value()); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue