ast.h 14 KB

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