Browse Source

Add simple arifmetic functions.

Tune exported suymbols.
test
Michael Uleysky 9 years ago
parent
commit
a31a47656d
  1. 4
      src/Makefile
  2. 148
      src/arifmetic.cpp
  3. 9
      src/arifmetic.h
  4. 6
      src/common.h
  5. 5
      src/debug.h
  6. 5
      src/globals.cpp
  7. 12
      src/globals.h
  8. 18
      src/init.cpp
  9. 1
      src/init.h
  10. 7
      src/main.cpp
  11. 8
      src/object.cpp
  12. 16
      src/object.h

4
src/Makefile

@ -1,5 +1,5 @@
CFLAGS=-O2 -g -std=gnu++11 CFLAGS=-O2 -g -std=gnu++11 -fvisibility=hidden -fpic
LDFLAGS= LDFLAGS=-fvisibility=hidden -Wl,--export-dynamic -fpic
CC=g++ CC=g++

148
src/arifmetic.cpp

@ -0,0 +1,148 @@
#include <math.h>
#include "object.h"
ObjectBase* Arifm_Add(ObjectList* input)
{
if(input->Size()!=2) return 0;
std::type_index t1(typeid(*input->At(0))),t2(typeid(*input->At(1)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0;
// Integer arifmetic
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(input->At(0))->Value() + dynamic_cast<const ObjectInt*>(input->At(1))->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(input->At(0))->Value();
else r1=dynamic_cast<const ObjectInt*>(input->At(0))->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(input->At(1))->Value();
else r2=dynamic_cast<const ObjectInt*>(input->At(1))->Value();
return new ObjectReal(r1+r2);
}
ObjectBase* Arifm_Sub(ObjectList* input)
{
if(input->Size()!=2) return 0;
std::type_index t1(typeid(*input->At(0))),t2(typeid(*input->At(1)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0;
// Integer arifmetic
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(input->At(0))->Value() - dynamic_cast<const ObjectInt*>(input->At(1))->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(input->At(0))->Value();
else r1=dynamic_cast<const ObjectInt*>(input->At(0))->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(input->At(1))->Value();
else r2=dynamic_cast<const ObjectInt*>(input->At(1))->Value();
return new ObjectReal(r1-r2);
}
ObjectBase* Arifm_Mul(ObjectList* input)
{
if(input->Size()!=2) return 0;
std::type_index t1(typeid(*input->At(0))),t2(typeid(*input->At(1)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0;
// Integer arifmetic
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(input->At(0))->Value() * dynamic_cast<const ObjectInt*>(input->At(1))->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(input->At(0))->Value();
else r1=dynamic_cast<const ObjectInt*>(input->At(0))->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(input->At(1))->Value();
else r2=dynamic_cast<const ObjectInt*>(input->At(1))->Value();
return new ObjectReal(r1*r2);
}
ObjectBase* Arifm_Div(ObjectList* input)
{
if(input->Size()!=2) return 0;
std::type_index t1(typeid(*input->At(0))),t2(typeid(*input->At(1)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0;
// Integer arifmetic
if(t1==ti && t2==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(input->At(0))->Value() / dynamic_cast<const ObjectInt*>(input->At(1))->Value());
// Real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(input->At(0))->Value();
else r1=dynamic_cast<const ObjectInt*>(input->At(0))->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(input->At(1))->Value();
else r2=dynamic_cast<const ObjectInt*>(input->At(1))->Value();
return new ObjectReal(r1/r2);
}
ObjectBase* Arifm_Pow(ObjectList* input)
{
if(input->Size()!=2) return 0;
std::type_index t1(typeid(*input->At(0))),t2(typeid(*input->At(1)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
if( (t1!=tr && t1!=ti) || (t2!=tr && t2!=ti) ) return 0;
// Only real arifmetic
double r1,r2;
if(t1==tr) r1=dynamic_cast<const ObjectReal*>(input->At(0))->Value();
else r1=dynamic_cast<const ObjectInt*>(input->At(0))->Value();
if(t2==tr) r2=dynamic_cast<const ObjectReal*>(input->At(1))->Value();
else r2=dynamic_cast<const ObjectInt*>(input->At(1))->Value();
return new ObjectReal(pow(r1,r2));
}
ObjectBase* Arifm_Neg(ObjectList* input)
{
if(input->Size()!=1) return 0;
std::type_index t(typeid(*input->At(0)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
// Integer arifmetic
if(t==ti) return new ObjectInt(-dynamic_cast<const ObjectInt*>(input->At(0))->Value());
// Real arifmetic
if(t==tr) return new ObjectReal(-dynamic_cast<const ObjectReal*>(input->At(0))->Value());
return 0;
}
ObjectBase* Arifm_Pos(ObjectList* input)
{
if(input->Size()!=1) return 0;
std::type_index t(typeid(*input->At(0)));
std::type_index tr(typeid(ObjectReal)),ti(typeid(ObjectInt));
// Integer arifmetic
if(t==ti) return new ObjectInt(dynamic_cast<const ObjectInt*>(input->At(0))->Value());
// Real arifmetic
if(t==tr) return new ObjectReal(dynamic_cast<const ObjectReal*>(input->At(0))->Value());
return 0;
}

9
src/arifmetic.h

@ -0,0 +1,9 @@
#include "object.h"
ObjectBase* Arifm_Add(ObjectList* input);
ObjectBase* Arifm_Sub(ObjectList* input);
ObjectBase* Arifm_Mul(ObjectList* input);
ObjectBase* Arifm_Div(ObjectList* input);
ObjectBase* Arifm_Pow(ObjectList* input);
ObjectBase* Arifm_Neg(ObjectList* input);
ObjectBase* Arifm_Pos(ObjectList* input);

6
src/common.h

@ -0,0 +1,6 @@
#ifndef COMMON_H
#define COMMON_H
#define EXPORT __attribute__ ((visibility ("default")))
#endif

5
src/debug.h

@ -1,10 +1,13 @@
#ifndef DEBUG_H #ifndef DEBUG_H
#define DEBUG_H #define DEBUG_H
#include <iostream> #include <iostream>
#include "common.h"
enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,WARNING,ERROR}; enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,WARNING,ERROR};
std::ostream& COUT(debug_level dl); extern "C" {
EXPORT std::ostream& COUT(debug_level dl);
}
debug_level SetDebugLevel(debug_level dl=INTERNALREQUEST); debug_level SetDebugLevel(debug_level dl=INTERNALREQUEST);

5
src/globals.cpp

@ -22,3 +22,8 @@ void ClearGlobals()
G_tosave.clear(); G_tosave.clear();
G_toprint.clear(); G_toprint.clear();
} }
void RegisterFunction(const std::string& name, Func func)
{
G_funcs.emplace(name,func);
}

12
src/globals.h

@ -6,17 +6,21 @@
#include "object.h" #include "object.h"
// Variables definitions // Variables definitions
extern std::map<std::string,ObjectBase*> G_vars; extern EXPORT std::map<std::string,ObjectBase*> G_vars;
// Functions addresses // Functions addresses
typedef ObjectBase* (*Func)(ObjectList*); typedef ObjectBase* (*Func)(ObjectList*);
extern std::multimap<std::string,Func> G_funcs; extern EXPORT std::multimap<std::string,Func> G_funcs;
// List of objects to save // List of objects to save
extern std::list<ObjectBase*> G_tosave; extern EXPORT std::list<ObjectBase*> EXPORT G_tosave;
// List of objects to print // List of objects to print
extern std::list<ObjectBase*> G_toprint; extern EXPORT std::list<ObjectBase*> EXPORT G_toprint;
void ClearGlobals(); void ClearGlobals();
extern "C" {
EXPORT void RegisterFunction(const std::string& name, Func func);
}
#endif #endif

18
src/init.cpp

@ -2,6 +2,8 @@
#include "init.h" #include "init.h"
#include "debug.h" #include "debug.h"
#include "object.h" #include "object.h"
#include "globals.h"
#include "arifmetic.h"
#include "parser/parser.h" #include "parser/parser.h"
#include "parser/grammatical.h" #include "parser/grammatical.h"
#include "parser/lexical.h" #include "parser/lexical.h"
@ -11,6 +13,7 @@ int ParseConfigFile(char* config)
yyscan_t scanner; yyscan_t scanner;
struct lexical_extra extra; struct lexical_extra extra;
FILE* conffd; FILE* conffd;
int ret;
conffd=fopen(config,"r"); conffd=fopen(config,"r");
if(conffd==0) if(conffd==0)
@ -26,8 +29,21 @@ int ParseConfigFile(char* config)
conflex_init_extra(&extra,&scanner); conflex_init_extra(&extra,&scanner);
confset_in(conffd,scanner); confset_in(conffd,scanner);
// {YYSTYPE qqq; while(conflex(&qqq,scanner)>0);} // {YYSTYPE qqq; while(conflex(&qqq,scanner)>0);}
confparse(scanner); ret=confparse(scanner);
conflex_destroy(scanner); conflex_destroy(scanner);
fclose(conffd); fclose(conffd);
return ret;
}
int RegisterArifmeticFunctions()
{
RegisterFunction("ADD",Arifm_Add);
RegisterFunction("SUB",Arifm_Sub);
RegisterFunction("MUL",Arifm_Mul);
RegisterFunction("DIV",Arifm_Div);
RegisterFunction("POW",Arifm_Pow);
RegisterFunction("POS",Arifm_Pos);
RegisterFunction("NEG",Arifm_Neg);
return 0; return 0;
} }

1
src/init.h

@ -6,5 +6,6 @@ typedef void* yyscan_t;
#endif #endif
int ParseConfigFile(char* config); int ParseConfigFile(char* config);
int RegisterArifmeticFunctions();
#endif #endif

7
src/main.cpp

@ -5,10 +5,15 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if(argc!=2) return 1; if(argc!=2) return 1;
int ret;
SetDebugLevel(INFO); SetDebugLevel(INFO);
ParseConfigFile(argv[1]); COUT(INFO)<<"Parse config file "<<argv[1]<<" ";
ret=ParseConfigFile(argv[1]); if(ret!=0) return 1;
COUT(INFO)<<"Ok"<<std::endl;
RegisterArifmeticFunctions();
COUT(INFO)<<G_vars.size()<<std::endl; COUT(INFO)<<G_vars.size()<<std::endl;
for(auto& i: G_vars) COUT(INFO)<<i.first<<"="+i.second->Dump()<<";"<<std::endl; for(auto& i: G_vars) COUT(INFO)<<i.first<<"="+i.second->Dump()<<";"<<std::endl;

8
src/object.cpp

@ -1,6 +1,6 @@
#include "object.h" #include "object.h"
template<> std::string ObjectSimple<bool>::type="bool"; template<> EXPORT std::string ObjectSimple<bool>::type="bool";
template<> std::string ObjectSimple<int64_t>::type="integer"; template<> EXPORT std::string ObjectSimple<int64_t>::type="integer";
template<> std::string ObjectSimple<double>::type="real"; template<> EXPORT std::string ObjectSimple<double>::type="real";
template<> std::string ObjectSimple<std::string>::type="string"; template<> EXPORT std::string ObjectSimple<std::string>::type="string";

16
src/object.h

@ -4,7 +4,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <list> #include <vector>
#include <sstream> #include <sstream>
#include <typeinfo> #include <typeinfo>
#include <typeindex> #include <typeindex>
@ -14,7 +14,7 @@
#define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ))) #define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ)))
// Base class for all objects // Base class for all objects
class ObjectBase class EXPORT ObjectBase
{ {
protected: protected:
// No save by default // No save by default
@ -68,7 +68,7 @@ public:
// Template for objects without specific constructor/destructor // Template for objects without specific constructor/destructor
template<class T> template<class T>
class ObjectSimple: public ObjectBase class EXPORT ObjectSimple: public ObjectBase
{ {
private: private:
T val; T val;
@ -118,7 +118,7 @@ inline const int8_t* ObjectSimple<std::string>::Blob(size_t* size) const
} }
// Class for name-value pair // Class for name-value pair
class ObjectPair: public ObjectBase class EXPORT ObjectPair: public ObjectBase
{ {
private: private:
std::string name; std::string name;
@ -151,10 +151,10 @@ public:
}; };
// Class for objects list // Class for objects list
class ObjectList: public ObjectBase class EXPORT ObjectList: public ObjectBase
{ {
private: private:
std::list<ObjectBase*> vals; std::vector<ObjectBase*> vals;
public: public:
ObjectList() {} ObjectList() {}
@ -173,10 +173,10 @@ public:
COUT(INFO)<<"Number of elements: "<<Size()<<std::endl; COUT(INFO)<<"Number of elements: "<<Size()<<std::endl;
return true; return true;
} }
std::list<ObjectBase*>::size_type Size() const {return vals.size();} std::vector<ObjectBase*>::size_type Size() const {return vals.size();}
std::string Type() const override {return "list";} std::string Type() const override {return "list";}
ObjectList* PushFront(ObjectBase* p) {vals.push_front(p); return this;}
ObjectList* PushBack(ObjectBase* p) {vals.push_back(p); return this;} ObjectList* PushBack(ObjectBase* p) {vals.push_back(p); return this;}
const ObjectBase* At(std::vector<ObjectBase*>::size_type i) const {return vals[i];}
std::string Dump() const override std::string Dump() const override
{ {
std::string s("("); std::string s("(");

Loading…
Cancel
Save