Browse Source

Rearrange code. common.h now have all api for modules.

test
Michael Uleysky 9 years ago
parent
commit
ef38fb1781
  1. 250
      src/common.h
  2. 19
      src/debug.cpp
  3. 8
      src/debug.h
  4. 148
      src/init.cpp
  5. 7
      src/init.h
  6. 2
      src/main.cpp
  7. 38
      src/object.cpp
  8. 314
      src/object.h
  9. 1
      src/parser/grammatical.y
  10. 2
      src/parser/lexical.l

250
src/common.h

@ -1,15 +1,261 @@
#ifndef COMMON_H #ifndef COMMON_H
#define COMMON_H #define COMMON_H
#include <iostream> #include <iostream>
#include <memory>
#include <set>
#include <string> #include <string>
#include <sstream>
#include <typeindex>
#include <typeinfo>
#include <vector>
#define EXPORT __attribute__ ((visibility ("default"))) #define EXPORT __attribute__ ((visibility ("default")))
enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,NORMAL,WARNING,ERROR}; enum debug_level {INTERNALREQUEST,MOREDEBUG,DEBUG,INFO,NORMAL,WARNING,ERROR};
EXPORT std::ostream& COUT(debug_level dl); EXPORT std::ostream& COUT(debug_level dl);
class ObjectBase; // Check if pointer is ObjectBase derivative class
class ObjectList; #define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ)))
#define IS_OTYPEI(quo,equ) (std::type_index(typeid(quo))==std::type_index(typeid(equ)))
typedef std::set<std::string> UsedType;
// Base class for all objects
class EXPORT ObjectBase
{
protected:
// No save by default
virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; }
virtual void DeallocBlob(const void* ptr) const {};
public:
ObjectBase() = default;
ObjectBase(const ObjectBase&) = delete;
bool Save(const char* fname) const;
// Pure virtual api
virtual ~ObjectBase(){}
virtual ObjectBase* Copy() const=0;
virtual bool Print() const=0;
virtual std::string Type() const=0;
// Virtual api with default functions. Modules types must not override them.
virtual std::string Dump() const {return "%"+Type()+"%";}
virtual ObjectBase* Evaluate(bool* err) {*err=false; return 0;}
virtual ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) {return 0;}
virtual void UsedFuncs(UsedType& funcs) const {}
virtual void UsedIdents(UsedType& ids) const {}
};
// Template for objects without specific constructor/destructor
template<class T>
class EXPORT ObjectSimple: public ObjectBase
{
private:
T val;
static std::string type;
const int8_t* Blob(size_t* size) const override {*size=sizeof(T); return reinterpret_cast<const int8_t*>(&val);}
public:
ObjectSimple(T t):val(t) {}
ObjectSimple(const T* t):val(*t) {}
~ObjectSimple() {}
// Pure virtual overrides
ObjectBase* Copy() const override {return new ObjectSimple<T>(val);}
bool Print() const override
{
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Value: "<<val<<std::endl;
return true;
}
std::string Type() const override {return type;}
// Non-default overrides
std::string Dump() const override
{
std::stringstream s;
if(std::type_index(typeid(T))==std::type_index(typeid(std::string)))
s<<"\""<<val<<"\"";
else
s<<val;
return s.str();
}
// Own functions
T Value() const {return val;}
void SetValue(T s) {val=s;}
};
// Simple objects
typedef ObjectSimple<bool> ObjectBool;
typedef ObjectSimple<int64_t> ObjectInt;
typedef ObjectSimple<double> ObjectReal;
typedef ObjectSimple<std::string> ObjectString;
template<>
inline const int8_t* ObjectString::Blob(size_t* size) const
{
*size=val.length();
return reinterpret_cast<const int8_t*>(val.c_str());
}
// Class for name-value pair
class EXPORT ObjectPair: public ObjectBase
{
private:
std::string name;
std::shared_ptr<ObjectBase> val;
public:
ObjectPair() {}
ObjectPair(const std::string& n, ObjectBase* v):name(n) {val.reset(v);}
ObjectPair(const std::string* n, ObjectBase* v):name(*n) {val.reset(v);}
~ObjectPair() {}
// Pure virtual overrides
ObjectBase* Copy() const override
{
auto ret=new ObjectPair;
ret->name=name; ret->val=val;
return ret;
}
bool Print() const override
{
if(!Exist()) return false;
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Name is: "<<Name()<<std::endl;
COUT(NORMAL)<<"Value type: "<<val->Type()<<std::endl;
return true;
}
std::string Type() const override {return "pair";}
// Non-default overrides
std::string Dump() const override { return Name()+"="+val->Dump(); }
ObjectBase* Evaluate(bool* err) override
{
auto p=val->Evaluate(err);
if(*err)
{
COUT(ERROR)<<" in pair "<<Dump()<<std::endl;
return 0;
}
if(0==p) return 0;
val.reset(p);
return 0;
}
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override
{
auto p=val->ReplaceVar(vname,ob);
if(0!=p) val.reset(p);
return 0;
}
void UsedFuncs(UsedType& funcs) const override {return val->UsedFuncs(funcs);}
void UsedIdents(UsedType& ids) const override {return val->UsedIdents(ids);}
// Own functions
bool Exist() const {return 0!=val.get();}
ObjectBase* Get(const std::string& gname) const
{
if(gname==name) return val->Copy();
else return 0;
}
std::string Name() const {return name;}
void SetPair(const std::string& n, ObjectBase* v) {if(!Exist()) {name=n; val.reset(v);}}
const ObjectBase* Value() const {return val.get();}
};
// Class for objects list
class EXPORT ObjectList: public ObjectBase
{
public:
typedef std::vector<ObjectBase*> ListValues;
private:
std::shared_ptr<ListValues> vals;
public:
ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});}
ObjectList(ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);}
~ObjectList() {}
// Pure virtual overrides
ObjectBase* Copy() const override
{
auto ret=new ObjectList;
ret->vals=vals;
return ret;
}
bool Print() const override
{
if(!Exist()) return false;
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Number of elements: "<<Size()<<std::endl;
return true;
}
std::string Type() const override {return "list";}
// Non-default overrides
std::string Dump() const override
{
std::string s("(");
for(auto& i: *vals) s+=i->Dump()+", ";
if(vals->size()!=0) s.resize(s.length()-2);
return s+")";
}
ObjectBase* Evaluate(bool* err) override
{
ObjectBase* p;
for(auto& i: *vals)
{
p=i->Evaluate(err);
if(*err)
{
COUT(ERROR)<<" in list member "<<i->Dump()<<std::endl;
return 0;
}
if(0!=p)
{
delete i;
i=p;
}
}
return 0;
}
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override
{
ObjectBase* p;
for(auto& i: *vals)
{
p=i->ReplaceVar(vname,ob);
if(0!=p)
{
delete i;
i=p;
}
}
return 0;
}
void UsedFuncs(UsedType& funcs) const override {for(auto& i: *vals) i->UsedFuncs(funcs);}
void UsedIdents(UsedType& ids) const override {for(auto& i: *vals) i->UsedIdents(ids);}
// Own functions
const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];}
bool Exist() const {return 0!=vals->size();}
ObjectBase* Get(const std::string& gname) const
{
ObjectBase* p;
for(auto& i: *vals)
{
p=0;
if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast<const ObjectPair*>(i)->Get(gname);
if(0!=p) return p;
if(IS_OTYPE(i,ObjectList)) p=dynamic_cast<const ObjectList*>(i)->Get(gname);
if(0!=p) return p;
}
return 0;
}
ListValues::size_type Size() const {return vals->size();}
ObjectList* PushBack(ObjectBase* p) {vals->push_back(p); return this;}
};
typedef ObjectBase* (*Func)(ObjectList*); typedef ObjectBase* (*Func)(ObjectList*);
extern "C" { extern "C" {

19
src/debug.cpp

@ -1,19 +0,0 @@
#include <iostream>
#include "debug.h"
std::ostream& COUT(debug_level dl)
{
if(dl==ERROR) return std::cerr;
if(dl>=SetDebugLevel(INTERNALREQUEST)) std::cout.clear();
else std::cout.setstate(std::cout.failbit);
return std::cout;
}
debug_level SetDebugLevel(debug_level dl)
{
static debug_level DEBUG_LEVEL=INFO;
if(dl==INTERNALREQUEST) return DEBUG_LEVEL;
debug_level s=DEBUG_LEVEL;
DEBUG_LEVEL=dl;
return s;
}

8
src/debug.h

@ -1,8 +0,0 @@
#ifndef DEBUG_H
#define DEBUG_H
#include <iostream>
#include "common.h"
debug_level SetDebugLevel(debug_level dl=INTERNALREQUEST);
#endif

148
src/init.cpp

@ -1,6 +1,5 @@
#include <inttypes.h> #include <inttypes.h>
#include "init.h" #include "init.h"
#include "debug.h"
#include "object.h" #include "object.h"
#include "globals.h" #include "globals.h"
#include "builtin.h" #include "builtin.h"
@ -18,34 +17,58 @@ typedef void* yyscan_t;
#undef YYSTYPE #undef YYSTYPE
#undef YYLTYPE #undef YYLTYPE
int BuildDepTree(DepTree* deptree, UsedType& used) {return deptree->CreateGlobalTree(used);}
int ParseOptions(int argc, char** argv, struct program_options& options)
int CheckFunctions()
{ {
int opt=0; UsedType funcs;
const char* optstr="t:hdgiq";
optind=1; for(auto& i:G_tosave)
do
{ {
opt=getopt(argc,argv,optstr); i->UsedFuncs(funcs);
switch(opt) for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end())
{ {
case(-1): break; COUT(ERROR)<<"Unknown function "<<f<<" in directive save"<<i->Dump()<<std::endl;
case('t'):{options.threads=atoi(optarg); if(options.threads<1) return 1; else break;} return 1;
case('h'):{options.help=true; break;}
case('d'):{options.dump=true; break;}
case('g'):{options.dl=DEBUG; break;}
case('i'):{options.dl=INFO; break;}
case('q'):{options.dl=WARNING; break;}
default: return 1;
} }
} while(-1!=opt); funcs.clear();
if(optind!=argc-1) return 1; }
options.config=argv[optind];
for(auto& i:G_toprint)
{
i->UsedFuncs(funcs);
for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end())
{
COUT(ERROR)<<"Unknown function "<<f<<" in directive print"<<i->Dump()<<std::endl;
return 1;
}
funcs.clear();
}
for(auto& i:G_vars)
{
i.second->UsedFuncs(funcs);
for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end())
{
COUT(ERROR)<<"Unknown function "<<f<<" in definition of variable "<<i.first<<std::endl;
return 1;
}
funcs.clear();
}
return 0; return 0;
} }
void DumpConfig()
{
for(auto& i: G_vars) COUT(NORMAL)<<i.first<<"="+i.second->Dump()<<";"<<std::endl;
for(auto& i: G_tosave) COUT(NORMAL)<<"save"<<i->Dump()<<";"<<std::endl;
for(auto& i: G_toprint) COUT(NORMAL)<<"print"<<i->Dump()<<";"<<std::endl;
}
int ParseConfigFile(const char* config) int ParseConfigFile(const char* config)
{ {
yyscan_t scanner; yyscan_t scanner;
@ -80,6 +103,33 @@ int ParseConfigFile(const char* config)
} }
int ParseOptions(int argc, char** argv, struct program_options& options)
{
int opt=0;
const char* optstr="t:hdgiq";
optind=1;
do
{
opt=getopt(argc,argv,optstr);
switch(opt)
{
case(-1): break;
case('t'):{options.threads=atoi(optarg); if(options.threads<1) return 1; else break;}
case('h'):{options.help=true; break;}
case('d'):{options.dump=true; break;}
case('g'):{options.dl=DEBUG; break;}
case('i'):{options.dl=INFO; break;}
case('q'):{options.dl=WARNING; break;}
default: return 1;
}
} while(-1!=opt);
if(optind!=argc-1) return 1;
options.config=argv[optind];
return 0;
}
int RegisterBuiltinFunctions() int RegisterBuiltinFunctions()
{ {
RegisterFunction("ADD",Arifm_Add); RegisterFunction("ADD",Arifm_Add);
@ -96,56 +146,20 @@ int RegisterBuiltinFunctions()
} }
int BuildDepTree(DepTree* deptree, UsedType& used) debug_level SetDebugLevel(debug_level dl)
{
return deptree->CreateGlobalTree(used);
}
int CheckFunctions()
{ {
UsedType funcs; static debug_level DEBUG_LEVEL=INFO;
if(dl==INTERNALREQUEST) return DEBUG_LEVEL;
for(auto& i:G_tosave) debug_level s=DEBUG_LEVEL;
{ DEBUG_LEVEL=dl;
i->UsedFuncs(funcs); return s;
for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end())
{
COUT(ERROR)<<"Unknown function "<<f<<" in directive save"<<i->Dump()<<std::endl;
return 1;
}
funcs.clear();
}
for(auto& i:G_toprint)
{
i->UsedFuncs(funcs);
for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end())
{
COUT(ERROR)<<"Unknown function "<<f<<" in directive print"<<i->Dump()<<std::endl;
return 1;
}
funcs.clear();
}
for(auto& i:G_vars)
{
i.second->UsedFuncs(funcs);
for(auto& f:funcs) if(G_funcs.find(f)==G_funcs.end())
{
COUT(ERROR)<<"Unknown function "<<f<<" in definition of variable "<<i.first<<std::endl;
return 1;
}
funcs.clear();
}
return 0;
} }
void DumpConfig() std::ostream& COUT(debug_level dl)
{ {
for(auto& i: G_vars) COUT(NORMAL)<<i.first<<"="+i.second->Dump()<<";"<<std::endl; if(dl==ERROR) return std::cerr;
for(auto& i: G_tosave) COUT(NORMAL)<<"save"<<i->Dump()<<";"<<std::endl; if(dl>=SetDebugLevel(INTERNALREQUEST)) std::cout.clear();
for(auto& i: G_toprint) COUT(NORMAL)<<"print"<<i->Dump()<<";"<<std::endl; else std::cout.setstate(std::cout.failbit);
} return std::cout;
}

