ast.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _AST_H_
  23. #define _AST_H_
  24. class ExprEvalState;
  25. class Namespace;
  26. class SimObject;
  27. class SimGroup;
  28. class CodeStream;
  29. /// Enable this #define if you are seeing the message "precompile size mismatch" in the console.
  30. /// This will help track down which node type is causing the error. It could be
  31. /// due to incorrect compiler optimization.
  32. //#define DEBUG_AST_NODES
  33. enum TypeReq
  34. {
  35. TypeReqNone,
  36. TypeReqUInt,
  37. TypeReqFloat,
  38. TypeReqString
  39. };
  40. /// Representation of a node for the scripting language parser.
  41. ///
  42. /// When the scripting language is evaluated, it is turned from a string representation,
  43. /// into a parse tree, thence into byte code, which is ultimately interpreted by the VM.
  44. ///
  45. /// This is the base class for the nodes in the parse tree. There are a great many subclasses,
  46. /// each representing a different language construct.
  47. struct StmtNode
  48. {
  49. StmtNode *next; ///< Next entry in parse tree.
  50. StmtNode();
  51. virtual ~StmtNode() {}
  52. /// @name next Accessors
  53. /// @{
  54. ///
  55. void append(StmtNode *next);
  56. StmtNode *getNext() const { return next; }
  57. /// @}
  58. /// @name Debug Info
  59. /// @{
  60. StringTableEntry dbgFileName; ///< Name of file this node is associated with.
  61. S32 dbgLineNumber; ///< Line number this node is associated with.
  62. #ifdef DEBUG_AST_NODES
  63. virtual String dbgStmtType() const = 0;
  64. #endif
  65. /// @}
  66. /// @name Breaking
  67. /// @{
  68. void addBreakLine(CodeStream &codeStream);
  69. /// @}
  70. /// @name Compilation
  71. /// @{
  72. virtual U32 compileStmt(CodeStream &codeStream, U32 ip) = 0;
  73. virtual void setPackage(StringTableEntry packageName);
  74. /// @}
  75. };
  76. /// Helper macro
  77. #ifndef DEBUG_AST_NODES
  78. # define DBG_STMT_TYPE(s) virtual String dbgStmtType() const { return String(#s); }
  79. #else
  80. # define DBG_STMT_TYPE(s)
  81. #endif
  82. struct BreakStmtNode : StmtNode
  83. {
  84. static BreakStmtNode *alloc( S32 lineNumber );
  85. U32 compileStmt(CodeStream &codeStream, U32 ip);
  86. DBG_STMT_TYPE(BreakStmtNode);
  87. };
  88. struct ContinueStmtNode : StmtNode
  89. {
  90. static ContinueStmtNode *alloc( S32 lineNumber );
  91. U32 compileStmt(CodeStream &codeStream, U32 ip);
  92. DBG_STMT_TYPE(ContinueStmtNode);
  93. };
  94. /// A mathematical expression.
  95. struct ExprNode : StmtNode
  96. {
  97. U32 compileStmt(CodeStream &codeStream, U32 ip);
  98. virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type) = 0;
  99. virtual TypeReq getPreferredType() = 0;
  100. };
  101. struct ReturnStmtNode : StmtNode
  102. {
  103. ExprNode *expr;
  104. static ReturnStmtNode *alloc( S32 lineNumber, ExprNode *expr );
  105. U32 compileStmt(CodeStream &codeStream, U32 ip);
  106. DBG_STMT_TYPE(ReturnStmtNode);
  107. };
  108. struct IfStmtNode : StmtNode
  109. {
  110. ExprNode *testExpr;
  111. StmtNode *ifBlock, *elseBlock;
  112. U32 endifOffset;
  113. U32 elseOffset;
  114. bool integer;
  115. bool propagate;
  116. static IfStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough );
  117. void propagateSwitchExpr(ExprNode *left, bool string);
  118. ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string);
  119. U32 compileStmt(CodeStream &codeStream, U32 ip);
  120. DBG_STMT_TYPE(IfStmtNode);
  121. };
  122. struct LoopStmtNode : StmtNode
  123. {
  124. ExprNode *testExpr;
  125. ExprNode *initExpr;
  126. ExprNode *endLoopExpr;
  127. StmtNode *loopBlock;
  128. bool isDoLoop;
  129. U32 breakOffset;
  130. U32 continueOffset;
  131. U32 loopBlockStartOffset;
  132. bool integer;
  133. static LoopStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop );
  134. U32 compileStmt(CodeStream &codeStream, U32 ip);
  135. DBG_STMT_TYPE(LoopStmtNode);
  136. };
  137. /// A "foreach" statement.
  138. struct IterStmtNode : StmtNode
  139. {
  140. /// Local variable name to use for the container element.
  141. StringTableEntry varName;
  142. /// Expression evaluating to a SimSet object.
  143. ExprNode* containerExpr;
  144. /// The statement body.
  145. StmtNode* body;
  146. /// If true, this is a 'foreach$'.
  147. bool isStringIter;
  148. /// Bytecode size of body statement. Set by precompileStmt.
  149. U32 bodySize;
  150. static IterStmtNode* alloc( S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter );
  151. U32 compileStmt( CodeStream &codeStream, U32 ip );
  152. };
  153. /// A binary mathematical expression (ie, left op right).
  154. struct BinaryExprNode : ExprNode
  155. {
  156. S32 op;
  157. ExprNode *left;
  158. ExprNode *right;
  159. };
  160. struct FloatBinaryExprNode : BinaryExprNode
  161. {
  162. static FloatBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right );
  163. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  164. TypeReq getPreferredType();
  165. DBG_STMT_TYPE(FloatBinaryExprNode);
  166. };
  167. struct ConditionalExprNode : ExprNode
  168. {
  169. ExprNode *testExpr;
  170. ExprNode *trueExpr;
  171. ExprNode *falseExpr;
  172. bool integer;
  173. static ConditionalExprNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr );
  174. virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  175. virtual TypeReq getPreferredType();
  176. DBG_STMT_TYPE(ConditionalExprNode);
  177. };
  178. struct IntBinaryExprNode : BinaryExprNode
  179. {
  180. TypeReq subType;
  181. U32 operand;
  182. static IntBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right );
  183. void getSubTypeOperand();
  184. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  185. TypeReq getPreferredType();
  186. DBG_STMT_TYPE(IntBinaryExprNode);
  187. };
  188. struct StreqExprNode : BinaryExprNode
  189. {
  190. bool eq;
  191. static StreqExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, bool eq );
  192. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  193. TypeReq getPreferredType();
  194. DBG_STMT_TYPE(StreqExprNode);
  195. };
  196. struct StrcatExprNode : BinaryExprNode
  197. {
  198. S32 appendChar;
  199. static StrcatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar );
  200. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  201. TypeReq getPreferredType();
  202. DBG_STMT_TYPE(StrcatExprNode);
  203. };
  204. struct CommaCatExprNode : BinaryExprNode
  205. {
  206. static CommaCatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right );
  207. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  208. TypeReq getPreferredType();
  209. DBG_STMT_TYPE(CommaCatExprNode);
  210. };
  211. struct IntUnaryExprNode : ExprNode
  212. {
  213. S32 op;
  214. ExprNode *expr;
  215. bool integer;
  216. static IntUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr );
  217. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  218. TypeReq getPreferredType();
  219. DBG_STMT_TYPE(IntUnaryExprNode);
  220. };
  221. struct FloatUnaryExprNode : ExprNode
  222. {
  223. S32 op;
  224. ExprNode *expr;
  225. static FloatUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr );
  226. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  227. TypeReq getPreferredType();
  228. DBG_STMT_TYPE(FloatUnaryExprNode);
  229. };
  230. struct VarNode : ExprNode
  231. {
  232. StringTableEntry varName;
  233. ExprNode *arrayIndex;
  234. static VarNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex );
  235. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  236. TypeReq getPreferredType();
  237. DBG_STMT_TYPE(VarNode);
  238. };
  239. struct IntNode : ExprNode
  240. {
  241. S32 value;
  242. U32 index; // if it's converted to float/string
  243. static IntNode *alloc( S32 lineNumber, S32 value );
  244. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  245. TypeReq getPreferredType();
  246. DBG_STMT_TYPE(IntNode);
  247. };
  248. struct FloatNode : ExprNode
  249. {
  250. F64 value;
  251. U32 index;
  252. static FloatNode *alloc( S32 lineNumber, F64 value );
  253. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  254. TypeReq getPreferredType();
  255. DBG_STMT_TYPE(FloatNode);
  256. };
  257. struct StrConstNode : ExprNode
  258. {
  259. char *str;
  260. F64 fVal;
  261. U32 index;
  262. bool tag;
  263. bool doc; // Specifies that this string is a documentation block.
  264. static StrConstNode *alloc( S32 lineNumber, char *str, bool tag, bool doc = false );
  265. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  266. TypeReq getPreferredType();
  267. DBG_STMT_TYPE(StrConstNode);
  268. };
  269. struct ConstantNode : ExprNode
  270. {
  271. StringTableEntry value;
  272. F64 fVal;
  273. U32 index;
  274. static ConstantNode *alloc( S32 lineNumber, StringTableEntry value );
  275. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  276. TypeReq getPreferredType();
  277. DBG_STMT_TYPE(ConstantNode);
  278. };
  279. struct AssignExprNode : ExprNode
  280. {
  281. StringTableEntry varName;
  282. ExprNode *expr;
  283. ExprNode *arrayIndex;
  284. TypeReq subType;
  285. static AssignExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr );
  286. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  287. TypeReq getPreferredType();
  288. DBG_STMT_TYPE(AssignExprNode);
  289. };
  290. struct AssignDecl
  291. {
  292. S32 lineNumber;
  293. S32 token;
  294. ExprNode *expr;
  295. bool integer;
  296. };
  297. struct AssignOpExprNode : ExprNode
  298. {
  299. StringTableEntry varName;
  300. ExprNode *expr;
  301. ExprNode *arrayIndex;
  302. S32 op;
  303. U32 operand;
  304. TypeReq subType;
  305. static AssignOpExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op );
  306. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  307. TypeReq getPreferredType();
  308. DBG_STMT_TYPE(AssignOpExprNode);
  309. };
  310. struct TTagSetStmtNode : StmtNode
  311. {
  312. StringTableEntry tag;
  313. ExprNode *valueExpr;
  314. ExprNode *stringExpr;
  315. static TTagSetStmtNode *alloc( S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr );
  316. U32 compileStmt(CodeStream &codeStream, U32 ip);
  317. DBG_STMT_TYPE(TTagSetStmtNode);
  318. };
  319. struct TTagDerefNode : ExprNode
  320. {
  321. ExprNode *expr;
  322. static TTagDerefNode *alloc( S32 lineNumber, ExprNode *expr );
  323. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  324. TypeReq getPreferredType();
  325. DBG_STMT_TYPE(TTagDerefNode);
  326. };
  327. struct TTagExprNode : ExprNode
  328. {
  329. StringTableEntry tag;
  330. static TTagExprNode *alloc( S32 lineNumber, StringTableEntry tag );
  331. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  332. TypeReq getPreferredType();
  333. DBG_STMT_TYPE(TTagExprNode);
  334. };
  335. struct FuncCallExprNode : ExprNode
  336. {
  337. StringTableEntry funcName;
  338. StringTableEntry nameSpace;
  339. ExprNode *args;
  340. U32 callType;
  341. enum {
  342. FunctionCall,
  343. MethodCall,
  344. ParentCall
  345. };
  346. static FuncCallExprNode *alloc( S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot );
  347. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  348. TypeReq getPreferredType();
  349. DBG_STMT_TYPE(FuncCallExprNode);
  350. };
  351. struct AssertCallExprNode : ExprNode
  352. {
  353. ExprNode *testExpr;
  354. const char *message;
  355. U32 messageIndex;
  356. static AssertCallExprNode *alloc( S32 lineNumber, ExprNode *testExpr, const char *message );
  357. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  358. TypeReq getPreferredType();
  359. DBG_STMT_TYPE(AssertCallExprNode);
  360. };
  361. struct SlotDecl
  362. {
  363. S32 lineNumber;
  364. ExprNode *object;
  365. StringTableEntry slotName;
  366. ExprNode *array;
  367. };
  368. struct SlotAccessNode : ExprNode
  369. {
  370. ExprNode *objectExpr, *arrayExpr;
  371. StringTableEntry slotName;
  372. static SlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName );
  373. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  374. TypeReq getPreferredType();
  375. DBG_STMT_TYPE(SlotAccessNode);
  376. };
  377. struct InternalSlotDecl
  378. {
  379. S32 lineNumber;
  380. ExprNode *object;
  381. ExprNode *slotExpr;
  382. bool recurse;
  383. };
  384. struct InternalSlotAccessNode : ExprNode
  385. {
  386. ExprNode *objectExpr, *slotExpr;
  387. bool recurse;
  388. static InternalSlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse );
  389. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  390. TypeReq getPreferredType();
  391. DBG_STMT_TYPE(InternalSlotAccessNode);
  392. };
  393. struct SlotAssignNode : ExprNode
  394. {
  395. ExprNode *objectExpr, *arrayExpr;
  396. StringTableEntry slotName;
  397. ExprNode *valueExpr;
  398. U32 typeID;
  399. static SlotAssignNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1 );
  400. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  401. TypeReq getPreferredType();
  402. DBG_STMT_TYPE(SlotAssignNode);
  403. };
  404. struct SlotAssignOpNode : ExprNode
  405. {
  406. ExprNode *objectExpr, *arrayExpr;
  407. StringTableEntry slotName;
  408. S32 op;
  409. ExprNode *valueExpr;
  410. U32 operand;
  411. TypeReq subType;
  412. static SlotAssignOpNode *alloc( S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr );
  413. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  414. TypeReq getPreferredType();
  415. DBG_STMT_TYPE(SlotAssignOpNode);
  416. };
  417. struct ObjectDeclNode : ExprNode
  418. {
  419. ExprNode *classNameExpr;
  420. StringTableEntry parentObject;
  421. ExprNode *objectNameExpr;
  422. ExprNode *argList;
  423. SlotAssignNode *slotDecls;
  424. ObjectDeclNode *subObjects;
  425. bool isDatablock;
  426. U32 failOffset;
  427. bool isClassNameInternal;
  428. bool isSingleton;
  429. static ObjectDeclNode *alloc( S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton );
  430. U32 precompileSubObject(bool);
  431. U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
  432. U32 compileSubObject(CodeStream &codeStream, U32 ip, bool);
  433. TypeReq getPreferredType();
  434. DBG_STMT_TYPE(ObjectDeclNode);
  435. };
  436. struct ObjectBlockDecl
  437. {
  438. SlotAssignNode *slots;
  439. ObjectDeclNode *decls;
  440. };
  441. struct FunctionDeclStmtNode : StmtNode
  442. {
  443. StringTableEntry fnName;
  444. VarNode *args;
  445. StmtNode *stmts;
  446. StringTableEntry nameSpace;
  447. StringTableEntry package;
  448. U32 endOffset;
  449. U32 argc;
  450. static FunctionDeclStmtNode *alloc( S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts );
  451. U32 compileStmt(CodeStream &codeStream, U32 ip);
  452. void setPackage(StringTableEntry packageName);
  453. DBG_STMT_TYPE(FunctionDeclStmtNode);
  454. };
  455. extern StmtNode *gStatementList;
  456. extern ExprEvalState gEvalState;;
  457. #endif