opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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 OpenSimulator 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  
28 using System.Collections.Generic;
29 using System.Text.RegularExpressions;
30 using NUnit.Framework;
31 using OpenSim.Region.ScriptEngine.Shared.CodeTools;
32 using OpenSim.Tests.Common;
33  
34 namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
35 {
36 /// <summary>
37 /// Tests the LSL compiler, both the code generation and transformation.
38 /// Each test has some LSL code as input and C# code as expected output.
39 /// The generated C# code is compared against the expected C# code.
40 /// </summary>
41 [TestFixture]
42 public class CSCodeGeneratorTest : OpenSimTestCase
43 {
44 [Test]
45 public void TestDefaultState()
46 {
47 TestHelpers.InMethod();
48  
49 string input = @"default
50 {
51 state_entry()
52 {
53 }
54 }
55 ";
56 string expected =
57 "\n public void default_event_state_entry()" +
58 "\n {" +
59 "\n }\n";
60  
61 CSCodeGenerator cg = new CSCodeGenerator();
62 string output = cg.Convert(input);
63 Assert.AreEqual(expected, output);
64 }
65  
66 [Test]
67 public void TestCustomState()
68 {
69 TestHelpers.InMethod();
70  
71 string input = @"default
72 {
73 state_entry()
74 {
75 }
76 }
77  
78 state another_state
79 {
80 no_sensor()
81 {
82 }
83 }
84 ";
85 string expected =
86 "\n public void default_event_state_entry()" +
87 "\n {" +
88 "\n }" +
89 "\n public void another_state_event_no_sensor()" +
90 "\n {" +
91 "\n }\n";
92  
93 CSCodeGenerator cg = new CSCodeGenerator();
94 string output = cg.Convert(input);
95 Assert.AreEqual(expected, output);
96 }
97  
98 [Test]
99 public void TestEventWithArguments()
100 {
101 TestHelpers.InMethod();
102  
103 string input = @"default
104 {
105 at_rot_target(integer tnum, rotation targetrot, rotation ourrot)
106 {
107 }
108 }
109 ";
110 string expected =
111 "\n public void default_event_at_rot_target(LSL_Types.LSLInteger tnum, LSL_Types.Quaternion targetrot, LSL_Types.Quaternion ourrot)" +
112 "\n {" +
113 "\n }\n";
114  
115 CSCodeGenerator cg = new CSCodeGenerator();
116 string output = cg.Convert(input);
117 Assert.AreEqual(expected, output);
118 }
119  
120 [Test]
121 public void TestIntegerDeclaration()
122 {
123 TestHelpers.InMethod();
124  
125 string input = @"default
126 {
127 touch_start(integer num_detected)
128 {
129 integer x;
130 }
131 }
132 ";
133 string expected =
134 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
135 "\n {" +
136 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
137 "\n }\n";
138  
139 CSCodeGenerator cg = new CSCodeGenerator();
140 string output = cg.Convert(input);
141 Assert.AreEqual(expected, output);
142 }
143  
144 [Test]
145 public void TestLoneIdent()
146 {
147 TestHelpers.InMethod();
148  
149 // A lone ident should be removed completely as it's an error in C#
150 // (MONO at least).
151 string input = @"default
152 {
153 touch_start(integer num_detected)
154 {
155 integer x;
156 x;
157 }
158 }
159 ";
160 string expected =
161 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
162 "\n {" +
163 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
164 "\n ;" +
165 "\n }\n";
166  
167 CSCodeGenerator cg = new CSCodeGenerator();
168 string output = cg.Convert(input);
169 Assert.AreEqual(expected, output);
170 }
171  
172 [Test]
173 public void TestAssignments()
174 {
175 TestHelpers.InMethod();
176  
177 string input = @"default
178 {
179 touch_start(integer num_detected)
180 {
181 string y;
182 integer x = 14;
183 y = ""Hello"";
184 }
185 }
186 ";
187 string expected =
188 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
189 "\n {" +
190 "\n LSL_Types.LSLString y = new LSL_Types.LSLString(\"\");" +
191 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14);" +
192 "\n y = new LSL_Types.LSLString(\"Hello\");" +
193 "\n }\n";
194  
195 CSCodeGenerator cg = new CSCodeGenerator();
196 string output = cg.Convert(input);
197 Assert.AreEqual(expected, output);
198 }
199  
200 [Test]
201 public void TestAdditionSubtractionOperator()
202 {
203 TestHelpers.InMethod();
204  
205 string input = @"default
206 {
207 touch_start(integer num_detected)
208 {
209 integer y = -3;
210 integer x = 14 + 6;
211 y = 12 +45+20+x + 23 + 1 + x + y;
212 y = 12 + -45 + - 20 + x + 23 + -1 + x + y;
213 }
214 }
215 ";
216 string expected =
217 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)\n" +
218 " {\n" +
219 " LSL_Types.LSLInteger y = -new LSL_Types.LSLInteger(3);\n" +
220 " LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);\n" +
221 " 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" +
222 " 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" +
223 " }\n";
224  
225 CSCodeGenerator cg = new CSCodeGenerator();
226 string output = cg.Convert(input);
227 Assert.AreEqual(expected, output);
228 }
229  
230 [Test]
231 public void TestStrings()
232 {
233 TestHelpers.InMethod();
234  
235 string input = @"default
236 {
237 touch_start(integer num_detected)
238 {
239 llOwnerSay(""Testing, 1, 2, 3"");
240 llSay(0, ""I can hear you!"");
241 some_custom_function(1, 2, 3 +x, 4, ""five"", ""arguments"");
242 }
243 }
244 ";
245 string expected =
246 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
247 "\n {" +
248 "\n llOwnerSay(new LSL_Types.LSLString(\"Testing, 1, 2, 3\"));" +
249 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"I can hear you!\"));" +
250 "\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\"));" +
251 "\n }" +
252 "\n";
253  
254 CSCodeGenerator cg = new CSCodeGenerator();
255 string output = cg.Convert(input);
256 Assert.AreEqual(expected, output);
257 }
258  
259 [Test]
260 public void TestBinaryExpression()
261 {
262 TestHelpers.InMethod();
263  
264 string input = @"default
265 {
266 touch_start(integer num_detected)
267 {
268 integer y;
269 integer x = 14 + 6;
270 y = 12 - 3;
271 y = 12 && 3;
272 y = 12 || 3;
273 y = 12 * 3;
274 y = 12 / 3;
275 y = 12 | 3;
276 y = 12 & 3;
277 y = 12 % 3;
278 y = 12 + 45 - 20 * x / 23 | 1 & x + y;
279 }
280 }
281 ";
282 string expected =
283 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
284 "\n {" +
285 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
286 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);" +
287 "\n y = new LSL_Types.LSLInteger(12) - new LSL_Types.LSLInteger(3);" +
288 "\n y = ((bool)(new LSL_Types.LSLInteger(12))) & ((bool)(new LSL_Types.LSLInteger(3)));" +
289 "\n y = ((bool)(new LSL_Types.LSLInteger(12))) | ((bool)(new LSL_Types.LSLInteger(3)));" +
290 "\n y = new LSL_Types.LSLInteger(12) * new LSL_Types.LSLInteger(3);" +
291 "\n y = new LSL_Types.LSLInteger(12) / new LSL_Types.LSLInteger(3);" +
292 "\n y = new LSL_Types.LSLInteger(12) | new LSL_Types.LSLInteger(3);" +
293 "\n y = new LSL_Types.LSLInteger(12) & new LSL_Types.LSLInteger(3);" +
294 "\n y = new LSL_Types.LSLInteger(12) % new LSL_Types.LSLInteger(3);" +
295 "\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;" +
296 "\n }\n";
297  
298 CSCodeGenerator cg = new CSCodeGenerator();
299 string output = cg.Convert(input);
300 Assert.AreEqual(expected, output);
301 }
302  
303 [Test]
304 public void TestFloatConstants()
305 {
306 TestHelpers.InMethod();
307  
308 string input = @"default
309 {
310 touch_start(integer num_detected)
311 {
312 float y = 1.1;
313 y = 1.123E3;
314 y = 1.123e3;
315 y = 1.123E+3;
316 y = 1.123e+3;
317 y = 1.123E-3;
318 y = 1.123e-3;
319 y = .4;
320 y = -1.123E3;
321 y = -1.123e3;
322 y = -1.123E+3;
323 y = -1.123e+3;
324 y = -1.123E-3;
325 y = -1.123e-3;
326 y = -.4;
327 y = 12.3 + -1.45E3 - 1.20e-2;
328 }
329 }
330 ";
331 string expected =
332 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
333 "\n {" +
334 "\n LSL_Types.LSLFloat y = new LSL_Types.LSLFloat(1.1);" +
335 "\n y = new LSL_Types.LSLFloat(1.123E3);" +
336 "\n y = new LSL_Types.LSLFloat(1.123e3);" +
337 "\n y = new LSL_Types.LSLFloat(1.123E+3);" +
338 "\n y = new LSL_Types.LSLFloat(1.123e+3);" +
339 "\n y = new LSL_Types.LSLFloat(1.123E-3);" +
340 "\n y = new LSL_Types.LSLFloat(1.123e-3);" +
341 "\n y = new LSL_Types.LSLFloat(.4);" +
342 "\n y = -new LSL_Types.LSLFloat(1.123E3);" +
343 "\n y = -new LSL_Types.LSLFloat(1.123e3);" +
344 "\n y = -new LSL_Types.LSLFloat(1.123E+3);" +
345 "\n y = -new LSL_Types.LSLFloat(1.123e+3);" +
346 "\n y = -new LSL_Types.LSLFloat(1.123E-3);" +
347 "\n y = -new LSL_Types.LSLFloat(1.123e-3);" +
348 "\n y = -new LSL_Types.LSLFloat(.4);" +
349 "\n y = new LSL_Types.LSLFloat(12.3) + -new LSL_Types.LSLFloat(1.45E3) - new LSL_Types.LSLFloat(1.20e-2);" +
350 "\n }\n";
351  
352 CSCodeGenerator cg = new CSCodeGenerator();
353 string output = cg.Convert(input);
354 Assert.AreEqual(expected, output);
355 }
356  
357 [Test]
358 public void TestComments()
359 {
360 TestHelpers.InMethod();
361  
362 string input = @"// this test tests comments
363 default
364 {
365 touch_start(integer num_detected) // this should be stripped
366 {
367 // fill in code here...
368 }
369 }
370 ";
371 string expected =
372 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
373 "\n {" +
374 "\n }\n";
375  
376 CSCodeGenerator cg = new CSCodeGenerator();
377 string output = cg.Convert(input);
378 Assert.AreEqual(expected, output);
379 }
380  
381 [Test]
382 public void TestStringsWithEscapedQuotesAndComments()
383 {
384 TestHelpers.InMethod();
385  
386 string input = @"// this test tests strings, with escaped quotes and comments in strings
387 default
388 {
389 touch_start(integer num_detected)
390 {
391 string s1 = ""this is a string."";
392 string s2 = ""this is a string ""+""with an escaped \"" inside it."";
393 s1 = s2+"" and this ""+""is a string with // comments."";
394  
395 string onemore = ""[\^@]"";
396  
397 string multiline = ""Good evening Sir,
398 my name is Steve.
399 I come from a rough area.
400 I used to be addicted to crack
401 but now I am off it and trying to stay clean.
402 That is why I am selling magazine subscriptions.""; // http://www.imdb.com/title/tt0151804/quotes
403 }
404 }
405 ";
406  
407 string expected =
408 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
409 "\n {" +
410 "\n LSL_Types.LSLString s1 = new LSL_Types.LSLString(\"this is a string.\");" +
411 "\n LSL_Types.LSLString s2 = new LSL_Types.LSLString(\"this is a string \") + new LSL_Types.LSLString(\"with an escaped \\\" inside it.\");" +
412 "\n s1 = s2 + new LSL_Types.LSLString(\" and this \") + new LSL_Types.LSLString(\"is a string with // comments.\");" +
413 "\n LSL_Types.LSLString onemore = new LSL_Types.LSLString(\"[\\^@]\");" +
414 "\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.\");" +
415 "\n }\n";
416  
417 CSCodeGenerator cg = new CSCodeGenerator();
418 string output = cg.Convert(input);
419 Assert.AreEqual(expected, output);
420 }
421  
422 [Test]
423 public void TestCStyleComments()
424 {
425 TestHelpers.InMethod();
426  
427 string input = @"/* this test tests comments
428 of the C variety
429 */
430 default
431 {
432 touch_start(integer /* you can't see me! */ num_detected) /* this should be stripped */
433 {
434 /*
435 * fill
436 * in
437 * code
438 * here...
439 */
440 }
441 }
442 ";
443 string expected =
444 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
445 "\n {" +
446 "\n }\n";
447  
448 CSCodeGenerator cg = new CSCodeGenerator();
449 string output = cg.Convert(input);
450 Assert.AreEqual(expected, output);
451 }
452  
453 [Test]
454 public void TestGlobalDefinedFunctions()
455 {
456 TestHelpers.InMethod();
457  
458 string input = @"// this test tests custom defined functions
459  
460 string onefunc()
461 {
462 return ""Hi from onefunc()!"";
463 }
464  
465 twofunc(string s)
466 {
467 llSay(1000, s);
468 }
469  
470 default
471 {
472 touch_start(integer num_detected)
473 {
474 llSay(2000, onefunc());
475 twofunc();
476 }
477 }
478 ";
479 string expected =
480 "\n LSL_Types.LSLString onefunc()" +
481 "\n {" +
482 "\n return new LSL_Types.LSLString(\"Hi from onefunc()!\");" +
483 "\n }" +
484 "\n void twofunc(LSL_Types.LSLString s)" +
485 "\n {" +
486 "\n llSay(new LSL_Types.LSLInteger(1000), s);" +
487 "\n }" +
488 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
489 "\n {" +
490 "\n llSay(new LSL_Types.LSLInteger(2000), onefunc());" +
491 "\n twofunc();" +
492 "\n }\n";
493  
494 CSCodeGenerator cg = new CSCodeGenerator();
495 string output = cg.Convert(input);
496 Assert.AreEqual(expected, output);
497 }
498  
499 [Test]
500 public void TestGlobalDeclaredVariables()
501 {
502 TestHelpers.InMethod();
503  
504 string input = @"// this test tests custom defined functions and global variables
505  
506 string globalString;
507 integer globalInt = 14;
508 integer anotherGlobal = 20 * globalInt;
509  
510 string onefunc()
511 {
512 globalString = "" ...and the global!"";
513 return ""Hi "" +
514 ""from "" +
515 ""onefunc()!"" + globalString;
516 }
517  
518 twofunc(string s)
519 {
520 llSay(1000, s);
521 }
522  
523 default
524 {
525 touch_start(integer num_detected)
526 {
527 llSay(2000, onefunc());
528 twofunc();
529 }
530 }
531 ";
532 string expected =
533 "\n LSL_Types.LSLString globalString = new LSL_Types.LSLString(\"\");" +
534 "\n LSL_Types.LSLInteger globalInt = new LSL_Types.LSLInteger(14);" +
535 "\n LSL_Types.LSLInteger anotherGlobal = new LSL_Types.LSLInteger(20) * globalInt;" +
536 "\n LSL_Types.LSLString onefunc()" +
537 "\n {" +
538 "\n globalString = new LSL_Types.LSLString(\" ...and the global!\");" +
539 "\n return new LSL_Types.LSLString(\"Hi \") + new LSL_Types.LSLString(\"from \") + new LSL_Types.LSLString(\"onefunc()!\") + globalString;" +
540 "\n }" +
541 "\n void twofunc(LSL_Types.LSLString s)" +
542 "\n {" +
543 "\n llSay(new LSL_Types.LSLInteger(1000), s);" +
544 "\n }" +
545 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
546 "\n {" +
547 "\n llSay(new LSL_Types.LSLInteger(2000), onefunc());" +
548 "\n twofunc();" +
549 "\n }\n";
550  
551 CSCodeGenerator cg = new CSCodeGenerator();
552 string output = cg.Convert(input);
553 Assert.AreEqual(expected, output);
554 }
555  
556 [Test]
557 public void TestMoreAssignments()
558 {
559 TestHelpers.InMethod();
560  
561 string input = @"// this test tests +=, -=, *=, /=, %=
562  
563 string globalString;
564 integer globalInt = 14;
565  
566 string onefunc(string addition)
567 {
568 globalInt -= 2;
569  
570 globalString += addition;
571 return ""Hi "" +
572 ""from "" +
573 ""onefunc()! "" + globalString;
574 }
575  
576 default
577 {
578 touch_start(integer num_detected)
579 {
580 llSay(2000, onefunc());
581  
582 integer x = 2;
583 x *= 3;
584 x /= 14 + -2;
585 x %= 10;
586 }
587 }
588 ";
589 string expected =
590 "\n LSL_Types.LSLString globalString = new LSL_Types.LSLString(\"\");" +
591 "\n LSL_Types.LSLInteger globalInt = new LSL_Types.LSLInteger(14);" +
592 "\n LSL_Types.LSLString onefunc(LSL_Types.LSLString addition)" +
593 "\n {" +
594 "\n globalInt -= new LSL_Types.LSLInteger(2);" +
595 "\n globalString += addition;" +
596 "\n return new LSL_Types.LSLString(\"Hi \") + new LSL_Types.LSLString(\"from \") + new LSL_Types.LSLString(\"onefunc()! \") + globalString;" +
597 "\n }" +
598 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
599 "\n {" +
600 "\n llSay(new LSL_Types.LSLInteger(2000), onefunc());" +
601 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(2);" +
602 "\n x *= new LSL_Types.LSLInteger(3);" +
603 "\n x /= new LSL_Types.LSLInteger(14) + -new LSL_Types.LSLInteger(2);" +
604 "\n x %= new LSL_Types.LSLInteger(10);" +
605 "\n }\n";
606  
607 CSCodeGenerator cg = new CSCodeGenerator();
608 string output = cg.Convert(input);
609 Assert.AreEqual(expected, output);
610 }
611  
612 [Test]
613 public void TestVectorConstantNotation()
614 {
615 TestHelpers.InMethod();
616  
617 string input = @"default
618 {
619 touch_start(integer num_detected)
620 {
621 vector y = <1.2, llGetMeAFloat(), 4.4>;
622 rotation x = <0.1, 0.1, one + 2, 0.9>;
623  
624 y = <0.1, 0.1, 1.1 - three - two+eight*8>;
625 }
626 }
627 ";
628 string expected =
629 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
630 "\n {" +
631 "\n LSL_Types.Vector3 y = new LSL_Types.Vector3(new LSL_Types.LSLFloat(1.2), llGetMeAFloat(), new LSL_Types.LSLFloat(4.4));" +
632 "\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));" +
633 "\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));" +
634 "\n }\n";
635  
636 CSCodeGenerator cg = new CSCodeGenerator();
637 string output = cg.Convert(input);
638 Assert.AreEqual(expected, output);
639 }
640  
641 [Test]
642 public void TestVectorMemberAccess()
643 {
644 TestHelpers.InMethod();
645  
646 string input = @"default
647 {
648 touch_start(integer num_detected)
649 {
650 vector y = <1.2, llGetMeAFloat(), 4.4>;
651 x = y.x + 1.1;
652 y.x = 1.1;
653 }
654 }
655 ";
656 string expected =
657 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
658 "\n {" +
659 "\n LSL_Types.Vector3 y = new LSL_Types.Vector3(new LSL_Types.LSLFloat(1.2), llGetMeAFloat(), new LSL_Types.LSLFloat(4.4));" +
660 "\n x = y.x + new LSL_Types.LSLFloat(1.1);" +
661 "\n y.x = new LSL_Types.LSLFloat(1.1);" +
662 "\n }\n";
663  
664 CSCodeGenerator cg = new CSCodeGenerator();
665 string output = cg.Convert(input);
666 Assert.AreEqual(expected, output);
667 }
668  
669 [Test]
670 public void TestExpressionInParentheses()
671 {
672 TestHelpers.InMethod();
673  
674 string input = @"default
675 {
676 touch_start(integer num_detected)
677 {
678 integer y = -3;
679 integer x = 14 + 6;
680 y = 12 +45+20+x + (23 + 1) + x + y;
681 y = (12 + -45 + -20 + x + 23 )+ -1 + x + y;
682 }
683 }
684 ";
685 string expected =
686 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
687 "\n {" +
688 "\n LSL_Types.LSLInteger y = -new LSL_Types.LSLInteger(3);" +
689 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);" +
690 "\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;" +
691 "\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;" +
692 "\n }\n";
693  
694 CSCodeGenerator cg = new CSCodeGenerator();
695 string output = cg.Convert(input);
696 Assert.AreEqual(expected, output);
697 }
698  
699 [Test]
700 public void TestIncrementDecrementOperator()
701 {
702 TestHelpers.InMethod();
703  
704 string input = @"// here we'll test the ++ and -- operators
705  
706 default
707 {
708 touch_start(integer num_detected)
709 {
710 integer y = -3;
711 integer x = 14 + 6;
712 y = 12 +45+20+x++ + (23 + 1) + ++x + -- y;
713 y = (12 + -45 + -20 + x-- + 23 )+ -1 + x -- + ++y;
714 }
715 }
716 ";
717 string expected =
718 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
719 "\n {" +
720 "\n LSL_Types.LSLInteger y = -new LSL_Types.LSLInteger(3);" +
721 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(14) + new LSL_Types.LSLInteger(6);" +
722 "\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;" +
723 "\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;" +
724 "\n }\n";
725  
726 CSCodeGenerator cg = new CSCodeGenerator();
727 string output = cg.Convert(input);
728 Assert.AreEqual(expected, output);
729 }
730  
731 [Test]
732 public void TestLists()
733 {
734 TestHelpers.InMethod();
735  
736 string input = @"// testing lists
737  
738 default
739 {
740 touch_start(integer num_detected)
741 {
742 list l = [];
743 list m = [1, two, ""three"", <4.0, 4.0, 4.0>, 5 + 5];
744 llCallSomeFunc(1, llAnotherFunc(), [1, 2, 3]);
745 }
746 }
747 ";
748 string expected =
749 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
750 "\n {" +
751 "\n LSL_Types.list l = new LSL_Types.list();" +
752 "\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));" +
753 "\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)));" +
754 "\n }\n";
755  
756 CSCodeGenerator cg = new CSCodeGenerator();
757 string output = cg.Convert(input);
758 Assert.AreEqual(expected, output);
759 }
760  
761 [Test]
762 public void TestIfStatement()
763 {
764 TestHelpers.InMethod();
765 // TestHelpers.EnableLogging();
766  
767 string input = @"// let's test if statements
768  
769 default
770 {
771 touch_start(integer num_detected)
772 {
773 integer x = 1;
774  
775 if (x) llSay(0, ""Hello"");
776 if (1)
777 {
778 llSay(0, ""Hi"");
779 integer r = 3;
780 return;
781 }
782  
783 if (f(x)) llSay(0, ""f(x) is true"");
784 else llSay(0, ""f(x) is false"");
785  
786 if (x + y) llSay(0, ""x + y is true"");
787 else if (y - x) llSay(0, ""y - x is true"");
788 else llSay(0, ""Who needs x and y anyway?"");
789  
790 if (x * y) llSay(0, ""x * y is true"");
791 else if (y / x)
792 {
793 llSay(0, ""uh-oh, y / x is true, exiting"");
794 return;
795 }
796 else llSay(0, ""Who needs x and y anyway?"");
797  
798 // and now for my last trick
799 if (x % y) llSay(0, ""x is true"");
800 else if (y & x) llSay(0, ""y is true"");
801 else if (z | x) llSay(0, ""z is true"");
802 else if (a * (b + x)) llSay(0, ""a is true"");
803 else if (b) llSay(0, ""b is true"");
804 else if (v) llSay(0, ""v is true"");
805 else llSay(0, ""Everything is lies!"");
806 }
807 }
808 ";
809 string expected =
810 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
811 "\n {" +
812 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
813 "\n if (x)" +
814 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hello\"));" +
815 "\n if (new LSL_Types.LSLInteger(1))" +
816 "\n {" +
817 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hi\"));" +
818 "\n LSL_Types.LSLInteger r = new LSL_Types.LSLInteger(3);" +
819 "\n return ;" +
820 "\n }" +
821 "\n if (f(x))" +
822 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"f(x) is true\"));" +
823 "\n else" +
824 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"f(x) is false\"));" +
825 "\n if (x + y)" +
826 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x + y is true\"));" +
827 "\n else" +
828 "\n if (y - x)" +
829 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y - x is true\"));" +
830 "\n else" +
831 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
832 "\n if (x * y)" +
833 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x * y is true\"));" +
834 "\n else" +
835 "\n if (y / x)" +
836 "\n {" +
837 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"uh-oh, y / x is true, exiting\"));" +
838 "\n return ;" +
839 "\n }" +
840 "\n else" +
841 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
842 "\n if (x % y)" +
843 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
844 "\n else" +
845 "\n if (y & x)" +
846 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y is true\"));" +
847 "\n else" +
848 "\n if (z | x)" +
849 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"z is true\"));" +
850 "\n else" +
851 "\n if (a * (b + x))" +
852 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"a is true\"));" +
853 "\n else" +
854 "\n if (b)" +
855 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"b is true\"));" +
856 "\n else" +
857 "\n if (v)" +
858 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"v is true\"));" +
859 "\n else" +
860 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Everything is lies!\"));" +
861 "\n }\n";
862  
863 CSCodeGenerator cg = new CSCodeGenerator();
864 string output = cg.Convert(input);
865 Assert.AreEqual(expected, output);
866 }
867  
868 [Test]
869 public void TestIfElseStatement()
870 {
871 TestHelpers.InMethod();
872  
873 string input = @"// let's test complex logical expressions
874  
875 default
876 {
877 touch_start(integer num_detected)
878 {
879 integer x = 1;
880 integer y = 0;
881  
882 if (x && y) llSay(0, ""Hello"");
883 if (x || y)
884 {
885 llSay(0, ""Hi"");
886 integer r = 3;
887 return;
888 }
889  
890 if (x && y || z) llSay(0, ""x is true"");
891 else llSay(0, ""x is false"");
892  
893 if (x == y) llSay(0, ""x is true"");
894 else if (y < x) llSay(0, ""y is true"");
895 else llSay(0, ""Who needs x and y anyway?"");
896  
897 if (x > y) llSay(0, ""x is true"");
898 else if (y <= x)
899 {
900 llSay(0, ""uh-oh, y is true, exiting"");
901 return;
902 }
903 else llSay(0, ""Who needs x and y anyway?"");
904  
905 // and now for my last trick
906 if (x >= y) llSay(0, ""x is true"");
907 else if (y != x) llSay(0, ""y is true"");
908 else if (!z) llSay(0, ""z is true"");
909 else if (!(a && b)) llSay(0, ""a is true"");
910 else if (b) llSay(0, ""b is true"");
911 else if (v) llSay(0, ""v is true"");
912 else llSay(0, ""Everything is lies!"");
913 }
914 }
915 ";
916 string expected =
917 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
918 "\n {" +
919 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
920 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
921 "\n if (((bool)(x)) & ((bool)(y)))" +
922 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hello\"));" +
923 "\n if (((bool)(x)) | ((bool)(y)))" +
924 "\n {" +
925 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Hi\"));" +
926 "\n LSL_Types.LSLInteger r = new LSL_Types.LSLInteger(3);" +
927 "\n return ;" +
928 "\n }" +
929 "\n if (((bool)(((bool)(x)) & ((bool)(y)))) | ((bool)(z)))" +
930 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
931 "\n else" +
932 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is false\"));" +
933 "\n if (x == y)" +
934 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
935 "\n else" +
936 "\n if (y < x)" +
937 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y is true\"));" +
938 "\n else" +
939 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
940 "\n if (x > y)" +
941 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
942 "\n else" +
943 "\n if (y <= x)" +
944 "\n {" +
945 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"uh-oh, y is true, exiting\"));" +
946 "\n return ;" +
947 "\n }" +
948 "\n else" +
949 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Who needs x and y anyway?\"));" +
950 "\n if (x >= y)" +
951 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"x is true\"));" +
952 "\n else" +
953 "\n if (y != x)" +
954 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"y is true\"));" +
955 "\n else" +
956 "\n if (!z)" +
957 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"z is true\"));" +
958 "\n else" +
959 "\n if (!(((bool)(a)) & ((bool)(b))))" +
960 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"a is true\"));" +
961 "\n else" +
962 "\n if (b)" +
963 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"b is true\"));" +
964 "\n else" +
965 "\n if (v)" +
966 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"v is true\"));" +
967 "\n else" +
968 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Everything is lies!\"));" +
969 "\n }\n";
970  
971 CSCodeGenerator cg = new CSCodeGenerator();
972 string output = cg.Convert(input);
973 Assert.AreEqual(expected, output);
974 }
975  
976 [Test]
977 public void TestWhileLoop()
978 {
979 TestHelpers.InMethod();
980  
981 string input = @"// let's test while loops
982  
983 default
984 {
985 touch_start(integer num_detected)
986 {
987 integer x = 1;
988 integer y = 0;
989  
990 while (x) llSay(0, ""To infinity, and beyond!"");
991 while (0 || (x && 0))
992 {
993 llSay(0, ""Never say never."");
994 return;
995 }
996 }
997 }
998 ";
999 string expected =
1000 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1001 "\n {" +
1002 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
1003 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
1004 "\n while (x)" +
1005 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"To infinity, and beyond!\"));" +
1006 "\n while (((bool)(new LSL_Types.LSLInteger(0))) | ((bool)((((bool)(x)) & ((bool)(new LSL_Types.LSLInteger(0)))))))" +
1007 "\n {" +
1008 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Never say never.\"));" +
1009 "\n return ;" +
1010 "\n }" +
1011 "\n }\n";
1012  
1013 CSCodeGenerator cg = new CSCodeGenerator();
1014 string output = cg.Convert(input);
1015 Assert.AreEqual(expected, output);
1016 }
1017  
1018 [Test]
1019 public void TestDoWhileLoop()
1020 {
1021 TestHelpers.InMethod();
1022  
1023 string input = @"// let's test do-while loops
1024  
1025 default
1026 {
1027 touch_start(integer num_detected)
1028 {
1029 integer x = 1;
1030 integer y = 0;
1031  
1032 do llSay(0, ""And we're doing..."");
1033 while (x);
1034  
1035 do
1036 {
1037 llSay(0, ""I like it here. I wish we could stay here forever."");
1038 y--;
1039 } while (y);
1040 }
1041 }
1042 ";
1043 string expected =
1044 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1045 "\n {" +
1046 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
1047 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
1048 "\n do" +
1049 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"And we're doing...\"));" +
1050 "\n while (x);" +
1051 "\n do" +
1052 "\n {" +
1053 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"I like it here. I wish we could stay here forever.\"));" +
1054 "\n y--;" +
1055 "\n }" +
1056 "\n while (y);" +
1057 "\n }\n";
1058  
1059 CSCodeGenerator cg = new CSCodeGenerator();
1060 string output = cg.Convert(input);
1061 Assert.AreEqual(expected, output);
1062 }
1063  
1064 [Test]
1065 public void TestForLoop()
1066 {
1067 TestHelpers.InMethod();
1068  
1069 string input = @"// let's test for loops
1070  
1071 default
1072 {
1073 touch_start(integer num_detected)
1074 {
1075 integer x = 1;
1076 integer y = 0;
1077  
1078 for (x = 10; x >= 0; x--)
1079 {
1080 llOwnerSay(""Launch in T minus "" + x);
1081 IncreaseRocketPower();
1082 }
1083  
1084 for (x = 0, y = 6; y > 0 && x != y; x++, y--) llOwnerSay(""Hi "" + x + "", "" + y);
1085 for (x = 0, y = 6; ! y; x++,y--) llOwnerSay(""Hi "" + x + "", "" + y);
1086 }
1087 }
1088 ";
1089 string expected =
1090 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1091 "\n {" +
1092 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
1093 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
1094 "\n for (x = new LSL_Types.LSLInteger(10); x >= new LSL_Types.LSLInteger(0); x--)" +
1095 "\n {" +
1096 "\n llOwnerSay(new LSL_Types.LSLString(\"Launch in T minus \") + x);" +
1097 "\n IncreaseRocketPower();" +
1098 "\n }" +
1099 "\n for (x = new LSL_Types.LSLInteger(0), y = new LSL_Types.LSLInteger(6); ((bool)(y > new LSL_Types.LSLInteger(0))) & ((bool)(x != y)); x++, y--)" +
1100 "\n llOwnerSay(new LSL_Types.LSLString(\"Hi \") + x + new LSL_Types.LSLString(\", \") + y);" +
1101 "\n for (x = new LSL_Types.LSLInteger(0), y = new LSL_Types.LSLInteger(6); !y; x++, y--)" +
1102 "\n llOwnerSay(new LSL_Types.LSLString(\"Hi \") + x + new LSL_Types.LSLString(\", \") + y);" +
1103 "\n }\n";
1104  
1105 CSCodeGenerator cg = new CSCodeGenerator();
1106 string output = cg.Convert(input);
1107 Assert.AreEqual(expected, output);
1108 }
1109  
1110 [Test]
1111 public void TestFloatsWithTrailingDecimal()
1112 {
1113 TestHelpers.InMethod();
1114  
1115 string input = @"// a curious feature of LSL that allows floats to be defined with a trailing dot
1116  
1117 default
1118 {
1119 touch_start(integer num_detected)
1120 {
1121 float y = 1.;
1122 y = 1.E3;
1123 y = 1.e3;
1124 y = 1.E+3;
1125 y = 1.e+3;
1126 y = 1.E-3;
1127 y = 1.e-3;
1128 y = -1.E3;
1129 y = -1.e3;
1130 y = -1.E+3;
1131 y = -1.e+3;
1132 y = -1.E-3;
1133 y = -1.e-3;
1134 y = 12. + -1.E3 - 1.e-2;
1135 vector v = <0.,0.,0.>;
1136 }
1137 }
1138 ";
1139 string expected =
1140 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1141 "\n {" +
1142 "\n LSL_Types.LSLFloat y = new LSL_Types.LSLFloat(1.0);" +
1143 "\n y = new LSL_Types.LSLFloat(1.0E3);" +
1144 "\n y = new LSL_Types.LSLFloat(1.0e3);" +
1145 "\n y = new LSL_Types.LSLFloat(1.0E+3);" +
1146 "\n y = new LSL_Types.LSLFloat(1.0e+3);" +
1147 "\n y = new LSL_Types.LSLFloat(1.0E-3);" +
1148 "\n y = new LSL_Types.LSLFloat(1.0e-3);" +
1149 "\n y = -new LSL_Types.LSLFloat(1.0E3);" +
1150 "\n y = -new LSL_Types.LSLFloat(1.0e3);" +
1151 "\n y = -new LSL_Types.LSLFloat(1.0E+3);" +
1152 "\n y = -new LSL_Types.LSLFloat(1.0e+3);" +
1153 "\n y = -new LSL_Types.LSLFloat(1.0E-3);" +
1154 "\n y = -new LSL_Types.LSLFloat(1.0e-3);" +
1155 "\n y = new LSL_Types.LSLFloat(12.0) + -new LSL_Types.LSLFloat(1.0E3) - new LSL_Types.LSLFloat(1.0e-2);" +
1156 "\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));" +
1157 "\n }\n";
1158  
1159 CSCodeGenerator cg = new CSCodeGenerator();
1160 string output = cg.Convert(input);
1161 Assert.AreEqual(expected, output);
1162 }
1163  
1164 [Test]
1165 public void TestUnaryAndBinaryOperators()
1166 {
1167 TestHelpers.InMethod();
1168  
1169 string input = @"// let's test a few more operators
1170  
1171 default
1172 {
1173 touch_start(integer num_detected)
1174 {
1175 integer x = 2;
1176 integer y = 1;
1177 integer z = x ^ y;
1178 x = ~ z;
1179 x = ~(y && z);
1180 y = x >> z;
1181 z = y << x;
1182 }
1183 }
1184 ";
1185 string expected =
1186 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1187 "\n {" +
1188 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(2);" +
1189 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(1);" +
1190 "\n LSL_Types.LSLInteger z = x ^ y;" +
1191 "\n x = ~z;" +
1192 "\n x = ~(((bool)(y)) & ((bool)(z)));" +
1193 "\n y = x >> z;" +
1194 "\n z = y << x;" +
1195 "\n }\n";
1196  
1197 CSCodeGenerator cg = new CSCodeGenerator();
1198 string output = cg.Convert(input);
1199 Assert.AreEqual(expected, output);
1200 }
1201  
1202 [Test]
1203 public void TestTypecasts()
1204 {
1205 TestHelpers.InMethod();
1206  
1207 string input = @"// let's test typecasts
1208  
1209 default
1210 {
1211 touch_start(integer num_detected)
1212 {
1213 string s = """";
1214 integer x = 1;
1215  
1216 s = (string) x++;
1217 s = (string) x;
1218 s = (string) <0., 0., 0.>;
1219 s = (string) <1., 1., 1., 1.>;
1220 s = (integer) ""1"";
1221 s = (string) llSomethingThatReturnsInteger();
1222 s = (string) 134;
1223 s = (string) (x ^ y | (z && l)) + (string) (x + y - 13);
1224 llOwnerSay(""s is: "" + s);
1225 }
1226 }
1227 ";
1228 string expected =
1229 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1230 "\n {" +
1231 "\n LSL_Types.LSLString s = new LSL_Types.LSLString(\"\");" +
1232 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(1);" +
1233 "\n s = (LSL_Types.LSLString) (x++);" +
1234 "\n s = (LSL_Types.LSLString) (x);" +
1235 "\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)));" +
1236 "\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)));" +
1237 "\n s = (LSL_Types.LSLInteger) (new LSL_Types.LSLString(\"1\"));" +
1238 "\n s = (LSL_Types.LSLString) (llSomethingThatReturnsInteger());" +
1239 "\n s = (LSL_Types.LSLString) (new LSL_Types.LSLInteger(134));" +
1240 "\n s = (LSL_Types.LSLString) (x ^ y | (((bool)(z)) & ((bool)(l)))) + (LSL_Types.LSLString) (x + y - new LSL_Types.LSLInteger(13));" +
1241 "\n llOwnerSay(new LSL_Types.LSLString(\"s is: \") + s);" +
1242 "\n }\n";
1243  
1244 CSCodeGenerator cg = new CSCodeGenerator();
1245 string output = cg.Convert(input);
1246 Assert.AreEqual(expected, output);
1247 }
1248  
1249 [Test]
1250 public void TestStates()
1251 {
1252 TestHelpers.InMethod();
1253  
1254 string input = @"// let's test states
1255  
1256 default
1257 {
1258 touch_start(integer num_detected)
1259 {
1260 llSay(0, ""Going to state 'statetwo'"");
1261 state statetwo;
1262 }
1263 }
1264  
1265 state statetwo
1266 {
1267 state_entry()
1268 {
1269 llSay(0, ""Going to the default state"");
1270 state default;
1271 }
1272 }
1273 ";
1274 string expected =
1275 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1276 "\n {" +
1277 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Going to state 'statetwo'\"));" +
1278 "\n state(\"statetwo\");" +
1279 "\n }" +
1280 "\n public void statetwo_event_state_entry()" +
1281 "\n {" +
1282 "\n llSay(new LSL_Types.LSLInteger(0), new LSL_Types.LSLString(\"Going to the default state\"));" +
1283 "\n state(\"default\");" +
1284 "\n }\n";
1285  
1286 CSCodeGenerator cg = new CSCodeGenerator();
1287 string output = cg.Convert(input);
1288 Assert.AreEqual(expected, output);
1289 }
1290  
1291 [Test]
1292 public void TestHexIntegerConstants()
1293 {
1294 TestHelpers.InMethod();
1295  
1296 string input = @"// let's test hex integers
1297  
1298 default
1299 {
1300 touch_start(integer num_detected)
1301 {
1302 integer x = 0x23;
1303 integer x = 0x2f34B;
1304 integer x = 0x2F34b;
1305 integer x = 0x2F34B;
1306 integer x = 0x2f34b;
1307 }
1308 }
1309 ";
1310 string expected =
1311 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1312 "\n {" +
1313 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x23);" +
1314 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2f34B);" +
1315 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2F34b);" +
1316 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2F34B);" +
1317 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0x2f34b);" +
1318 "\n }\n";
1319  
1320 CSCodeGenerator cg = new CSCodeGenerator();
1321 string output = cg.Convert(input);
1322 Assert.AreEqual(expected, output);
1323 }
1324  
1325 [Test]
1326 public void TestJumps()
1327 {
1328 TestHelpers.InMethod();
1329  
1330 string input = @"// let's test jumps
1331  
1332 default
1333 {
1334 touch_start(integer num_detected)
1335 {
1336 jump here;
1337 llOwnerSay(""Uh oh, the jump didn't work"");
1338 @here;
1339 llOwnerSay(""After the jump"");
1340 }
1341 }
1342 ";
1343 string expected =
1344 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1345 "\n {" +
1346 "\n goto here;" +
1347 "\n llOwnerSay(new LSL_Types.LSLString(\"Uh oh, the jump didn't work\"));" +
1348 "\n here: NoOp();" +
1349 "\n llOwnerSay(new LSL_Types.LSLString(\"After the jump\"));" +
1350 "\n }\n";
1351  
1352 CSCodeGenerator cg = new CSCodeGenerator();
1353 string output = cg.Convert(input);
1354 Assert.AreEqual(expected, output);
1355 }
1356  
1357 [Test]
1358 public void TestImplicitVariableInitialization()
1359 {
1360 TestHelpers.InMethod();
1361  
1362 string input = @"// let's test implicitly initializing variables
1363  
1364 default
1365 {
1366 touch_start(integer num_detected)
1367 {
1368 integer i; integer j = 14;
1369 float f; float g = 14.0;
1370 string s; string t = ""Hi there"";
1371 list l; list m = [1, 2, 3];
1372 vector v; vector w = <1.0, 0.1, 0.5>;
1373 rotation r; rotation u = <0.8, 0.7, 0.6, llSomeFunc()>;
1374 key k; key n = ""ping"";
1375 }
1376 }
1377 ";
1378 string expected =
1379 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1380 "\n {" +
1381 "\n LSL_Types.LSLInteger i = new LSL_Types.LSLInteger(0);" +
1382 "\n LSL_Types.LSLInteger j = new LSL_Types.LSLInteger(14);" +
1383 "\n LSL_Types.LSLFloat f = new LSL_Types.LSLFloat(0.0);" +
1384 "\n LSL_Types.LSLFloat g = new LSL_Types.LSLFloat(14.0);" +
1385 "\n LSL_Types.LSLString s = new LSL_Types.LSLString(\"\");" +
1386 "\n LSL_Types.LSLString t = new LSL_Types.LSLString(\"Hi there\");" +
1387 "\n LSL_Types.list l = new LSL_Types.list();" +
1388 "\n LSL_Types.list m = new LSL_Types.list(new LSL_Types.LSLInteger(1), new LSL_Types.LSLInteger(2), new LSL_Types.LSLInteger(3));" +
1389 "\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));" +
1390 "\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));" +
1391 "\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));" +
1392 "\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());" +
1393 "\n LSL_Types.LSLString k = new LSL_Types.LSLString(\"\");" +
1394 "\n LSL_Types.LSLString n = new LSL_Types.LSLString(\"ping\");" +
1395 "\n }\n";
1396  
1397 CSCodeGenerator cg = new CSCodeGenerator();
1398 string output = cg.Convert(input);
1399 Assert.AreEqual(expected, output);
1400 }
1401  
1402 [Test]
1403 public void TestMultipleEqualsExpression()
1404 {
1405 TestHelpers.InMethod();
1406  
1407 string input = @"// let's test x = y = 5 type expressions
1408  
1409 default
1410 {
1411 touch_start(integer num_detected)
1412 {
1413 integer x;
1414 integer y;
1415 x = y = 5;
1416 x += y -= 5;
1417 llOwnerSay(""x is: "" + (string) x + "", y is: "" + (string) y);
1418 }
1419 }
1420 ";
1421 string expected =
1422 "\n public void default_event_touch_start(LSL_Types.LSLInteger num_detected)" +
1423 "\n {" +
1424 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
1425 "\n LSL_Types.LSLInteger y = new LSL_Types.LSLInteger(0);" +
1426 "\n x = y = new LSL_Types.LSLInteger(5);" +
1427 "\n x += y -= new LSL_Types.LSLInteger(5);" +
1428 "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x) + new LSL_Types.LSLString(\", y is: \") + (LSL_Types.LSLString) (y));" +
1429 "\n }\n";
1430  
1431 CSCodeGenerator cg = new CSCodeGenerator();
1432 string output = cg.Convert(input);
1433 Assert.AreEqual(expected, output);
1434 }
1435  
1436 [Test]
1437 public void TestUnaryExpressionLastInVectorConstant()
1438 {
1439 TestHelpers.InMethod();
1440  
1441 string input = @"// let's test unary expressions some more
1442  
1443 default
1444 {
1445 state_entry()
1446 {
1447 vector v = <x,y,-0.5>;
1448 }
1449 }
1450 ";
1451 string expected =
1452 "\n public void default_event_state_entry()" +
1453 "\n {" +
1454 "\n LSL_Types.Vector3 v = new LSL_Types.Vector3(x, y, -new LSL_Types.LSLFloat(0.5));" +
1455 "\n }\n";
1456  
1457 CSCodeGenerator cg = new CSCodeGenerator();
1458 string output = cg.Convert(input);
1459 Assert.AreEqual(expected, output);
1460 }
1461  
1462 [Test]
1463 public void TestVectorMemberPlusEquals()
1464 {
1465 TestHelpers.InMethod();
1466  
1467 string input = @"// let's test unary expressions some more
1468  
1469 default
1470 {
1471 state_entry()
1472 {
1473 vector v = llGetPos();
1474 v.z += 4;
1475 v.z -= 4;
1476 v.z *= 4;
1477 v.z /= 4;
1478 v.z %= 4;
1479 }
1480 }
1481 ";
1482 string expected =
1483 "\n public void default_event_state_entry()" +
1484 "\n {" +
1485 "\n LSL_Types.Vector3 v = llGetPos();" +
1486 "\n v.z += new LSL_Types.LSLInteger(4);" +
1487 "\n v.z -= new LSL_Types.LSLInteger(4);" +
1488 "\n v.z *= new LSL_Types.LSLInteger(4);" +
1489 "\n v.z /= new LSL_Types.LSLInteger(4);" +
1490 "\n v.z %= new LSL_Types.LSLInteger(4);" +
1491 "\n }\n";
1492  
1493 CSCodeGenerator cg = new CSCodeGenerator();
1494 string output = cg.Convert(input);
1495 Assert.AreEqual(expected, output);
1496 }
1497  
1498 [Test]
1499 public void TestWhileLoopWithNoBody()
1500 {
1501 TestHelpers.InMethod();
1502  
1503 string input = @"default
1504 {
1505 state_entry()
1506 {
1507 while (1<0);
1508 }
1509 }";
1510  
1511 string expected =
1512 "\n public void default_event_state_entry()" +
1513 "\n {" +
1514 "\n while (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0))" +
1515 "\n ;" +
1516 "\n }\n";
1517  
1518 CSCodeGenerator cg = new CSCodeGenerator();
1519 string output = cg.Convert(input);
1520 Assert.AreEqual(expected, output);
1521 }
1522  
1523 [Test]
1524 public void TestDoWhileLoopWithNoBody()
1525 {
1526 TestHelpers.InMethod();
1527  
1528 string input = @"default
1529 {
1530 state_entry()
1531 {
1532 do;
1533 while (1<0);
1534 }
1535 }";
1536  
1537 string expected =
1538 "\n public void default_event_state_entry()" +
1539 "\n {" +
1540 "\n do" +
1541 "\n ;" +
1542 "\n while (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0));" +
1543 "\n }\n";
1544  
1545 CSCodeGenerator cg = new CSCodeGenerator();
1546 string output = cg.Convert(input);
1547 Assert.AreEqual(expected, output);
1548 }
1549  
1550 [Test]
1551 public void TestIfWithNoBody()
1552 {
1553 TestHelpers.InMethod();
1554  
1555 string input = @"default
1556 {
1557 state_entry()
1558 {
1559 if (1<0);
1560 }
1561 }";
1562  
1563 string expected =
1564 "\n public void default_event_state_entry()" +
1565 "\n {" +
1566 "\n if (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0))" +
1567 "\n ;" +
1568 "\n }\n";
1569  
1570 CSCodeGenerator cg = new CSCodeGenerator();
1571 string output = cg.Convert(input);
1572 Assert.AreEqual(expected, output);
1573 }
1574  
1575 [Test]
1576 public void TestIfElseWithNoBody()
1577 {
1578 TestHelpers.InMethod();
1579  
1580 string input = @"default
1581 {
1582 state_entry()
1583 {
1584 if (1<0);
1585 else;
1586 }
1587 }";
1588  
1589 string expected =
1590 "\n public void default_event_state_entry()" +
1591 "\n {" +
1592 "\n if (new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0))" +
1593 "\n ;" +
1594 "\n else" +
1595 "\n ;" +
1596 "\n }\n";
1597  
1598 CSCodeGenerator cg = new CSCodeGenerator();
1599 string output = cg.Convert(input);
1600 Assert.AreEqual(expected, output);
1601 }
1602  
1603 [Test]
1604 public void TestForLoopWithNoBody()
1605 {
1606 TestHelpers.InMethod();
1607  
1608 string input = @"default
1609 {
1610 state_entry()
1611 {
1612 for (x = 4; 1<0; x += 2);
1613 }
1614 }";
1615  
1616 string expected =
1617 "\n public void default_event_state_entry()" +
1618 "\n {" +
1619 "\n for (x = new LSL_Types.LSLInteger(4); new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0); x += new LSL_Types.LSLInteger(2))" +
1620 "\n ;" +
1621 "\n }\n";
1622  
1623 CSCodeGenerator cg = new CSCodeGenerator();
1624 string output = cg.Convert(input);
1625 Assert.AreEqual(expected, output);
1626 }
1627  
1628 [Test]
1629 public void TestForLoopWithNoAssignment()
1630 {
1631 TestHelpers.InMethod();
1632  
1633 string input = @"default
1634 {
1635 state_entry()
1636 {
1637 integer x = 4;
1638 for (; 1<0; x += 2);
1639 }
1640 }";
1641  
1642 string expected =
1643 "\n public void default_event_state_entry()" +
1644 "\n {" +
1645 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(4);" +
1646 "\n for (; new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0); x += new LSL_Types.LSLInteger(2))" +
1647 "\n ;" +
1648 "\n }\n";
1649  
1650 CSCodeGenerator cg = new CSCodeGenerator();
1651 string output = cg.Convert(input);
1652 Assert.AreEqual(expected, output);
1653 }
1654  
1655 [Test]
1656 public void TestForLoopWithOnlyIdentInAssignment()
1657 {
1658 TestHelpers.InMethod();
1659  
1660 string input = @"default
1661 {
1662 state_entry()
1663 {
1664 integer x = 4;
1665 for (x; 1<0; x += 2);
1666 }
1667 }";
1668  
1669 string expected =
1670 "\n public void default_event_state_entry()" +
1671 "\n {" +
1672 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(4);" +
1673 "\n for (; new LSL_Types.LSLInteger(1) < new LSL_Types.LSLInteger(0); x += new LSL_Types.LSLInteger(2))" +
1674 "\n ;" +
1675 "\n }\n";
1676  
1677 CSCodeGenerator cg = new CSCodeGenerator();
1678 string output = cg.Convert(input);
1679 Assert.AreEqual(expected, output);
1680 }
1681  
1682 [Test]
1683 public void TestAssignmentInIfWhileDoWhile()
1684 {
1685 TestHelpers.InMethod();
1686  
1687 string input = @"default
1688 {
1689 state_entry()
1690 {
1691 integer x;
1692  
1693 while (x = 14) llOwnerSay(""x is: "" + (string) x);
1694  
1695 if (x = 24) llOwnerSay(""x is: "" + (string) x);
1696  
1697 do
1698 llOwnerSay(""x is: "" + (string) x);
1699 while (x = 44);
1700 }
1701 }";
1702  
1703 string expected =
1704 "\n public void default_event_state_entry()" +
1705 "\n {" +
1706 "\n LSL_Types.LSLInteger x = new LSL_Types.LSLInteger(0);" +
1707 "\n while (x = new LSL_Types.LSLInteger(14))" +
1708 "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x));" +
1709 "\n if (x = new LSL_Types.LSLInteger(24))" +
1710 "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x));" +
1711 "\n do" +
1712 "\n llOwnerSay(new LSL_Types.LSLString(\"x is: \") + (LSL_Types.LSLString) (x));" +
1713 "\n while (x = new LSL_Types.LSLInteger(44));" +
1714 "\n }\n";
1715  
1716 CSCodeGenerator cg = new CSCodeGenerator();
1717 string output = cg.Convert(input);
1718 Assert.AreEqual(expected, output);
1719 }
1720  
1721 [Test]
1722 public void TestLSLListHack()
1723 {
1724 TestHelpers.InMethod();
1725  
1726 string input = @"default
1727 {
1728 state_entry()
1729 {
1730 list l = [""hello""];
1731 l = (l=[]) + l + ""world"";
1732 }
1733 }";
1734  
1735 string expected =
1736 "\n public void default_event_state_entry()" +
1737 "\n {" +
1738 "\n LSL_Types.list l = new LSL_Types.list(new LSL_Types.LSLString(\"hello\"));" +
1739 "\n l = (l = new LSL_Types.list()) + l + new LSL_Types.LSLString(\"world\");" +
1740 "\n }\n";
1741  
1742 CSCodeGenerator cg = new CSCodeGenerator();
1743 string output = cg.Convert(input);
1744 Assert.AreEqual(expected, output);
1745 }
1746  
1747 [Test]
1748 public void TestSyntaxError()
1749 {
1750 TestHelpers.InMethod();
1751  
1752 bool gotException = false;
1753  
1754 string input = @"default
1755 {
1756 state_entry()
1757 {
1758 integer y
1759 }
1760 }
1761 ";
1762 try
1763 {
1764 CSCodeGenerator cg = new CSCodeGenerator();
1765 cg.Convert(input);
1766 }
1767 catch (System.Exception e)
1768 {
1769 // The syntax error is on line 5, char 4 (expected ';', found
1770 // '}').
1771 Assert.AreEqual("(5,4) syntax error", e.Message);
1772 gotException = true;
1773 }
1774  
1775 Assert.That(gotException, Is.True);
1776 }
1777  
1778 [Test]
1779 public void TestSyntaxErrorDeclaringVariableInForLoop()
1780 {
1781 TestHelpers.InMethod();
1782  
1783 bool gotException = false;
1784  
1785 string input = @"default
1786 {
1787 state_entry()
1788 {
1789 for (integer x = 0; x < 10; x++) llOwnerSay(""x is: "" + (string) x);
1790 }
1791 }
1792 ";
1793 try
1794 {
1795 CSCodeGenerator cg = new CSCodeGenerator();
1796 cg.Convert(input);
1797 }
1798 catch (System.Exception e)
1799 {
1800 // The syntax error is on line 4, char 13 (Syntax error)
1801 Assert.AreEqual("(4,13) syntax error", e.Message);
1802  
1803 gotException = true;
1804 }
1805  
1806 Assert.That(gotException, Is.True);
1807 }
1808 }
1809 }