// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_valop #define tools_valop #include "ival_func" namespace tools { class valop { static const std::string& s_class() { static const std::string s_v("tools::valop"); return s_v; } public: enum e_type { CMP_GT = 1, CMP_GE = 2, CMP_LT = 3, CMP_LE = 4, CMP_EQ = 5, CMP_NE = 6, CMP_AND = 7, CMP_OR = 8, ADD = 9, MUL = 10, SUB = 11, DIV = 12, ASSIGN = 13, MINUS = 14, UNSIGNED_INTEGER = 15, REAL = 16, NAME = 17, STRING = 18, //PI = 19, FUNC = 20, BOOL_TRUE = 21, BOOL_FALSE = 22, NOT = 23, // math edition : SYMBOL = 100, ASIDE = 101, NVMUL = 102, //not visible mul EQUAL = 103, SUPS = 104, //super script SUBS = 105 //sub script }; public: valop(e_type a_type) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ } valop(e_type a_type,valop* a_A) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ } valop(e_type a_type,valop* a_A,valop* a_B) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(a_B),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ } valop(e_type a_type,ival_func* a_function,valop* a_A) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_function = a_function?a_function->copy():0; } valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(a_B),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_function = a_function?a_function->copy():0; } valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(0),m_E(0),m_F(0),m_tag(0){ m_function = a_function?a_function->copy():0; } valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C,valop* a_D) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(a_D),m_E(0),m_F(0),m_tag(0){ m_function = a_function?a_function->copy():0; } valop(e_type a_type,ival_func* a_function,valop* a_A,valop* a_B,valop* a_C,valop* a_D,valop* a_E) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(a_D),m_E(a_E),m_F(0),m_tag(0){ m_function = a_function?a_function->copy():0; } valop(e_type a_type,ival_func* a_function, valop* a_A,valop* a_B,valop* a_C, valop* a_D,valop* a_E,valop* a_F) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(a_A),m_B(a_B),m_C(a_C),m_D(a_D),m_E(a_E),m_F(a_F),m_tag(0){ m_function = a_function?a_function->copy():0; } valop(e_type a_type,bool a_v) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_variable.set(a_v); } valop(e_type a_type,unsigned int a_number) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_variable.set(a_number); } valop(e_type a_type,double a_number) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_variable.set(a_number); } valop(e_type a_type,const std::string& a_string) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_variable.set(a_string); } //NOTE : the below is needed so that valop("t") not put on valop(bool). valop(e_type a_type,const char* a_cstr) :m_type(a_type),m_function(0),m_index(not_found()) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ m_variable.set(a_cstr); } valop(e_type a_type,const std::string& a_name,int a_index) :m_type(a_type),m_function(0),m_name(a_name),m_index(a_index) ,m_A(0),m_B(0),m_C(0),m_D(0),m_E(0),m_F(0),m_tag(0){ // a_name needed to not confuse with the constructor (e_type,unsigned int). } virtual ~valop() { delete m_function; delete m_A; delete m_B; delete m_C; delete m_D; delete m_E; delete m_F; } public: valop(const valop& a_from) :m_type(a_from.m_type) ,m_function(a_from.m_function?a_from.m_function->copy():0) ,m_variable(a_from.m_variable) ,m_name(a_from.m_name) ,m_index(a_from.m_index) ,m_A(a_from.m_A?new valop(*a_from.m_A):0) ,m_B(a_from.m_B?new valop(*a_from.m_B):0) ,m_C(a_from.m_C?new valop(*a_from.m_C):0) ,m_D(a_from.m_D?new valop(*a_from.m_D):0) ,m_E(a_from.m_E?new valop(*a_from.m_E):0) ,m_F(a_from.m_F?new valop(*a_from.m_F):0) ,m_tag(a_from.m_tag) { } valop& operator=(const valop& a_from) { if(&a_from==this) return *this; m_type = a_from.m_type; delete m_function; m_function = a_from.m_function?a_from.m_function->copy():0; m_variable = a_from.m_variable; m_name = a_from.m_name; m_index = a_from.m_index; delete m_A; delete m_B; delete m_C; delete m_D; delete m_E; delete m_F; m_A = a_from.m_A?new valop(*a_from.m_A):0; m_B = a_from.m_B?new valop(*a_from.m_B):0; m_C = a_from.m_C?new valop(*a_from.m_C):0; m_D = a_from.m_D?new valop(*a_from.m_D):0; m_E = a_from.m_E?new valop(*a_from.m_E):0; m_F = a_from.m_F?new valop(*a_from.m_F):0; m_tag = a_from.m_tag; return *this; } protected: static int not_found() {return -1;} public: e_type m_type; ival_func* m_function; //owner value m_variable; std::string m_name; int m_index; valop* m_A; valop* m_B; valop* m_C; valop* m_D; valop* m_E; valop* m_F; public: int m_tag; }; class valop_visitor { public: virtual ~valop_visitor() {} public: virtual bool binary(unsigned int,const valop&,const valop&) = 0; virtual bool unary(unsigned int,const valop&) = 0; virtual bool variable(unsigned int,const value&) = 0; virtual bool option(const valop&) = 0; virtual bool func_1(const valop&,const valop&) = 0; virtual bool func_2(const valop&,const valop&,const valop&) = 0; virtual bool func_3(const valop&,const valop&,const valop&,const valop&) = 0; virtual bool func_4(const valop&,const valop&,const valop&, const valop&,const valop&) = 0; virtual bool func_5(const valop&,const valop&,const valop&, const valop&,const valop&,const valop&) = 0; virtual bool func_6(const valop&,const valop&,const valop&, const valop&,const valop&, const valop&,const valop&) = 0; public: bool visit(const valop& a_valop) { switch(a_valop.m_type) { case valop::CMP_GT: case valop::CMP_GE: case valop::CMP_LT: case valop::CMP_LE: case valop::CMP_EQ: case valop::CMP_NE: case valop::CMP_AND: case valop::CMP_OR: case valop::ADD: case valop::MUL: case valop::SUB: case valop::DIV: case valop::ASIDE: case valop::NVMUL: case valop::EQUAL: case valop::SUPS: case valop::SUBS: if(!a_valop.m_A || !a_valop.m_B) break; return binary(a_valop.m_type,*a_valop.m_A,*a_valop.m_B); case valop::BOOL_TRUE: case valop::BOOL_FALSE: case valop::UNSIGNED_INTEGER: case valop::REAL: case valop::STRING: case valop::SYMBOL: return variable(a_valop.m_type,a_valop.m_variable); case valop::NAME: return option(a_valop); case valop::MINUS: case valop::NOT: case valop::ASSIGN: if(!a_valop.m_A) break; return unary(a_valop.m_type,*a_valop.m_A); case valop::FUNC:{ if(!a_valop.m_A) break; if(!a_valop.m_function) { return false; } size_t argn = a_valop.m_function->number_of_arguments(); if(argn==1) { return func_1(a_valop,*a_valop.m_A); } else if(argn==2) { if(!a_valop.m_B) break; return func_2(a_valop,*a_valop.m_A,*a_valop.m_B); } else if(argn==3) { if(!a_valop.m_B || !a_valop.m_C) break; return func_3(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C); } else if(argn==4) { if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D) break; return func_4(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D); } else if(argn==5) { if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D || !a_valop.m_E) break; return func_5(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D,*a_valop.m_E); } else if(argn==6) { if(!a_valop.m_B || !a_valop.m_C || !a_valop.m_D || !a_valop.m_E || !a_valop.m_F) break; return func_6(a_valop,*a_valop.m_A,*a_valop.m_B,*a_valop.m_C,*a_valop.m_D,*a_valop.m_E,*a_valop.m_F); } else { return false; }} default: break; } return false; } }; } #endif