You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
4.1 KiB
111 lines
4.1 KiB
#ifndef OBJECT_H |
|
#define OBJECT_H |
|
#include <errno.h> |
|
#include <inttypes.h> |
|
#include <stack> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include "common.h" |
|
|
|
// Bison location |
|
struct grammatic_location |
|
{ |
|
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: |
|
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) |
|
{ |
|
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; |
|
} |
|
StackElem(Type t, const struct grammatic_location& loc, const std::string& s):type(t),obj(nullptr),location(loc) |
|
{ |
|
if(TYPE_VARIABLE==t || TYPE_FUNCTION==t || TYPE_MKPAIR==t) name=s; |
|
else type=TYPE_EMPTY; |
|
} |
|
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) |
|
{ |
|
// Simple copy of pointer |
|
obj=s.obj; |
|
// Prevent destruction of ObjectBase in StackElem destructor |
|
s.type=TYPE_EMPTY; |
|
} |
|
} |
|
|
|
const ObjectBase* Object() const {return isObject()?obj:nullptr;} |
|
// Detach object |
|
const ObjectBase* PickObject() |
|
{ |
|
if(isObject()) |
|
{ |
|
type=TYPE_EMPTY; |
|
return obj; |
|
} |
|
else return nullptr; |
|
} |
|
bool ReplaceByObject(const ObjectBase* ob) |
|
{ |
|
if(isObject()) {delete ob; return false;} |
|
type=TYPE_OBJECT; |
|
obj=ob; |
|
return true; |
|
} |
|
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;} |
|
|
|
private: |
|
Type type; |
|
const 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); |
|
const 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
|
|
|