CSCodeGeneratorTest.cs 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System.Collections.Generic;
  28. using System.Text.RegularExpressions;
  29. using NUnit.Framework;
  30. using OpenSim.Region.ScriptEngine.Shared.CodeTools;
  31. namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
  32. {
  33. /// <summary>
  34. /// Tests the LSL compiler, both the code generation and transformation.
  35. /// Each test has some LSL code as input and C# code as expected output.
  36. /// The generated C# code is compared against the expected C# code.
  37. /// </summary>
  38. [TestFixture]
  39. public class CSCodeGeneratorTest
  40. {
  41. [Test]
  42. public void TestDefaultState()
  43. {
  44. string input = @"default
  45. {
  46. state_entry()
  47. {
  48. }
  49. }
  50. ";
  51. string expected =
  52. "\n public void default_event_state_entry()" +
  53. "\n {" +
  54. "\n }\n";
  55. CSCodeGenerator cg = new CSCodeGenerator();
  56. string output = cg.Convert(input);
  57. Assert.AreEqual(expected, output);
  58. }
  59. [Test]
  60. public void TestCustomState()
  61. {
  62. string input = @"default
  63. {
  64. state_entry()
  65. {
  66. }
  67. }
  68. state another_state
  69. {
  70. no_sensor()
  71. {
  72. }
  73. }
  74. ";
  75. string expected =
  76. "\n public void default_event_state_entry()" +
  77. "\n {" +
  78. "\n }" +
  79. "\n public void another_state_event_no_sensor()" +
  80. "\n {" +
  81. "\n }\n";
  82. CSCodeGenerator cg = new CSCodeGenerator();
  83. string output = cg.Convert(input);
  84. Assert.AreEqual(expected, output);
  85. }
  86. [Test]
  87. public void TestEventWithArguments()
  88. {
  89. string input = @"default
  90. {
  91. at_rot_target(integer tnum, rotation targetrot, rotation ourrot)
  92. {
  93. }
  94. }
  95. ";
  96. string expected =
  97. "\n public void default_event_at_rot_target(LSL_Types.LSLInteger tnum, LSL_Types.Quaternion targetrot, LSL_Types.Quaternion ourrot)" +
  98. "\n {" +
  99. "\n }\n";
  100. CSCodeGenerator cg = new CSCodeGenerator();
  101. string output = cg.Convert(input);
  102. Assert.AreEqual(expected, output);
  103. }
  104. [Test]
  105. public void TestIntegerDeclaration()
  106. {
  107. string input = @"default
  108. {
  109. touch_start(integer num_detected)
  110. {
  111. integer x;
  112. }
  113. }
  114. ";
  115. string expected =
  116. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  117. "\n {" +
  118. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
  119. "\n }\n";
  120. CSCodeGenerator cg = new CSCodeGenerator();
  121. string output = cg.Convert(input);
  122. Assert.AreEqual(expected, output);
  123. }
  124. [Test]
  125. public void TestAssignments()
  126. {
  127. string input = @"default
  128. {
  129. touch_start(integer num_detected)
  130. {
  131. string y;
  132. integer x = 14;
  133. y = ""Hello"";
  134. }
  135. }
  136. ";
  137. string expected =
  138. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  139. "\n {" +
  140. "\n LSL_Types.LSLString y = new LSL_Types.LSLString(\"\");" +
  141. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14);" +
  142. "\n y = new LSL_Types.LSLString(\"Hello\");" +
  143. "\n }\n";
  144. CSCodeGenerator cg = new CSCodeGenerator();
  145. string output = cg.Convert(input);
  146. Assert.AreEqual(expected, output);
  147. }
  148. [Test]
  149. public void TestAdditionSubtractionOperator()
  150. {
  151. string input = @"default
  152. {
  153. touch_start(integer num_detected)
  154. {
  155. integer y = -3;
  156. integer x = 14 + 6;
  157. y = 12 +45+20+x + 23 + 1 + x + y;
  158. y = 12 + -45 + - 20 + x + 23 + -1 + x + y;
  159. }
  160. }
  161. ";
  162. string expected =
  163. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)\n" +
  164. " {\n" +
  165. " LSL_Types.LSLInteger y = -new LSL_Types.LSLInteger(3);\n" +
  166. " LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);\n" +
  167. " y = new LSL_Types.LSLInteger(12) + new LSL_Types.LSLInteger(45) + new LSL_Types.LSLInteger(20) + x + new LSL_Types.LSLInteger(23) + new LSL_Types.LSLInteger(1) + x + y;\n" +
  168. " y = new LSL_Types.LSLInteger(12) + -new LSL_Types.LSLInteger(45) + -new LSL_Types.LSLInteger(20) + x + new LSL_Types.LSLInteger(23) + -new LSL_Types.LSLInteger(1) + x + y;\n" +
  169. " }\n";
  170. CSCodeGenerator cg = new CSCodeGenerator();
  171. string output = cg.Convert(input);
  172. Assert.AreEqual(expected, output);
  173. }
  174. [Test]
  175. public void TestStrings()
  176. {
  177. string input = @"default
  178. {
  179. touch_start(integer num_detected)
  180. {
  181. llOwnerSay(""Testing, 1, 2, 3"");
  182. llSay(0, ""I can hear you!"");
  183. some_custom_function(1, 2, 3 +x, 4, ""five"", ""arguments"");
  184. }
  185. }
  186. ";
  187. string expected =
  188. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  189. "\n {" +
  190. "\n llOwnerSay(new LSL_Types.LSLString(\"Testing, 1, 2, 3\"));" +
  191. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"I can hear you!\"));" +
  192. "\n some_custom_function(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger(2), new LSL_Types.LSLInteger(3) + x, new LSL_Types.LSLInteger(4), new LSL_Types.LSLString(\"five\"), new LSL_Types.LSLString(\"arguments\"));" +
  193. "\n }" +
  194. "\n";
  195. CSCodeGenerator cg = new CSCodeGenerator();
  196. string output = cg.Convert(input);
  197. Assert.AreEqual(expected, output);
  198. }
  199. [Test]
  200. public void TestBinaryExpression()
  201. {
  202. string input = @"default
  203. {
  204. touch_start(integer num_detected)
  205. {
  206. integer y;
  207. integer x = 14 + 6;
  208. y = 12 - 3;
  209. y = 12 * 3;
  210. y = 12 / 3;
  211. y = 12 | 3;
  212. y = 12 & 3;
  213. y = 12 % 3;
  214. y = 12 + 45 - 20 * x / 23 | 1 & x + y;
  215. }
  216. }
  217. ";
  218. string expected =
  219. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  220. "\n {" +
  221. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
  222. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);" +
  223. "\n y = new LSL_Types.LSLInteger(12) - new LSL_Types.LSLInteger(3);" +
  224. "\n y = new LSL_Types.LSLInteger(12) * new LSL_Types.LSLInteger(3);" +
  225. "\n y = new LSL_Types.LSLInteger(12) / new LSL_Types.LSLInteger(3);" +
  226. "\n y = new LSL_Types.LSLInteger(12) | new LSL_Types.LSLInteger(3);" +
  227. "\n y = new LSL_Types.LSLInteger(12) & new LSL_Types.LSLInteger(3);" +
  228. "\n y = new LSL_Types.LSLInteger(12) % new LSL_Types.LSLInteger(3);" +
  229. "\n y = new LSL_Types.LSLInteger(12) + new LSL_Types.LSLInteger(45) - new LSL_Types.LSLInteger(20) * x / new LSL_Types.LSLInteger(23) | new LSL_Types.LSLInteger(1) & x + y;" +
  230. "\n }\n";
  231. CSCodeGenerator cg = new CSCodeGenerator();
  232. string output = cg.Convert(input);
  233. Assert.AreEqual(expected, output);
  234. }
  235. [Test]
  236. public void TestFloatConstants()
  237. {
  238. string input = @"default
  239. {
  240. touch_start(integer num_detected)
  241. {
  242. float y = 1.1;
  243. y = 1.123E3;
  244. y = 1.123e3;
  245. y = 1.123E+3;
  246. y = 1.123e+3;
  247. y = 1.123E-3;
  248. y = 1.123e-3;
  249. y = .4;
  250. y = -1.123E3;
  251. y = -1.123e3;
  252. y = -1.123E+3;
  253. y = -1.123e+3;
  254. y = -1.123E-3;
  255. y = -1.123e-3;
  256. y = -.4;
  257. y = 12.3 + -1.45E3 - 1.20e-2;
  258. }
  259. }
  260. ";
  261. string expected =
  262. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  263. "\n {" +
  264. "\n LSL_Types.LSLFloat y = new LSL_Types.LSLFloat(1.1);" +
  265. "\n y = new LSL_Types.LSLFloat(1.123E3);" +
  266. "\n y = new LSL_Types.LSLFloat(1.123e3);" +
  267. "\n y = new LSL_Types.LSLFloat(1.123E+3);" +
  268. "\n y = new LSL_Types.LSLFloat(1.123e+3);" +
  269. "\n y = new LSL_Types.LSLFloat(1.123E-3);" +
  270. "\n y = new LSL_Types.LSLFloat(1.123e-3);" +
  271. "\n y = new LSL_Types.LSLFloat(.4);" +
  272. "\n y = -new LSL_Types.LSLFloat(1.123E3);" +
  273. "\n y = -new LSL_Types.LSLFloat(1.123e3);" +
  274. "\n y = -new LSL_Types.LSLFloat(1.123E+3);" +
  275. "\n y = -new LSL_Types.LSLFloat(1.123e+3);" +
  276. "\n y = -new LSL_Types.LSLFloat(1.123E-3);" +
  277. "\n y = -new LSL_Types.LSLFloat(1.123e-3);" +
  278. "\n y = -new LSL_Types.LSLFloat(.4);" +
  279. "\n y = new LSL_Types.LSLFloat(12.3) + -new LSL_Types.LSLFloat(1.45E3) - new LSL_Types.LSLFloat(1.20e-2);" +
  280. "\n }\n";
  281. CSCodeGenerator cg = new CSCodeGenerator();
  282. string output = cg.Convert(input);
  283. Assert.AreEqual(expected, output);
  284. }
  285. [Test]
  286. public void TestComments()
  287. {
  288. string input = @"// this test tests comments
  289. default
  290. {
  291. touch_start(integer num_detected) // this should be stripped
  292. {
  293. // fill in code here...
  294. }
  295. }
  296. ";
  297. string expected =
  298. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  299. "\n {" +
  300. "\n }\n";
  301. CSCodeGenerator cg = new CSCodeGenerator();
  302. string output = cg.Convert(input);
  303. Assert.AreEqual(expected, output);
  304. }
  305. [Test]
  306. public void TestStringsWithEscapedQuotesAndComments()
  307. {
  308. string input = @"// this test tests strings, with escaped quotes and comments in strings
  309. default
  310. {
  311. touch_start(integer num_detected)
  312. {
  313. string s1 = ""this is a string."";
  314. string s2 = ""this is a string ""+""with an escaped \"" inside it."";
  315. s1 = s2+"" and this ""+""is a string with // comments."";
  316. string onemore = ""[\^@]"";
  317. string multiline = ""Good evening Sir,
  318. my name is Steve.
  319. I come from a rough area.
  320. I used to be addicted to crack
  321. but now I am off it and trying to stay clean.
  322. That is why I am selling magazine subscriptions.""; // http://www.imdb.com/title/tt0151804/quotes
  323. }
  324. }
  325. ";
  326. string expected =
  327. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  328. "\n {" +
  329. "\n LSL_Types.LSLString s1 = new LSL_Types.LSLString(\"this is a string.\");" +
  330. "\n LSL_Types.LSLString s2 = new LSL_Types.LSLString(\"this is a string \") + new LSL_Types.LSLString(\"with an escaped \\\" inside it.\");" +
  331. "\n s1 = s2 + new LSL_Types.LSLString(\" and this \") + new LSL_Types.LSLString(\"is a string with // comments.\");" +
  332. "\n LSL_Types.LSLString onemore = new LSL_Types.LSLString(\"[\\^@]\");" +
  333. "\n LSL_Types.LSLString multiline = new LSL_Types.LSLString(\"Good evening Sir,\\n my name is Steve.\\n I come from a rough area.\\n I used to be addicted to crack\\n but now I am off it and trying to stay clean.\\n That is why I am selling magazine subscriptions.\");" +
  334. "\n }\n";
  335. CSCodeGenerator cg = new CSCodeGenerator();
  336. string output = cg.Convert(input);
  337. Assert.AreEqual(expected, output);
  338. }
  339. [Test]
  340. public void TestGlobalDefinedFunctions()
  341. {
  342. string input = @"// this test tests custom defined functions
  343. string onefunc()
  344. {
  345. return ""Hi from onefunc()!"";
  346. }
  347. twofunc(string s)
  348. {
  349. llSay(1000, s);
  350. }
  351. default
  352. {
  353. touch_start(integer num_detected)
  354. {
  355. llSay(2000, onefunc());
  356. twofunc();
  357. }
  358. }
  359. ";
  360. string expected =
  361. "\n LSL_Types.LSLString onefunc()" +
  362. "\n {" +
  363. "\n return new LSL_Types.LSLString(\"Hi from onefunc()!\");" +
  364. "\n }" +
  365. "\n void twofunc(LSL_Types.LSLString s)" +
  366. "\n {" +
  367. "\n llSay(new LSL_Types.LSLInteger(1000), s);" +
  368. "\n }" +
  369. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  370. "\n {" +
  371. "\n llSay(new LSL_Types.LSLInteger(2000), onefunc());" +
  372. "\n twofunc();" +
  373. "\n }\n";
  374. CSCodeGenerator cg = new CSCodeGenerator();
  375. string output = cg.Convert(input);
  376. Assert.AreEqual(expected, output);
  377. }
  378. [Test]
  379. public void TestGlobalDeclaredVariables()
  380. {
  381. string input = @"// this test tests custom defined functions and global variables
  382. string globalString;
  383. integer globalInt = 14;
  384. integer anotherGlobal = 20 * globalInt;
  385. string onefunc()
  386. {
  387. globalString = "" ...and the global!"";
  388. return ""Hi "" +
  389. ""from "" +
  390. ""onefunc()!"" + globalString;
  391. }
  392. twofunc(string s)
  393. {
  394. llSay(1000, s);
  395. }
  396. default
  397. {
  398. touch_start(integer num_detected)
  399. {
  400. llSay(2000, onefunc());
  401. twofunc();
  402. }
  403. }
  404. ";
  405. string expected =
  406. "\n LSL_Types.LSLString globalString = new LSL_Types.LSLString(\"\");" +
  407. "\n LSL_Types.LSLInteger globalInt = new LSL_Types.LSLInteger(14);" +
  408. "\n LSL_Types.LSLInteger anotherGlobal = new LSL_Types.LSLInteger(20) * globalInt;" +
  409. "\n LSL_Types.LSLString onefunc()" +
  410. "\n {" +
  411. "\n globalString = new LSL_Types.LSLString(\" ...and the global!\");" +
  412. "\n return new LSL_Types.LSLString(\"Hi \") + new LSL_Types.LSLString(\"from \") + new LSL_Types.LSLString(\"onefunc()!\") + globalString;" +
  413. "\n }" +
  414. "\n void twofunc(LSL_Types.LSLString s)" +
  415. "\n {" +
  416. "\n llSay(new LSL_Types.LSLInteger(1000), s);" +
  417. "\n }" +
  418. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  419. "\n {" +
  420. "\n llSay(new LSL_Types.LSLInteger(2000), onefunc());" +
  421. "\n twofunc();" +
  422. "\n }\n";
  423. CSCodeGenerator cg = new CSCodeGenerator();
  424. string output = cg.Convert(input);
  425. Assert.AreEqual(expected, output);
  426. }
  427. [Test]
  428. public void TestMoreAssignments()
  429. {
  430. string input = @"// this test tests +=, -=, *=, /=, %=
  431. string globalString;
  432. integer globalInt = 14;
  433. string onefunc(string addition)
  434. {
  435. globalInt -= 2;
  436. globalString += addition;
  437. return ""Hi "" +
  438. ""from "" +
  439. ""onefunc()! "" + globalString;
  440. }
  441. default
  442. {
  443. touch_start(integer num_detected)
  444. {
  445. llSay(2000, onefunc());
  446. integer x = 2;
  447. x *= 3;
  448. x /= 14 + -2;
  449. x %= 10;
  450. }
  451. }
  452. ";
  453. string expected =
  454. "\n LSL_Types.LSLString globalString = new LSL_Types.LSLString(\"\");" +
  455. "\n LSL_Types.LSLInteger globalInt = new LSL_Types.LSLInteger(14);" +
  456. "\n LSL_Types.LSLString onefunc(LSL_Types.LSLString addition)" +
  457. "\n {" +
  458. "\n globalInt -= new LSL_Types.LSLInteger(2);" +
  459. "\n globalString += addition;" +
  460. "\n return new LSL_Types.LSLString(\"Hi \") + new LSL_Types.LSLString(\"from \") + new LSL_Types.LSLString(\"onefunc()! \") + globalString;" +
  461. "\n }" +
  462. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  463. "\n {" +
  464. "\n llSay(new LSL_Types.LSLInteger(2000), onefunc());" +
  465. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(2);" +
  466. "\n x *= new LSL_Types.LSLInteger(3);" +
  467. "\n x /= new LSL_Types.LSLInteger(14) + -new LSL_Types.LSLInteger(2);" +
  468. "\n x %= new LSL_Types.LSLInteger(10);" +
  469. "\n }\n";
  470. CSCodeGenerator cg = new CSCodeGenerator();
  471. string output = cg.Convert(input);
  472. Assert.AreEqual(expected, output);
  473. }
  474. [Test]
  475. public void TestVectorConstantNotation()
  476. {
  477. string input = @"default
  478. {
  479. touch_start(integer num_detected)
  480. {
  481. vector y = <1.2, llGetMeAFloat(), 4.4>;
  482. rotation x = <0.1, 0.1, one + 2, 0.9>;
  483. y = <0.1, 0.1, 1.1 - three - two+eight*8>;
  484. }
  485. }
  486. ";
  487. string expected =
  488. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  489. "\n {" +
  490. "\n LSL_Types.Vector3 y = new LSL_Types.Vector3(new LSL_Types.LSLFloat(1.2), llGetMeAFloat(), new LSL_Types.LSLFloat(4.4));" +
  491. "\n LSL_Types.Quaternion x = new LSL_Types.Quaternion(new LSL_Types.LSLFloat(0.1), new LSL_Types.LSLFloat(0.1), one + new LSL_Types.LSLInteger(2), new LSL_Types.LSLFloat(0.9));" +
  492. "\n y = new LSL_Types.Vector3(new LSL_Types.LSLFloat(0.1), new LSL_Types.LSLFloat(0.1), new LSL_Types.LSLFloat(1.1) - three - two + eight * new LSL_Types.LSLInteger(8));" +
  493. "\n }\n";
  494. CSCodeGenerator cg = new CSCodeGenerator();
  495. string output = cg.Convert(input);
  496. Assert.AreEqual(expected, output);
  497. }
  498. [Test]
  499. public void TestVectorMemberAccess()
  500. {
  501. string input = @"default
  502. {
  503. touch_start(integer num_detected)
  504. {
  505. vector y = <1.2, llGetMeAFloat(), 4.4>;
  506. x = y.x + 1.1;
  507. y.x = 1.1;
  508. }
  509. }
  510. ";
  511. string expected =
  512. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  513. "\n {" +
  514. "\n LSL_Types.Vector3 y = new LSL_Types.Vector3(new LSL_Types.LSLFloat(1.2), llGetMeAFloat(), new LSL_Types.LSLFloat(4.4));" +
  515. "\n x = y.x + new LSL_Types.LSLFloat(1.1);" +
  516. "\n y.x = new LSL_Types.LSLFloat(1.1);" +
  517. "\n }\n";
  518. CSCodeGenerator cg = new CSCodeGenerator();
  519. string output = cg.Convert(input);
  520. Assert.AreEqual(expected, output);
  521. }
  522. [Test]
  523. public void TestExpressionInParentheses()
  524. {
  525. string input = @"default
  526. {
  527. touch_start(integer num_detected)
  528. {
  529. integer y = -3;
  530. integer x = 14 + 6;
  531. y = 12 +45+20+x + (23 + 1) + x + y;
  532. y = (12 + -45 + -20 + x + 23 )+ -1 + x + y;
  533. }
  534. }
  535. ";
  536. string expected =
  537. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  538. "\n {" +
  539. "\n LSL_Types.LSLInteger y = -new LSL_Types.LSLInteger(3);" +
  540. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);" +
  541. "\n y = new LSL_Types.LSLInteger(12) + new LSL_Types.LSLInteger(45) + new LSL_Types.LSLInteger(20) + x + (new LSL_Types.LSLInteger(23) + new LSL_Types.LSLInteger(1)) + x + y;" +
  542. "\n y = (new LSL_Types.LSLInteger(12) + -new LSL_Types.LSLInteger(45) + -new LSL_Types.LSLInteger(20) + x + new LSL_Types.LSLInteger(23)) + -new LSL_Types.LSLInteger(1) + x + y;" +
  543. "\n }\n";
  544. CSCodeGenerator cg = new CSCodeGenerator();
  545. string output = cg.Convert(input);
  546. Assert.AreEqual(expected, output);
  547. }
  548. [Test]
  549. public void TestIncrementDecrementOperator()
  550. {
  551. string input = @"// here we'll test the ++ and -- operators
  552. default
  553. {
  554. touch_start(integer num_detected)
  555. {
  556. integer y = -3;
  557. integer x = 14 + 6;
  558. y = 12 +45+20+x++ + (23 + 1) + ++x + -- y;
  559. y = (12 + -45 + -20 + x-- + 23 )+ -1 + x -- + ++y;
  560. }
  561. }
  562. ";
  563. string expected =
  564. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  565. "\n {" +
  566. "\n LSL_Types.LSLInteger y = -new LSL_Types.LSLInteger(3);" +
  567. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);" +
  568. "\n y = new LSL_Types.LSLInteger(12) + new LSL_Types.LSLInteger(45) + new LSL_Types.LSLInteger(20) + x++ + (new LSL_Types.LSLInteger(23) + new LSL_Types.LSLInteger(1)) + ++x + --y;" +
  569. "\n y = (new LSL_Types.LSLInteger(12) + -new LSL_Types.LSLInteger(45) + -new LSL_Types.LSLInteger(20) + x-- + new LSL_Types.LSLInteger(23)) + -new LSL_Types.LSLInteger(1) + x-- + ++y;" +
  570. "\n }\n";
  571. CSCodeGenerator cg = new CSCodeGenerator();
  572. string output = cg.Convert(input);
  573. Assert.AreEqual(expected, output);
  574. }
  575. [Test]
  576. public void TestLists()
  577. {
  578. string input = @"// testing lists
  579. default
  580. {
  581. touch_start(integer num_detected)
  582. {
  583. list l = [];
  584. list m = [1, two, ""three"", <4.0, 4.0, 4.0>, 5 + 5];
  585. llCallSomeFunc(1, llAnotherFunc(), [1, 2, 3]);
  586. }
  587. }
  588. ";
  589. string expected =
  590. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  591. "\n {" +
  592. "\n LSL_Types.list l = new LSL_Types.list();" +
  593. "\n LSL_Types.list m = new LSL_Types.list(new LSL_Types.LSLInteger(1), two, new LSL_Types.LSLString(\"three\"), new LSL_Types.Vector3(new LSL_Types.LSLFloat(4.0), new LSL_Types.LSLFloat(4.0), new LSL_Types.LSLFloat(4.0)), new LSL_Types.LSLInteger(5) + new LSL_Types.LSLInteger(5));" +
  594. "\n llCallSomeFunc(new LSL_Types.LSLInteger(1), llAnotherFunc(), new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger(2), new LSL_Types.LSLInteger(3)));" +
  595. "\n }\n";
  596. CSCodeGenerator cg = new CSCodeGenerator();
  597. string output = cg.Convert(input);
  598. Assert.AreEqual(expected, output);
  599. }
  600. [Test]
  601. public void TestIfStatement()
  602. {
  603. string input = @"// let's test if statements
  604. default
  605. {
  606. touch_start(integer num_detected)
  607. {
  608. integer x = 1;
  609. if (x) llSay(0, ""Hello"");
  610. if (1)
  611. {
  612. llSay(0, ""Hi"");
  613. integer r = 3;
  614. return;
  615. }
  616. if (f(x)) llSay(0, ""f(x) is true"");
  617. else llSay(0, ""f(x) is false"");
  618. if (x + y) llSay(0, ""x + y is true"");
  619. else if (y - x) llSay(0, ""y - x is true"");
  620. else llSay(0, ""Who needs x and y anyway?"");
  621. if (x * y) llSay(0, ""x * y is true"");
  622. else if (y / x)
  623. {
  624. llSay(0, ""uh-oh, y / x is true, exiting"");
  625. return;
  626. }
  627. else llSay(0, ""Who needs x and y anyway?"");
  628. // and now for my last trick
  629. if (x % y) llSay(0, ""x is true"");
  630. else if (y & x) llSay(0, ""y is true"");
  631. else if (z | x) llSay(0, ""z is true"");
  632. else if (a * (b + x)) llSay(0, ""a is true"");
  633. else if (b) llSay(0, ""b is true"");
  634. else if (v) llSay(0, ""v is true"");
  635. else llSay(0, ""Everything is lies!"");
  636. }
  637. }
  638. ";
  639. string expected =
  640. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  641. "\n {" +
  642. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
  643. "\n if (x)" +
  644. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hello\"));" +
  645. "\n if (new LSL_Types.LSLInteger(1))" +
  646. "\n {" +
  647. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hi\"));" +
  648. "\n LSL_Types.LSLInteger r = new LSL_Types.LSLInteger(3);" +
  649. "\n return ;" +
  650. "\n }" +
  651. "\n if (f(x))" +
  652. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"f(x) is true\"));" +
  653. "\n else" +
  654. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"f(x) is false\"));" +
  655. "\n if (x + y)" +
  656. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x + y is true\"));" +
  657. "\n else" +
  658. "\n if (y - x)" +
  659. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y - x is true\"));" +
  660. "\n else" +
  661. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
  662. "\n if (x * y)" +
  663. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x * y is true\"));" +
  664. "\n else" +
  665. "\n if (y / x)" +
  666. "\n {" +
  667. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"uh-oh, y / x is true, exiting\"));" +
  668. "\n return ;" +
  669. "\n }" +
  670. "\n else" +
  671. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
  672. "\n if (x % y)" +
  673. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
  674. "\n else" +
  675. "\n if (y & x)" +
  676. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y is true\"));" +
  677. "\n else" +
  678. "\n if (z | x)" +
  679. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"z is true\"));" +
  680. "\n else" +
  681. "\n if (a * (b + x))" +
  682. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"a is true\"));" +
  683. "\n else" +
  684. "\n if (b)" +
  685. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"b is true\"));" +
  686. "\n else" +
  687. "\n if (v)" +
  688. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"v is true\"));" +
  689. "\n else" +
  690. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Everything is lies!\"));" +
  691. "\n }\n";
  692. CSCodeGenerator cg = new CSCodeGenerator();
  693. string output = cg.Convert(input);
  694. Assert.AreEqual(expected, output);
  695. }
  696. [Test]
  697. public void TestIfElseStatement()
  698. {
  699. string input = @"// let's test complex logical expressions
  700. default
  701. {
  702. touch_start(integer num_detected)
  703. {
  704. integer x = 1;
  705. integer y = 0;
  706. if (x && y) llSay(0, ""Hello"");
  707. if (x || y)
  708. {
  709. llSay(0, ""Hi"");
  710. integer r = 3;
  711. return;
  712. }
  713. if (x && y || z) llSay(0, ""x is true"");
  714. else llSay(0, ""x is false"");
  715. if (x == y) llSay(0, ""x is true"");
  716. else if (y < x) llSay(0, ""y is true"");
  717. else llSay(0, ""Who needs x and y anyway?"");
  718. if (x > y) llSay(0, ""x is true"");
  719. else if (y <= x)
  720. {
  721. llSay(0, ""uh-oh, y is true, exiting"");
  722. return;
  723. }
  724. else llSay(0, ""Who needs x and y anyway?"");
  725. // and now for my last trick
  726. if (x >= y) llSay(0, ""x is true"");
  727. else if (y != x) llSay(0, ""y is true"");
  728. else if (!z) llSay(0, ""z is true"");
  729. else if (!(a && b)) llSay(0, ""a is true"");
  730. else if (b) llSay(0, ""b is true"");
  731. else if (v) llSay(0, ""v is true"");
  732. else llSay(0, ""Everything is lies!"");
  733. }
  734. }
  735. ";
  736. string expected =
  737. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  738. "\n {" +
  739. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
  740. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
  741. "\n if (x && y)" +
  742. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hello\"));" +
  743. "\n if (x || y)" +
  744. "\n {" +
  745. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hi\"));" +
  746. "\n LSL_Types.LSLInteger r = new LSL_Types.LSLInteger(3);" +
  747. "\n return ;" +
  748. "\n }" +
  749. "\n if (x && y || z)" +
  750. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
  751. "\n else" +
  752. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is false\"));" +
  753. "\n if (x == y)" +
  754. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
  755. "\n else" +
  756. "\n if (y < x)" +
  757. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y is true\"));" +
  758. "\n else" +
  759. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
  760. "\n if (x > y)" +
  761. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
  762. "\n else" +
  763. "\n if (y <= x)" +
  764. "\n {" +
  765. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"uh-oh, y is true, exiting\"));" +
  766. "\n return ;" +
  767. "\n }" +
  768. "\n else" +
  769. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
  770. "\n if (x >= y)" +
  771. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
  772. "\n else" +
  773. "\n if (y != x)" +
  774. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y is true\"));" +
  775. "\n else" +
  776. "\n if (!z)" +
  777. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"z is true\"));" +
  778. "\n else" +
  779. "\n if (!(a && b))" +
  780. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"a is true\"));" +
  781. "\n else" +
  782. "\n if (b)" +
  783. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"b is true\"));" +
  784. "\n else" +
  785. "\n if (v)" +
  786. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"v is true\"));" +
  787. "\n else" +
  788. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Everything is lies!\"));" +
  789. "\n }\n";
  790. CSCodeGenerator cg = new CSCodeGenerator();
  791. string output = cg.Convert(input);
  792. Assert.AreEqual(expected, output);
  793. }
  794. [Test]
  795. public void TestWhileLoop()
  796. {
  797. string input = @"// let's test while loops
  798. default
  799. {
  800. touch_start(integer num_detected)
  801. {
  802. integer x = 1;
  803. integer y = 0;
  804. while (x) llSay(0, ""To infinity, and beyond!"");
  805. while (0 || (x && 0))
  806. {
  807. llSay(0, ""Never say never."");
  808. return;
  809. }
  810. }
  811. }
  812. ";
  813. string expected =
  814. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  815. "\n {" +
  816. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
  817. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
  818. "\n while (x)" +
  819. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"To infinity, and beyond!\"));" +
  820. "\n while (new LSL_Types.LSLInteger(0) || (x && new LSL_Types.LSLInteger(0)))" +
  821. "\n {" +
  822. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Never say never.\"));" +
  823. "\n return ;" +
  824. "\n }" +
  825. "\n }\n";
  826. CSCodeGenerator cg = new CSCodeGenerator();
  827. string output = cg.Convert(input);
  828. Assert.AreEqual(expected, output);
  829. }
  830. [Test]
  831. public void TestDoWhileLoop()
  832. {
  833. string input = @"// let's test do-while loops
  834. default
  835. {
  836. touch_start(integer num_detected)
  837. {
  838. integer x = 1;
  839. integer y = 0;
  840. do llSay(0, ""And we're doing..."");
  841. while (x);
  842. do
  843. {
  844. llSay(0, ""I like it here. I wish we could stay here forever."");
  845. y--;
  846. } while (y);
  847. }
  848. }
  849. ";
  850. string expected =
  851. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  852. "\n {" +
  853. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
  854. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
  855. "\n do" +
  856. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"And we're doing...\"));" +
  857. "\n while (x);" +
  858. "\n do" +
  859. "\n {" +
  860. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"I like it here. I wish we could stay here forever.\"));" +
  861. "\n y--;" +
  862. "\n }" +
  863. "\n while (y);" +
  864. "\n }\n";
  865. CSCodeGenerator cg = new CSCodeGenerator();
  866. string output = cg.Convert(input);
  867. Assert.AreEqual(expected, output);
  868. }
  869. [Test]
  870. public void TestForLoop()
  871. {
  872. string input = @"// let's test for loops
  873. default
  874. {
  875. touch_start(integer num_detected)
  876. {
  877. integer x = 1;
  878. integer y = 0;
  879. for (x = 10; x >= 0; x--)
  880. {
  881. llOwnerSay(""Launch in T minus "" + x);
  882. IncreaseRocketPower();
  883. }
  884. for (x = 0, y = 6; y > 0 && x != y; x++, y--) llOwnerSay(""Hi "" + x + "", "" + y);
  885. for (x = 0, y = 6; ! y; x++,y--) llOwnerSay(""Hi "" + x + "", "" + y);
  886. }
  887. }
  888. ";
  889. string expected =
  890. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  891. "\n {" +
  892. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
  893. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
  894. "\n for (x = new LSL_Types.LSLInteger(10); x >= new LSL_Types.LSLInteger(0); x--)" +
  895. "\n {" +
  896. "\n llOwnerSay(new LSL_Types.LSLString(\"Launch in T minus \") + x);" +
  897. "\n IncreaseRocketPower();" +
  898. "\n }" +
  899. "\n for (x = new LSL_Types.LSLInteger(0), y = new LSL_Types.LSLInteger(6); y > new LSL_Types.LSLInteger(0) && x != y; x++, y--)" +
  900. "\n llOwnerSay(new LSL_Types.LSLString(\"Hi \") + x + new LSL_Types.LSLString(\", \") + y);" +
  901. "\n for (x = new LSL_Types.LSLInteger(0), y = new LSL_Types.LSLInteger(6); !y; x++, y--)" +
  902. "\n llOwnerSay(new LSL_Types.LSLString(\"Hi \") + x + new LSL_Types.LSLString(\", \") + y);" +
  903. "\n }\n";
  904. CSCodeGenerator cg = new CSCodeGenerator();
  905. string output = cg.Convert(input);
  906. Assert.AreEqual(expected, output);
  907. }
  908. [Test]
  909. public void TestFloatsWithTrailingDecimal()
  910. {
  911. string input = @"// a curious feature of LSL that allows floats to be defined with a trailing dot
  912. default
  913. {
  914. touch_start(integer num_detected)
  915. {
  916. float y = 1.;
  917. y = 1.E3;
  918. y = 1.e3;
  919. y = 1.E+3;
  920. y = 1.e+3;
  921. y = 1.E-3;
  922. y = 1.e-3;
  923. y = -1.E3;
  924. y = -1.e3;
  925. y = -1.E+3;
  926. y = -1.e+3;
  927. y = -1.E-3;
  928. y = -1.e-3;
  929. y = 12. + -1.E3 - 1.e-2;
  930. vector v = <0.,0.,0.>;
  931. }
  932. }
  933. ";
  934. string expected =
  935. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  936. "\n {" +
  937. "\n LSL_Types.LSLFloat y = new LSL_Types.LSLFloat(1.0);" +
  938. "\n y = new LSL_Types.LSLFloat(1.0E3);" +
  939. "\n y = new LSL_Types.LSLFloat(1.0e3);" +
  940. "\n y = new LSL_Types.LSLFloat(1.0E+3);" +
  941. "\n y = new LSL_Types.LSLFloat(1.0e+3);" +
  942. "\n y = new LSL_Types.LSLFloat(1.0E-3);" +
  943. "\n y = new LSL_Types.LSLFloat(1.0e-3);" +
  944. "\n y = -new LSL_Types.LSLFloat(1.0E3);" +
  945. "\n y = -new LSL_Types.LSLFloat(1.0e3);" +
  946. "\n y = -new LSL_Types.LSLFloat(1.0E+3);" +
  947. "\n y = -new LSL_Types.LSLFloat(1.0e+3);" +
  948. "\n y = -new LSL_Types.LSLFloat(1.0E-3);" +
  949. "\n y = -new LSL_Types.LSLFloat(1.0e-3);" +
  950. "\n y = new LSL_Types.LSLFloat(12.0) + -new LSL_Types.LSLFloat(1.0E3) - new LSL_Types.LSLFloat(1.0e-2);" +
  951. "\n LSL_Types.Vector3 v = new LSL_Types.Vector3(new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0));" +
  952. "\n }\n";
  953. CSCodeGenerator cg = new CSCodeGenerator();
  954. string output = cg.Convert(input);
  955. Assert.AreEqual(expected, output);
  956. }
  957. [Test]
  958. public void TestUnaryAndBinaryOperators()
  959. {
  960. string input = @"// let's test a few more operators
  961. default
  962. {
  963. touch_start(integer num_detected)
  964. {
  965. integer x = 2;
  966. integer y = 1;
  967. integer z = x ^ y;
  968. x = ~ z;
  969. x = ~(y && z);
  970. y = x >> z;
  971. z = y << x;
  972. }
  973. }
  974. ";
  975. string expected =
  976. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  977. "\n {" +
  978. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(2);" +
  979. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(1);" +
  980. "\n LSL_Types.LSLInteger z = x ^ y;" +
  981. "\n x = ~z;" +
  982. "\n x = ~(y && z);" +
  983. "\n y = x >> z;" +
  984. "\n z = y << x;" +
  985. "\n }\n";
  986. CSCodeGenerator cg = new CSCodeGenerator();
  987. string output = cg.Convert(input);
  988. Assert.AreEqual(expected, output);
  989. }
  990. [Test]
  991. public void TestTypecasts()
  992. {
  993. string input = @"// let's test typecasts
  994. default
  995. {
  996. touch_start(integer num_detected)
  997. {
  998. string s = """";
  999. integer x = 1;
  1000. s = (string) x++;
  1001. s = (string) x;
  1002. s = (string) <0., 0., 0.>;
  1003. s = (string) <1., 1., 1., 1.>;
  1004. s = (integer) ""1"";
  1005. s = (string) llSomethingThatReturnsInteger();
  1006. s = (string) 134;
  1007. s = (string) (x ^ y | (z && l)) + (string) (x + y - 13);
  1008. llOwnerSay(""s is: "" + s);
  1009. }
  1010. }
  1011. ";
  1012. string expected =
  1013. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  1014. "\n {" +
  1015. "\n LSL_Types.LSLString s = new LSL_Types.LSLString(\"\");" +
  1016. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
  1017. "\n s = (LSL_Types.LSLString) (x++);" +
  1018. "\n s = (LSL_Types.LSLString) (x);" +
  1019. "\n s = (LSL_Types.LSLString) (new LSL_Types.Vector3(new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0)));" +
  1020. "\n s = (LSL_Types.LSLString) (new LSL_Types.Quaternion(new LSL_Types.LSLFloat(1.0), new LSL_Types.LSLFloat(1.0), new LSL_Types.LSLFloat(1.0), new LSL_Types.LSLFloat(1.0)));" +
  1021. "\n s = (LSL_Types.LSLInteger) (new LSL_Types.LSLString(\"1\"));" +
  1022. "\n s = (LSL_Types.LSLString) (llSomethingThatReturnsInteger());" +
  1023. "\n s = (LSL_Types.LSLString) (new LSL_Types.LSLInteger(134));" +
  1024. "\n s = (LSL_Types.LSLString) (x ^ y | (z && l)) + (LSL_Types.LSLString) (x + y - new LSL_Types.LSLInteger(13));" +
  1025. "\n llOwnerSay(new LSL_Types.LSLString(\"s is: \") + s);" +
  1026. "\n }\n";
  1027. CSCodeGenerator cg = new CSCodeGenerator();
  1028. string output = cg.Convert(input);
  1029. Assert.AreEqual(expected, output);
  1030. }
  1031. [Test]
  1032. public void TestStates()
  1033. {
  1034. string input = @"// let's test states
  1035. default
  1036. {
  1037. touch_start(integer num_detected)
  1038. {
  1039. llSay(0, ""Going to state 'statetwo'"");
  1040. state statetwo;
  1041. }
  1042. }
  1043. state statetwo
  1044. {
  1045. state_entry()
  1046. {
  1047. llSay(0, ""Going to the default state"");
  1048. state default;
  1049. }
  1050. }
  1051. ";
  1052. string expected =
  1053. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  1054. "\n {" +
  1055. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Going to state 'statetwo'\"));" +
  1056. "\n state(\"statetwo\");" +
  1057. "\n }" +
  1058. "\n public void statetwo_event_state_entry()" +
  1059. "\n {" +
  1060. "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Going to the default state\"));" +
  1061. "\n state(\"default\");" +
  1062. "\n }\n";
  1063. CSCodeGenerator cg = new CSCodeGenerator();
  1064. string output = cg.Convert(input);
  1065. Assert.AreEqual(expected, output);
  1066. }
  1067. [Test]
  1068. public void TestHexIntegerConstants()
  1069. {
  1070. string input = @"// let's test hex integers
  1071. default
  1072. {
  1073. touch_start(integer num_detected)
  1074. {
  1075. integer x = 0x23;
  1076. integer x = 0x2f34B;
  1077. integer x = 0x2F34b;
  1078. integer x = 0x2F34B;
  1079. integer x = 0x2f34b;
  1080. }
  1081. }
  1082. ";
  1083. string expected =
  1084. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  1085. "\n {" +
  1086. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x23);" +
  1087. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2f34B);" +
  1088. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2F34b);" +
  1089. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2F34B);" +
  1090. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2f34b);" +
  1091. "\n }\n";
  1092. CSCodeGenerator cg = new CSCodeGenerator();
  1093. string output = cg.Convert(input);
  1094. Assert.AreEqual(expected, output);
  1095. }
  1096. [Test]
  1097. public void TestJumps()
  1098. {
  1099. string input = @"// let's test jumps
  1100. default
  1101. {
  1102. touch_start(integer num_detected)
  1103. {
  1104. jump here;
  1105. llOwnerSay(""Uh oh, the jump didn't work"");
  1106. @here;
  1107. llOwnerSay(""After the jump"");
  1108. }
  1109. }
  1110. ";
  1111. string expected =
  1112. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  1113. "\n {" +
  1114. "\n goto here;" +
  1115. "\n llOwnerSay(new LSL_Types.LSLString(\"Uh oh, the jump didn't work\"));" +
  1116. "\n here: NoOp();" +
  1117. "\n llOwnerSay(new LSL_Types.LSLString(\"After the jump\"));" +
  1118. "\n }\n";
  1119. CSCodeGenerator cg = new CSCodeGenerator();
  1120. string output = cg.Convert(input);
  1121. Assert.AreEqual(expected, output);
  1122. }
  1123. [Test]
  1124. public void TestImplicitVariableInitialization()
  1125. {
  1126. string input = @"// let's test implicitly initializing variables
  1127. default
  1128. {
  1129. touch_start(integer num_detected)
  1130. {
  1131. integer i; integer j = 14;
  1132. float f; float g = 14.0;
  1133. string s; string t = ""Hi there"";
  1134. list l; list m = [1, 2, 3];
  1135. vector v; vector w = <1.0, 0.1, 0.5>;
  1136. rotation r; rotation u = <0.8, 0.7, 0.6, llSomeFunc()>;
  1137. key k; key n = ""ping"";
  1138. }
  1139. }
  1140. ";
  1141. string expected =
  1142. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  1143. "\n {" +
  1144. "\n LSL_Types.LSLInteger i = new LSL_Types.LSLInteger(0);" +
  1145. "\n LSL_Types.LSLInteger j = new LSL_Types.LSLInteger(14);" +
  1146. "\n LSL_Types.LSLFloat f = new LSL_Types.LSLFloat(0.0);" +
  1147. "\n LSL_Types.LSLFloat g = new LSL_Types.LSLFloat(14.0);" +
  1148. "\n LSL_Types.LSLString s = new LSL_Types.LSLString(\"\");" +
  1149. "\n LSL_Types.LSLString t = new LSL_Types.LSLString(\"Hi there\");" +
  1150. "\n LSL_Types.list l = new LSL_Types.list();" +
  1151. "\n LSL_Types.list m = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger(2), new LSL_Types.LSLInteger(3));" +
  1152. "\n LSL_Types.Vector3 v = new LSL_Types.Vector3(new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0));" +
  1153. "\n LSL_Types.Vector3 w = new LSL_Types.Vector3(new LSL_Types.LSLFloat(1.0), new LSL_Types.LSLFloat(0.1), new LSL_Types.LSLFloat(0.5));" +
  1154. "\n LSL_Types.Quaternion r = new LSL_Types.Quaternion(new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0), new LSL_Types.LSLFloat(0.0));" +
  1155. "\n LSL_Types.Quaternion u = new LSL_Types.Quaternion(new LSL_Types.LSLFloat(0.8), new LSL_Types.LSLFloat(0.7), new LSL_Types.LSLFloat(0.6), llSomeFunc());" +
  1156. "\n LSL_Types.LSLString k = new LSL_Types.LSLString(\"\");" +
  1157. "\n LSL_Types.LSLString n = new LSL_Types.LSLString(\"ping\");" +
  1158. "\n }\n";
  1159. CSCodeGenerator cg = new CSCodeGenerator();
  1160. string output = cg.Convert(input);
  1161. Assert.AreEqual(expected, output);
  1162. }
  1163. [Test]
  1164. public void TestMultipleEqualsExpression()
  1165. {
  1166. string input = @"// let's test x = y = 5 type expressions
  1167. default
  1168. {
  1169. touch_start(integer num_detected)
  1170. {
  1171. integer x;
  1172. integer y;
  1173. x = y = 5;
  1174. x += y -= 5;
  1175. llOwnerSay(""x is: "" + (string) x + "", y is: "" + (string) y);
  1176. }
  1177. }
  1178. ";
  1179. string expected =
  1180. "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
  1181. "\n {" +
  1182. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
  1183. "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
  1184. "\n x = y = new LSL_Types.LSLInteger(5);" +
  1185. "\n x += y -= new LSL_Types.LSLInteger(5);" +
  1186. "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x) + new LSL_Types.LSLString(\", y is: \") + (LSL_Types.LSLString) (y));" +
  1187. "\n }\n";
  1188. CSCodeGenerator cg = new CSCodeGenerator();
  1189. string output = cg.Convert(input);
  1190. Assert.AreEqual(expected, output);
  1191. }
  1192. [Test]
  1193. public void TestUnaryExpressionLastInVectorConstant()
  1194. {
  1195. string input = @"// let's test unary expressions some more
  1196. default
  1197. {
  1198. state_entry()
  1199. {
  1200. vector v = <x,y,-0.5>;
  1201. }
  1202. }
  1203. ";
  1204. string expected =
  1205. "\n public void default_event_state_entry()" +
  1206. "\n {" +
  1207. "\n LSL_Types.Vector3 v = new LSL_Types.Vector3(x, y, -new LSL_Types.LSLFloat(0.5));" +
  1208. "\n }\n";
  1209. CSCodeGenerator cg = new CSCodeGenerator();
  1210. string output = cg.Convert(input);
  1211. Assert.AreEqual(expected, output);
  1212. }
  1213. [Test]
  1214. public void TestVectorMemberPlusEquals()
  1215. {
  1216. string input = @"// let's test unary expressions some more
  1217. default
  1218. {
  1219. state_entry()
  1220. {
  1221. vector v = llGetPos();
  1222. v.z += 4;
  1223. v.z -= 4;
  1224. v.z *= 4;
  1225. v.z /= 4;
  1226. v.z %= 4;
  1227. }
  1228. }
  1229. ";
  1230. string expected =
  1231. "\n public void default_event_state_entry()" +
  1232. "\n {" +
  1233. "\n LSL_Types.Vector3 v = llGetPos();" +
  1234. "\n v.z += new LSL_Types.LSLInteger(4);" +
  1235. "\n v.z -= new LSL_Types.LSLInteger(4);" +
  1236. "\n v.z *= new LSL_Types.LSLInteger(4);" +
  1237. "\n v.z /= new LSL_Types.LSLInteger(4);" +
  1238. "\n v.z %= new LSL_Types.LSLInteger(4);" +
  1239. "\n }\n";
  1240. CSCodeGenerator cg = new CSCodeGenerator();
  1241. string output = cg.Convert(input);
  1242. Assert.AreEqual(expected, output);
  1243. }
  1244. [Test]
  1245. public void TestWhileLoopWithNoBody()
  1246. {
  1247. string input = @"default
  1248. {
  1249. state_entry()
  1250. {
  1251. while (1<0);
  1252. }
  1253. }";
  1254. string expected =
  1255. "\n public void default_event_state_entry()" +
  1256. "\n {" +
  1257. "\n while (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0))" +
  1258. "\n ;" +
  1259. "\n }\n";
  1260. CSCodeGenerator cg = new CSCodeGenerator();
  1261. string output = cg.Convert(input);
  1262. Assert.AreEqual(expected, output);
  1263. }
  1264. [Test]
  1265. public void TestDoWhileLoopWithNoBody()
  1266. {
  1267. string input = @"default
  1268. {
  1269. state_entry()
  1270. {
  1271. do;
  1272. while (1<0);
  1273. }
  1274. }";
  1275. string expected =
  1276. "\n public void default_event_state_entry()" +
  1277. "\n {" +
  1278. "\n do" +
  1279. "\n ;" +
  1280. "\n while (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0));" +
  1281. "\n }\n";
  1282. CSCodeGenerator cg = new CSCodeGenerator();
  1283. string output = cg.Convert(input);
  1284. Assert.AreEqual(expected, output);
  1285. }
  1286. [Test]
  1287. public void TestIfWithNoBody()
  1288. {
  1289. string input = @"default
  1290. {
  1291. state_entry()
  1292. {
  1293. if (1<0);
  1294. }
  1295. }";
  1296. string expected =
  1297. "\n public void default_event_state_entry()" +
  1298. "\n {" +
  1299. "\n if (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0))" +
  1300. "\n ;" +
  1301. "\n }\n";
  1302. CSCodeGenerator cg = new CSCodeGenerator();
  1303. string output = cg.Convert(input);
  1304. Assert.AreEqual(expected, output);
  1305. }
  1306. [Test]
  1307. public void TestIfElseWithNoBody()
  1308. {
  1309. string input = @"default
  1310. {
  1311. state_entry()
  1312. {
  1313. if (1<0);
  1314. else;
  1315. }
  1316. }";
  1317. string expected =
  1318. "\n public void default_event_state_entry()" +
  1319. "\n {" +
  1320. "\n if (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0))" +
  1321. "\n ;" +
  1322. "\n else" +
  1323. "\n ;" +
  1324. "\n }\n";
  1325. CSCodeGenerator cg = new CSCodeGenerator();
  1326. string output = cg.Convert(input);
  1327. Assert.AreEqual(expected, output);
  1328. }
  1329. [Test]
  1330. public void TestForLoopWithNoBody()
  1331. {
  1332. string input = @"default
  1333. {
  1334. state_entry()
  1335. {
  1336. for (x = 4; 1<0; x += 2);
  1337. }
  1338. }";
  1339. string expected =
  1340. "\n public void default_event_state_entry()" +
  1341. "\n {" +
  1342. "\n for (x = new LSL_Types.LSLInteger(4); new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0); x += new LSL_Types.LSLInteger(2))" +
  1343. "\n ;" +
  1344. "\n }\n";
  1345. CSCodeGenerator cg = new CSCodeGenerator();
  1346. string output = cg.Convert(input);
  1347. Assert.AreEqual(expected, output);
  1348. }
  1349. [Test]
  1350. public void TestAssignmentInIfWhileDoWhile()
  1351. {
  1352. string input = @"default
  1353. {
  1354. state_entry()
  1355. {
  1356. integer x;
  1357. while (x = 14) llOwnerSay(""x is: "" + (string) x);
  1358. if (x = 24) llOwnerSay(""x is: "" + (string) x);
  1359. do
  1360. llOwnerSay(""x is: "" + (string) x);
  1361. while (x = 44);
  1362. }
  1363. }";
  1364. string expected =
  1365. "\n public void default_event_state_entry()" +
  1366. "\n {" +
  1367. "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
  1368. "\n while (x = new LSL_Types.LSLInteger(14))" +
  1369. "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x));" +
  1370. "\n if (x = new LSL_Types.LSLInteger(24))" +
  1371. "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x));" +
  1372. "\n do" +
  1373. "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x));" +
  1374. "\n while (x = new LSL_Types.LSLInteger(44));" +
  1375. "\n }\n";
  1376. CSCodeGenerator cg = new CSCodeGenerator();
  1377. string output = cg.Convert(input);
  1378. Assert.AreEqual(expected, output);
  1379. }
  1380. [Test]
  1381. public void TestLSLListHack()
  1382. {
  1383. string input = @"default
  1384. {
  1385. state_entry()
  1386. {
  1387. list l = [""hello""];
  1388. l = (l=[]) + l + ""world"";
  1389. }
  1390. }";
  1391. string expected =
  1392. "\n public void default_event_state_entry()" +
  1393. "\n {" +
  1394. "\n LSL_Types.list l = new LSL_Types.list(new LSL_Types.LSLString(\"hello\"));" +
  1395. "\n l = (l = new LSL_Types.list()) + l + new LSL_Types.LSLString(\"world\");" +
  1396. "\n }\n";
  1397. CSCodeGenerator cg = new CSCodeGenerator();
  1398. string output = cg.Convert(input);
  1399. Assert.AreEqual(expected, output);
  1400. }
  1401. [Test]
  1402. [ExpectedException(typeof(System.Exception))]
  1403. public void TestSyntaxError()
  1404. {
  1405. string input = @"default
  1406. {
  1407. state_entry()
  1408. {
  1409. integer y
  1410. }
  1411. }
  1412. ";
  1413. try
  1414. {
  1415. CSCodeGenerator cg = new CSCodeGenerator();
  1416. cg.Convert(input);
  1417. }
  1418. catch (System.Exception e)
  1419. {
  1420. // The syntax error is on line 6, char 5 (expected ';', found
  1421. // '}').
  1422. Assert.AreEqual("Line (4,4) syntax error", e.Message);
  1423. throw;
  1424. }
  1425. }
  1426. [Test]
  1427. [ExpectedException(typeof(System.Exception))]
  1428. public void TestSyntaxErrorDeclaringVariableInForLoop()
  1429. {
  1430. string input = @"default
  1431. {
  1432. state_entry()
  1433. {
  1434. for (integer x = 0; x < 10; x++) llOwnerSay(""x is: "" + (string) x);
  1435. }
  1436. }
  1437. ";
  1438. try
  1439. {
  1440. CSCodeGenerator cg = new CSCodeGenerator();
  1441. cg.Convert(input);
  1442. }
  1443. catch (System.Exception e)
  1444. {
  1445. // The syntax error is on line 5, char 14 (Syntax error)
  1446. Assert.AreEqual("Line (3,13) syntax error", e.Message);
  1447. throw;
  1448. }
  1449. }
  1450. }
  1451. }