lscript_tree.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:399k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  2. {
  3. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  4. }
  5. type = mReturnType;
  6. }
  7. break;
  8. case LSCP_TO_STACK:
  9. {
  10. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  11. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  12. chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
  13. operation2stack(chunk, mReturnType, mRightType);
  14. store2stack(this, mLValue, chunk, mReturnType);
  15. }
  16. break;
  17. case LSCP_EMIT_CIL_ASSEMBLY:
  18. {
  19. print_cil_load_address(fp, mLValue, entry);
  20. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  21. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLValue->mReturnType);
  22. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  23. print_cil_numeric_cast(fp, mLValue->mReturnType, mRightSide->mReturnType);
  24. print_cil_div(fp, mLValue->mReturnType, mRightSide->mReturnType);
  25. print_cil_assignment(fp, mLValue, entry);
  26. }
  27. break;
  28. default:
  29. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  30. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  31. break;
  32. }
  33. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  34. }
  35. S32 LLScriptDivAssignment::getSize()
  36. {
  37. return 0;
  38. }
  39. static void print_cil_mod(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
  40. {
  41. switch(left_type)
  42. {
  43. case LST_INTEGER:
  44. // Numeric remainder.
  45. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Modulo(int32, int32)n");
  46. break;
  47. case LST_VECTOR:
  48. // Vector cross product.
  49. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'Modulo'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)n");
  50. break;
  51. default:
  52. // Error.
  53. break;
  54. }
  55. }
  56. void LLScriptModAssignment::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  57. {
  58. if (gErrorToText.getErrors())
  59. {
  60. return;
  61. }
  62. switch(pass)
  63. {
  64. case LSCP_PRETTY_PRINT:
  65. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  66. fprintf(fp, " %%= ");
  67. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  68. break;
  69. case LSCP_EMIT_ASSEMBLY:
  70. {
  71. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  72. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  73. fprintf(fp, "MOD %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  74. print_assignment(fp, mLValue);
  75. }
  76. break;
  77. case LSCP_TYPE:
  78. {
  79. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  80. mLeftType = type;
  81. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  82. mRightType = type;
  83. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  84. {
  85. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  86. }
  87. type = mReturnType;
  88. }
  89. break;
  90. case LSCP_TO_STACK:
  91. {
  92. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  93. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  94. chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
  95. operation2stack(chunk, mReturnType, mRightType);
  96. store2stack(this, mLValue, chunk, mReturnType);
  97. }
  98. break;
  99. case LSCP_EMIT_CIL_ASSEMBLY:
  100. {
  101. print_cil_load_address(fp, mLValue, entry);
  102. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  103. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  104. print_cil_mod(fp, mLValue->mReturnType, mRightSide->mReturnType);
  105. print_cil_assignment(fp, mLValue, entry);
  106. }
  107. break;
  108. default:
  109. mLValue->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  110. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  111. break;
  112. }
  113. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  114. }
  115. S32 LLScriptModAssignment::getSize()
  116. {
  117. return 0;
  118. }
  119. static void print_cil_eq(LLFILE* fp, LSCRIPTType left_type, LSCRIPTType right_type)
  120. {
  121. switch(right_type)
  122. {
  123. case LST_INTEGER:
  124. case LST_FLOATINGPOINT:
  125. // Numeric equality.
  126. fprintf(fp, "ceqn");
  127. break;
  128. case LST_STRING:
  129.         // NOTE: babbage: strings and keys can be compared, so a cast
  130.         // may be required
  131.         print_cil_cast(fp, left_type, right_type);
  132. // String equality.
  133. fprintf(fp, "call bool valuetype [mscorlib]System.String::op_Equality(string, string)n");
  134. break;
  135. case LST_KEY:
  136.         // NOTE: babbage: strings and keys can be compared, so a cast 
  137.         // may be required
  138.         print_cil_cast(fp, left_type, right_type);
  139. // Key equality.
  140. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(valuetype [ScriptTypes]LindenLab.SecondLife.Key, valuetype [ScriptTypes]LindenLab.SecondLife.Key)n");
  141. break;
  142. case LST_VECTOR:
  143. // Vector equality.
  144. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(class [ScriptTypes]LindenLab.SecondLife.Vector, class [ScriptTypes]LindenLab.SecondLife.Vector)n");
  145. break;
  146. case LST_QUATERNION:
  147. // Rotation equality.
  148. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::'Equals'(class [ScriptTypes]LindenLab.SecondLife.Quaternion, class [ScriptTypes]LindenLab.SecondLife.Quaternion)n");
  149. break;
  150. case LST_LIST:
  151. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::Equals(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)n");
  152. break;
  153. default:
  154. // Error.
  155. break;
  156. }
  157. }
  158. void LLScriptEquality::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  159. {
  160. if (gErrorToText.getErrors())
  161. {
  162. return;
  163. }
  164. switch(pass)
  165. {
  166. case LSCP_PRETTY_PRINT:
  167. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  168. fprintf(fp, " == ");
  169. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  170. break;
  171. case LSCP_EMIT_ASSEMBLY:
  172. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  173. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  174. fprintf(fp, "EQ %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  175. break;
  176. case LSCP_TYPE:
  177. {
  178. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  179. mLeftType = type;
  180. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  181. mRightType = type;
  182. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  183. {
  184. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  185. }
  186. type = mReturnType;
  187. }
  188. break;
  189. case LSCP_TO_STACK:
  190. {
  191. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  192. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  193. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  194. chunk->addByte(LSCRIPTOpCodes[LOPC_EQ]);
  195. chunk->addByte(typebyte);
  196. }
  197. break;
  198. case LSCP_EMIT_CIL_ASSEMBLY:
  199. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  200. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  201. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  202. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  203. print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  204. break;
  205. default:
  206. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  207. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  208. break;
  209. }
  210. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  211. }
  212. S32 LLScriptEquality::getSize()
  213. {
  214. return 0;
  215. }
  216. void LLScriptNotEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  217. {
  218. if (gErrorToText.getErrors())
  219. {
  220. return;
  221. }
  222. switch(pass)
  223. {
  224. case LSCP_PRETTY_PRINT:
  225. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  226. fprintf(fp, " != ");
  227. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  228. break;
  229. case LSCP_EMIT_ASSEMBLY:
  230. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  231. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  232. fprintf(fp, "NEQ %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  233. break;
  234. case LSCP_TYPE:
  235. {
  236. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  237. mLeftType = type;
  238. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  239. mRightType = type;
  240. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  241. {
  242. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  243. }
  244. type = mReturnType;
  245. }
  246. break;
  247. case LSCP_TO_STACK:
  248. {
  249. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  250. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  251. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  252. chunk->addByte(LSCRIPTOpCodes[LOPC_NEQ]);
  253. chunk->addByte(typebyte);
  254. }
  255. break;
  256. case LSCP_EMIT_CIL_ASSEMBLY:
  257. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  258. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  259. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  260. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  261. if (LST_LIST == mLeftSide->mReturnType)
  262. {
  263.     fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::NotEquals(class [mscorlib]System.Collections.ArrayList, class [mscorlib]System.Collections.ArrayList)n");
  264. }
  265. else
  266. {  
  267.     print_cil_eq(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  268.     fprintf(fp, "ldc.i4.0n");
  269.     fprintf(fp, "ceqn"); // Compare result of first compare equal with 0 to get compare not equal.
  270. }    
  271. break;
  272. default:
  273. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  274. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  275. break;
  276. }
  277. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  278. }
  279. S32 LLScriptNotEquals::getSize()
  280. {
  281. return 0;
  282. }
  283. static void print_cil_lte(LLFILE* fp)
  284. {
  285. // NOTE: LSL pushes operands backwards, so <= becomes >=
  286. fprintf(fp, "cltn");
  287. fprintf(fp, "ldc.i4.0n");
  288. fprintf(fp, "ceqn");
  289. }
  290. void LLScriptLessEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  291. {
  292. if (gErrorToText.getErrors())
  293. {
  294. return;
  295. }
  296. switch(pass)
  297. {
  298. case LSCP_PRETTY_PRINT:
  299. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  300. fprintf(fp, " <= ");
  301. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  302. break;
  303. case LSCP_EMIT_ASSEMBLY:
  304. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  305. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  306. fprintf(fp, "LEQ %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  307. break;
  308. case LSCP_TYPE:
  309. {
  310. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  311. mLeftType = type;
  312. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  313. mRightType = type;
  314. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  315. {
  316. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  317. }
  318. type = mReturnType;
  319. }
  320. break;
  321. case LSCP_TO_STACK:
  322. {
  323. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  324. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  325. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  326. chunk->addByte(LSCRIPTOpCodes[LOPC_LEQ]);
  327. chunk->addByte(typebyte);
  328. }
  329. break;
  330. case LSCP_EMIT_CIL_ASSEMBLY:
  331. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  332. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  333. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  334. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  335. print_cil_lte(fp);
  336. break;
  337. default:
  338. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  339. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  340. break;
  341. }
  342. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  343. }
  344. S32 LLScriptLessEquals::getSize()
  345. {
  346. return 0;
  347. }
  348. static void print_cil_gte(LLFILE* fp)
  349. {   
  350. // NOTE: LSL pushes operands backwards, so >= becomes <=
  351. fprintf(fp, "cgtn");
  352. fprintf(fp, "ldc.i4.0n");
  353. fprintf(fp, "ceqn");
  354. }
  355. void LLScriptGreaterEquals::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  356. {
  357. if (gErrorToText.getErrors())
  358. {
  359. return;
  360. }
  361. switch(pass)
  362. {
  363. case LSCP_PRETTY_PRINT:
  364. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  365. fprintf(fp, " >= ");
  366. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  367. break;
  368. case LSCP_EMIT_ASSEMBLY:
  369. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  370. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  371. fprintf(fp, "GEQ %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  372. break;
  373. case LSCP_TYPE:
  374. {
  375. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  376. mLeftType = type;
  377. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  378. mRightType = type;
  379. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  380. {
  381. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  382. }
  383. type = mReturnType;
  384. }
  385. break;
  386. case LSCP_TO_STACK:
  387. {
  388. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  389. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  390. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  391. chunk->addByte(LSCRIPTOpCodes[LOPC_GEQ]);
  392. chunk->addByte(typebyte);
  393. }
  394. break;
  395. case LSCP_EMIT_CIL_ASSEMBLY:
  396. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  397. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  398. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  399. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  400. print_cil_gte(fp);
  401. break;
  402. default:
  403. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  404. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  405. break;
  406. }
  407. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  408. }
  409. S32 LLScriptGreaterEquals::getSize()
  410. {
  411. return 0;
  412. }
  413. static void print_cil_lt(LLFILE* fp)
  414. {
  415. // NOTE: LSL pushes operands backwards, so < becomes >
  416. fprintf(fp, "cgtn");
  417. }
  418. void LLScriptLessThan::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  419. {
  420. if (gErrorToText.getErrors())
  421. {
  422. return;
  423. }
  424. switch(pass)
  425. {
  426. case LSCP_PRETTY_PRINT:
  427. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  428. fprintf(fp, " < ");
  429. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  430. break;
  431. case LSCP_EMIT_ASSEMBLY:
  432. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  433. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  434. fprintf(fp, "LESS %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  435. break;
  436. case LSCP_TYPE:
  437. {
  438. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  439. mLeftType = type;
  440. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  441. mRightType = type;
  442. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  443. {
  444. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  445. }
  446. type = mReturnType;
  447. }
  448. break;
  449. case LSCP_TO_STACK:
  450. {
  451. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  452. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  453. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  454. chunk->addByte(LSCRIPTOpCodes[LOPC_LESS]);
  455. chunk->addByte(typebyte);
  456. }
  457. break;
  458. case LSCP_EMIT_CIL_ASSEMBLY:
  459. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  460. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  461. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  462. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  463. print_cil_lt(fp);
  464. break;
  465. default:
  466. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  467. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  468. break;
  469. }
  470. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  471. }
  472. S32 LLScriptLessThan::getSize()
  473. {
  474. return 0;
  475. }
  476. static void print_cil_gt(LLFILE* fp)
  477. {   
  478.     // NOTE: LSL pushes operands backwards, so > becomes <
  479. fprintf(fp, "cltn");
  480. }
  481. void LLScriptGreaterThan::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  482. {
  483. if (gErrorToText.getErrors())
  484. {
  485. return;
  486. }
  487. switch(pass)
  488. {
  489. case LSCP_PRETTY_PRINT:
  490. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  491. fprintf(fp, " > ");
  492. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  493. break;
  494. case LSCP_EMIT_ASSEMBLY:
  495. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  496. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  497. fprintf(fp, "GREATER %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  498. break;
  499. case LSCP_TYPE:
  500. {
  501. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  502. mLeftType = type;
  503. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  504. mRightType = type;
  505. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  506. {
  507. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  508. }
  509. type = mReturnType;
  510. }
  511. break;
  512. case LSCP_TO_STACK:
  513. {
  514. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  515. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  516. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  517. chunk->addByte(LSCRIPTOpCodes[LOPC_GREATER]);
  518. chunk->addByte(typebyte);
  519. }
  520. break;
  521. case LSCP_EMIT_CIL_ASSEMBLY:
  522. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  523. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  524. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  525. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  526. print_cil_gt(fp);
  527. break;
  528. default:
  529. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  530. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  531. break;
  532. }
  533. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  534. }
  535. S32 LLScriptGreaterThan::getSize()
  536. {
  537. return 0;
  538. }
  539. void LLScriptPlus::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  540. {
  541. if (gErrorToText.getErrors())
  542. {
  543. return;
  544. }
  545. switch(pass)
  546. {
  547. case LSCP_PRETTY_PRINT:
  548. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  549. fprintf(fp, " + ");
  550. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  551. break;
  552. case LSCP_EMIT_ASSEMBLY:
  553. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  554. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  555. fprintf(fp, "ADD %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  556. break;
  557. case LSCP_TYPE:
  558. {
  559. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  560. mLeftType = type;
  561. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  562. mRightType = type;
  563. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  564. {
  565. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  566. }
  567. type = mReturnType;
  568. }
  569. break;
  570. case LSCP_TO_STACK:
  571. {
  572. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  573. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  574. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  575. chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
  576. chunk->addByte(typebyte);
  577. }
  578. break;
  579. case LSCP_EMIT_CIL_ASSEMBLY:
  580. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  581. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  582. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  583. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  584. print_cil_add(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  585. break;
  586. default:
  587. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  588. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  589. break;
  590. }
  591. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  592. }
  593. S32 LLScriptPlus::getSize()
  594. {
  595. return 0;
  596. }
  597. void LLScriptMinus::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  598. {
  599. if (gErrorToText.getErrors())
  600. {
  601. return;
  602. }
  603. switch(pass)
  604. {
  605. case LSCP_PRETTY_PRINT:
  606. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  607. fprintf(fp, " - ");
  608. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  609. break;
  610. case LSCP_EMIT_ASSEMBLY:
  611. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  612. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  613. fprintf(fp, "SUB %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  614. break;
  615. case LSCP_TYPE:
  616. {
  617. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  618. mLeftType = type;
  619. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  620. mRightType = type;
  621. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  622. {
  623. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  624. }
  625. type = mReturnType;
  626. }
  627. break;
  628. case LSCP_TO_STACK:
  629. {
  630. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  631. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  632. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  633. chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
  634. chunk->addByte(typebyte);
  635. }
  636. break;
  637. case LSCP_EMIT_CIL_ASSEMBLY:
  638. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  639. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  640. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  641. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  642. print_cil_sub(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  643. break;
  644. default:
  645. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  646. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  647. break;
  648. }
  649. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  650. }
  651. S32 LLScriptMinus::getSize()
  652. {
  653. return 0;
  654. }
  655. void LLScriptTimes::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  656. {
  657. if (gErrorToText.getErrors())
  658. {
  659. return;
  660. }
  661. switch(pass)
  662. {
  663. case LSCP_PRETTY_PRINT:
  664. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  665. fprintf(fp, " * ");
  666. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  667. break;
  668. case LSCP_EMIT_ASSEMBLY:
  669. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  670. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  671. fprintf(fp, "MUL %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  672. break;
  673. case LSCP_TYPE:
  674. {
  675. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  676. mLeftType = type;
  677. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  678. mRightType = type;
  679. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  680. {
  681. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  682. }
  683. type = mReturnType;
  684. }
  685. break;
  686. case LSCP_TO_STACK:
  687. {
  688. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  689. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  690. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  691. chunk->addByte(LSCRIPTOpCodes[LOPC_MUL]);
  692. chunk->addByte(typebyte);
  693. }
  694. break;
  695. case LSCP_EMIT_CIL_ASSEMBLY:
  696. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  697. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  698. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  699. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  700. print_cil_mul(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  701. break;
  702. default:
  703. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  704. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  705. break;
  706. }
  707. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  708. }
  709. S32 LLScriptTimes::getSize()
  710. {
  711. return 0;
  712. }
  713. void LLScriptDivide::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  714. {
  715. if (gErrorToText.getErrors())
  716. {
  717. return;
  718. }
  719. switch(pass)
  720. {
  721. case LSCP_PRETTY_PRINT:
  722. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  723. fprintf(fp, " / ");
  724. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  725. break;
  726. case LSCP_EMIT_ASSEMBLY:
  727. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  728. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  729. fprintf(fp, "DIV %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  730. break;
  731. case LSCP_TYPE:
  732. {
  733. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  734. mLeftType = type;
  735. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  736. mRightType = type;
  737. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  738. {
  739. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  740. }
  741. type = mReturnType;
  742. }
  743. break;
  744. case LSCP_TO_STACK:
  745. {
  746. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  747. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  748. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  749. chunk->addByte(LSCRIPTOpCodes[LOPC_DIV]);
  750. chunk->addByte(typebyte);
  751. }
  752. break;
  753. case LSCP_EMIT_CIL_ASSEMBLY:
  754. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  755. print_cil_numeric_cast(fp, mRightSide->mReturnType, mLeftSide->mReturnType);
  756. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  757. print_cil_numeric_cast(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  758. print_cil_div(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  759. break;
  760. default:
  761. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  762. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  763. break;
  764. }
  765. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  766. }
  767. S32 LLScriptDivide::getSize()
  768. {
  769. return 0;
  770. }
  771. void LLScriptMod::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  772. {
  773. if (gErrorToText.getErrors())
  774. {
  775. return;
  776. }
  777. switch(pass)
  778. {
  779. case LSCP_PRETTY_PRINT:
  780. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  781. fprintf(fp, " %% ");
  782. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  783. break;
  784. case LSCP_EMIT_ASSEMBLY:
  785. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  786. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  787. fprintf(fp, "MOD %s, %sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mLeftType]);
  788. break;
  789. case LSCP_TYPE:
  790. {
  791. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  792. mLeftType = type;
  793. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  794. mRightType = type;
  795. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  796. {
  797. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  798. }
  799. type = mReturnType;
  800. }
  801. break;
  802. case LSCP_TO_STACK:
  803. {
  804. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  805. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  806. U8 typebyte = LSCRIPTTypeByte[mRightType] | LSCRIPTTypeHi4Bits[mLeftType];
  807. chunk->addByte(LSCRIPTOpCodes[LOPC_MOD]);
  808. chunk->addByte(typebyte);
  809. }
  810. break;
  811. case LSCP_EMIT_CIL_ASSEMBLY:
  812. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  813. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  814. print_cil_mod(fp, mLeftSide->mReturnType, mRightSide->mReturnType);
  815. break;
  816. default:
  817. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  818. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  819. break;
  820. }
  821. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  822. }
  823. S32 LLScriptMod::getSize()
  824. {
  825. return 0;
  826. }
  827. void LLScriptBitAnd::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  828. {
  829. if (gErrorToText.getErrors())
  830. {
  831. return;
  832. }
  833. switch(pass)
  834. {
  835. case LSCP_PRETTY_PRINT:
  836. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  837. fprintf(fp, " & ");
  838. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  839. break;
  840. case LSCP_EMIT_ASSEMBLY:
  841. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  842. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  843. fprintf(fp, "BITANDn");
  844. break;
  845. case LSCP_TYPE:
  846. {
  847. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  848. mLeftType = type;
  849. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  850. mRightType = type;
  851. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  852. {
  853. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  854. }
  855. type = mReturnType;
  856. }
  857. break;
  858. case LSCP_TO_STACK:
  859. {
  860. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  861. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  862. chunk->addByte(LSCRIPTOpCodes[LOPC_BITAND]);
  863. }
  864. break;
  865. case LSCP_EMIT_CIL_ASSEMBLY:
  866. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  867. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  868. fprintf(fp, "andn");
  869. break;
  870. default:
  871. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  872. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  873. break;
  874. }
  875. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  876. }
  877. S32 LLScriptBitAnd::getSize()
  878. {
  879. return 0;
  880. }
  881. void LLScriptBitOr::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  882. {
  883. if (gErrorToText.getErrors())
  884. {
  885. return;
  886. }
  887. switch(pass)
  888. {
  889. case LSCP_PRETTY_PRINT:
  890. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  891. fprintf(fp, " | ");
  892. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  893. break;
  894. case LSCP_EMIT_ASSEMBLY:
  895. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  896. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  897. fprintf(fp, "BITORn");
  898. break;
  899. case LSCP_TYPE:
  900. {
  901. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  902. mLeftType = type;
  903. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  904. mRightType = type;
  905. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  906. {
  907. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  908. }
  909. type = mReturnType;
  910. }
  911. break;
  912. case LSCP_TO_STACK:
  913. {
  914. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  915. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  916. chunk->addByte(LSCRIPTOpCodes[LOPC_BITOR]);
  917. }
  918. break;
  919. case LSCP_EMIT_CIL_ASSEMBLY:
  920. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  921. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  922. fprintf(fp, "orn");
  923. break;
  924. default:
  925. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  926. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  927. break;
  928. }
  929. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  930. }
  931. S32 LLScriptBitOr::getSize()
  932. {
  933. return 0;
  934. }
  935. void LLScriptBitXor::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  936. {
  937. if (gErrorToText.getErrors())
  938. {
  939. return;
  940. }
  941. switch(pass)
  942. {
  943. case LSCP_PRETTY_PRINT:
  944. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  945. fprintf(fp, " ^ ");
  946. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  947. break;
  948. case LSCP_EMIT_ASSEMBLY:
  949. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  950. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  951. fprintf(fp, "BITXORn");
  952. break;
  953. case LSCP_TYPE:
  954. {
  955. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  956. mLeftType = type;
  957. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  958. mRightType = type;
  959. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  960. {
  961. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  962. }
  963. type = mReturnType;
  964. }
  965. break;
  966. case LSCP_TO_STACK:
  967. {
  968. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  969. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  970. chunk->addByte(LSCRIPTOpCodes[LOPC_BITXOR]);
  971. }
  972. break;
  973. case LSCP_EMIT_CIL_ASSEMBLY:
  974. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  975. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  976. fprintf(fp, "xorn");
  977. break;
  978. default:
  979. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  980. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  981. break;
  982. }
  983. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  984. }
  985. S32 LLScriptBitXor::getSize()
  986. {
  987. return 0;
  988. }
  989. void LLScriptBooleanAnd::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  990. {
  991. if (gErrorToText.getErrors())
  992. {
  993. return;
  994. }
  995. switch(pass)
  996. {
  997. case LSCP_PRETTY_PRINT:
  998. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  999. fprintf(fp, " && ");
  1000. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1001. break;
  1002. case LSCP_EMIT_ASSEMBLY:
  1003. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1004. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1005. fprintf(fp, "BOOLANDn");
  1006. break;
  1007. case LSCP_TYPE:
  1008. {
  1009. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1010. mLeftType = type;
  1011. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1012. mRightType = type;
  1013. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  1014. {
  1015. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1016. }
  1017. type = mReturnType;
  1018. }
  1019. break;
  1020. case LSCP_TO_STACK:
  1021. {
  1022. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1023. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1024. chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLAND]);
  1025. }
  1026. break;
  1027. case LSCP_EMIT_CIL_ASSEMBLY:
  1028. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1029. fprintf(fp, "ldc.i4.0n");
  1030. fprintf(fp, "ceqn");
  1031. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1032. fprintf(fp, "ldc.i4.0n");
  1033. fprintf(fp, "ceqn");
  1034. fprintf(fp, "orn");
  1035.                 fprintf(fp, "ldc.i4.0n");
  1036.                 fprintf(fp, "ceqn");
  1037. break;
  1038. default:
  1039. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1040. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1041. break;
  1042. }
  1043. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1044. }
  1045. S32 LLScriptBooleanAnd::getSize()
  1046. {
  1047. return 0;
  1048. }
  1049. void LLScriptBooleanOr::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1050. {
  1051. if (gErrorToText.getErrors())
  1052. {
  1053. return;
  1054. }
  1055. switch(pass)
  1056. {
  1057. case LSCP_PRETTY_PRINT:
  1058. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1059. fprintf(fp, " || ");
  1060. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1061. break;
  1062. case LSCP_EMIT_ASSEMBLY:
  1063. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1064. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1065. fprintf(fp, "BOOLORn");
  1066. break;
  1067. case LSCP_TYPE:
  1068. {
  1069. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1070. mLeftType = type;
  1071. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1072. mRightType = type;
  1073. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  1074. {
  1075. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1076. }
  1077. type = mReturnType;
  1078. }
  1079. break;
  1080. case LSCP_TO_STACK:
  1081. {
  1082. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1083. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1084. chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLOR]);
  1085. }
  1086. break;
  1087. case LSCP_EMIT_CIL_ASSEMBLY:
  1088. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1089. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1090. fprintf(fp, "orn");
  1091.                 fprintf(fp, "ldc.i4.0n");
  1092.                 fprintf(fp, "ceqn");
  1093. fprintf(fp, "ldc.i4.0n");
  1094. fprintf(fp, "ceqn");
  1095. break;
  1096. default:
  1097. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1098. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1099. break;
  1100. }
  1101. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1102. }
  1103. S32 LLScriptBooleanOr::getSize()
  1104. {
  1105. return 0;
  1106. }
  1107. void LLScriptShiftLeft::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1108. {
  1109. if (gErrorToText.getErrors())
  1110. {
  1111. return;
  1112. }
  1113. switch(pass)
  1114. {
  1115. case LSCP_PRETTY_PRINT:
  1116. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1117. fprintf(fp, " << ");
  1118. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1119. break;
  1120. case LSCP_EMIT_ASSEMBLY:
  1121. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1122. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1123. fprintf(fp, "SHLn");
  1124. break;
  1125. case LSCP_TYPE:
  1126. {
  1127. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1128. mLeftType = type;
  1129. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1130. mRightType = type;
  1131. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  1132. {
  1133. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1134. }
  1135. type = mReturnType;
  1136. }
  1137. break;
  1138. case LSCP_TO_STACK:
  1139. {
  1140. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1141. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1142. chunk->addByte(LSCRIPTOpCodes[LOPC_SHL]);
  1143. }
  1144. break;
  1145. case LSCP_EMIT_CIL_ASSEMBLY:
  1146. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1147. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1148. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftLeft(int32, int32)n");
  1149. break;
  1150. default:
  1151. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1152. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1153. break;
  1154. }
  1155. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1156. }
  1157. S32 LLScriptShiftLeft::getSize()
  1158. {
  1159. return 0;
  1160. }
  1161. void LLScriptShiftRight::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1162. {
  1163. if (gErrorToText.getErrors())
  1164. {
  1165. return;
  1166. }
  1167. switch(pass)
  1168. {
  1169. case LSCP_PRETTY_PRINT:
  1170. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1171. fprintf(fp, " >> ");
  1172. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1173. break;
  1174. case LSCP_EMIT_ASSEMBLY:
  1175. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1176. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1177. fprintf(fp, "SHRn");
  1178. break;
  1179. case LSCP_TYPE:
  1180. {
  1181. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1182. mLeftType = type;
  1183. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1184. mRightType = type;
  1185. if (!legal_binary_expression(mReturnType, mLeftType, mRightType, mType))
  1186. {
  1187. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1188. }
  1189. type = mReturnType;
  1190. }
  1191. break;
  1192. case LSCP_TO_STACK:
  1193. {
  1194. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1195. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1196. chunk->addByte(LSCRIPTOpCodes[LOPC_SHR]);
  1197. }
  1198. break;
  1199. case LSCP_EMIT_CIL_ASSEMBLY:
  1200. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1201. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1202. fprintf(fp, "call int32 [LslUserScript]LindenLab.SecondLife.LslUserScript::ShiftRight(int32, int32)n");
  1203. break;
  1204. default:
  1205. mLeftSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1206. mRightSide->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1207. break;
  1208. }
  1209. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1210. }
  1211. S32 LLScriptShiftRight::getSize()
  1212. {
  1213. return 0;
  1214. }
  1215. void LLScriptParenthesis::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1216. {
  1217. if (gErrorToText.getErrors())
  1218. {
  1219. return;
  1220. }
  1221. switch(pass)
  1222. {
  1223. case LSCP_PRETTY_PRINT:
  1224. fprintf(fp, "( ");
  1225. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1226. fprintf(fp, " )");
  1227. break;
  1228. case LSCP_TYPE:
  1229. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1230. mReturnType = mLeftType = type;
  1231. break;
  1232. case LSCP_EMIT_ASSEMBLY:
  1233. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1234. mReturnType = mLeftType = type;
  1235. break;
  1236. default:
  1237. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1238. break;
  1239. }
  1240. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1241. }
  1242. S32 LLScriptParenthesis::getSize()
  1243. {
  1244. return 0;
  1245. }
  1246. void LLScriptUnaryMinus::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1247. {
  1248. if (gErrorToText.getErrors())
  1249. {
  1250. return;
  1251. }
  1252. switch(pass)
  1253. {
  1254. case LSCP_PRETTY_PRINT:
  1255. fprintf(fp, "-");
  1256. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1257. break;
  1258. case LSCP_EMIT_ASSEMBLY:
  1259. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1260. fprintf(fp, "NEG %sn", LSCRIPTTypeNames[mLeftType]);
  1261. break;
  1262. case LSCP_TYPE:
  1263. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1264. if (!legal_unary_expression(type, type, mType))
  1265. {
  1266. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1267. }
  1268. else
  1269. {
  1270. mReturnType = mLeftType = type;
  1271. }
  1272. break;
  1273. case LSCP_TO_STACK:
  1274. {
  1275. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1276. U8 typebyte = LSCRIPTTypeByte[mLeftType];
  1277. chunk->addByte(LSCRIPTOpCodes[LOPC_NEG]);
  1278. chunk->addByte(typebyte);
  1279. }
  1280. break;
  1281. case LSCP_EMIT_CIL_ASSEMBLY:
  1282.     {
  1283. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1284. print_cil_neg(fp, mLeftType);
  1285.     }
  1286.     break;
  1287. default:
  1288. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1289. break;
  1290. }
  1291. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1292. }
  1293. S32 LLScriptUnaryMinus::getSize()
  1294. {
  1295. return 0;
  1296. }
  1297. void LLScriptBooleanNot::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1298. {
  1299. if (gErrorToText.getErrors())
  1300. {
  1301. return;
  1302. }
  1303. switch(pass)
  1304. {
  1305. case LSCP_PRETTY_PRINT:
  1306. fprintf(fp, "!");
  1307. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1308. break;
  1309. case LSCP_EMIT_ASSEMBLY:
  1310. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1311. fprintf(fp, "BOOLNOTn");
  1312. break;
  1313. case LSCP_TYPE:
  1314. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1315. if (!legal_unary_expression(type, type, mType))
  1316. {
  1317. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1318. }
  1319. else
  1320. {
  1321. mReturnType = mLeftType = type;
  1322. }
  1323. break;
  1324. case LSCP_TO_STACK:
  1325. {
  1326. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1327. chunk->addByte(LSCRIPTOpCodes[LOPC_BOOLNOT]);
  1328. }
  1329. break;
  1330. case LSCP_EMIT_CIL_ASSEMBLY:
  1331. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1332. fprintf(fp, "ldc.i4.0n");
  1333. fprintf(fp, "ceqn"); // If f(e) is (e == 0), f(e) returns 1 if e is 0 and 0 otherwise, therefore f(e) implements boolean not.
  1334. break;
  1335. default:
  1336. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1337. break;
  1338. }
  1339. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1340. }
  1341. S32 LLScriptBooleanNot::getSize()
  1342. {
  1343. return 0;
  1344. }
  1345. void LLScriptBitNot::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1346. {
  1347. if (gErrorToText.getErrors())
  1348. {
  1349. return;
  1350. }
  1351. switch(pass)
  1352. {
  1353. case LSCP_PRETTY_PRINT:
  1354. fprintf(fp, "~");
  1355. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1356. break;
  1357. case LSCP_EMIT_ASSEMBLY:
  1358. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1359. fprintf(fp, "BITNOTn");
  1360. break;
  1361. case LSCP_TYPE:
  1362. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1363. if (!legal_unary_expression(type, type, mType))
  1364. {
  1365. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1366. }
  1367. else
  1368. {
  1369. mReturnType = mLeftType = type;
  1370. }
  1371. break;
  1372. case LSCP_TO_STACK:
  1373. {
  1374. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1375. chunk->addByte(LSCRIPTOpCodes[LOPC_BITNOT]);
  1376. }
  1377. break;
  1378. case LSCP_EMIT_CIL_ASSEMBLY:
  1379. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1380. fprintf(fp, "notn");
  1381. break;
  1382. default:
  1383. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1384. break;
  1385. }
  1386. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1387. }
  1388. S32 LLScriptBitNot::getSize()
  1389. {
  1390. return 0;
  1391. }
  1392. void LLScriptPreIncrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1393. {
  1394. if (gErrorToText.getErrors())
  1395. {
  1396. return;
  1397. }
  1398. switch(pass)
  1399. {
  1400. case LSCP_PRETTY_PRINT:
  1401. fprintf(fp, "++");
  1402. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1403. break;
  1404. case LSCP_EMIT_ASSEMBLY:
  1405. {
  1406. if (mReturnType == LST_INTEGER)
  1407. {
  1408. fprintf(fp, "PUSHARGI 1n");
  1409. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1410. fprintf(fp, "n");
  1411. fprintf(fp, "ADD integer, integern");
  1412. }
  1413. else if (mReturnType == LST_FLOATINGPOINT)
  1414. {
  1415. fprintf(fp, "PUSHARGF 1n");
  1416. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1417. fprintf(fp, "n");
  1418. fprintf(fp, "ADD float, floatn");
  1419. }
  1420. else
  1421. {
  1422. fprintf(fp, "Unexpected Typen");
  1423. }
  1424. print_assignment(fp, mExpression);
  1425. }
  1426. break;
  1427. case LSCP_TYPE:
  1428. if (mExpression->mType != LET_LVALUE)
  1429. {
  1430. gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
  1431. }
  1432. else
  1433. {
  1434. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1435. if (!legal_unary_expression(type, type, mType))
  1436. {
  1437. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1438. }
  1439. else
  1440. {
  1441. mReturnType = mLeftType = type;
  1442. }
  1443. }
  1444. break;
  1445. case LSCP_TO_STACK:
  1446. {
  1447. if (mReturnType == LST_INTEGER)
  1448. {
  1449. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
  1450. chunk->addInteger(1);
  1451. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1452. chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
  1453. chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
  1454. }
  1455. else if (mReturnType == LST_FLOATINGPOINT)
  1456. {
  1457. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
  1458. chunk->addFloat(1.f);
  1459. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1460. chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
  1461. chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
  1462. }
  1463. store2stack(this, mExpression, chunk, mReturnType);
  1464. }
  1465. break;
  1466. case LSCP_EMIT_CIL_ASSEMBLY:
  1467. {
  1468. print_cil_load_address(fp, mExpression, entry);
  1469. if (mReturnType == LST_INTEGER)
  1470. {
  1471. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1472. fprintf(fp, "ldc.i4.1n");
  1473. fprintf(fp, "addn");
  1474. }
  1475. else if (mReturnType == LST_FLOATINGPOINT)
  1476. {
  1477. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1478. fprintf(fp, "ldc.r8 1n");
  1479. fprintf(fp, "addn");
  1480. }
  1481. else
  1482. {
  1483. fprintf(fp, "Unexpected Typen");
  1484. }
  1485. print_cil_assignment(fp, mExpression, entry);
  1486. }
  1487. break;
  1488. default:
  1489. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1490. break;
  1491. }
  1492. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1493. }
  1494. S32 LLScriptPreIncrement::getSize()
  1495. {
  1496. return 0;
  1497. }
  1498. void LLScriptPreDecrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1499. {
  1500. if (gErrorToText.getErrors())
  1501. {
  1502. return;
  1503. }
  1504. switch(pass)
  1505. {
  1506. case LSCP_PRETTY_PRINT:
  1507. fprintf(fp, "--");
  1508. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1509. break;
  1510. case LSCP_EMIT_ASSEMBLY:
  1511. {
  1512. if (mReturnType == LST_INTEGER)
  1513. {
  1514. fprintf(fp, "PUSHARGI 1n");
  1515. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1516. fprintf(fp, "n");
  1517. fprintf(fp, "SUB integer, integern");
  1518. }
  1519. else if (mReturnType == LST_FLOATINGPOINT)
  1520. {
  1521. fprintf(fp, "PUSHARGF 1n");
  1522. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1523. fprintf(fp, "n");
  1524. fprintf(fp, "SUB float, floatn");
  1525. }
  1526. else
  1527. {
  1528. fprintf(fp, "Unexpected Typen");
  1529. }
  1530. print_assignment(fp, mExpression);
  1531. }
  1532. break;
  1533. case LSCP_TYPE:
  1534. if (mExpression->mType != LET_LVALUE)
  1535. {
  1536. gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
  1537. }
  1538. else
  1539. {
  1540. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1541. if (!legal_unary_expression(type, type, mType))
  1542. {
  1543. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1544. }
  1545. else
  1546. {
  1547. mReturnType = mLeftType = type;
  1548. }
  1549. }
  1550. break;
  1551. case LSCP_TO_STACK:
  1552. {
  1553. if (mReturnType == LST_INTEGER)
  1554. {
  1555. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
  1556. chunk->addInteger(1);
  1557. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1558. chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
  1559. chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
  1560. }
  1561. else if (mReturnType == LST_FLOATINGPOINT)
  1562. {
  1563. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
  1564. chunk->addFloat(1.f);
  1565. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1566. chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
  1567. chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
  1568. }
  1569. store2stack(this, mExpression, chunk, mReturnType);
  1570. }
  1571. break;
  1572. case LSCP_EMIT_CIL_ASSEMBLY:
  1573. {
  1574. print_cil_load_address(fp, mExpression, entry);
  1575. if (mReturnType == LST_INTEGER)
  1576. {
  1577. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1578. fprintf(fp, "ldc.i4.1n");
  1579. fprintf(fp, "subn");
  1580. }
  1581. else if (mReturnType == LST_FLOATINGPOINT)
  1582. {
  1583. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1584. fprintf(fp, "ldc.r8 1n");
  1585. fprintf(fp, "subn");
  1586. }
  1587. else
  1588. {
  1589. fprintf(fp, "Unexpected Typen");
  1590. }
  1591. print_cil_assignment(fp, mExpression, entry);
  1592. }
  1593. break;
  1594. default:
  1595. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1596. break;
  1597. }
  1598. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1599. }
  1600. S32 LLScriptPreDecrement::getSize()
  1601. {
  1602. return 0;
  1603. }
  1604. void LLScriptTypeCast::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1605. {
  1606. if (gErrorToText.getErrors())
  1607. {
  1608. return;
  1609. }
  1610. switch(pass)
  1611. {
  1612. case LSCP_PRETTY_PRINT:
  1613. fprintf(fp, "( ");
  1614. mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1615. fprintf(fp, ") ");
  1616. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1617. break;
  1618. case LSCP_EMIT_ASSEMBLY:
  1619. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mRightType], LSCRIPTTypeNames[mType->mType]);
  1620. break;
  1621. case LSCP_TYPE:
  1622. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1623. mRightType = type;
  1624. if (!legal_casts(mType->mType, type))
  1625. {
  1626. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1627. }
  1628. type = mType->mType;
  1629. mReturnType = mLeftType = type;
  1630. break;
  1631. case LSCP_TO_STACK:
  1632. {
  1633. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1634. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1635. U8 castbyte = LSCRIPTTypeByte[mType->mType] | LSCRIPTTypeHi4Bits[mRightType];
  1636. chunk->addByte(castbyte);
  1637. }
  1638. break;
  1639. case LSCP_EMIT_CIL_ASSEMBLY:
  1640. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1641. print_cil_cast(fp, mRightType, mType->mType);
  1642. break;
  1643. default:
  1644. mType->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1645. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1646. break;
  1647. }
  1648. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1649. }
  1650. S32 LLScriptTypeCast::getSize()
  1651. {
  1652. return 0;
  1653. }
  1654. void LLScriptVectorInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1655. {
  1656. if (gErrorToText.getErrors())
  1657. {
  1658. return;
  1659. }
  1660. switch(pass)
  1661. {
  1662. case LSCP_PRETTY_PRINT:
  1663. fprintf(fp, "< ");
  1664. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1665. fprintf(fp, ", ");
  1666. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1667. fprintf(fp, ", ");
  1668. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1669. fprintf(fp, " >");
  1670. break;
  1671. case LSCP_EMIT_ASSEMBLY:
  1672. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1673. if (mExpression1->mReturnType != LST_FLOATINGPOINT)
  1674. {
  1675. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1676. }
  1677. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1678. if (mExpression2->mReturnType != LST_FLOATINGPOINT)
  1679. {
  1680. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1681. }
  1682. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1683. if (mExpression3->mReturnType != LST_FLOATINGPOINT)
  1684. {
  1685. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1686. }
  1687. break;
  1688. case LSCP_TYPE:
  1689. // vector's take floats
  1690. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1691. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1692. {
  1693. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1694. }
  1695. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1696. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1697. {
  1698. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1699. }
  1700. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1701. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1702. {
  1703. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1704. }
  1705. mReturnType = type = LST_VECTOR;
  1706. if (mNextp)
  1707. {
  1708. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1709. }
  1710. break;
  1711. case LSCP_TO_STACK:
  1712. pass = LSCP_TO_STACK;
  1713. mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1714. if (mExpression1->mReturnType != LST_FLOATINGPOINT)
  1715. {
  1716. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1717. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
  1718. chunk->addByte(castbyte);
  1719. }
  1720. mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1721. if (mExpression2->mReturnType != LST_FLOATINGPOINT)
  1722. {
  1723. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1724. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
  1725. chunk->addByte(castbyte);
  1726. }
  1727. mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1728. if (mExpression3->mReturnType != LST_FLOATINGPOINT)
  1729. {
  1730. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1731. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
  1732. chunk->addByte(castbyte);
  1733. }
  1734. break;
  1735. case LSCP_EMIT_CIL_ASSEMBLY:
  1736. // Load arguments.
  1737. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1738. if (mExpression1->mReturnType != LST_FLOATINGPOINT)
  1739. {
  1740. print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
  1741. }
  1742. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1743. if (mExpression2->mReturnType != LST_FLOATINGPOINT)
  1744. {
  1745. print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
  1746. }
  1747. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1748. if (mExpression3->mReturnType != LST_FLOATINGPOINT)
  1749. {
  1750. print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
  1751. }
  1752. // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
  1753. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Vector class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateVector'(float32, float32, float32)n");
  1754. break;
  1755. default:
  1756. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1757. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1758. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1759. break;
  1760. }
  1761. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1762. }
  1763. S32 LLScriptVectorInitializer::getSize()
  1764. {
  1765. return 0;
  1766. }
  1767. void LLScriptQuaternionInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1768. {
  1769. if (gErrorToText.getErrors())
  1770. {
  1771. return;
  1772. }
  1773. switch(pass)
  1774. {
  1775. case LSCP_PRETTY_PRINT:
  1776. fprintf(fp, "< ");
  1777. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1778. fprintf(fp, ", ");
  1779. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1780. fprintf(fp, ", ");
  1781. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1782. fprintf(fp, ", ");
  1783. mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1784. fprintf(fp, " >");
  1785. break;
  1786. case LSCP_EMIT_ASSEMBLY:
  1787. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1788. if (mExpression1->mReturnType != LST_FLOATINGPOINT)
  1789. {
  1790. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression1->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1791. }
  1792. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1793. if (mExpression2->mReturnType != LST_FLOATINGPOINT)
  1794. {
  1795. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression2->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1796. }
  1797. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1798. if (mExpression3->mReturnType != LST_FLOATINGPOINT)
  1799. {
  1800. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression3->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1801. }
  1802. mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1803. if (mExpression4->mReturnType != LST_FLOATINGPOINT)
  1804. {
  1805. fprintf(fp, "CAST %s->%sn", LSCRIPTTypeNames[mExpression4->mReturnType], LSCRIPTTypeNames[LST_FLOATINGPOINT]);
  1806. }
  1807. break;
  1808. case LSCP_TYPE:
  1809. // vector's take floats
  1810. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1811. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1812. {
  1813. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1814. }
  1815. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1816. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1817. {
  1818. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1819. }
  1820. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1821. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1822. {
  1823. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1824. }
  1825. mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1826. if (!legal_assignment(LST_FLOATINGPOINT, type))
  1827. {
  1828. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  1829. }
  1830. mReturnType = type = LST_QUATERNION;
  1831. if (mNextp)
  1832. {
  1833. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1834. }
  1835. break;
  1836. case LSCP_TO_STACK:
  1837. pass = LSCP_TO_STACK;
  1838. mExpression1->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1839. if (mExpression1->mReturnType != LST_FLOATINGPOINT)
  1840. {
  1841. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1842. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression1->mReturnType];
  1843. chunk->addByte(castbyte);
  1844. }
  1845. mExpression2->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1846. if (mExpression2->mReturnType != LST_FLOATINGPOINT)
  1847. {
  1848. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1849. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression2->mReturnType];
  1850. chunk->addByte(castbyte);
  1851. }
  1852. mExpression3->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1853. if (mExpression3->mReturnType != LST_FLOATINGPOINT)
  1854. {
  1855. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1856. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression3->mReturnType];
  1857. chunk->addByte(castbyte);
  1858. }
  1859. mExpression4->recurse(fp, tabs, tabsize, LSCP_TO_STACK, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1860. if (mExpression4->mReturnType != LST_FLOATINGPOINT)
  1861. {
  1862. chunk->addByte(LSCRIPTOpCodes[LOPC_CAST]);
  1863. U8 castbyte = LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[mExpression4->mReturnType];
  1864. chunk->addByte(castbyte);
  1865. }
  1866. break;
  1867. case LSCP_EMIT_CIL_ASSEMBLY:
  1868. // Load arguments.
  1869. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1870. if (mExpression1->mReturnType != LST_FLOATINGPOINT)
  1871. {
  1872. print_cil_cast(fp, mExpression1->mReturnType, LST_FLOATINGPOINT);
  1873. }
  1874. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1875. if (mExpression2->mReturnType != LST_FLOATINGPOINT)
  1876. {
  1877. print_cil_cast(fp, mExpression2->mReturnType, LST_FLOATINGPOINT);
  1878. }
  1879. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1880. if (mExpression3->mReturnType != LST_FLOATINGPOINT)
  1881. {
  1882. print_cil_cast(fp, mExpression3->mReturnType, LST_FLOATINGPOINT);
  1883. }
  1884. mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1885. if (mExpression4->mReturnType != LST_FLOATINGPOINT)
  1886. {
  1887. print_cil_cast(fp, mExpression4->mReturnType, LST_FLOATINGPOINT);
  1888. }
  1889. // Call named ctor, which leaves new Vector on stack, so it can be saved in to local or argument just like a primitive type.
  1890. fprintf(fp, "call class [ScriptTypes]LindenLab.SecondLife.Quaternion class [LslUserScript]LindenLab.SecondLife.LslUserScript::'CreateQuaternion'(float32, float32, float32, float32)n");
  1891. break;
  1892. default:
  1893. mExpression1->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1894. mExpression2->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1895. mExpression3->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1896. mExpression4->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1897. break;
  1898. }
  1899. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1900. }
  1901. S32 LLScriptQuaternionInitializer::getSize()
  1902. {
  1903. return 0;
  1904. }
  1905. void LLScriptListInitializer::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1906. {
  1907. if (gErrorToText.getErrors())
  1908. {
  1909. return;
  1910. }
  1911. switch(pass)
  1912. {
  1913. case LSCP_PRETTY_PRINT:
  1914. fprintf(fp, "[ ");
  1915. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1916. fprintf(fp, " ]");
  1917. break;
  1918. case LSCP_EMIT_ASSEMBLY:
  1919. count = 0;
  1920. if (mExpressionList)
  1921. {
  1922. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1923. fprintf(fp, "STACKTOL %llun", count);
  1924. }
  1925. break;
  1926. case LSCP_TYPE:
  1927. if (mExpressionList)
  1928. {
  1929. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1930. mReturnType = type = LST_LIST;
  1931. }
  1932. mReturnType = type = LST_LIST;
  1933. break;
  1934. case LSCP_TO_STACK:
  1935. {
  1936. if (mExpressionList)
  1937. {
  1938. pass = LSCP_TO_STACK;
  1939. U64 list_element_count = 0;
  1940. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, list_element_count, chunk, heap, stacksize, entry, entrycount, NULL);
  1941. chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
  1942. chunk->addInteger((S32)list_element_count);
  1943. }
  1944. else
  1945. {
  1946. chunk->addByte(LSCRIPTOpCodes[LOPC_STACKTOL]);
  1947. chunk->addInteger(0);
  1948. }
  1949. break;
  1950. }
  1951. case LSCP_EMIT_CIL_ASSEMBLY:
  1952. {
  1953. // Push boxed elements on stack.
  1954. U64 list_element_count = 0;
  1955. if (mExpressionList)
  1956. {
  1957. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, list_element_count, chunk, heap, stacksize, entry, entrycount, NULL);
  1958. }
  1959. // Create list on stack.
  1960. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::CreateList()n");
  1961. // Call Prepend to add remaining boxed expressions.
  1962. for(U64 i = 0; i < list_element_count; i++)
  1963. {
  1964. fprintf(fp, "call class [mscorlib]System.Collections.ArrayList class [LslUserScript]LindenLab.SecondLife.LslUserScript::Prepend(object, class [mscorlib]System.Collections.ArrayList)n");
  1965. }
  1966. break;
  1967. }
  1968. default:
  1969. if (mExpressionList)
  1970. {
  1971. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1972. }
  1973. break;
  1974. }
  1975. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1976. }
  1977. S32 LLScriptListInitializer::getSize()
  1978. {
  1979. return 0;
  1980. }
  1981. void LLScriptPostIncrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  1982. {
  1983. if (gErrorToText.getErrors())
  1984. {
  1985. return;
  1986. }
  1987. switch(pass)
  1988. {
  1989. case LSCP_PRETTY_PRINT:
  1990. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1991. fprintf(fp, "++");
  1992. break;
  1993. case LSCP_EMIT_ASSEMBLY:
  1994. {
  1995. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  1996. if (mReturnType == LST_INTEGER)
  1997. {
  1998. fprintf(fp, "PUSHARGI 1n");
  1999. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2000. fprintf(fp, "ADD integer, integern");
  2001. }
  2002. else if (mReturnType == LST_FLOATINGPOINT)
  2003. {
  2004. fprintf(fp, "PUSHARGF 1n");
  2005. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2006. fprintf(fp, "ADD float, floatn");
  2007. }
  2008. else
  2009. {
  2010. fprintf(fp, "Unexpected Typen");
  2011. }
  2012. print_assignment(fp, mExpression);
  2013. fprintf(fp, "%sn", LSCRIPTTypePop[mReturnType]);
  2014. }
  2015. break;
  2016. case LSCP_TYPE:
  2017. if (mExpression->mType != LET_LVALUE)
  2018. {
  2019. gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
  2020. }
  2021. else
  2022. {
  2023. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2024. if (!legal_unary_expression(type, type, mType))
  2025. {
  2026. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  2027. }
  2028. else
  2029. {
  2030. mReturnType = mLeftType = type;
  2031. }
  2032. }
  2033. break;
  2034. case LSCP_TO_STACK:
  2035. {
  2036. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2037. if (mReturnType == LST_INTEGER)
  2038. {
  2039. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
  2040. chunk->addInteger(1);
  2041. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2042. chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
  2043. chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
  2044. }
  2045. else if (mReturnType == LST_FLOATINGPOINT)
  2046. {
  2047. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
  2048. chunk->addFloat(1.f);
  2049. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2050. chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
  2051. chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
  2052. }
  2053. store2stack(this, mExpression, chunk, mReturnType);
  2054. switch(mReturnType)
  2055. {
  2056. case LST_INTEGER:
  2057. case LST_FLOATINGPOINT:
  2058. chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
  2059. break;
  2060. case LST_KEY:
  2061. case LST_STRING:
  2062. chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
  2063. break;
  2064. case LST_LIST:
  2065. chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
  2066. break;
  2067. case LST_VECTOR:
  2068. chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
  2069. break;
  2070. case LST_QUATERNION:
  2071. chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
  2072. break;
  2073. default:
  2074. chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
  2075. break;
  2076. }
  2077. }
  2078. break;
  2079. case LSCP_EMIT_CIL_ASSEMBLY:
  2080. {
  2081. // Push original value on to stack.
  2082. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2083. // Load address if needed for store.
  2084. print_cil_load_address(fp, mExpression, entry);
  2085. // Load value again.
  2086. // TODO: Work out if sideeffects can result in 2 evaluations of expression giving different values.
  2087. // Original LSL2 uses this method, so any bugs due to side effects will probably be identical ;-)
  2088. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2089. if (mReturnType == LST_INTEGER)
  2090. {
  2091. fprintf(fp, "ldc.i4.1n");
  2092. }
  2093. else if (mReturnType == LST_FLOATINGPOINT)
  2094. {
  2095. fprintf(fp, "ldc.r8 1n");
  2096. }
  2097. else
  2098. {
  2099. fprintf(fp, "Unexpected Typen");
  2100. }
  2101. fprintf(fp, "addn");
  2102. print_cil_assignment(fp, mExpression, entry);
  2103. // Pop assignment result to leave original expression result on stack. 
  2104. // TODO: Optimise away redundant pop/dup pairs.
  2105. fprintf(fp, "popn"); 
  2106. }
  2107. break;
  2108. default:
  2109. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2110. break;
  2111. }
  2112. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2113. }
  2114. S32 LLScriptPostIncrement::getSize()
  2115. {
  2116. return 0;
  2117. }
  2118. void LLScriptPostDecrement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2119. {
  2120. if (gErrorToText.getErrors())
  2121. {
  2122. return;
  2123. }
  2124. switch(pass)
  2125. {
  2126. case LSCP_PRETTY_PRINT:
  2127. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2128. fprintf(fp, "--");
  2129. break;
  2130. case LSCP_EMIT_ASSEMBLY:
  2131. {
  2132. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2133. if (mReturnType == LST_INTEGER)
  2134. {
  2135. fprintf(fp, "PUSHARGI 1n");
  2136. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2137. fprintf(fp, "SUB integer, integern");
  2138. }
  2139. else if (mReturnType == LST_FLOATINGPOINT)
  2140. {
  2141. fprintf(fp, "PUSHARGF 1n");
  2142. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2143. fprintf(fp, "SUB float, floatn");
  2144. }
  2145. else
  2146. {
  2147. fprintf(fp, "Unexpected Typen");
  2148. }
  2149. print_assignment(fp, mExpression);
  2150. fprintf(fp, "%sn", LSCRIPTTypePop[mReturnType]);
  2151. }
  2152. break;
  2153. case LSCP_TYPE:
  2154. if (mExpression->mType != LET_LVALUE)
  2155. {
  2156. gErrorToText.writeError(fp, this, LSERROR_EXPRESSION_ON_LVALUE);
  2157. }
  2158. else
  2159. {
  2160. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2161. if (!legal_unary_expression(type, type, mType))
  2162. {
  2163. gErrorToText.writeError(fp, this, LSERROR_TYPE_MISMATCH);
  2164. }
  2165. else
  2166. {
  2167. mReturnType = mLeftType = type;
  2168. }
  2169. }
  2170. break;
  2171. case LSCP_TO_STACK:
  2172. {
  2173. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2174. if (mReturnType == LST_INTEGER)
  2175. {
  2176. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
  2177. chunk->addInteger(1);
  2178. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2179. chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
  2180. chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
  2181. }
  2182. else if (mReturnType == LST_FLOATINGPOINT)
  2183. {
  2184. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGF]);
  2185. chunk->addFloat(1.f);
  2186. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2187. chunk->addByte(LSCRIPTOpCodes[LOPC_SUB]);
  2188. chunk->addByte(LSCRIPTTypeByte[LST_FLOATINGPOINT] | LSCRIPTTypeHi4Bits[LST_FLOATINGPOINT]);
  2189. }
  2190. store2stack(this, mExpression, chunk, mReturnType);
  2191. switch(mReturnType)
  2192. {
  2193. case LST_INTEGER:
  2194. case LST_FLOATINGPOINT:
  2195. chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
  2196. break;
  2197. case LST_KEY:
  2198. case LST_STRING:
  2199. chunk->addByte(LSCRIPTOpCodes[LOPC_POPS]);
  2200. break;
  2201. case LST_LIST:
  2202. chunk->addByte(LSCRIPTOpCodes[LOPC_POPL]);
  2203. break;
  2204. case LST_VECTOR:
  2205. chunk->addByte(LSCRIPTOpCodes[LOPC_POPV]);
  2206. break;
  2207. case LST_QUATERNION:
  2208. chunk->addByte(LSCRIPTOpCodes[LOPC_POPQ]);
  2209. break;
  2210. default:
  2211. chunk->addByte(LSCRIPTOpCodes[LOPC_POP]);
  2212. break;
  2213. }
  2214. }
  2215. break;
  2216. case LSCP_EMIT_CIL_ASSEMBLY:
  2217. {
  2218. // Push original value on to stack.
  2219. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2220. // Load address if needed for store.
  2221. print_cil_load_address(fp, mExpression, entry);
  2222. // Load value again.
  2223. // TODO: Work out if sideeffects can result in 2 evaluations of expression giving different values.
  2224. // Original LSL2 uses this method, so any bugs due to side effects will probably be identical ;-)
  2225. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2226. if (mReturnType == LST_INTEGER)
  2227. {
  2228. fprintf(fp, "ldc.i4.1n");
  2229. }
  2230. else if (mReturnType == LST_FLOATINGPOINT)
  2231. {
  2232. fprintf(fp, "ldc.r8 1n");
  2233. }
  2234. else
  2235. {
  2236. fprintf(fp, "Unexpected Typen");
  2237. }
  2238. fprintf(fp, "subn");
  2239. print_cil_assignment(fp, mExpression, entry);
  2240. // Pop assignment result to leave original expression result on stack. 
  2241. // TODO: Optimise away redundant pop/dup pairs.
  2242. fprintf(fp, "popn"); 
  2243. }
  2244. break;
  2245. default:
  2246. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2247. break;
  2248. }
  2249. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2250. }
  2251. S32 LLScriptPostDecrement::getSize()
  2252. {
  2253. return 0;
  2254. }
  2255. // Generate arg list.
  2256. static void print_cil_arg_list(LLFILE *fp, LLScriptArgString& args)
  2257. {
  2258. int i = 0;
  2259. bool finished = (i >= args.getNumber());
  2260. while(! finished)
  2261. {
  2262. print_cil_type(fp, args.getType(i));
  2263. ++i;
  2264. finished = (i >= args.getNumber());
  2265. if(! finished)
  2266. {
  2267. fprintf(fp, ", ");
  2268. }
  2269. }
  2270. }
  2271. void LLScriptFunctionCall::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2272. {
  2273. if (gErrorToText.getErrors())
  2274. {
  2275. return;
  2276. }
  2277. switch(pass)
  2278. {
  2279. case LSCP_PRETTY_PRINT:
  2280. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2281. fprintf(fp, "( ");
  2282. if (mExpressionList)
  2283. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2284. fprintf(fp, " )");
  2285. break;
  2286. case LSCP_EMIT_ASSEMBLY:
  2287. if (mIdentifier->mScopeEntry->mType)
  2288. fprintf(fp, "%sn", LSCRIPTTypePush[mIdentifier->mScopeEntry->mType]);
  2289. fprintf(fp,"PUSHEn");
  2290. fprintf(fp, "PUSHBPn");
  2291. if (mExpressionList)
  2292. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
  2293. fprintf(fp, "PUSHARGE %dn", mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
  2294. fprintf(fp, "PUSHSPn");
  2295. fprintf(fp, "PUSHARGI %dn", mIdentifier->mScopeEntry->mSize);
  2296. fprintf(fp, "ADD integer, integern");
  2297. fprintf(fp, "POPBPn");
  2298. if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
  2299. {
  2300. fprintf(fp, "CALL ");
  2301. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2302. }
  2303. else
  2304. {
  2305. fprintf(fp, "CALLLID ");
  2306. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2307. fprintf(fp, ", %d", (U32)mIdentifier->mScopeEntry->mLibraryNumber);
  2308. }
  2309. fprintf(fp, "n");
  2310. fprintf(fp, "POPBPn");
  2311. break;
  2312. case LSCP_SCOPE_PASS1:
  2313. if (mExpressionList)
  2314. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2315. break;
  2316. case LSCP_SCOPE_PASS2:
  2317. {
  2318. LLScriptScopeEntry *entry = scope->findEntryTyped(mIdentifier->mName, LIT_FUNCTION);
  2319. if (!entry)
  2320. {
  2321. gErrorToText.writeError(fp, this, LSERROR_UNDEFINED_NAME);
  2322. }
  2323. else
  2324. {
  2325. // if we did find it, make sure this identifier is associated with the correct scope entry
  2326. mIdentifier->mScopeEntry = entry;
  2327. }
  2328. if (mExpressionList)
  2329. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2330. }
  2331. break;
  2332. case LSCP_TYPE:
  2333. if (mIdentifier->mScopeEntry)
  2334. {
  2335. U64 argcount = 0;
  2336. if (mExpressionList)
  2337. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, argcount, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
  2338. if (!mIdentifier->mScopeEntry->mFunctionArgs.mString)
  2339. {
  2340. if (argcount)
  2341. {
  2342. gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
  2343. }
  2344. }
  2345. else if (argcount != strlen(mIdentifier->mScopeEntry->mFunctionArgs.mString))
  2346. {
  2347. gErrorToText.writeError(fp, this, LSERROR_FUNCTION_TYPE_ERROR);
  2348. }
  2349. }
  2350. if (mIdentifier->mScopeEntry)
  2351. type = mIdentifier->mScopeEntry->mType;
  2352. else
  2353. type = LST_NULL;
  2354. mReturnType = type;
  2355. break;
  2356. case LSCP_TO_STACK:
  2357. switch(mIdentifier->mScopeEntry->mType)
  2358. {
  2359. case LST_INTEGER:
  2360. case LST_FLOATINGPOINT:
  2361. case LST_STRING:
  2362. case LST_KEY:
  2363. case LST_LIST:
  2364. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
  2365. break;
  2366. case LST_VECTOR:
  2367. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEV]);
  2368. break;
  2369. case LST_QUATERNION:
  2370. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHEQ]);
  2371. break;
  2372. default:
  2373. break;
  2374. }
  2375. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHE]);
  2376. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHBP]);
  2377. if (mExpressionList)
  2378. {
  2379. // Don't let this change the count.
  2380. U64 dummy_count = 0;
  2381. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, dummy_count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
  2382. //mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, mIdentifier->mScopeEntry, 0, NULL);
  2383. }
  2384. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGE]);
  2385. chunk->addInteger(mIdentifier->mScopeEntry->mSize - mIdentifier->mScopeEntry->mOffset);
  2386. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHSP]);
  2387. chunk->addByte(LSCRIPTOpCodes[LOPC_PUSHARGI]);
  2388. chunk->addInteger(mIdentifier->mScopeEntry->mSize);
  2389. chunk->addByte(LSCRIPTOpCodes[LOPC_ADD]);
  2390. chunk->addByte(LSCRIPTTypeByte[LST_INTEGER] | LSCRIPTTypeHi4Bits[LST_INTEGER]);
  2391. chunk->addByte(LSCRIPTOpCodes[LOPC_POPBP]);
  2392. if (mIdentifier->mScopeEntry->mIDType != LIT_LIBRARY_FUNCTION)
  2393. {
  2394. chunk->addByte(LSCRIPTOpCodes[LOPC_CALL]);
  2395. chunk->addInteger(mIdentifier->mScopeEntry->mCount);
  2396. }
  2397. else
  2398. {
  2399. chunk->addByte(LSCRIPTOpCodes[LOPC_CALLLIB_TWO_BYTE]);
  2400. chunk->addU16(mIdentifier->mScopeEntry->mLibraryNumber);
  2401. }
  2402. break;
  2403. case LSCP_EMIT_CIL_ASSEMBLY:
  2404. {
  2405. bool library_call = (mIdentifier->mScopeEntry->mIDType == LIT_LIBRARY_FUNCTION);
  2406. if(! library_call)
  2407. {
  2408. // Load this pointer.
  2409. fprintf(fp, "ldarg.0n");
  2410. }
  2411. // Load args on to stack.
  2412. if (mExpressionList)
  2413. {
  2414. //mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Needed for is_parameter calls */, 0, NULL);
  2415. llassert(LET_FUNC_EXPRESSION_LIST == mExpressionList->mType);
  2416. print_cil_func_expression_list((LLScriptFuncExpressionList*) mExpressionList, fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry /* Caller entry needed for is_parameter calls */, 0, NULL, mIdentifier->mScopeEntry /* Callee entry needed for argument casting */);
  2417. }
  2418. // Make call.
  2419. if (! library_call)
  2420. {
  2421. fprintf(fp, "call instance ");
  2422. }
  2423. else
  2424. {
  2425. fprintf(fp, "call ");
  2426. }
  2427. print_cil_type(fp, mIdentifier->mScopeEntry->mType);
  2428. fprintf(fp, " class ");
  2429. if (library_call)
  2430. {
  2431. fprintf(fp, "[LslLibrary]LindenLab.SecondLife.Library::'");
  2432. }
  2433. else
  2434. {
  2435. // Prefix function name with g to distinguish from
  2436. // event handlers.
  2437. fprintf(fp, "%s", gScriptp->getClassName());
  2438. fprintf(fp, "::'g");
  2439. }
  2440. fprintf(fp, "%s", mIdentifier->mName);
  2441. fprintf(fp, "'(");
  2442. print_cil_arg_list(fp, mIdentifier->mScopeEntry->mFunctionArgs);
  2443. fprintf(fp, ")n");
  2444. }
  2445. break;
  2446. default:
  2447. mIdentifier->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2448. if (mExpressionList)
  2449. mExpressionList->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2450. break;
  2451. }
  2452. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2453. }
  2454. S32 LLScriptFunctionCall::getSize()
  2455. {
  2456. return 0;
  2457. }
  2458. void LLScriptPrint::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2459. {
  2460. if (gErrorToText.getErrors())
  2461. {
  2462. return;
  2463. }
  2464. switch(pass)
  2465. {
  2466. case LSCP_PRETTY_PRINT:
  2467. fprintf(fp, " PRINT ( ");
  2468. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2469. fprintf(fp, " )");
  2470. break;
  2471. case LSCP_EMIT_ASSEMBLY:
  2472. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2473. fprintf(fp, "PRINT %sn", LSCRIPTTypeNames[mLeftType]);
  2474. break;
  2475. case LSCP_TYPE:
  2476. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2477. mLeftType = type;
  2478. mReturnType = LST_NULL;
  2479. break;
  2480. case LSCP_TO_STACK:
  2481. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2482. chunk->addByte(LSCRIPTOpCodes[LOPC_PRINT]);
  2483. chunk->addByte(LSCRIPTTypeByte[mLeftType]);
  2484. break;
  2485. case LSCP_EMIT_CIL_ASSEMBLY:
  2486.         mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2487. print_cil_cast(fp, mLeftType, LST_STRING);
  2488.           fprintf(fp, "call void class [LslLibrary]LindenLab.SecondLife.Library::Print(string)");
  2489.         break;
  2490. default:
  2491. mExpression->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2492. break;
  2493. }
  2494. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2495. }
  2496. S32 LLScriptPrint::getSize()
  2497. {
  2498. return 0;
  2499. }
  2500. void LLScriptConstantExpression::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2501. {
  2502. if (gErrorToText.getErrors())
  2503. {
  2504. return;
  2505. }
  2506. switch(pass)
  2507. {
  2508. case LSCP_PRETTY_PRINT:
  2509. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2510. break;
  2511. case LSCP_TYPE:
  2512. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2513. mReturnType = type;
  2514. break;
  2515. case LSCP_TO_STACK:
  2516. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2517. break;
  2518. default:
  2519. mConstant->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2520. break;
  2521. }
  2522. gonext(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2523. }
  2524. S32 LLScriptConstantExpression::getSize()
  2525. {
  2526. return 0;
  2527. }
  2528. void LLScriptStatement::addStatement(LLScriptStatement *event)
  2529. {
  2530. if (mNextp)
  2531. {
  2532. event->mNextp = mNextp;
  2533. }
  2534. mNextp = event;
  2535. }
  2536. void LLScriptStatement::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2537. {
  2538. fprintf(fp, "Statement Base Class -- should never get here!n");
  2539. }
  2540. S32 LLScriptStatement::getSize()
  2541. {
  2542. printf("Statement Base Class -- should never get here!n");
  2543. return 0;
  2544. }
  2545. void LLScriptStatement::gonext(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2546. {
  2547. if (gErrorToText.getErrors())
  2548. {
  2549. return;
  2550. }
  2551. switch(pass)
  2552. {
  2553. case LSCP_PRETTY_PRINT:
  2554. if (mNextp)
  2555. {
  2556. fprintf(fp, ", ");
  2557. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2558. }
  2559. break;
  2560. case LSCP_EMIT_ASSEMBLY:
  2561. if (mNextp)
  2562. {
  2563. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2564. }
  2565. break;
  2566. default:
  2567. if (mNextp)
  2568. {
  2569. mNextp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2570. }
  2571. break;
  2572. }
  2573. }
  2574. S32 LLScriptStatementSequence::getSize()
  2575. {
  2576. return 0;
  2577. }
  2578. void LLScriptStatementSequence::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
  2579. {
  2580. if (gErrorToText.getErrors())
  2581. {
  2582. return;
  2583. }
  2584. switch(pass)
  2585. {
  2586. case LSCP_PRETTY_PRINT:
  2587. mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2588. mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2589. break;
  2590. case LSCP_EMIT_ASSEMBLY:
  2591. mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2592. mSecondp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2593. break;
  2594. case LSCP_PRUNE:
  2595. mFirstp->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
  2596. if (prunearg)
  2597. {
  2598. // babbage: only warn on first dead code block found.
  2599. if(ptype != LSPRUNE_DEAD_CODE)
  2600. {
  2601. gErrorToText.writeWarning(fp, this, LSWARN_DEAD_CODE);
  2602. }
  2603. // babbage: set prune type to LSPRUNE_DEAD_CODE to mask other
  2604. // prune errors.
  2605. ptype = LSPRUNE_DEAD_CODE;
  2606. // babbage: reset prunearg, to track whether return needed at
  2607. // end of dead code path as CIL always needs a return/throw.
  2608. prunearg = FALSE;