OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
CSCodeGeneratorTest.cs
Go to the documentation of this file.
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 {
41  [TestFixture]
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 
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 
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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 }
Tests the LSL compiler, both the code generation and transformation. Each test has some LSL code as i...