//----------------------------------------------------------------------------- // 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