You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.3 KiB
92 lines
2.3 KiB
#include <cmath> |
|
#include "object.h" |
|
|
|
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; |
|
}
|
|
|