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 |
||||
#define OBJECT_H |
||||
#include <stdio.h> |
||||
#include <errno.h> |
||||
#include <string.h> |
||||
#include <inttypes.h> |
||||
#include <stack> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include "common.h" |
||||
|
||||
// Class for storing identifiers
|
||||
class OId: public ObjectBase |
||||
// Bison location
|
||||
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: |
||||
OId(const std::string* t):name(*t) {} |
||||
~OId() {} |
||||
// Pure virtual overrides
|
||||
ObjectBase* Copy() const override |
||||
enum Type {TYPE_EMPTY,TYPE_BEGINLIST,TYPE_ENDLIST,TYPE_MKPAIR,TYPE_OBJECT,TYPE_VARIABLE,TYPE_FUNCTION}; |
||||
StackElem(Type t, const struct grammatic_location& loc, const char* s=nullptr):type(t),obj(nullptr),location(loc) |
||||
{ |
||||
COUT(WARNING)<<"OId::Copy: this call must never be happens."<<std::endl; |
||||
return new OId(&name); |
||||
if(TYPE_BEGINLIST==t || TYPE_ENDLIST==t) return; |
||||
if( (TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) && nullptr!=s) name=s; |
||||
else type=TYPE_EMPTY; |
||||
} |
||||
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 |
||||
StackElem(Type t, const struct grammatic_location& loc, const std::string& s):type(t),obj(nullptr),location(loc) |
||||
{ |
||||
COUT(ERROR)<<"Variable "<<name<<" still not defined."<<std::endl; |
||||
*err=true; |
||||
return 0; |
||||
if(TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) name=s; |
||||
else type=TYPE_EMPTY; |
||||
} |
||||
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(TYPE_OBJECT==type) |
||||
{ |
||||
if(vname==Name()) return ob->Copy(); |
||||
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
|
||||
class OFunc: public ObjectBase |
||||
const ObjectBase* Object() const {return isObject()?obj:nullptr;} |
||||
// Detach object
|
||||
ObjectBase* PickObject() |
||||
{ |
||||
std::string name; |
||||
ObjectList* args; |
||||
public: |
||||
OFunc(const std::string* t, ObjectBase* p):name(*t) |
||||
if(isObject()) |
||||
{ |
||||
if(OBType<ObjectList>(p)) args=dynamic_cast<ObjectList*>(p); |
||||
else args=new ObjectList(p); |
||||
type=TYPE_EMPTY; |
||||
return obj; |
||||
} |
||||
OFunc(const char* t, ObjectBase* p):name(t) |
||||
{ |
||||
if(OBType<ObjectList>(p)) args=dynamic_cast<ObjectList*>(p); |
||||
else args=new ObjectList(p); |
||||
else return nullptr; |
||||
} |
||||
~OFunc() {if(args!=0) delete args;} |
||||
// Pure virtual overrides
|
||||
ObjectBase* Copy() const override |
||||
bool ReplaceByObject(ObjectBase* ob) |
||||
{ |
||||
COUT(WARNING)<<"OFunc::Copy: this call must never be happens."<<std::endl; |
||||
return new OFunc(&name,args->Copy()); |
||||
if(isObject()) {delete ob; return false;} |
||||
type=TYPE_OBJECT; |
||||
obj=ob; |
||||
return true; |
||||
} |
||||
bool Print() const override {return false;} |
||||
std::string Type() const override {return "FUNC";} |
||||
std::string Name() const {return (isVar() || isFunc() || isMKPair())?name:std::string();} |
||||
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
|
||||
std::string Dump() const override {return Name()+args->Dump();}; |
||||
ObjectBase* Evaluate(bool* err) 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);} |
||||
void UsedIdents(UsedType& ids) const override {args->UsedIdents(ids);} |
||||
|
||||
// Own functions
|
||||
std::string Name() const {return name;} |
||||
// void SetName(std::string s) {name=s;}
|
||||
private: |
||||
Type type; |
||||
ObjectBase* obj; |
||||
std::string name; |
||||
struct grammatic_location location; |
||||
}; |
||||
|
||||
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 |
||||
|
Loading…
Reference in new issue