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