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

#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
ObjectBase* PickObject()
{
if(isObject())
{
type=TYPE_EMPTY;
return obj;
}
else return nullptr;
}
bool ReplaceByObject(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;
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