Browse Source
1) Use plain representation of expressions instead of recursive objects. 2) Make G_tosave, G_toprint and G_vars local. 3) DepTree nodes contains expressions itself instead of references on global objects. 4) Location tracking of errors.ObjPtr
Michael Uleysky
8 years ago
13 changed files with 576 additions and 455 deletions
@ -1,84 +1,111 @@ |
|||||||
#ifndef OBJECT_H |
#ifndef OBJECT_H |
||||||
#define OBJECT_H |
#define OBJECT_H |
||||||
#include <stdio.h> |
|
||||||
#include <errno.h> |
#include <errno.h> |
||||||
#include <string.h> |
|
||||||
#include <inttypes.h> |
#include <inttypes.h> |
||||||
|
#include <stack> |
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
#include "common.h" |
#include "common.h" |
||||||
|
|
||||||
// Class for storing identifiers
|
// Bison location
|
||||||
class OId: public ObjectBase |
struct grammatic_location |
||||||
{ |
{ |
||||||
std::string name; |
struct incloc |
||||||
|
{ |
||||||
|
int line,column; |
||||||
|
std::string filename; |
||||||
|
}; |
||||||
|
int first_line; |
||||||
|
int first_column; |
||||||
|
int last_line; |
||||||
|
int last_column; |
||||||
|
std::list<struct incloc> incstack; |
||||||
|
std::string filename; |
||||||
|
}; |
||||||
|
|
||||||
|
class StackElem |
||||||
|
{ |
||||||
|
StackElem()=delete; |
||||||
|
StackElem(const StackElem&)=delete; |
||||||
public: |
public: |
||||||
OId(const std::string* t):name(*t) {} |
enum Type {TYPE_EMPTY,TYPE_BEGINLIST,TYPE_ENDLIST,TYPE_MKPAIR,TYPE_OBJECT,TYPE_VARIABLE,TYPE_FUNCTION}; |
||||||
~OId() {} |
StackElem(Type t, const struct grammatic_location& loc, const char* s=nullptr):type(t),obj(nullptr),location(loc) |
||||||
// Pure virtual overrides
|
|
||||||
ObjectBase* Copy() const override |
|
||||||
{ |
{ |
||||||
COUT(WARNING)<<"OId::Copy: this call must never be happens."<<std::endl; |
if(TYPE_BEGINLIST==t || TYPE_ENDLIST==t) return; |
||||||
return new OId(&name); |
if( (TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) && nullptr!=s) name=s; |
||||||
|
else type=TYPE_EMPTY; |
||||||
} |
} |
||||||
bool Print() const override {return false;} |
StackElem(Type t, const struct grammatic_location& loc, const std::string& s):type(t),obj(nullptr),location(loc) |
||||||
std::string Type() const override {return "IDENT";} |
|
||||||
|
|
||||||
// Non-default overrides
|
|
||||||
std::string Dump() const override {return name;}; |
|
||||||
ObjectBase* Evaluate(bool* err) override |
|
||||||
{ |
{ |
||||||
COUT(ERROR)<<"Variable "<<name<<" still not defined."<<std::endl; |
if(TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) name=s; |
||||||
*err=true; |
else type=TYPE_EMPTY; |
||||||
return 0; |
|
||||||
} |
} |
||||||
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override |
StackElem(ObjectBase* o, const struct grammatic_location& loc):type(TYPE_OBJECT),obj(o),location(loc) {} |
||||||
|
~StackElem() {if(TYPE_OBJECT==type) delete obj;} |
||||||
|
StackElem(StackElem&& s):type(s.type),name(s.name),location(s.location) |
||||||
{ |
{ |
||||||
if(vname==Name()) return ob->Copy(); |
if(TYPE_OBJECT==type) |
||||||
else return 0; |
{ |
||||||
|
// Simple copy of pointer
|
||||||
|
obj=s.obj; |
||||||
|
// Prevent destruction of ObjectBase in StackElem destructor
|
||||||
|
s.type=TYPE_EMPTY; |
||||||
|
} |
||||||
} |
} |
||||||
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
|
const ObjectBase* Object() const {return isObject()?obj:nullptr;} |
||||||
class OFunc: public ObjectBase |
// Detach object
|
||||||
{ |
ObjectBase* PickObject() |
||||||
std::string name; |
|
||||||
ObjectList* args; |
|
||||||
public: |
|
||||||
OFunc(const std::string* t, ObjectBase* p):name(*t) |
|
||||||
{ |
{ |
||||||
if(OBType<ObjectList>(p)) args=dynamic_cast<ObjectList*>(p); |
if(isObject()) |
||||||
else args=new ObjectList(p); |
|
||||||
} |
|
||||||
OFunc(const char* t, ObjectBase* p):name(t) |
|
||||||
{ |
{ |
||||||
if(OBType<ObjectList>(p)) args=dynamic_cast<ObjectList*>(p); |
type=TYPE_EMPTY; |
||||||
else args=new ObjectList(p); |
return obj; |
||||||
|
} |
||||||
|
else return nullptr; |
||||||
} |
} |
||||||
~OFunc() {if(args!=0) delete args;} |
bool ReplaceByObject(ObjectBase* ob) |
||||||
// Pure virtual overrides
|
|
||||||
ObjectBase* Copy() const override |
|
||||||
{ |
{ |
||||||
COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<<std::endl; |
if(isObject()) {delete ob; return false;} |
||||||
return new OFunc(&name,args->Copy()); |
type=TYPE_OBJECT; |
||||||
|
obj=ob; |
||||||
|
return true; |
||||||
} |
} |
||||||
bool Print() const override {return false;} |
std::string Name() const {return (isVar() || isFunc() || isMKPair())?name:std::string();} |
||||||
std::string Type() const override {return "FUNC";} |
bool isObject() const {return (TYPE_OBJECT==type);} |
||||||
|
bool isVar() const {return (TYPE_VARIABLE==type);} |
||||||
|
bool isFunc() const {return (TYPE_FUNCTION==type);} |
||||||
|
bool isBList() const {return (TYPE_BEGINLIST==type);} |
||||||
|
bool isEList() const {return (TYPE_ENDLIST==type);} |
||||||
|
bool isMKPair() const {return (TYPE_MKPAIR==type);} |
||||||
|
const struct grammatic_location& Location() const {return location;} |
||||||
|
Type T() const {return type;} |
||||||
|
|
||||||
// Non-default overrides
|
private: |
||||||
std::string Dump() const override {return Name()+args->Dump();}; |
Type type; |
||||||
ObjectBase* Evaluate(bool* err) override; |
ObjectBase* obj; |
||||||
ObjectBase* ReplaceVar(const std::string& vname, ObjectBase* ob) override {return args->ReplaceVar(vname,ob);} |
std::string name; |
||||||
void UsedFuncs(UsedType& funcs) const override {funcs.insert(name); args->UsedFuncs(funcs);} |
struct grammatic_location location; |
||||||
void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);} |
|
||||||
|
|
||||||
// Own functions
|
|
||||||
std::string Name() const {return name;} |
|
||||||
// void SetName(std::string s) {name=s;}
|
|
||||||
}; |
}; |
||||||
|
|
||||||
|
typedef std::list<StackElem> ExecExpr; |
||||||
|
|
||||||
|
inline StackElem SEBList(const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_BEGINLIST,loc);} |
||||||
|
inline StackElem SEEList(const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_ENDLIST,loc);} |
||||||
|
inline StackElem SEObj(ObjectBase* o, const struct grammatic_location& loc) {return StackElem(o,loc);} |
||||||
|
inline StackElem SEMKPair(const std::string& s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_MKPAIR,loc,s);} |
||||||
|
inline StackElem SEVar(const std::string& s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_VARIABLE,loc,s);} |
||||||
|
inline StackElem SEFunc(const std::string& s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_FUNCTION,loc,s);} |
||||||
|
inline StackElem SEMKPair(const std::string* s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_MKPAIR,loc,*s);} |
||||||
|
inline StackElem SEVar(const std::string* s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_VARIABLE,loc,*s);} |
||||||
|
inline StackElem SEFunc(const std::string* s, const struct grammatic_location& loc) {return StackElem(StackElem::TYPE_FUNCTION,loc,*s);} |
||||||
|
|
||||||
|
std::string DumpExprE(const ExecExpr& exp); |
||||||
|
std::string DumpExpr(const ExecExpr& exp); |
||||||
|
UsedType UsedVars(const ExecExpr& exp); |
||||||
|
UsedType UsedFuncs(const ExecExpr& exp); |
||||||
|
ObjectBase* Evaluate(ExecExpr& exp, bool* err); |
||||||
|
//inline void ReplaceVar(ExecExpr& exp, const std::string& var, ObjectBase* ob) {for(auto& se: exp) if(se.isVar() && var==se.Name()) se.ReplaceByObject(ob);}
|
||||||
|
void ReplaceVar(ExecExpr& exp, const std::string& var, const ObjectBase* ob);// {for(auto& se: exp) if(se.isVar() && var==se.Name()) se.ReplaceByObject(ob);}
|
||||||
|
|
||||||
#endif |
#endif |
||||||
|
Loading…
Reference in new issue