ast.h 15 KB

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