7
src/init.h

@ -10,11 +10,12 @@ struct program_options
const char* config; const char* config;
}; };
int ParseOptions(int argc, char** argv, struct program_options& options);
int ParseConfigFile(const char* config);
int RegisterBuiltinFunctions();
int BuildDepTree(DepTree* deptree, UsedType& used); int BuildDepTree(DepTree* deptree, UsedType& used);
int CheckFunctions(); int CheckFunctions();
void DumpConfig(); void DumpConfig();
int ParseConfigFile(const char* config);
int ParseOptions(int argc, char** argv, struct program_options& options);
int RegisterBuiltinFunctions();
debug_level SetDebugLevel(debug_level dl=INTERNALREQUEST);
#endif #endif

2
src/main.cpp

@ -1,6 +1,4 @@
#include "debug.h"
#include "init.h" #include "init.h"
#include "globals.h"
static void usage(const char* prg) static void usage(const char* prg)
{ {

38
src/object.cpp

@ -6,6 +6,44 @@ template<> EXPORT std::string ObjectSimple<int64_t>::type="integer";
template<> EXPORT std::string ObjectSimple<double>::type="real"; template<> EXPORT std::string ObjectSimple<double>::type="real";
template<> EXPORT std::string ObjectSimple<std::string>::type="string"; template<> EXPORT std::string ObjectSimple<std::string>::type="string";
bool ObjectBase::Save(const char* fname) const
{
size_t size,offset=0,wr;
const int8_t* dptr;
FILE* fd;
int serrno;
fd=fopen(fname,"w");
serrno=errno;
if(0==fd)
{
COUT(ERROR)<<"Can't open file "<<fname<<" for writing: "<<strerror(serrno)<<std::endl;
return false;
}
dptr=Blob(&size);
if(0==dptr)
{
COUT(ERROR)<<"Can't get blob for writing to "<<fname<<std::endl;
fclose(fd);
return false;
}
while(offset!=size)
{
wr=fwrite(dptr+offset,1,size-offset,fd);
if(0==wr)
{
COUT(ERROR)<<"Failed to write in file "<<fname<<std::endl;
fclose(fd); DeallocBlob(dptr);
return false;
}
offset+=wr;
}
fclose(fd);
DeallocBlob(dptr);
return true;
}
ObjectBase* OFunc::Evaluate(bool* err) ObjectBase* OFunc::Evaluate(bool* err)
{ {
*err=false; *err=false;

314
src/object.h

@ -4,278 +4,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <vector> #include "common.h"
#include <sstream>
#include <set>
#include <memory>
#include <typeinfo>
#include <typeindex>
#include "debug.h"
// Check if pointer is ObjectBase derivative class
#define IS_OTYPE(quo,equ) (std::type_index(typeid(*quo))==std::type_index(typeid(equ)))
#define IS_OTYPEI(quo,equ) (std::type_index(typeid(quo))==std::type_index(typeid(equ)))
typedef std::set<std::string> UsedType;
// Base class for all objects
class EXPORT ObjectBase
{
protected:
// No save by default
virtual const int8_t* Blob(size_t* size) const { *size=0; return 0; }
virtual void DeallocBlob(const void* ptr) const {};
public:
ObjectBase() = default;
ObjectBase(const ObjectBase&) = delete;
virtual ~ObjectBase(){}
virtual std::string Type() const=0;
virtual bool Print() const=0;
bool Save(const char* fname) const
{
size_t size,offset=0,wr;
const int8_t* dptr;
FILE* fd;
int serrno;
fd=fopen(fname,"w");
serrno=errno;
if(0==fd)
{
COUT(ERROR)<<"Can't open file "<<fname<<" for writing: "<<strerror(serrno)<<std::endl;
return false;
}
dptr=Blob(&size);
if(0==dptr)
{
COUT(ERROR)<<"Can't get blob for writing to "<<fname<<std::endl;
fclose(fd);
return false;
}
while(offset!=size)
{
wr=fwrite(dptr+offset,1,size-offset,fd);
if(0==wr)
{
COUT(ERROR)<<"Failed to write in file "<<fname<<std::endl;
fclose(fd); DeallocBlob(dptr);
return false;
}
offset+=wr;
}
fclose(fd);
DeallocBlob(dptr);
return true;
}
virtual std::string Dump() const {return "%"+Type()+"%";}
virtual void UsedFuncs(UsedType& funcs) const {}
virtual void UsedIdents(UsedType& ids) const {}
virtual ObjectBase* Copy() const=0;
virtual ObjectBase* Evaluate(bool* err) {*err=false; return 0;}
virtual ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) {return 0;}
};
// Template for objects without specific constructor/destructor
template<class T>
class EXPORT ObjectSimple: public ObjectBase
{
private:
T val;
static std::string type;
const int8_t* Blob(size_t* size) const override
{
*size=sizeof(T);
return reinterpret_cast<const int8_t*>(&val);
}
public:
ObjectSimple(T t):val(t) {}
ObjectSimple(const T* t):val(*t) {}
~ObjectSimple() {}
bool Print() const override
{
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Value: "<<val<<std::endl;
return true;
}
std::string Type() const override {return type;}
T Value() const {return val;}
void SetValue(T s) {val=s;}
std::string Dump() const override
{
std::stringstream s;
if(std::type_index(typeid(T))==std::type_index(typeid(std::string)))
s<<"\""<<val<<"\"";
else
s<<val;
return s.str();
}
ObjectBase* Copy() const override {return new ObjectSimple<T>(val);}
};
// Simple objects
typedef ObjectSimple<bool> ObjectBool;
typedef ObjectSimple<int64_t> ObjectInt;
typedef ObjectSimple<double> ObjectReal;
typedef ObjectSimple<std::string> ObjectString;
template<>
inline const int8_t* ObjectString::Blob(size_t* size) const
{
*size=val.length();
return reinterpret_cast<const int8_t*>(val.c_str());
}
// Class for name-value pair
class EXPORT ObjectPair: public ObjectBase
{
private:
std::string name;
std::shared_ptr<ObjectBase> val;
public:
ObjectPair() {}
ObjectPair(const std::string& n, ObjectBase* v):name(n) {val.reset(v);}
ObjectPair(const std::string* n, ObjectBase* v):name(*n) {val.reset(v);}
~ObjectPair() {}
bool Exist() const {return 0!=val.get();}
bool Print() const override
{
if(!Exist()) return false;
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Name is: "<<Name()<<std::endl;
COUT(NORMAL)<<"Value type: "<<val->Type()<<std::endl;
return true;
}
std::string Type() const override {return "pair";}
std::string Name() const {return name;}
const ObjectBase* Value() const {return val.get();}
void SetPair(const std::string& n, ObjectBase* v) {if(!Exist()) {name=n; val.reset(v);}}
std::string Dump() const override { return Name()+"="+val->Dump(); }
void UsedFuncs(UsedType& funcs) const override {return val->UsedFuncs(funcs);}
void UsedIdents(UsedType& ids) const override {return val->UsedIdents(ids);}
ObjectBase* Copy() const override
{
auto ret=new ObjectPair;
ret->name=name;
ret->val=val;
return ret;
}
ObjectBase* Evaluate(bool* err) override
{
auto p=val->Evaluate(err);
if(*err)
{
COUT(ERROR)<<" in pair "<<Dump()<<std::endl;
return 0;
}
if(0==p) return 0;
val.reset(p);
return 0;
}
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override
{
auto p=val->ReplaceVar(vname,ob);
if(0!=p) val.reset(p);
return 0;
}
ObjectBase* Get(const std::string& gname) const
{
if(gname==name) return val->Copy();
else return 0;
}
};
// Class for objects list
class EXPORT ObjectList: public ObjectBase
{
public:
typedef std::vector<ObjectBase*> ListValues;
private:
std::shared_ptr<ListValues> vals;
public:
ObjectList() {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;});}
ObjectList(ObjectBase* o) {vals.reset(new ListValues, [](ListValues* p){for(auto& i: *p) delete i; delete p;}); PushBack(o);}
~ObjectList() {}
bool Exist() const {return 0!=vals->size();}
bool Print() const override
{
if(!Exist()) return false;
COUT(NORMAL)<<std::endl<<"Object type: "<<Type()<<std::endl;
COUT(NORMAL)<<"Number of elements: "<<Size()<<std::endl;
return true;
}
ListValues::size_type Size() const {return vals->size();}
std::string Type() const override {return "list";}
ObjectList* PushBack(ObjectBase* p) {vals->push_back(p); return this;}
const ObjectBase* At(ListValues::size_type i) const {return (*vals)[i];}
std::string Dump() const override
{
std::string s("(");
for(auto& i: *vals) s+=i->Dump()+", ";
if(vals->size()!=0) s.resize(s.length()-2);
return s+")";
}
void UsedFuncs(UsedType& funcs) const override {for(auto& i: *vals) i->UsedFuncs(funcs);}
void UsedIdents(UsedType& ids) const override {for(auto& i: *vals) i->UsedIdents(ids);}
ObjectBase* Copy() const override
{
auto ret=new ObjectList;
ret->vals=vals;
return ret;
}
ObjectBase* Evaluate(bool* err) override
{
ObjectBase* p;
for(auto& i: *vals)
{
p=i->Evaluate(err);
if(*err)
{
COUT(ERROR)<<" in list member "<<i->Dump()<<std::endl;
return 0;
}
if(0!=p)
{
delete i;
i=p;
}
}
return 0;
}
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override
{
ObjectBase* p;
for(auto& i: *vals)
{
p=i->ReplaceVar(vname,ob);
if(0!=p)
{
delete i;
i=p;
}
}
return 0;
}
ObjectBase* Get(const std::string& gname) const
{
ObjectBase* p;
for(auto& i: *vals)
{
p=0;
if(IS_OTYPE(i,ObjectPair)) p=dynamic_cast<const ObjectPair*>(i)->Get(gname);
if(0!=p) return p;
if(IS_OTYPE(i,ObjectList)) p=dynamic_cast<const ObjectList*>(i)->Get(gname);
if(0!=p) return p;
}
return 0;
}
};
// Class for storing identifiers // Class for storing identifiers
class OId: public ObjectBase class OId: public ObjectBase
@ -285,17 +14,17 @@ class OId: public ObjectBase
public: public:
OId(const std::string* t):name(*t) {} OId(const std::string* t):name(*t) {}
~OId() {} ~OId() {}
bool Print() const override {return false;} // Pure virtual overrides
std::string Type() const override {return "IDENT";}
std::string Name() const {return name;}
void SetName(const std::string& s) {name=s;}
std::string Dump() const override {return name;};
void UsedIdents(UsedType& ids) const override {ids.insert(name);}
ObjectBase* Copy() const override ObjectBase* Copy() const override
{ {
COUT(WARNING)<<"OId::Copy: this call must never be happens."<<std::endl; COUT(WARNING)<<"OId::Copy: this call must never be happens."<<std::endl;
return new OId(&name); return new OId(&name);
} }
bool Print() const override {return false;}
std::string Type() const override {return "IDENT";}
// Non-default overrides
std::string Dump() const override {return name;};
ObjectBase* Evaluate(bool* err) override ObjectBase* Evaluate(bool* err) override
{ {
COUT(ERROR)<<"Variable "<<name<<" still not defined."<<std::endl; COUT(ERROR)<<"Variable "<<name<<" still not defined."<<std::endl;
@ -307,6 +36,11 @@ public:
if(vname==Name()) return ob->Copy(); if(vname==Name()) return ob->Copy();
else return 0; else return 0;
} }
void UsedIdents(UsedType& ids) const override {ids.insert(name);}
// Own functions
std::string Name() const {return name;}
// void SetName(const std::string& s) {name=s;}
}; };
// Class for storing functions // Class for storing functions
@ -326,23 +60,25 @@ public:
else args=new ObjectList(p); else args=new ObjectList(p);
} }
~OFunc() {if(args!=0) delete args;} ~OFunc() {if(args!=0) delete args;}
bool Print() const override {return false;} // Pure virtual overrides
std::string Type() const override {return "FUNC";}
std::string Name() const {return name;}
void SetName(std::string s) {name=s;}
std::string Dump() const override {return Name()+args->Dump();};
void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);}
void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);}
ObjectBase* Copy() const override ObjectBase* Copy() const override
{ {
COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<<std::endl; COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<<std::endl;
return new OFunc(&name,args->Copy()); return new OFunc(&name,args->Copy());
} }
bool Print() const override {return false;}
std::string Type() const override {return "FUNC";}
// Non-default overrides
std::string Dump() const override {return Name()+args->Dump();};
ObjectBase* Evaluate(bool* err) override; ObjectBase* Evaluate(bool* err) override;
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override {return args->ReplaceVar(vname,ob);}
{ void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);}
return args->ReplaceVar(vname,ob); void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);}
}
// Own functions
std::string Name() const {return name;}
// void SetName(std::string s) {name=s;}
}; };
#endif #endif

1
src/parser/grammatical.y

@ -18,7 +18,6 @@
#include <inttypes.h> #include <inttypes.h>
#include <algorithm> #include <algorithm>
#include "parser.h" #include "parser.h"
#include "../debug.h"
#include "../object.h" #include "../object.h"
#include "../globals.h" #include "../globals.h"
// We can't include lexical.h before grammatical.h, because of strange errors, but grammatical.h only needs definition of yyscan_t // We can't include lexical.h before grammatical.h, because of strange errors, but grammatical.h only needs definition of yyscan_t

2
src/parser/lexical.l

@ -15,7 +15,7 @@
%x INCLUDE %x INCLUDE
%{ %{
#include "../debug.h" #include "../common.h"
#include "parser.h" #include "parser.h"
// flex use register keyword, but it deprecated in C++11. // flex use register keyword, but it deprecated in C++11.
#define register #define register

Loading…
Cancel
Save