123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _AST_H_
- #define _AST_H_
- class ExprEvalState;
- class Namespace;
- class SimObject;
- class SimGroup;
- class CodeStream;
- /// Enable this #define if you are seeing the message "precompile size mismatch" in the console.
- /// This will help track down which node type is causing the error. It could be
- /// due to incorrect compiler optimization.
- //#define DEBUG_AST_NODES
- enum TypeReq
- {
- TypeReqNone,
- TypeReqUInt,
- TypeReqFloat,
- TypeReqString
- };
- enum ExprNodeName
- {
- NameExprNode,
- NameFloatNode,
- NameIntNode,
- NameVarNode
- };
- /// 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();
- virtual ~StmtNode() {}
- /// @name next Accessors
- /// @{
- ///
- void append(StmtNode* next);
- StmtNode* getNext() const { return next; }
- /// @}
- /// @name Debug Info
- /// @{
- StringTableEntry dbgFileName; ///< Name of file this node is associated with.
- S32 dbgLineNumber; ///< Line number this node is associated with.
- #ifdef DEBUG_AST_NODES
- virtual String dbgStmtType() const = 0;
- #endif
- /// @}
- /// @name Breaking
- /// @{
- void addBreakLine(CodeStream& codeStream);
- /// @}
- /// @name Compilation
- /// @{
- virtual U32 compileStmt(CodeStream& codeStream, U32 ip) = 0;
- virtual void setPackage(StringTableEntry packageName);
- /// @}
- };
- /// Helper macro
- #ifndef DEBUG_AST_NODES
- # define DBG_STMT_TYPE(s) virtual const char* dbgStmtType() const { return "#s"; }
- #else
- # define DBG_STMT_TYPE(s)
- #endif
- struct BreakStmtNode : StmtNode
- {
- static BreakStmtNode* alloc(S32 lineNumber);
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- DBG_STMT_TYPE(BreakStmtNode);
- };
- struct ContinueStmtNode : StmtNode
- {
- static ContinueStmtNode* alloc(S32 lineNumber);
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- DBG_STMT_TYPE(ContinueStmtNode);
- };
- /// A mathematical expression.
- struct ExprNode : StmtNode
- {
- ExprNode* optimizedNode;
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- virtual U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) = 0;
- virtual TypeReq getPreferredType() = 0;
- virtual ExprNodeName getExprNodeNameEnum() const { return NameExprNode; }
- };
- struct ReturnStmtNode : StmtNode
- {
- ExprNode* expr;
- static ReturnStmtNode* alloc(S32 lineNumber, ExprNode* expr);
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- DBG_STMT_TYPE(ReturnStmtNode);
- };
- 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 compileStmt(CodeStream& codeStream, U32 ip);
- DBG_STMT_TYPE(IfStmtNode);
- };
- 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 compileStmt(CodeStream& codeStream, U32 ip);
- DBG_STMT_TYPE(LoopStmtNode);
- };
- /// A "foreach" statement.
- struct IterStmtNode : StmtNode
- {
- /// Local variable name to use for the container element.
- StringTableEntry varName;
- /// Expression evaluating to a SimSet object.
- ExprNode* containerExpr;
- /// The statement body.
- StmtNode* body;
- /// If true, this is a 'foreach$'.
- bool isStringIter;
- /// Bytecode size of body statement. Set by precompileStmt.
- U32 bodySize;
- static IterStmtNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter);
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- };
- /// A binary mathematical expression (ie, left op right).
- struct BinaryExprNode : ExprNode
- {
- S32 op;
- ExprNode* left;
- ExprNode* right;
- };
- struct FloatBinaryExprNode : BinaryExprNode
- {
- static FloatBinaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- bool optimize();
- TypeReq getPreferredType();
- DBG_STMT_TYPE(FloatBinaryExprNode);
- };
- struct ConditionalExprNode : ExprNode
- {
- ExprNode* testExpr;
- ExprNode* trueExpr;
- ExprNode* falseExpr;
- bool integer;
- static ConditionalExprNode* alloc(S32 lineNumber, ExprNode* testExpr, ExprNode* trueExpr, ExprNode* falseExpr);
- virtual U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- virtual TypeReq getPreferredType();
- DBG_STMT_TYPE(ConditionalExprNode);
- };
- struct IntBinaryExprNode : BinaryExprNode
- {
- TypeReq subType;
- U32 operand;
- static IntBinaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right);
- void getSubTypeOperand();
- bool optimize();
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(IntBinaryExprNode);
- };
- struct StreqExprNode : BinaryExprNode
- {
- bool eq;
- static StreqExprNode* alloc(S32 lineNumber, ExprNode* left, ExprNode* right, bool eq);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(StreqExprNode);
- };
- struct StrcatExprNode : BinaryExprNode
- {
- S32 appendChar;
- static StrcatExprNode* alloc(S32 lineNumber, ExprNode* left, ExprNode* right, S32 appendChar);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(StrcatExprNode);
- };
- struct CommaCatExprNode : BinaryExprNode
- {
- static CommaCatExprNode* alloc(S32 lineNumber, ExprNode* left, ExprNode* right);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(CommaCatExprNode);
- };
- struct IntUnaryExprNode : ExprNode
- {
- S32 op;
- ExprNode* expr;
- bool integer;
- static IntUnaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* expr);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(IntUnaryExprNode);
- };
- struct FloatUnaryExprNode : ExprNode
- {
- S32 op;
- ExprNode* expr;
- static FloatUnaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* expr);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(FloatUnaryExprNode);
- };
- struct VarNode : ExprNode
- {
- StringTableEntry varName;
- ExprNode* arrayIndex;
- static VarNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- virtual ExprNodeName getExprNodeNameEnum() const { return NameVarNode; }
- DBG_STMT_TYPE(VarNode);
- };
- struct IntNode : ExprNode
- {
- S32 value;
- U32 index; // if it's converted to float/string
- static IntNode* alloc(S32 lineNumber, S32 value);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- virtual ExprNodeName getExprNodeNameEnum() const { return NameIntNode; }
- DBG_STMT_TYPE(IntNode);
- };
- struct FloatNode : ExprNode
- {
- F64 value;
- U32 index;
- static FloatNode* alloc(S32 lineNumber, F64 value);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- virtual ExprNodeName getExprNodeNameEnum() const { return NameFloatNode; }
- DBG_STMT_TYPE(FloatNode);
- };
- struct StrConstNode : ExprNode
- {
- char* str;
- F64 fVal;
- U32 index;
- bool tag;
- bool doc; // Specifies that this string is a documentation block.
- static StrConstNode* alloc(S32 lineNumber, char* str, bool tag, bool doc = false);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(StrConstNode);
- };
- struct ConstantNode : ExprNode
- {
- StringTableEntry value;
- F64 fVal;
- U32 index;
- static ConstantNode* alloc(S32 lineNumber, StringTableEntry value);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(ConstantNode);
- };
- struct AssignExprNode : ExprNode
- {
- StringTableEntry varName;
- ExprNode* expr;
- ExprNode* arrayIndex;
- TypeReq subType;
- static AssignExprNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex, ExprNode* expr);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(AssignExprNode);
- };
- struct AssignDecl
- {
- S32 lineNumber;
- S32 token;
- ExprNode* expr;
- bool integer;
- };
- struct AssignOpExprNode : ExprNode
- {
- StringTableEntry varName;
- ExprNode* expr;
- ExprNode* arrayIndex;
- S32 op;
- U32 operand;
- TypeReq subType;
- static AssignOpExprNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex, ExprNode* expr, S32 op);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(AssignOpExprNode);
- };
- struct TTagSetStmtNode : StmtNode
- {
- StringTableEntry tag;
- ExprNode* valueExpr;
- ExprNode* stringExpr;
- static TTagSetStmtNode* alloc(S32 lineNumber, StringTableEntry tag, ExprNode* valueExpr, ExprNode* stringExpr);
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- DBG_STMT_TYPE(TTagSetStmtNode);
- };
- struct TTagDerefNode : ExprNode
- {
- ExprNode* expr;
- static TTagDerefNode* alloc(S32 lineNumber, ExprNode* expr);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(TTagDerefNode);
- };
- struct TTagExprNode : ExprNode
- {
- StringTableEntry tag;
- static TTagExprNode* alloc(S32 lineNumber, StringTableEntry tag);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(TTagExprNode);
- };
- struct FuncCallExprNode : ExprNode
- {
- StringTableEntry funcName;
- StringTableEntry nameSpace;
- ExprNode* args;
- U32 callType;
- enum {
- FunctionCall,
- StaticCall,
- MethodCall,
- ParentCall
- };
- static FuncCallExprNode* alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode* args, bool dot);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(FuncCallExprNode);
- };
- struct AssertCallExprNode : ExprNode
- {
- ExprNode* testExpr;
- const char* message;
- U32 messageIndex;
- static AssertCallExprNode* alloc(S32 lineNumber, ExprNode* testExpr, const char* message);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(AssertCallExprNode);
- };
- struct SlotDecl
- {
- S32 lineNumber;
- ExprNode* object;
- StringTableEntry slotName;
- ExprNode* array;
- };
- struct SlotAccessNode : ExprNode
- {
- ExprNode* objectExpr, * arrayExpr;
- StringTableEntry slotName;
- static SlotAccessNode* alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* arrayExpr, StringTableEntry slotName);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(SlotAccessNode);
- };
- struct InternalSlotDecl
- {
- S32 lineNumber;
- ExprNode* object;
- ExprNode* slotExpr;
- bool recurse;
- };
- struct InternalSlotAccessNode : ExprNode
- {
- ExprNode* objectExpr, * slotExpr;
- bool recurse;
- static InternalSlotAccessNode* alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* slotExpr, bool recurse);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(InternalSlotAccessNode);
- };
- struct SlotAssignNode : ExprNode
- {
- ExprNode* objectExpr, * arrayExpr;
- StringTableEntry slotName;
- ExprNode* valueExpr;
- U32 typeID;
- static SlotAssignNode* alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* arrayExpr, StringTableEntry slotName, ExprNode* valueExpr, U32 typeID = -1);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(SlotAssignNode);
- };
- struct SlotAssignOpNode : ExprNode
- {
- ExprNode* objectExpr, * arrayExpr;
- StringTableEntry slotName;
- S32 op;
- ExprNode* valueExpr;
- U32 operand;
- TypeReq subType;
- static SlotAssignOpNode* alloc(S32 lineNumber, ExprNode* objectExpr, StringTableEntry slotName, ExprNode* arrayExpr, S32 op, ExprNode* valueExpr);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(SlotAssignOpNode);
- };
- struct ObjectDeclNode : ExprNode
- {
- ExprNode* classNameExpr;
- StringTableEntry parentObject;
- ExprNode* objectNameExpr;
- ExprNode* argList;
- SlotAssignNode* slotDecls;
- ObjectDeclNode* subObjects;
- bool isDatablock;
- U32 failOffset;
- bool isClassNameInternal;
- bool isSingleton;
- static ObjectDeclNode* alloc(S32 lineNumber, ExprNode* classNameExpr, ExprNode* objectNameExpr, ExprNode* argList, StringTableEntry parentObject, SlotAssignNode* slotDecls, ObjectDeclNode* subObjects, bool isDatablock, bool classNameInternal, bool isSingleton);
- U32 precompileSubObject(bool);
- U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
- U32 compileSubObject(CodeStream& codeStream, U32 ip, bool);
- TypeReq getPreferredType();
- DBG_STMT_TYPE(ObjectDeclNode);
- };
- 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(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode* args, StmtNode* stmts);
- U32 compileStmt(CodeStream& codeStream, U32 ip);
- void setPackage(StringTableEntry packageName);
- DBG_STMT_TYPE(FunctionDeclStmtNode);
- };
- extern StmtNode* gStatementList;
- extern ExprEvalState gEvalState;
- #endif
|