diff --git a/src/Makefile b/src/Makefile index 5f3b9bc..c1cbf73 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ -CFLAGS=-O2 -g -std=gnu++11 -LDFLAGS= +CFLAGS=-O2 -g -std=gnu++11 -fvisibility=hidden -fpic +LDFLAGS=-fvisibility=hidden -Wl,--export-dynamic -fpic CC=g++ diff --git a/src/arifmetic.cpp b/src/arifmetic.cpp new file mode 100644 index 0000000..ba34354 --- /dev/null +++ b/src/arifmetic.cpp @@ -0,0 +1,148 @@ +#include +#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(input->At(0))->Value() + dynamic_cast(input->At(1))->Value()); + + // Real arifmetic + double r1,r2; + + if(t1==tr) r1=dynamic_cast(input->At(0))->Value(); + else r1=dynamic_cast(input->At(0))->Value(); + + if(t2==tr) r2=dynamic_cast(input->At(1))->Value(); + else r2=dynamic_cast(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(input->At(0))->Value() - dynamic_cast(input->At(1))->Value()); + + // Real arifmetic + double r1,r2; + + if(t1==tr) r1=dynamic_cast(input->At(0))->Value(); + else r1=dynamic_cast(input->At(0))->Value(); + + if(t2==tr) r2=dynamic_cast(input->At(1))->Value(); + else r2=dynamic_cast(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(input->At(0))->Value() * dynamic_cast(input->At(1))->Value()); + + // Real arifmetic + double r1,r2; + + if(t1==tr) r1=dynamic_cast(input->At(0))->Value(); + else r1=dynamic_cast(input->At(0))->Value(); + + if(t2==tr) r2=dynamic_cast(input->At(1))->Value(); + else r2=dynamic_cast(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(input->At(0))->Value() / dynamic_cast(input->At(1))->Value()); + + // Real arifmetic + double r1,r2; + + if(t1==tr) r1=dynamic_cast(input->At(0))->Value(); + else r1=dynamic_cast(input->At(0))->Value(); + + if(t2==tr) r2=dynamic_cast(input->At(1))->Value(); + else r2=dynamic_cast(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(input->At(0))->Value(); + else r1=dynamic_cast(input->At(0))->Value(); + + if(t2==tr) r2=dynamic_cast(input->At(1))->Value(); + else r2=dynamic_cast(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(input->At(0))->Value()); + // Real arifmetic + if(t==tr) return new ObjectReal(-dynamic_cast(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(input->At(0))->Value()); + // Real arifmetic + if(t==tr) return new ObjectReal(dynamic_cast(input->At(0))->Value()); + + return 0; +} \ No newline at end of file diff --git a/src/arifmetic.h b/src/arifmetic.h new file mode 100644 index 0000000..9fd4b5c --- /dev/null +++ b/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); \ No newline at end of file diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..6e7b27e --- /dev/null +++ b/src/common.h @@ -0,0 +1,6 @@ +#ifndef COMMON_H +#define COMMON_H + +#define EXPORT __attribute__ ((visibility ("default"))) + +#endif \ No newline at end of file diff --git a/src/debug.h b/src/debug.h index b5f6896..76803b4 100644 --- a/src/debug.h +++ b/src/debug.h @@ -1,10 +1,13 @@ #ifndef DEBUG_H #define DEBUG_H #include +#include "common.h" 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); diff --git a/src/globals.cpp b/src/globals.cpp index c5031db..47d79e4 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -22,3 +22,8 @@ void ClearGlobals() G_tosave.clear(); G_toprint.clear(); } + +void RegisterFunction(const std::string& name, Func func) +{ + G_funcs.emplace(name,func); +} \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index c468ec9..76c296a 100644 --- a/src/globals.h +++ b/src/globals.h @@ -6,17 +6,21 @@ #include "object.h" // Variables definitions -extern std::map G_vars; +extern EXPORT std::map G_vars; // Functions addresses typedef ObjectBase* (*Func)(ObjectList*); -extern std::multimap G_funcs; +extern EXPORT std::multimap G_funcs; // List of objects to save -extern std::list G_tosave; +extern EXPORT std::list EXPORT G_tosave; // List of objects to print -extern std::list G_toprint; +extern EXPORT std::list EXPORT G_toprint; void ClearGlobals(); + +extern "C" { +EXPORT void RegisterFunction(const std::string& name, Func func); +} #endif diff --git a/src/init.cpp b/src/init.cpp index 11d57e3..4a7ae58 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2,6 +2,8 @@ #include "init.h" #include "debug.h" #include "object.h" +#include "globals.h" +#include "arifmetic.h" #include "parser/parser.h" #include "parser/grammatical.h" #include "parser/lexical.h" @@ -11,6 +13,7 @@ int ParseConfigFile(char* config) yyscan_t scanner; struct lexical_extra extra; FILE* conffd; + int ret; conffd=fopen(config,"r"); if(conffd==0) @@ -26,8 +29,21 @@ int ParseConfigFile(char* config) conflex_init_extra(&extra,&scanner); confset_in(conffd,scanner); // {YYSTYPE qqq; while(conflex(&qqq,scanner)>0);} - confparse(scanner); + ret=confparse(scanner); conflex_destroy(scanner); 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; } diff --git a/src/init.h b/src/init.h index 539ba37..10b2e51 100644 --- a/src/init.h +++ b/src/init.h @@ -6,5 +6,6 @@ typedef void* yyscan_t; #endif int ParseConfigFile(char* config); +int RegisterArifmeticFunctions(); #endif diff --git a/src/main.cpp b/src/main.cpp index ea540b1..3efaf9f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,10 +5,15 @@ int main(int argc, char** argv) { if(argc!=2) return 1; + int ret; SetDebugLevel(INFO); - ParseConfigFile(argv[1]); + COUT(INFO)<<"Parse config file "< std::string ObjectSimple::type="bool"; -template<> std::string ObjectSimple::type="integer"; -template<> std::string ObjectSimple::type="real"; -template<> std::string ObjectSimple::type="string"; +template<> EXPORT std::string ObjectSimple::type="bool"; +template<> EXPORT std::string ObjectSimple::type="integer"; +template<> EXPORT std::string ObjectSimple::type="real"; +template<> EXPORT std::string ObjectSimple::type="string"; diff --git a/src/object.h b/src/object.h index 7ce27ee..bde6f5d 100644 --- a/src/object.h +++ b/src/object.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ #define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ))) // Base class for all objects -class ObjectBase +class EXPORT ObjectBase { protected: // No save by default @@ -68,7 +68,7 @@ public: // Template for objects without specific constructor/destructor template -class ObjectSimple: public ObjectBase +class EXPORT ObjectSimple: public ObjectBase { private: T val; @@ -118,7 +118,7 @@ inline const int8_t* ObjectSimple::Blob(size_t* size) const } // Class for name-value pair -class ObjectPair: public ObjectBase +class EXPORT ObjectPair: public ObjectBase { private: std::string name; @@ -151,10 +151,10 @@ public: }; // Class for objects list -class ObjectList: public ObjectBase +class EXPORT ObjectList: public ObjectBase { private: - std::list vals; + std::vector vals; public: ObjectList() {} @@ -173,10 +173,10 @@ public: COUT(INFO)<<"Number of elements: "<::size_type Size() const {return vals.size();} + std::vector::size_type Size() const {return vals.size();} 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;} + const ObjectBase* At(std::vector::size_type i) const {return vals[i];} std::string Dump() const override { std::string s("(");