ast.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  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. /// Enable this #define if you are seeing the message "precompile size mismatch" in the console.
  29. /// This will help track down which node type is causing the error. It could be
  30. /// due to incorrect compiler optimization.
  31. //#define DEBUG_AST_NODES
  32. enum TypeReq
  33. {
  34. TypeReqNone,
  35. TypeReqUInt,
  36. TypeReqFloat,
  37. TypeReqString
  38. };
  39. /// Representation of a node for the scripting language parser.
  40. ///
  41. /// When the scripting language is evaluated, it is turned from a string representation,
  42. /// into a parse tree, thence into byte code, which is ultimately interpreted by the VM.
  43. ///
  44. /// This is the base class for the nodes in the parse tree. There are a great many subclasses,
  45. /// each representing a different language construct.
  46. struct StmtNode
  47. {
  48. StmtNode *next; ///< Next entry in parse tree.
  49. StmtNode();
  50. virtual ~StmtNode() {}
  51. /// @name next Accessors
  52. /// @{
  53. ///
  54. void append(StmtNode *next);
  55. StmtNode *getNext() const { return next; }
  56. /// @}
  57. /// @name Debug Info
  58. /// @{
  59. StringTableEntry dbgFileName; ///< Name of file this node is associated with.
  60. S32 dbgLineNumber; ///< Line number this node is associated with.
  61. #ifdef DEBUG_AST_NODES
  62. virtual String dbgStmtType() const = 0;
  63. #endif
  64. /// @}
  65. /// @name Breaking
  66. /// @{
  67. void addBreakCount();
  68. void addBreakLine(U32 ip);
  69. /// @}
  70. /// @name Compilation
  71. /// @{
  72. virtual U32 precompileStmt(U32 loopCount) = 0;
  73. virtual U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint) = 0;
  74. virtual void setPackage(StringTableEntry packageName);
  75. /// @}
  76. };
  77. /// Helper macro
  78. #ifndef DEBUG_AST_NODES
  79. # define DBG_STMT_TYPE(s) virtual String dbgStmtType() const { return String(#s); }
  80. #else
  81. # define DBG_STMT_TYPE(s)
  82. #endif
  83. struct BreakStmtNode : StmtNode
  84. {
  85. static BreakStmtNode *alloc( S32 lineNumber );
  86. U32 precompileStmt(U32 loopCount);
  87. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  88. DBG_STMT_TYPE(BreakStmtNode);
  89. };
  90. struct ContinueStmtNode : StmtNode
  91. {
  92. static ContinueStmtNode *alloc( S32 lineNumber );
  93. U32 precompileStmt(U32 loopCount);
  94. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  95. DBG_STMT_TYPE(ContinueStmtNode);
  96. };
  97. /// A mathematical expression.
  98. struct ExprNode : StmtNode
  99. {
  100. U32 precompileStmt(U32 loopCount);
  101. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  102. virtual U32 precompile(TypeReq type) = 0;
  103. virtual U32 compile(U32 *codeStream, U32 ip, TypeReq type) = 0;
  104. virtual TypeReq getPreferredType() = 0;
  105. };
  106. struct ReturnStmtNode : StmtNode
  107. {
  108. ExprNode *expr;
  109. static ReturnStmtNode *alloc( S32 lineNumber, ExprNode *expr );
  110. U32 precompileStmt(U32 loopCount);
  111. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  112. DBG_STMT_TYPE(ReturnStmtNode);
  113. };
  114. struct IfStmtNode : StmtNode
  115. {
  116. ExprNode *testExpr;
  117. StmtNode *ifBlock, *elseBlock;
  118. U32 endifOffset;
  119. U32 elseOffset;
  120. bool integer;
  121. bool propagate;
  122. static IfStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough );
  123. void propagateSwitchExpr(ExprNode *left, bool string);
  124. ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string);
  125. U32 precompileStmt(U32 loopCount);
  126. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  127. DBG_STMT_TYPE(IfStmtNode);
  128. };
  129. struct LoopStmtNode : StmtNode
  130. {
  131. ExprNode *testExpr;
  132. ExprNode *initExpr;
  133. ExprNode *endLoopExpr;
  134. StmtNode *loopBlock;
  135. bool isDoLoop;
  136. U32 breakOffset;
  137. U32 continueOffset;
  138. U32 loopBlockStartOffset;
  139. bool integer;
  140. static LoopStmtNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop );
  141. U32 precompileStmt(U32 loopCount);
  142. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  143. DBG_STMT_TYPE(LoopStmtNode);
  144. };
  145. /// A "foreach" statement.
  146. struct IterStmtNode : StmtNode
  147. {
  148. /// Local variable name to use for the container element.
  149. StringTableEntry varName;
  150. /// Expression evaluating to a SimSet object.
  151. ExprNode* containerExpr;
  152. /// The statement body.
  153. StmtNode* body;
  154. /// If true, this is a 'foreach$'.
  155. bool isStringIter;
  156. /// Bytecode size of body statement. Set by precompileStmt.
  157. U32 bodySize;
  158. static IterStmtNode* alloc( S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter );
  159. U32 precompileStmt( U32 loopCount );
  160. U32 compileStmt( U32* codeStream, U32 ip, U32 continuePoint, U32 breakPoint );
  161. };
  162. /// A binary mathematical expression (ie, left op right).
  163. struct BinaryExprNode : ExprNode
  164. {
  165. S32 op;
  166. ExprNode *left;
  167. ExprNode *right;
  168. };
  169. struct FloatBinaryExprNode : BinaryExprNode
  170. {
  171. static FloatBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right );
  172. U32 precompile(TypeReq type);
  173. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  174. TypeReq getPreferredType();
  175. DBG_STMT_TYPE(FloatBinaryExprNode);
  176. };
  177. struct ConditionalExprNode : ExprNode
  178. {
  179. ExprNode *testExpr;
  180. ExprNode *trueExpr;
  181. ExprNode *falseExpr;
  182. bool integer;
  183. static ConditionalExprNode *alloc( S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr );
  184. virtual U32 precompile(TypeReq type);
  185. virtual U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  186. virtual TypeReq getPreferredType();
  187. DBG_STMT_TYPE(ConditionalExprNode);
  188. };
  189. struct IntBinaryExprNode : BinaryExprNode
  190. {
  191. TypeReq subType;
  192. U32 operand;
  193. static IntBinaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *left, ExprNode *right );
  194. void getSubTypeOperand();
  195. U32 precompile(TypeReq type);
  196. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  197. TypeReq getPreferredType();
  198. DBG_STMT_TYPE(IntBinaryExprNode);
  199. };
  200. struct StreqExprNode : BinaryExprNode
  201. {
  202. bool eq;
  203. static StreqExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, bool eq );
  204. U32 precompile(TypeReq type);
  205. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  206. TypeReq getPreferredType();
  207. DBG_STMT_TYPE(StreqExprNode);
  208. };
  209. struct StrcatExprNode : BinaryExprNode
  210. {
  211. S32 appendChar;
  212. static StrcatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar );
  213. U32 precompile(TypeReq type);
  214. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  215. TypeReq getPreferredType();
  216. DBG_STMT_TYPE(StrcatExprNode);
  217. };
  218. struct CommaCatExprNode : BinaryExprNode
  219. {
  220. static CommaCatExprNode *alloc( S32 lineNumber, ExprNode *left, ExprNode *right );
  221. U32 precompile(TypeReq type);
  222. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  223. TypeReq getPreferredType();
  224. DBG_STMT_TYPE(CommaCatExprNode);
  225. };
  226. struct IntUnaryExprNode : ExprNode
  227. {
  228. S32 op;
  229. ExprNode *expr;
  230. bool integer;
  231. static IntUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr );
  232. U32 precompile(TypeReq type);
  233. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  234. TypeReq getPreferredType();
  235. DBG_STMT_TYPE(IntUnaryExprNode);
  236. };
  237. struct FloatUnaryExprNode : ExprNode
  238. {
  239. S32 op;
  240. ExprNode *expr;
  241. static FloatUnaryExprNode *alloc( S32 lineNumber, S32 op, ExprNode *expr );
  242. U32 precompile(TypeReq type);
  243. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  244. TypeReq getPreferredType();
  245. DBG_STMT_TYPE(FloatUnaryExprNode);
  246. };
  247. struct VarNode : ExprNode
  248. {
  249. StringTableEntry varName;
  250. ExprNode *arrayIndex;
  251. static VarNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex );
  252. U32 precompile(TypeReq type);
  253. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  254. TypeReq getPreferredType();
  255. DBG_STMT_TYPE(VarNode);
  256. };
  257. struct IntNode : ExprNode
  258. {
  259. S32 value;
  260. U32 index; // if it's converted to float/string
  261. static IntNode *alloc( S32 lineNumber, S32 value );
  262. U32 precompile(TypeReq type);
  263. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  264. TypeReq getPreferredType();
  265. DBG_STMT_TYPE(IntNode);
  266. };
  267. struct FloatNode : ExprNode
  268. {
  269. F64 value;
  270. U32 index;
  271. static FloatNode *alloc( S32 lineNumber, F64 value );
  272. U32 precompile(TypeReq type);
  273. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  274. TypeReq getPreferredType();
  275. DBG_STMT_TYPE(FloatNode);
  276. };
  277. struct StrConstNode : ExprNode
  278. {
  279. char *str;
  280. F64 fVal;
  281. U32 index;
  282. bool tag;
  283. bool doc; // Specifies that this string is a documentation block.
  284. static StrConstNode *alloc( S32 lineNumber, char *str, bool tag, bool doc = false );
  285. U32 precompile(TypeReq type);
  286. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  287. TypeReq getPreferredType();
  288. DBG_STMT_TYPE(StrConstNode);
  289. };
  290. struct ConstantNode : ExprNode
  291. {
  292. StringTableEntry value;
  293. F64 fVal;
  294. U32 index;
  295. static ConstantNode *alloc( S32 lineNumber, StringTableEntry value );
  296. U32 precompile(TypeReq type);
  297. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  298. TypeReq getPreferredType();
  299. DBG_STMT_TYPE(ConstantNode);
  300. };
  301. struct AssignExprNode : ExprNode
  302. {
  303. StringTableEntry varName;
  304. ExprNode *expr;
  305. ExprNode *arrayIndex;
  306. TypeReq subType;
  307. static AssignExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr );
  308. U32 precompile(TypeReq type);
  309. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  310. TypeReq getPreferredType();
  311. DBG_STMT_TYPE(AssignExprNode);
  312. };
  313. struct AssignDecl
  314. {
  315. S32 lineNumber;
  316. S32 token;
  317. ExprNode *expr;
  318. bool integer;
  319. };
  320. struct AssignOpExprNode : ExprNode
  321. {
  322. StringTableEntry varName;
  323. ExprNode *expr;
  324. ExprNode *arrayIndex;
  325. S32 op;
  326. U32 operand;
  327. TypeReq subType;
  328. static AssignOpExprNode *alloc( S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op );
  329. U32 precompile(TypeReq type);
  330. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  331. TypeReq getPreferredType();
  332. DBG_STMT_TYPE(AssignOpExprNode);
  333. };
  334. struct TTagSetStmtNode : StmtNode
  335. {
  336. StringTableEntry tag;
  337. ExprNode *valueExpr;
  338. ExprNode *stringExpr;
  339. static TTagSetStmtNode *alloc( S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr );
  340. U32 precompileStmt(U32 loopCount);
  341. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  342. DBG_STMT_TYPE(TTagSetStmtNode);
  343. };
  344. struct TTagDerefNode : ExprNode
  345. {
  346. ExprNode *expr;
  347. static TTagDerefNode *alloc( S32 lineNumber, ExprNode *expr );
  348. U32 precompile(TypeReq type);
  349. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  350. TypeReq getPreferredType();
  351. DBG_STMT_TYPE(TTagDerefNode);
  352. };
  353. struct TTagExprNode : ExprNode
  354. {
  355. StringTableEntry tag;
  356. static TTagExprNode *alloc( S32 lineNumber, StringTableEntry tag );
  357. U32 precompile(TypeReq type);
  358. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  359. TypeReq getPreferredType();
  360. DBG_STMT_TYPE(TTagExprNode);
  361. };
  362. struct FuncCallExprNode : ExprNode
  363. {
  364. StringTableEntry funcName;
  365. StringTableEntry nameSpace;
  366. ExprNode *args;
  367. U32 callType;
  368. enum {
  369. FunctionCall,
  370. MethodCall,
  371. ParentCall
  372. };
  373. static FuncCallExprNode *alloc( S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot );
  374. U32 precompile(TypeReq type);
  375. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  376. TypeReq getPreferredType();
  377. DBG_STMT_TYPE(FuncCallExprNode);
  378. };
  379. struct AssertCallExprNode : ExprNode
  380. {
  381. ExprNode *testExpr;
  382. const char *message;
  383. U32 messageIndex;
  384. static AssertCallExprNode *alloc( S32 lineNumber, ExprNode *testExpr, const char *message );
  385. U32 precompile(TypeReq type);
  386. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  387. TypeReq getPreferredType();
  388. DBG_STMT_TYPE(AssertCallExprNode);
  389. };
  390. struct SlotDecl
  391. {
  392. S32 lineNumber;
  393. ExprNode *object;
  394. StringTableEntry slotName;
  395. ExprNode *array;
  396. };
  397. struct SlotAccessNode : ExprNode
  398. {
  399. ExprNode *objectExpr, *arrayExpr;
  400. StringTableEntry slotName;
  401. static SlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName );
  402. U32 precompile(TypeReq type);
  403. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  404. TypeReq getPreferredType();
  405. DBG_STMT_TYPE(SlotAccessNode);
  406. };
  407. struct InternalSlotDecl
  408. {
  409. S32 lineNumber;
  410. ExprNode *object;
  411. ExprNode *slotExpr;
  412. bool recurse;
  413. };
  414. struct InternalSlotAccessNode : ExprNode
  415. {
  416. ExprNode *objectExpr, *slotExpr;
  417. bool recurse;
  418. static InternalSlotAccessNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse );
  419. U32 precompile(TypeReq type);
  420. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  421. TypeReq getPreferredType();
  422. DBG_STMT_TYPE(InternalSlotAccessNode);
  423. };
  424. struct SlotAssignNode : ExprNode
  425. {
  426. ExprNode *objectExpr, *arrayExpr;
  427. StringTableEntry slotName;
  428. ExprNode *valueExpr;
  429. U32 typeID;
  430. static SlotAssignNode *alloc( S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1 );
  431. U32 precompile(TypeReq type);
  432. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  433. TypeReq getPreferredType();
  434. DBG_STMT_TYPE(SlotAssignNode);
  435. };
  436. struct SlotAssignOpNode : ExprNode
  437. {
  438. ExprNode *objectExpr, *arrayExpr;
  439. StringTableEntry slotName;
  440. S32 op;
  441. ExprNode *valueExpr;
  442. U32 operand;
  443. TypeReq subType;
  444. static SlotAssignOpNode *alloc( S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr );
  445. U32 precompile(TypeReq type);
  446. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  447. TypeReq getPreferredType();
  448. DBG_STMT_TYPE(SlotAssignOpNode);
  449. };
  450. struct ObjectDeclNode : ExprNode
  451. {
  452. ExprNode *classNameExpr;
  453. StringTableEntry parentObject;
  454. ExprNode *objectNameExpr;
  455. ExprNode *argList;
  456. SlotAssignNode *slotDecls;
  457. ObjectDeclNode *subObjects;
  458. bool isDatablock;
  459. U32 failOffset;
  460. bool isClassNameInternal;
  461. bool isSingleton;
  462. static ObjectDeclNode *alloc( S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton );
  463. U32 precompile(TypeReq type);
  464. U32 precompileSubObject(bool);
  465. U32 compile(U32 *codeStream, U32 ip, TypeReq type);
  466. U32 compileSubObject(U32 *codeStream, U32 ip, bool);
  467. TypeReq getPreferredType();
  468. DBG_STMT_TYPE(ObjectDeclNode);
  469. };
  470. struct ObjectBlockDecl
  471. {
  472. SlotAssignNode *slots;
  473. ObjectDeclNode *decls;
  474. };
  475. struct FunctionDeclStmtNode : StmtNode
  476. {
  477. StringTableEntry fnName;
  478. VarNode *args;
  479. StmtNode *stmts;
  480. StringTableEntry nameSpace;
  481. StringTableEntry package;
  482. U32 endOffset;
  483. U32 argc;
  484. static FunctionDeclStmtNode *alloc( S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts );
  485. U32 precompileStmt(U32 loopCount);
  486. U32 compileStmt(U32 *codeStream, U32 ip, U32 continuePoint, U32 breakPoint);
  487. void setPackage(StringTableEntry packageName);
  488. DBG_STMT_TYPE(FunctionDeclStmtNode);
  489. };
  490. extern StmtNode *gStatementList;
  491. extern void createFunction(const char *fnName, VarNode *args, StmtNode *statements);
  492. extern ExprEvalState gEvalState;
  493. extern bool lookupFunction(const char *fnName, VarNode **args, StmtNode **statements);
  494. typedef const char *(*cfunc)(S32 argc, char **argv);
  495. extern bool lookupCFunction(const char *fnName, cfunc *f);
  496. #endif