2017-04-17 06:17:10 -06:00

462 lines
12 KiB
C++
Executable File

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _AST_H_
#define _AST_H_
class ExprEvalState;
class Namespace;
class SimObject;
class SimGroup;
enum TypeReq {
TypeReqNone,
TypeReqUInt,
TypeReqFloat,
TypeReqString
};
/// Representation of a node for the scripting language parser.
///
/// When the scripting language is evaluated, it is turned from a string representation,
/// into a parse tree, thence into byte code, which is ultimately interpreted by the VM.
///
/// This is the base class for the nodes in the parse tree. There are a great many subclasses,
/// each representing a different language construct.
struct StmtNode
{
StmtNode *next; ///< Next entry in parse tree.
StmtNode();
/// @name next Accessors
/// @{
///
void append(StmtNode *next);
StmtNode *getNext() { return next; }
/// @}
/// @name Debug Info
/// @{
StringTableEntry dbgFileName; ///< Name of file this node is associated with.
S32 dbgLineNumber; ///< Line number this node is associated with.
/// @}
/// @name Breaking
/// @{
void addBreakCount();
void addBreakLine(U32 ip);
/// @}
/// @name Compilation
/// @{
virtual U32 precompileStmt(U32 loopCount) = 0;
virtual U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint) = 0;
virtual void setPackage(StringTableEntry packageName);
/// @}
};
struct BreakStmtNode : StmtNode
{
static BreakStmtNode *alloc();
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
};
struct ContinueStmtNode : StmtNode
{
static ContinueStmtNode *alloc();
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
};
/// A mathematical expression.
struct ExprNode : StmtNode
{
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
virtual U32 precompile(TypeReq type) = 0;
virtual U32 compile(U32 *codeStream, U32 ip, TypeReq type) = 0;
virtual TypeReq getPreferredType() = 0;
};
struct ReturnStmtNode : StmtNode
{
ExprNode *expr;
static ReturnStmtNode *alloc(ExprNode *expr);
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
};
struct IfStmtNode : StmtNode
{
ExprNode *testExpr;
StmtNode *ifBlock, *elseBlock;
U32 endifOffset;
U32 elseOffset;
bool integer;
bool propagate;
static IfStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough);
void propagateSwitchExpr(ExprNode *left, bool string);
ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string);
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
};
struct LoopStmtNode : StmtNode
{
ExprNode *testExpr;
ExprNode *initExpr;
ExprNode *endLoopExpr;
StmtNode *loopBlock;
bool isDoLoop;
U32 breakOffset;
U32 continueOffset;
U32 loopBlockStartOffset;
bool integer;
static LoopStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop);
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
};
/// A binary mathematical expression (ie, left op right).
struct BinaryExprNode : ExprNode
{
S32 op;
ExprNode *left;
ExprNode *right;
};
struct FloatBinaryExprNode : BinaryExprNode
{
static FloatBinaryExprNode *alloc(S32 op, ExprNode *left, ExprNode *right);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct ConditionalExprNode : ExprNode
{
ExprNode *testExpr;
ExprNode *trueExpr;
ExprNode *falseExpr;
bool integer;
static ConditionalExprNode *alloc(ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr);
virtual U32 precompile(TypeReq type);
virtual U32 compile(U32 *codeStream, U32 ip, TypeReq type);
virtual TypeReq getPreferredType();
};
struct IntBinaryExprNode : BinaryExprNode
{
TypeReq subType;
U32 operand;
static IntBinaryExprNode *alloc(S32 op, ExprNode *left, ExprNode *right);
void getSubTypeOperand();
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct StreqExprNode : BinaryExprNode
{
bool eq;
static StreqExprNode *alloc(ExprNode *left, ExprNode *right, bool eq);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct StrcatExprNode : BinaryExprNode
{
int appendChar;
static StrcatExprNode *alloc(ExprNode *left, ExprNode *right, int appendChar);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct CommaCatExprNode : BinaryExprNode
{
static CommaCatExprNode *alloc(ExprNode *left, ExprNode *right);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct IntUnaryExprNode : ExprNode
{
S32 op;
ExprNode *expr;
bool integer;
static IntUnaryExprNode *alloc(S32 op, ExprNode *expr);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct FloatUnaryExprNode : ExprNode
{
S32 op;
ExprNode *expr;
static FloatUnaryExprNode *alloc(S32 op, ExprNode *expr);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct VarNode : ExprNode
{
StringTableEntry varName;
ExprNode *arrayIndex;
static VarNode *alloc(StringTableEntry varName, ExprNode *arrayIndex);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct IntNode : ExprNode
{
S32 value;
U32 index; // if it's converted to float/string
static IntNode *alloc(S32 value);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct FloatNode : ExprNode
{
F64 value;
U32 index;
static FloatNode *alloc(F64 value);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct StrConstNode : ExprNode
{
char *str;
F64 fVal;
U32 index;
bool tag;
static StrConstNode *alloc(char *str, bool tag);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct ConstantNode : ExprNode
{
StringTableEntry value;
F64 fVal;
U32 index;
static ConstantNode *alloc(StringTableEntry value);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct AssignExprNode : ExprNode
{
StringTableEntry varName;
ExprNode *expr;
ExprNode *arrayIndex;
TypeReq subType;
static AssignExprNode *alloc(StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct AssignDecl
{
S32 token;
ExprNode *expr;
bool integer;
};
struct AssignOpExprNode : ExprNode
{
StringTableEntry varName;
ExprNode *expr;
ExprNode *arrayIndex;
S32 op;
U32 operand;
TypeReq subType;
static AssignOpExprNode *alloc(StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct TTagSetStmtNode : StmtNode
{
StringTableEntry tag;
ExprNode *valueExpr;
ExprNode *stringExpr;
static TTagSetStmtNode *alloc(StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr);
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
};
struct TTagDerefNode : ExprNode
{
ExprNode *expr;
static TTagDerefNode *alloc(ExprNode *expr);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct TTagExprNode : ExprNode
{
StringTableEntry tag;
static TTagExprNode *alloc(StringTableEntry tag);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct FuncCallExprNode : ExprNode
{
StringTableEntry funcName;
StringTableEntry nameSpace;
ExprNode *args;
U32 callType;
enum {
FunctionCall,
MethodCall,
ParentCall
};
static FuncCallExprNode *alloc(StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct SlotDecl
{
ExprNode *object;
StringTableEntry slotName;
ExprNode *array;
};
struct SlotAccessNode : ExprNode
{
ExprNode *objectExpr, *arrayExpr;
StringTableEntry slotName;
static SlotAccessNode *alloc(ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct SlotAssignNode : ExprNode
{
ExprNode *objectExpr, *arrayExpr;
StringTableEntry slotName;
ExprNode *valueExpr;
static SlotAssignNode *alloc(ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct SlotAssignOpNode : ExprNode
{
ExprNode *objectExpr, *arrayExpr;
StringTableEntry slotName;
S32 op;
ExprNode *valueExpr;
U32 operand;
TypeReq subType;
static SlotAssignOpNode *alloc(ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr);
U32 precompile(TypeReq type);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
};
struct ObjectDeclNode : ExprNode
{
ExprNode *classNameExpr;
StringTableEntry parentObject;
ExprNode *objectNameExpr;
ExprNode *argList;
SlotAssignNode *slotDecls;
ObjectDeclNode *subObjects;
bool structDecl;
U32 failOffset;
static ObjectDeclNode *alloc(ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool structDecl);
U32 precompile(TypeReq type);
U32 precompileSubObject(bool);
U32 compile(U32 *codeStream, U32 ip, TypeReq type);
U32 compileSubObject(U32 *codeStream, U32 ip, bool);
TypeReq getPreferredType();
};
struct ObjectBlockDecl
{
SlotAssignNode *slots;
ObjectDeclNode *decls;
};
struct FunctionDeclStmtNode : StmtNode
{
StringTableEntry fnName;
VarNode *args;
StmtNode *stmts;
StringTableEntry nameSpace;
StringTableEntry package;
U32 endOffset;
U32 argc;
static FunctionDeclStmtNode *alloc(StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts);
U32 precompileStmt(U32 loopCount);
U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
void setPackage(StringTableEntry packageName);
};
extern StmtNode *statementList;
extern void createFunction(const char *fnName, VarNode *args, StmtNode *statements);
extern ExprEvalState gEvalState;
extern bool lookupFunction(const char *fnName, VarNode **args, StmtNode **statements);
typedef const char *(*cfunc)(S32 argc, char **argv);
extern bool lookupCFunction(const char *fnName, cfunc *f);
#endif