Thursday, August 22, 2013

Expression Parsing - August 22, 2013

Posting early today, non-work stuff going on that needs my attention this afternoon.

Despite having some cough/cold thing going on, 1700 lines of code later we have a functional multi-type expression parser.  There's still some function-calling functionality to add, but I can evaluate with proper operator precedence at least.

I've written similar things before, but not supporting multiple types.  Thanks to the hell magic of templates, anything that has overridden operators in C++ is pretty easy to add as a new type, though all of the permutations of <type1> <operator> <type2> are entered manually - I can't really think of any good way to get around that.


Current built in types:
bool
int
float
VECTOR4
COORD4
EULER
QUAT
SQT
MATRIX4

Variables are bound from C++ and looked up by name, so we can directly read (or modify) values from the game.  Currently there is just a single set of variables, but it should be pretty easy to allow multiple sets, so you could have something like a set of "global" variables, and then have some local to the game object or component the script is attached to.

There's quite a bit of template stuff going on, this is basically the core of storing values:

//The base class for storing anything with a result type
template <typename T>
class cTypedExpr : public cExpr
{
public:
    virtual eType Type() const { return GetType<T>(); }
};


//Stores a constant of a specific type
template <typename T>
class cTypedConstant : public cTypedExpr<T>
{
public:
    cTypedConstant(const T &v) : mValue(v) { }

    virtual void Eval(cResult<T> &result) { result.mValue = mValue; }

    T mValue;
};


//Stores a pointer to a type, and lets us get it as an l-value
template <typename T>
class cTypedIdentifier : public cTypedExpr<T>
{
public:
    cTypedIdentifier(T *v) : mValue(v) { }

    virtual bool IsLValue() const { return true; }
    virtual void Eval(cResult<T> &result) { result.mValue = *mValue; }
    virtual void LValue(cLValue<T> &result) { result.mValue = mValue; }

    T *mValue;
};


If you're not familiar with compilers, an l-value is, basically, the left side of an assignment operation, so you need to get the memory address to write to, not just the value.

Hopefully I'll get this tied into the game in some useful way tonight.

Now, if I add for/while/if statements, and variable declarations, I'll have my own programming language...

No comments:

Post a Comment