aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMike Mazur2008-07-23 02:51:45 +0000
committerMike Mazur2008-07-23 02:51:45 +0000
commitba17b0df273c87edf30151f3c470780cdf5f997e (patch)
tree94b8c9280c7b8b82d4117882c69298672029c7b6 /OpenSim
parentUpdate svn properties. Minor formatting cleanup. (diff)
downloadopensim-SC-ba17b0df273c87edf30151f3c470780cdf5f997e.zip
opensim-SC-ba17b0df273c87edf30151f3c470780cdf5f997e.tar.gz
opensim-SC-ba17b0df273c87edf30151f3c470780cdf5f997e.tar.bz2
opensim-SC-ba17b0df273c87edf30151f3c470780cdf5f997e.tar.xz
First version of position mapping between LSL <-> C# implemented.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs369
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs357
-rw-r--r--OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs (renamed from OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSLCompilerTest.cs)6
-rw-r--r--OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CompilerTest.cs120
5 files changed, 623 insertions, 234 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs
index f7aee66..f129859 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs
@@ -35,56 +35,89 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
35 public class CSCodeGenerator 35 public class CSCodeGenerator
36 { 36 {
37 private SYMBOL m_astRoot = null; 37 private SYMBOL m_astRoot = null;
38 private int m_braceCount; // for indentation 38 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap;
39 private int m_indentWidth = 4; // for indentation
40 private int m_braceCount; // for indentation
41 private int m_CSharpLine; // the current line of generated C# code
42 private int m_CSharpCol; // the current column of generated C# code
39 43
40 /// <summary> 44 /// <summary>
41 /// Pass the new CodeGenerator a string containing the LSL source. 45 /// Creates an 'empty' CSCodeGenerator instance.
42 /// </summary> 46 /// </summary>
43 /// <param name="script">String containing LSL source.</param> 47 public CSCodeGenerator()
44 public CSCodeGenerator(string script)
45 { 48 {
46 Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); 49 ResetCounters();
47 // Obviously this needs to be in a try/except block. 50 }
48 LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); 51
49 m_astRoot = codeTransformer.Transform(); 52 /// <summary>
53 /// Get the mapping between LSL and C# line/column number.
54 /// </summary>
55 /// <returns>Dictionary\<KeyValuePair\<int, int\>, KeyValuePair\<int, int\>\>.</returns>
56 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> PositionMap
57 {
58 get { return m_positionMap; }
59 }
60
61 /// <summary>
62 /// Get the mapping between LSL and C# line/column number.
63 /// </summary>
64 /// <returns>SYMBOL pointing to root of the abstract syntax tree.</returns>
65 public SYMBOL ASTRoot
66 {
67 get { return m_astRoot; }
50 } 68 }
51 69
52 /// <summary> 70 /// <summary>
53 /// Pass the new CodeGenerator an abstract syntax tree. 71 /// Resets various counters and metadata.
54 /// </summary> 72 /// </summary>
55 /// <param name="astRoot">The root node of the AST.</param> 73 private void ResetCounters()
56 public CSCodeGenerator(SYMBOL astRoot)
57 { 74 {
58 m_braceCount = 0; 75 m_braceCount = 0;
59 m_astRoot = astRoot; 76 m_CSharpLine = 0;
77 m_CSharpCol = 1;
78 m_positionMap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
79 m_astRoot = null;
60 } 80 }
61 81
62 /// <summary> 82 /// <summary>
63 /// Generate the code from the AST we have. 83 /// Generate the code from the AST we have.
64 /// </summary> 84 /// </summary>
85 /// <param name="script">The LSL source as a string.</param>
65 /// <returns>String containing the generated C# code.</returns> 86 /// <returns>String containing the generated C# code.</returns>
66 public string Generate() 87 public string Convert(string script)
67 { 88 {
89 ResetCounters();
90 Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true));
91 // Obviously this needs to be in a try/except block.
92 LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script));
93 m_astRoot = codeTransformer.Transform();
94
68 string retstr = String.Empty; 95 string retstr = String.Empty;
69 96
70 // standard preamble 97 // standard preamble
71 //retstr = "using OpenSim.Region.ScriptEngine.Common;\n"; 98 //retstr = GenerateLine("using OpenSim.Region.ScriptEngine.Common;");
72 //retstr += "using System.Collections.Generic;\n\n"; 99 //retstr += GenerateLine("using System.Collections.Generic;");
73 //retstr += "namespace SecondLife\n"; 100 //retstr += GenerateLine("");
74 //retstr += "{\n"; 101 //retstr += GenerateLine("namespace SecondLife");
75 //retstr += " public class Script : OpenSim.Region.ScriptEngine.Common\n"; 102 //retstr += GenerateLine("{");
76 //retstr += " {\n"; 103 m_braceCount++;
104 //retstr += GenerateIndentedLine("public class Script : OpenSim.Region.ScriptEngine.Common");
105 //retstr += GenerateIndentedLine("{");
106 m_braceCount++;
107
108 // line number
109 m_CSharpLine += 3;
77 110
78 // here's the payload 111 // here's the payload
79 m_braceCount += 2; 112 retstr += GenerateLine();
80 retstr += "\n";
81 foreach (SYMBOL s in m_astRoot.kids) 113 foreach (SYMBOL s in m_astRoot.kids)
82 retstr += GenerateNode(s); 114 retstr += GenerateNode(s);
83 115
84 // close braces! 116 // close braces!
85 //retstr += " }\n"; 117 m_braceCount--;
86 //retstr += "}\n"; 118 //retstr += GenerateIndentedLine("}");
87 m_braceCount -= 2; 119 m_braceCount--;
120 //retstr += GenerateLine("}");
88 121
89 return retstr; 122 return retstr;
90 } 123 }
@@ -155,11 +188,11 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
155 else if (s is Constant) 188 else if (s is Constant)
156 retstr += GenerateConstant((Constant) s); 189 retstr += GenerateConstant((Constant) s);
157 else if (s is IdentDotExpression) 190 else if (s is IdentDotExpression)
158 retstr += ((IdentDotExpression) s).Name + "." + ((IdentDotExpression) s).Member; 191 retstr += Generate(((IdentDotExpression) s).Name + "." + ((IdentDotExpression) s).Member, s);
159 else if (s is IdentExpression) 192 else if (s is IdentExpression)
160 retstr += ((IdentExpression) s).Name; 193 retstr += Generate(((IdentExpression) s).Name, s);
161 else if (s is IDENT) 194 else if (s is IDENT)
162 retstr += ((TOKEN) s).yytext; 195 retstr += Generate(((TOKEN) s).yytext, s);
163 else 196 else
164 { 197 {
165 foreach (SYMBOL kid in s.kids) 198 foreach (SYMBOL kid in s.kids)
@@ -188,13 +221,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
188 else 221 else
189 remainingKids.Add(kid); 222 remainingKids.Add(kid);
190 223
191 retstr += WriteIndented(String.Format("{0} {1}(", gf.ReturnType, gf.Name)); 224 retstr += GenerateIndented(String.Format("{0} {1}(", gf.ReturnType, gf.Name), gf);
192 225
193 // print the state arguments, if any 226 // print the state arguments, if any
194 foreach (SYMBOL kid in argumentDeclarationListKids) 227 foreach (SYMBOL kid in argumentDeclarationListKids)
195 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid); 228 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
196 229
197 retstr += ")\n"; 230 retstr += GenerateLine(")");
198 231
199 foreach (SYMBOL kid in remainingKids) 232 foreach (SYMBOL kid in remainingKids)
200 retstr += GenerateNode(kid); 233 retstr += GenerateNode(kid);
@@ -215,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
215 { 248 {
216 retstr += Indent(); 249 retstr += Indent();
217 retstr += GenerateNode(s); 250 retstr += GenerateNode(s);
218 retstr += ";\n"; 251 retstr += GenerateLine(";");
219 } 252 }
220 253
221 return retstr; 254 return retstr;
@@ -233,8 +266,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
233 foreach (SYMBOL kid in s.kids) 266 foreach (SYMBOL kid in s.kids)
234 if (kid is StateEvent) 267 if (kid is StateEvent)
235 retstr += GenerateStateEvent((StateEvent) kid, s.Name); 268 retstr += GenerateStateEvent((StateEvent) kid, s.Name);
236 else
237 retstr += String.Format("ERROR: State '{0}' contains a '{1}\n", s.Name, kid.GetType());
238 269
239 return retstr; 270 return retstr;
240 } 271 }
@@ -260,13 +291,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
260 remainingKids.Add(kid); 291 remainingKids.Add(kid);
261 292
262 // "state" (function) declaration 293 // "state" (function) declaration
263 retstr += WriteIndented(String.Format("public void {0}_event_{1}(", parentStateName, se.Name)); 294 retstr += GenerateIndented(String.Format("public void {0}_event_{1}(", parentStateName, se.Name), se);
264 295
265 // print the state arguments, if any 296 // print the state arguments, if any
266 foreach (SYMBOL kid in argumentDeclarationListKids) 297 foreach (SYMBOL kid in argumentDeclarationListKids)
267 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid); 298 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
268 299
269 retstr += ")\n"; 300 retstr += GenerateLine(")");
270 301
271 foreach (SYMBOL kid in remainingKids) 302 foreach (SYMBOL kid in remainingKids)
272 retstr += GenerateNode(kid); 303 retstr += GenerateNode(kid);
@@ -278,7 +309,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
278 /// Generates the code for an ArgumentDeclarationList node. 309 /// Generates the code for an ArgumentDeclarationList node.
279 /// </summary> 310 /// </summary>
280 /// <param name="adl">The ArgumentDeclarationList node.</param> 311 /// <param name="adl">The ArgumentDeclarationList node.</param>
281 /// <returns>String containing C# code for SYMBOL s.</returns> 312 /// <returns>String containing C# code for ArgumentDeclarationList adl.</returns>
282 private string GenerateArgumentDeclarationList(ArgumentDeclarationList adl) 313 private string GenerateArgumentDeclarationList(ArgumentDeclarationList adl)
283 { 314 {
284 string retstr = String.Empty; 315 string retstr = String.Empty;
@@ -287,9 +318,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
287 318
288 foreach (Declaration d in adl.kids) 319 foreach (Declaration d in adl.kids)
289 { 320 {
290 retstr += String.Format("{0} {1}", d.Datatype, d.Id); 321 retstr += Generate(String.Format("{0} {1}", d.Datatype, d.Id), d);
291 if (0 < comma--) 322 if (0 < comma--)
292 retstr += ", "; 323 retstr += Generate(", ");
293 } 324 }
294 325
295 return retstr; 326 return retstr;
@@ -299,7 +330,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
299 /// Generates the code for an ArgumentList node. 330 /// Generates the code for an ArgumentList node.
300 /// </summary> 331 /// </summary>
301 /// <param name="al">The ArgumentList node.</param> 332 /// <param name="al">The ArgumentList node.</param>
302 /// <returns>String containing C# code for SYMBOL s.</returns> 333 /// <returns>String containing C# code for ArgumentList al.</returns>
303 private string GenerateArgumentList(ArgumentList al) 334 private string GenerateArgumentList(ArgumentList al)
304 { 335 {
305 string retstr = String.Empty; 336 string retstr = String.Empty;
@@ -310,7 +341,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
310 { 341 {
311 retstr += GenerateNode(s); 342 retstr += GenerateNode(s);
312 if (0 < comma--) 343 if (0 < comma--)
313 retstr += ", "; 344 retstr += Generate(", ");
314 } 345 }
315 346
316 return retstr; 347 return retstr;
@@ -320,13 +351,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
320 /// Generates the code for a CompoundStatement node. 351 /// Generates the code for a CompoundStatement node.
321 /// </summary> 352 /// </summary>
322 /// <param name="cs">The CompoundStatement node.</param> 353 /// <param name="cs">The CompoundStatement node.</param>
323 /// <returns>String containing C# code for SYMBOL s.</returns> 354 /// <returns>String containing C# code for CompoundStatement cs.</returns>
324 private string GenerateCompoundStatement(CompoundStatement cs) 355 private string GenerateCompoundStatement(CompoundStatement cs)
325 { 356 {
326 string retstr = String.Empty; 357 string retstr = String.Empty;
327 358
328 // opening brace 359 // opening brace
329 retstr += WriteIndentedLine("{"); 360 retstr += GenerateIndentedLine("{");
330 m_braceCount++; 361 m_braceCount++;
331 362
332 foreach (SYMBOL kid in cs.kids) 363 foreach (SYMBOL kid in cs.kids)
@@ -334,7 +365,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
334 365
335 // closing brace 366 // closing brace
336 m_braceCount--; 367 m_braceCount--;
337 retstr += WriteIndentedLine("}"); 368 retstr += GenerateIndentedLine("}");
338 369
339 return retstr; 370 return retstr;
340 } 371 }
@@ -343,17 +374,17 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
343 /// Generates the code for a Declaration node. 374 /// Generates the code for a Declaration node.
344 /// </summary> 375 /// </summary>
345 /// <param name="d">The Declaration node.</param> 376 /// <param name="d">The Declaration node.</param>
346 /// <returns>String containing C# code for SYMBOL s.</returns> 377 /// <returns>String containing C# code for Declaration d.</returns>
347 private string GenerateDeclaration(Declaration d) 378 private string GenerateDeclaration(Declaration d)
348 { 379 {
349 return String.Format("{0} {1}", d.Datatype, d.Id); 380 return Generate(String.Format("{0} {1}", d.Datatype, d.Id), d);
350 } 381 }
351 382
352 /// <summary> 383 /// <summary>
353 /// Generates the code for a Statement node. 384 /// Generates the code for a Statement node.
354 /// </summary> 385 /// </summary>
355 /// <param name="s">The Statement node.</param> 386 /// <param name="s">The Statement node.</param>
356 /// <returns>String containing C# code for SYMBOL s.</returns> 387 /// <returns>String containing C# code for Statement s.</returns>
357 private string GenerateStatement(Statement s) 388 private string GenerateStatement(Statement s)
358 { 389 {
359 string retstr = String.Empty; 390 string retstr = String.Empty;
@@ -367,7 +398,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
367 retstr += GenerateNode(kid); 398 retstr += GenerateNode(kid);
368 399
369 if (printSemicolon) 400 if (printSemicolon)
370 retstr += ";\n"; 401 retstr += GenerateLine(";");
371 402
372 return retstr; 403 return retstr;
373 } 404 }
@@ -376,13 +407,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
376 /// Generates the code for an Assignment node. 407 /// Generates the code for an Assignment node.
377 /// </summary> 408 /// </summary>
378 /// <param name="a">The Assignment node.</param> 409 /// <param name="a">The Assignment node.</param>
379 /// <returns>String containing C# code for SYMBOL s.</returns> 410 /// <returns>String containing C# code for Assignment a.</returns>
380 private string GenerateAssignment(Assignment a) 411 private string GenerateAssignment(Assignment a)
381 { 412 {
382 string retstr = String.Empty; 413 string retstr = String.Empty;
383 414
384 retstr += GenerateNode((SYMBOL) a.kids.Pop()); 415 retstr += GenerateNode((SYMBOL) a.kids.Pop());
385 retstr +=String.Format(" {0} ", a.AssignmentType); 416 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
386 foreach (SYMBOL kid in a.kids) 417 foreach (SYMBOL kid in a.kids)
387 retstr += GenerateNode(kid); 418 retstr += GenerateNode(kid);
388 419
@@ -393,12 +424,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
393 /// Generates the code for a ReturnStatement node. 424 /// Generates the code for a ReturnStatement node.
394 /// </summary> 425 /// </summary>
395 /// <param name="rs">The ReturnStatement node.</param> 426 /// <param name="rs">The ReturnStatement node.</param>
396 /// <returns>String containing C# code for SYMBOL s.</returns> 427 /// <returns>String containing C# code for ReturnStatement rs.</returns>
397 private string GenerateReturnStatement(ReturnStatement rs) 428 private string GenerateReturnStatement(ReturnStatement rs)
398 { 429 {
399 string retstr = String.Empty; 430 string retstr = String.Empty;
400 431
401 retstr += "return "; 432 retstr += Generate("return ", rs);
402 433
403 foreach (SYMBOL kid in rs.kids) 434 foreach (SYMBOL kid in rs.kids)
404 retstr += GenerateNode(kid); 435 retstr += GenerateNode(kid);
@@ -410,34 +441,34 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
410 /// Generates the code for a JumpLabel node. 441 /// Generates the code for a JumpLabel node.
411 /// </summary> 442 /// </summary>
412 /// <param name="jl">The JumpLabel node.</param> 443 /// <param name="jl">The JumpLabel node.</param>
413 /// <returns>String containing C# code for SYMBOL s.</returns> 444 /// <returns>String containing C# code for JumpLabel jl.</returns>
414 private string GenerateJumpLabel(JumpLabel jl) 445 private string GenerateJumpLabel(JumpLabel jl)
415 { 446 {
416 return String.Format("{0}:\n", jl.LabelName); 447 return Generate(String.Format("{0}:\n", jl.LabelName), jl);
417 } 448 }
418 449
419 /// <summary> 450 /// <summary>
420 /// Generates the code for a JumpStatement node. 451 /// Generates the code for a JumpStatement node.
421 /// </summary> 452 /// </summary>
422 /// <param name="js">The JumpStatement node.</param> 453 /// <param name="js">The JumpStatement node.</param>
423 /// <returns>String containing C# code for SYMBOL s.</returns> 454 /// <returns>String containing C# code for JumpStatement js.</returns>
424 private string GenerateJumpStatement(JumpStatement js) 455 private string GenerateJumpStatement(JumpStatement js)
425 { 456 {
426 return String.Format("goto {0}", js.TargetName); 457 return Generate(String.Format("goto {0}", js.TargetName), js);
427 } 458 }
428 459
429 /// <summary> 460 /// <summary>
430 /// Generates the code for a IfStatement node. 461 /// Generates the code for an IfStatement node.
431 /// </summary> 462 /// </summary>
432 /// <param name="ifs">The IfStatement node.</param> 463 /// <param name="ifs">The IfStatement node.</param>
433 /// <returns>String containing C# code for SYMBOL s.</returns> 464 /// <returns>String containing C# code for IfStatement ifs.</returns>
434 private string GenerateIfStatement(IfStatement ifs) 465 private string GenerateIfStatement(IfStatement ifs)
435 { 466 {
436 string retstr = String.Empty; 467 string retstr = String.Empty;
437 468
438 retstr += WriteIndented("if ("); 469 retstr += GenerateIndented("if (", ifs);
439 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 470 retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
440 retstr += ")\n"; 471 retstr += GenerateLine(")");
441 472
442 // CompoundStatement handles indentation itself but we need to do it 473 // CompoundStatement handles indentation itself but we need to do it
443 // otherwise. 474 // otherwise.
@@ -448,7 +479,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
448 479
449 if (0 < ifs.kids.Count) // do it again for an else 480 if (0 < ifs.kids.Count) // do it again for an else
450 { 481 {
451 retstr += WriteIndentedLine("else"); 482 retstr += GenerateIndentedLine("else", ifs);
452 483
453 indentHere = ifs.kids.Top is Statement; 484 indentHere = ifs.kids.Top is Statement;
454 if (indentHere) m_braceCount++; 485 if (indentHere) m_braceCount++;
@@ -463,24 +494,24 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
463 /// Generates the code for a StateChange node. 494 /// Generates the code for a StateChange node.
464 /// </summary> 495 /// </summary>
465 /// <param name="sc">The StateChange node.</param> 496 /// <param name="sc">The StateChange node.</param>
466 /// <returns>String containing C# code for SYMBOL s.</returns> 497 /// <returns>String containing C# code for StateChange sc.</returns>
467 private string GenerateStateChange(StateChange sc) 498 private string GenerateStateChange(StateChange sc)
468 { 499 {
469 return String.Format("state(\"{0}\")", sc.NewState); 500 return Generate(String.Format("state(\"{0}\")", sc.NewState), sc);
470 } 501 }
471 502
472 /// <summary> 503 /// <summary>
473 /// Generates the code for a WhileStatement node. 504 /// Generates the code for a WhileStatement node.
474 /// </summary> 505 /// </summary>
475 /// <param name="ws">The WhileStatement node.</param> 506 /// <param name="ws">The WhileStatement node.</param>
476 /// <returns>String containing C# code for SYMBOL s.</returns> 507 /// <returns>String containing C# code for WhileStatement ws.</returns>
477 private string GenerateWhileStatement(WhileStatement ws) 508 private string GenerateWhileStatement(WhileStatement ws)
478 { 509 {
479 string retstr = String.Empty; 510 string retstr = String.Empty;
480 511
481 retstr += WriteIndented("while ("); 512 retstr += GenerateIndented("while (", ws);
482 retstr += GenerateNode((SYMBOL) ws.kids.Pop()); 513 retstr += GenerateNode((SYMBOL) ws.kids.Pop());
483 retstr += ")\n"; 514 retstr += GenerateLine(")");
484 515
485 // CompoundStatement handles indentation itself but we need to do it 516 // CompoundStatement handles indentation itself but we need to do it
486 // otherwise. 517 // otherwise.
@@ -496,12 +527,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
496 /// Generates the code for a DoWhileStatement node. 527 /// Generates the code for a DoWhileStatement node.
497 /// </summary> 528 /// </summary>
498 /// <param name="dws">The DoWhileStatement node.</param> 529 /// <param name="dws">The DoWhileStatement node.</param>
499 /// <returns>String containing C# code for SYMBOL s.</returns> 530 /// <returns>String containing C# code for DoWhileStatement dws.</returns>
500 private string GenerateDoWhileStatement(DoWhileStatement dws) 531 private string GenerateDoWhileStatement(DoWhileStatement dws)
501 { 532 {
502 string retstr = String.Empty; 533 string retstr = String.Empty;
503 534
504 retstr += WriteIndentedLine("do"); 535 retstr += GenerateIndentedLine("do", dws);
505 536
506 // CompoundStatement handles indentation itself but we need to do it 537 // CompoundStatement handles indentation itself but we need to do it
507 // otherwise. 538 // otherwise.
@@ -510,9 +541,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
510 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 541 retstr += GenerateNode((SYMBOL) dws.kids.Pop());
511 if (indentHere) m_braceCount--; 542 if (indentHere) m_braceCount--;
512 543
513 retstr += WriteIndented("while ("); 544 retstr += GenerateIndented("while (", dws);
514 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 545 retstr += GenerateNode((SYMBOL) dws.kids.Pop());
515 retstr += ");\n"; 546 retstr += GenerateLine(");");
516 547
517 return retstr; 548 return retstr;
518 } 549 }
@@ -521,25 +552,25 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
521 /// Generates the code for a ForLoop node. 552 /// Generates the code for a ForLoop node.
522 /// </summary> 553 /// </summary>
523 /// <param name="fl">The ForLoop node.</param> 554 /// <param name="fl">The ForLoop node.</param>
524 /// <returns>String containing C# code for SYMBOL s.</returns> 555 /// <returns>String containing C# code for ForLoop fl.</returns>
525 private string GenerateForLoop(ForLoop fl) 556 private string GenerateForLoop(ForLoop fl)
526 { 557 {
527 string retstr = String.Empty; 558 string retstr = String.Empty;
528 559
529 retstr += WriteIndented("for ("); 560 retstr += GenerateIndented("for (", fl);
530 561
531 // for ( x = 0 ; x < 10 ; x++ ) 562 // for ( x = 0 ; x < 10 ; x++ )
532 // ^^^^^^^ 563 // ^^^^^^^
533 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop()); 564 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
534 retstr += "; "; 565 retstr += Generate("; ");
535 // for ( x = 0 ; x < 10 ; x++ ) 566 // for ( x = 0 ; x < 10 ; x++ )
536 // ^^^^^^^^ 567 // ^^^^^^^^
537 retstr += GenerateNode((SYMBOL) fl.kids.Pop()); 568 retstr += GenerateNode((SYMBOL) fl.kids.Pop());
538 retstr += "; "; 569 retstr += Generate("; ");
539 // for ( x = 0 ; x < 10 ; x++ ) 570 // for ( x = 0 ; x < 10 ; x++ )
540 // ^^^^^ 571 // ^^^^^
541 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop()); 572 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
542 retstr += ")\n"; 573 retstr += GenerateLine(")");
543 574
544 // CompoundStatement handles indentation itself but we need to do it 575 // CompoundStatement handles indentation itself but we need to do it
545 // otherwise. 576 // otherwise.
@@ -555,7 +586,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
555 /// Generates the code for a ForLoopStatement node. 586 /// Generates the code for a ForLoopStatement node.
556 /// </summary> 587 /// </summary>
557 /// <param name="fls">The ForLoopStatement node.</param> 588 /// <param name="fls">The ForLoopStatement node.</param>
558 /// <returns>String containing C# code for SYMBOL s.</returns> 589 /// <returns>String containing C# code for ForLoopStatement fls.</returns>
559 private string GenerateForLoopStatement(ForLoopStatement fls) 590 private string GenerateForLoopStatement(ForLoopStatement fls)
560 { 591 {
561 string retstr = String.Empty; 592 string retstr = String.Empty;
@@ -566,7 +597,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
566 { 597 {
567 retstr += GenerateNode(s); 598 retstr += GenerateNode(s);
568 if (0 < comma--) 599 if (0 < comma--)
569 retstr += ", "; 600 retstr += Generate(", ");
570 } 601 }
571 602
572 return retstr; 603 return retstr;
@@ -576,13 +607,13 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
576 /// Generates the code for a BinaryExpression node. 607 /// Generates the code for a BinaryExpression node.
577 /// </summary> 608 /// </summary>
578 /// <param name="be">The BinaryExpression node.</param> 609 /// <param name="be">The BinaryExpression node.</param>
579 /// <returns>String containing C# code for SYMBOL s.</returns> 610 /// <returns>String containing C# code for BinaryExpression be.</returns>
580 private string GenerateBinaryExpression(BinaryExpression be) 611 private string GenerateBinaryExpression(BinaryExpression be)
581 { 612 {
582 string retstr = String.Empty; 613 string retstr = String.Empty;
583 614
584 retstr += GenerateNode((SYMBOL) be.kids.Pop()); 615 retstr += GenerateNode((SYMBOL) be.kids.Pop());
585 retstr += String.Format(" {0} ", be.ExpressionSymbol); 616 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be);
586 foreach (SYMBOL kid in be.kids) 617 foreach (SYMBOL kid in be.kids)
587 retstr += GenerateNode(kid); 618 retstr += GenerateNode(kid);
588 619
@@ -593,12 +624,12 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
593 /// Generates the code for a UnaryExpression node. 624 /// Generates the code for a UnaryExpression node.
594 /// </summary> 625 /// </summary>
595 /// <param name="ue">The UnaryExpression node.</param> 626 /// <param name="ue">The UnaryExpression node.</param>
596 /// <returns>String containing C# code for SYMBOL s.</returns> 627 /// <returns>String containing C# code for UnaryExpression ue.</returns>
597 private string GenerateUnaryExpression(UnaryExpression ue) 628 private string GenerateUnaryExpression(UnaryExpression ue)
598 { 629 {
599 string retstr = String.Empty; 630 string retstr = String.Empty;
600 631
601 retstr += ue.UnarySymbol; 632 retstr += Generate(ue.UnarySymbol, ue);
602 retstr += GenerateNode((SYMBOL) ue.kids.Pop()); 633 retstr += GenerateNode((SYMBOL) ue.kids.Pop());
603 634
604 return retstr; 635 return retstr;
@@ -608,15 +639,15 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
608 /// Generates the code for a ParenthesisExpression node. 639 /// Generates the code for a ParenthesisExpression node.
609 /// </summary> 640 /// </summary>
610 /// <param name="pe">The ParenthesisExpression node.</param> 641 /// <param name="pe">The ParenthesisExpression node.</param>
611 /// <returns>String containing C# code for SYMBOL s.</returns> 642 /// <returns>String containing C# code for ParenthesisExpression pe.</returns>
612 private string GenerateParenthesisExpression(ParenthesisExpression pe) 643 private string GenerateParenthesisExpression(ParenthesisExpression pe)
613 { 644 {
614 string retstr = String.Empty; 645 string retstr = String.Empty;
615 646
616 retstr += "("; 647 retstr += Generate("(");
617 foreach (SYMBOL kid in pe.kids) 648 foreach (SYMBOL kid in pe.kids)
618 retstr += GenerateNode(kid); 649 retstr += GenerateNode(kid);
619 retstr += ")"; 650 retstr += Generate(")");
620 651
621 return retstr; 652 return retstr;
622 } 653 }
@@ -625,7 +656,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
625 /// Generates the code for a IncrementDecrementExpression node. 656 /// Generates the code for a IncrementDecrementExpression node.
626 /// </summary> 657 /// </summary>
627 /// <param name="ide">The IncrementDecrementExpression node.</param> 658 /// <param name="ide">The IncrementDecrementExpression node.</param>
628 /// <returns>String containing C# code for SYMBOL s.</returns> 659 /// <returns>String containing C# code for IncrementDecrementExpression ide.</returns>
629 private string GenerateIncrementDecrementExpression(IncrementDecrementExpression ide) 660 private string GenerateIncrementDecrementExpression(IncrementDecrementExpression ide)
630 { 661 {
631 string retstr = String.Empty; 662 string retstr = String.Empty;
@@ -633,10 +664,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
633 if (0 < ide.kids.Count) 664 if (0 < ide.kids.Count)
634 { 665 {
635 IdentDotExpression dot = (IdentDotExpression) ide.kids.Top; 666 IdentDotExpression dot = (IdentDotExpression) ide.kids.Top;
636 retstr += String.Format("{0}", ide.PostOperation ? dot.Name + "." + dot.Member + ide.Operation : ide.Operation + dot.Name + "." + dot.Member); 667 retstr += Generate(String.Format("{0}", ide.PostOperation ? dot.Name + "." + dot.Member + ide.Operation : ide.Operation + dot.Name + "." + dot.Member), ide);
637 } 668 }
638 else 669 else
639 retstr += String.Format("{0}", ide.PostOperation ? ide.Name + ide.Operation : ide.Operation + ide.Name); 670 retstr += Generate(String.Format("{0}", ide.PostOperation ? ide.Name + ide.Operation : ide.Operation + ide.Name), ide);
640 671
641 return retstr; 672 return retstr;
642 } 673 }
@@ -645,15 +676,15 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
645 /// Generates the code for a TypecastExpression node. 676 /// Generates the code for a TypecastExpression node.
646 /// </summary> 677 /// </summary>
647 /// <param name="te">The TypecastExpression node.</param> 678 /// <param name="te">The TypecastExpression node.</param>
648 /// <returns>String containing C# code for SYMBOL s.</returns> 679 /// <returns>String containing C# code for TypecastExpression te.</returns>
649 private string GenerateTypecastExpression(TypecastExpression te) 680 private string GenerateTypecastExpression(TypecastExpression te)
650 { 681 {
651 string retstr = String.Empty; 682 string retstr = String.Empty;
652 683
653 // we wrap all typecasted statements in parentheses 684 // we wrap all typecasted statements in parentheses
654 retstr += String.Format("({0}) (", te.TypecastType); 685 retstr += Generate(String.Format("({0}) (", te.TypecastType), te);
655 retstr += GenerateNode((SYMBOL) te.kids.Pop()); 686 retstr += GenerateNode((SYMBOL) te.kids.Pop());
656 retstr += ")"; 687 retstr += Generate(")");
657 688
658 return retstr; 689 return retstr;
659 } 690 }
@@ -662,17 +693,17 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
662 /// Generates the code for a FunctionCall node. 693 /// Generates the code for a FunctionCall node.
663 /// </summary> 694 /// </summary>
664 /// <param name="fc">The FunctionCall node.</param> 695 /// <param name="fc">The FunctionCall node.</param>
665 /// <returns>String containing C# code for SYMBOL s.</returns> 696 /// <returns>String containing C# code for FunctionCall fc.</returns>
666 private string GenerateFunctionCall(FunctionCall fc) 697 private string GenerateFunctionCall(FunctionCall fc)
667 { 698 {
668 string retstr = String.Empty; 699 string retstr = String.Empty;
669 700
670 retstr += String.Format("{0}(", fc.Id); 701 retstr += Generate(String.Format("{0}(", fc.Id), fc);
671 702
672 foreach (SYMBOL kid in fc.kids) 703 foreach (SYMBOL kid in fc.kids)
673 retstr += GenerateNode(kid); 704 retstr += GenerateNode(kid);
674 705
675 retstr += ")"; 706 retstr += Generate(")");
676 707
677 return retstr; 708 return retstr;
678 } 709 }
@@ -681,7 +712,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
681 /// Generates the code for a Constant node. 712 /// Generates the code for a Constant node.
682 /// </summary> 713 /// </summary>
683 /// <param name="c">The Constant node.</param> 714 /// <param name="c">The Constant node.</param>
684 /// <returns>String containing C# code for SYMBOL s.</returns> 715 /// <returns>String containing C# code for Constant c.</returns>
685 private string GenerateConstant(Constant c) 716 private string GenerateConstant(Constant c)
686 { 717 {
687 string retstr = String.Empty; 718 string retstr = String.Empty;
@@ -697,10 +728,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
697 728
698 // need to quote strings 729 // need to quote strings
699 if ("LSL_Types.LSLString" == c.Type) 730 if ("LSL_Types.LSLString" == c.Type)
700 retstr += "\""; 731 retstr += Generate("\"");
701 retstr += c.Value; 732 retstr += Generate(c.Value, c);
702 if ("LSL_Types.LSLString" == c.Type) 733 if ("LSL_Types.LSLString" == c.Type)
703 retstr += "\""; 734 retstr += Generate("\"");
704 735
705 return retstr; 736 return retstr;
706 } 737 }
@@ -709,18 +740,18 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
709 /// Generates the code for a VectorConstant node. 740 /// Generates the code for a VectorConstant node.
710 /// </summary> 741 /// </summary>
711 /// <param name="vc">The VectorConstant node.</param> 742 /// <param name="vc">The VectorConstant node.</param>
712 /// <returns>String containing C# code for SYMBOL s.</returns> 743 /// <returns>String containing C# code for VectorConstant vc.</returns>
713 private string GenerateVectorConstant(VectorConstant vc) 744 private string GenerateVectorConstant(VectorConstant vc)
714 { 745 {
715 string retstr = String.Empty; 746 string retstr = String.Empty;
716 747
717 retstr += String.Format("new {0}(", vc.Type); 748 retstr += Generate(String.Format("new {0}(", vc.Type), vc);
718 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 749 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
719 retstr += ", "; 750 retstr += Generate(", ");
720 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 751 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
721 retstr += ", "; 752 retstr += Generate(", ");
722 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 753 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
723 retstr += ")"; 754 retstr += Generate(")");
724 755
725 return retstr; 756 return retstr;
726 } 757 }
@@ -729,20 +760,20 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
729 /// Generates the code for a RotationConstant node. 760 /// Generates the code for a RotationConstant node.
730 /// </summary> 761 /// </summary>
731 /// <param name="rc">The RotationConstant node.</param> 762 /// <param name="rc">The RotationConstant node.</param>
732 /// <returns>String containing C# code for SYMBOL s.</returns> 763 /// <returns>String containing C# code for RotationConstant rc.</returns>
733 private string GenerateRotationConstant(RotationConstant rc) 764 private string GenerateRotationConstant(RotationConstant rc)
734 { 765 {
735 string retstr = String.Empty; 766 string retstr = String.Empty;
736 767
737 retstr += String.Format("new {0}(", rc.Type); 768 retstr += Generate(String.Format("new {0}(", rc.Type), rc);
738 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 769 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
739 retstr += ", "; 770 retstr += Generate(", ");
740 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 771 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
741 retstr += ", "; 772 retstr += Generate(", ");
742 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 773 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
743 retstr += ", "; 774 retstr += Generate(", ");
744 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 775 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
745 retstr += ")"; 776 retstr += Generate(")");
746 777
747 return retstr; 778 return retstr;
748 } 779 }
@@ -751,51 +782,155 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
751 /// Generates the code for a ListConstant node. 782 /// Generates the code for a ListConstant node.
752 /// </summary> 783 /// </summary>
753 /// <param name="lc">The ListConstant node.</param> 784 /// <param name="lc">The ListConstant node.</param>
754 /// <returns>String containing C# code for SYMBOL s.</returns> 785 /// <returns>String containing C# code for ListConstant lc.</returns>
755 private string GenerateListConstant(ListConstant lc) 786 private string GenerateListConstant(ListConstant lc)
756 { 787 {
757 string retstr = String.Empty; 788 string retstr = String.Empty;
758 789
759 retstr += String.Format("new {0}(", lc.Type); 790 retstr += Generate(String.Format("new {0}(", lc.Type), lc);
760 791
761 foreach (SYMBOL kid in lc.kids) 792 foreach (SYMBOL kid in lc.kids)
762 retstr += GenerateNode(kid); 793 retstr += GenerateNode(kid);
763 794
764 retstr += ")"; 795 retstr += Generate(")");
796
797 return retstr;
798 }
799
800 /// <summary>
801 /// Prints a newline.
802 /// </summary>
803 /// <returns>A newline.</returns>
804 private string GenerateLine()
805 {
806 return GenerateLine("");
807 }
808
809 /// <summary>
810 /// Prints text, followed by a newline.
811 /// </summary>
812 /// <param name="s">String of text to print.</param>
813 /// <returns>String s followed by newline.</returns>
814 private string GenerateLine(string s)
815 {
816 return GenerateLine(s, null);
817 }
818
819 /// <summary>
820 /// Prints text, followed by a newline.
821 /// </summary>
822 /// <param name="s">String of text to print.</param>
823 /// <param name="sym">Symbol being generated to extract original line
824 /// number and column from.</param>
825 /// <returns>String s followed by newline.</returns>
826 private string GenerateLine(string s, SYMBOL sym)
827 {
828 string retstr = Generate(s, sym) + "\n";
829
830 m_CSharpLine++;
831 m_CSharpCol = 1;
765 832
766 return retstr; 833 return retstr;
767 } 834 }
768 835
769 /// <summary> 836 /// <summary>
837 /// Prints text.
838 /// </summary>
839 /// <param name="s">String of text to print.</param>
840 /// <returns>String s.</returns>
841 private string Generate(string s)
842 {
843 return Generate(s, null);
844 }
845
846 /// <summary>
847 /// Prints text.
848 /// </summary>
849 /// <param name="s">String of text to print.</param>
850 /// <param name="sym">Symbol being generated to extract original line
851 /// number and column from.</param>
852 /// <returns>String s.</returns>
853 private string Generate(string s, SYMBOL sym)
854 {
855 if (null != sym)
856 m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position));
857
858 m_CSharpCol += s.Length;
859
860 return s;
861 }
862
863 /// <summary>
770 /// Prints text correctly indented, followed by a newline. 864 /// Prints text correctly indented, followed by a newline.
771 /// </summary> 865 /// </summary>
772 /// <param name="s">String of text to print.</param> 866 /// <param name="s">String of text to print.</param>
773 /// <returns>String containing C# code for SYMBOL s.</returns> 867 /// <returns>Properly indented string s followed by newline.</returns>
774 private string WriteIndentedLine(string s) 868 private string GenerateIndentedLine(string s)
775 { 869 {
776 return WriteIndented(s) + "\n"; 870 return GenerateIndentedLine(s, null);
871 }
872
873 /// <summary>
874 /// Prints text correctly indented, followed by a newline.
875 /// </summary>
876 /// <param name="s">String of text to print.</param>
877 /// <param name="sym">Symbol being generated to extract original line
878 /// number and column from.</param>
879 /// <returns>Properly indented string s followed by newline.</returns>
880 private string GenerateIndentedLine(string s, SYMBOL sym)
881 {
882 string retstr = GenerateIndented(s, sym) + "\n";
883
884 m_CSharpLine++;
885 m_CSharpCol = 1;
886
887 return retstr;
777 } 888 }
778 889
779 /// <summary> 890 /// <summary>
780 /// Prints text correctly indented. 891 /// Prints text correctly indented.
781 /// </summary> 892 /// </summary>
782 /// <param name="s">String of text to print.</param> 893 /// <param name="s">String of text to print.</param>
783 /// <returns>String containing C# code for SYMBOL s.</returns> 894 /// <returns>Properly indented string s.</returns>
784 private string WriteIndented(string s) 895 //private string GenerateIndented(string s)
896 //{
897 // return GenerateIndented(s, null);
898 //}
899 // THIS FUNCTION IS COMMENTED OUT TO SUPPRESS WARNINGS
900
901 /// <summary>
902 /// Prints text correctly indented.
903 /// </summary>
904 /// <param name="s">String of text to print.</param>
905 /// <param name="sym">Symbol being generated to extract original line
906 /// number and column from.</param>
907 /// <returns>Properly indented string s.</returns>
908 private string GenerateIndented(string s, SYMBOL sym)
785 { 909 {
786 return Indent() + s; 910 string retstr = Indent() + s;
911
912 if (null != sym)
913 m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position));
914
915 m_CSharpCol += s.Length;
916
917 return retstr;
787 } 918 }
788 919
789 /// <summary> 920 /// <summary>
790 /// Prints correct indentation. 921 /// Prints correct indentation.
791 /// </summary> 922 /// </summary>
792 /// <returns>String containing C# code for SYMBOL s.</returns> 923 /// <returns>Indentation based on brace count.</returns>
793 private string Indent() 924 private string Indent()
794 { 925 {
795 string retstr = String.Empty; 926 string retstr = String.Empty;
796 927
797 for (int i = 0; i < m_braceCount; i++) 928 for (int i = 0; i < m_braceCount; i++)
798 retstr += " "; 929 for (int j = 0; j < m_indentWidth; j++)
930 {
931 retstr += " ";
932 m_CSharpCol++;
933 }
799 934
800 return retstr; 935 return retstr;
801 } 936 }
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
index ed6e783..73894d5 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
73 private string ScriptEnginesPath = "ScriptEngines"; 73 private string ScriptEnginesPath = "ScriptEngines";
74 74
75 private static LSL2CSConverter LSL_Converter = new LSL2CSConverter(); 75 private static LSL2CSConverter LSL_Converter = new LSL2CSConverter();
76 //private static CSCodeGenerator LSL_Converter; 76 //private static CSCodeGenerator LSL_Converter = new CSCodeGenerator();
77 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); 77 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
78 private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); 78 private static VBCodeProvider VBcodeProvider = new VBCodeProvider();
79 private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider(); 79 private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider();
@@ -276,8 +276,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
276 { 276 {
277 // Its LSL, convert it to C# 277 // Its LSL, convert it to C#
278 compileScript = LSL_Converter.Convert(Script); 278 compileScript = LSL_Converter.Convert(Script);
279 //LSL_Converter = new CSCodeGenerator(Script); 279 //compileScript = LSL_Converter.Convert(Script);
280 //compileScript = LSL_Converter.Generate();
281 l = enumCompileType.cs; 280 l = enumCompileType.cs;
282 } 281 }
283 282
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 7d7384e..3bdad4d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -35,56 +35,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
35 public class CSCodeGenerator : ICodeConverter 35 public class CSCodeGenerator : ICodeConverter
36 { 36 {
37 private SYMBOL m_astRoot = null; 37 private SYMBOL m_astRoot = null;
38 private int m_braceCount; // for indentation 38 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap;
39 private int m_indentWidth = 4; // for indentation
40 private int m_braceCount; // for indentation
41 private int m_CSharpLine; // the current line of generated C# code
42 private int m_CSharpCol; // the current column of generated C# code
39 43
40 /// <summary> 44 /// <summary>
41 /// Pass the new CodeGenerator a string containing the LSL source. 45 /// Creates an 'empty' CSCodeGenerator instance.
42 /// </summary> 46 /// </summary>
43 /// <param name="script">String containing LSL source.</param>
44 public CSCodeGenerator() 47 public CSCodeGenerator()
45 { 48 {
49 ResetCounters();
46 } 50 }
47 51
48 /// <summary> 52 /// <summary>
49 /// Pass the new CodeGenerator an abstract syntax tree. 53 /// Get the mapping between LSL and C# line/column number.
50 /// </summary> 54 /// </summary>
51 /// <param name="astRoot">The root node of the AST.</param> 55 /// <returns>Dictionary\<KeyValuePair\<int, int\>, KeyValuePair\<int, int\>\>.</returns>
52 public CSCodeGenerator(SYMBOL astRoot) 56 public Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> PositionMap
57 {
58 get { return m_positionMap; }
59 }
60
61 /// <summary>
62 /// Get the mapping between LSL and C# line/column number.
63 /// </summary>
64 /// <returns>SYMBOL pointing to root of the abstract syntax tree.</returns>
65 public SYMBOL ASTRoot
66 {
67 get { return m_astRoot; }
68 }
69
70 /// <summary>
71 /// Resets various counters and metadata.
72 /// </summary>
73 private void ResetCounters()
53 { 74 {
54 m_braceCount = 0; 75 m_braceCount = 0;
55 m_astRoot = astRoot; 76 m_CSharpLine = 0;
77 m_CSharpCol = 1;
78 m_positionMap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
79 m_astRoot = null;
56 } 80 }
57 81
58 /// <summary> 82 /// <summary>
59 /// Generate the code from the AST we have. 83 /// Generate the code from the AST we have.
60 /// </summary> 84 /// </summary>
85 /// <param name="script">The LSL source as a string.</param>
61 /// <returns>String containing the generated C# code.</returns> 86 /// <returns>String containing the generated C# code.</returns>
62 public string Convert(string script) 87 public string Convert(string script)
63 { 88 {
89 ResetCounters();
64 Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true)); 90 Parser p = new LSLSyntax(new yyLSLSyntax(), new ErrorHandler(true));
65 // Obviously this needs to be in a try/except block. 91 // Obviously this needs to be in a try/except block.
66 LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script)); 92 LSL2CSCodeTransformer codeTransformer = new LSL2CSCodeTransformer(p.Parse(script));
67 m_astRoot = codeTransformer.Transform(); 93 m_astRoot = codeTransformer.Transform();
94
68 string retstr = String.Empty; 95 string retstr = String.Empty;
69 96
70 // standard preamble 97 // standard preamble
71 //retstr = "using OpenSim.Region.ScriptEngine.Common;\n"; 98 //retstr = GenerateLine("using OpenSim.Region.ScriptEngine.Common;");
72 //retstr += "using System.Collections.Generic;\n\n"; 99 //retstr += GenerateLine("using System.Collections.Generic;");
73 //retstr += "namespace SecondLife\n"; 100 //retstr += GenerateLine("");
74 //retstr += "{\n"; 101 //retstr += GenerateLine("namespace SecondLife");
75 //retstr += " public class Script : OpenSim.Region.ScriptEngine.Common\n"; 102 //retstr += GenerateLine("{");
76 //retstr += " {\n"; 103 m_braceCount++;
104 //retstr += GenerateIndentedLine("public class Script : OpenSim.Region.ScriptEngine.Common");
105 //retstr += GenerateIndentedLine("{");
106 m_braceCount++;
107
108 // line number
109 m_CSharpLine += 3;
77 110
78 // here's the payload 111 // here's the payload
79 m_braceCount += 2; 112 retstr += GenerateLine();
80 retstr += "\n";
81 foreach (SYMBOL s in m_astRoot.kids) 113 foreach (SYMBOL s in m_astRoot.kids)
82 retstr += GenerateNode(s); 114 retstr += GenerateNode(s);
83 115
84 // close braces! 116 // close braces!
85 //retstr += " }\n"; 117 m_braceCount--;
86 //retstr += "}\n"; 118 //retstr += GenerateIndentedLine("}");
87 m_braceCount -= 2; 119 m_braceCount--;
120 //retstr += GenerateLine("}");
88 121
89 return retstr; 122 return retstr;
90 } 123 }
@@ -155,11 +188,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
155 else if (s is Constant) 188 else if (s is Constant)
156 retstr += GenerateConstant((Constant) s); 189 retstr += GenerateConstant((Constant) s);
157 else if (s is IdentDotExpression) 190 else if (s is IdentDotExpression)
158 retstr += ((IdentDotExpression) s).Name + "." + ((IdentDotExpression) s).Member; 191 retstr += Generate(((IdentDotExpression) s).Name + "." + ((IdentDotExpression) s).Member, s);
159 else if (s is IdentExpression) 192 else if (s is IdentExpression)
160 retstr += ((IdentExpression) s).Name; 193 retstr += Generate(((IdentExpression) s).Name, s);
161 else if (s is IDENT) 194 else if (s is IDENT)
162 retstr += ((TOKEN) s).yytext; 195 retstr += Generate(((TOKEN) s).yytext, s);
163 else 196 else
164 { 197 {
165 foreach (SYMBOL kid in s.kids) 198 foreach (SYMBOL kid in s.kids)
@@ -188,13 +221,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
188 else 221 else
189 remainingKids.Add(kid); 222 remainingKids.Add(kid);
190 223
191 retstr += WriteIndented(String.Format("{0} {1}(", gf.ReturnType, gf.Name)); 224 retstr += GenerateIndented(String.Format("{0} {1}(", gf.ReturnType, gf.Name), gf);
192 225
193 // print the state arguments, if any 226 // print the state arguments, if any
194 foreach (SYMBOL kid in argumentDeclarationListKids) 227 foreach (SYMBOL kid in argumentDeclarationListKids)
195 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid); 228 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
196 229
197 retstr += ")\n"; 230 retstr += GenerateLine(")");
198 231
199 foreach (SYMBOL kid in remainingKids) 232 foreach (SYMBOL kid in remainingKids)
200 retstr += GenerateNode(kid); 233 retstr += GenerateNode(kid);
@@ -215,7 +248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
215 { 248 {
216 retstr += Indent(); 249 retstr += Indent();
217 retstr += GenerateNode(s); 250 retstr += GenerateNode(s);
218 retstr += ";\n"; 251 retstr += GenerateLine(";");
219 } 252 }
220 253
221 return retstr; 254 return retstr;
@@ -233,8 +266,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
233 foreach (SYMBOL kid in s.kids) 266 foreach (SYMBOL kid in s.kids)
234 if (kid is StateEvent) 267 if (kid is StateEvent)
235 retstr += GenerateStateEvent((StateEvent) kid, s.Name); 268 retstr += GenerateStateEvent((StateEvent) kid, s.Name);
236 else
237 retstr += String.Format("ERROR: State '{0}' contains a '{1}\n", s.Name, kid.GetType());
238 269
239 return retstr; 270 return retstr;
240 } 271 }
@@ -260,13 +291,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
260 remainingKids.Add(kid); 291 remainingKids.Add(kid);
261 292
262 // "state" (function) declaration 293 // "state" (function) declaration
263 retstr += WriteIndented(String.Format("public void {0}_event_{1}(", parentStateName, se.Name)); 294 retstr += GenerateIndented(String.Format("public void {0}_event_{1}(", parentStateName, se.Name), se);
264 295
265 // print the state arguments, if any 296 // print the state arguments, if any
266 foreach (SYMBOL kid in argumentDeclarationListKids) 297 foreach (SYMBOL kid in argumentDeclarationListKids)
267 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid); 298 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
268 299
269 retstr += ")\n"; 300 retstr += GenerateLine(")");
270 301
271 foreach (SYMBOL kid in remainingKids) 302 foreach (SYMBOL kid in remainingKids)
272 retstr += GenerateNode(kid); 303 retstr += GenerateNode(kid);
@@ -278,7 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
278 /// Generates the code for an ArgumentDeclarationList node. 309 /// Generates the code for an ArgumentDeclarationList node.
279 /// </summary> 310 /// </summary>
280 /// <param name="adl">The ArgumentDeclarationList node.</param> 311 /// <param name="adl">The ArgumentDeclarationList node.</param>
281 /// <returns>String containing C# code for SYMBOL s.</returns> 312 /// <returns>String containing C# code for ArgumentDeclarationList adl.</returns>
282 private string GenerateArgumentDeclarationList(ArgumentDeclarationList adl) 313 private string GenerateArgumentDeclarationList(ArgumentDeclarationList adl)
283 { 314 {
284 string retstr = String.Empty; 315 string retstr = String.Empty;
@@ -287,9 +318,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
287 318
288 foreach (Declaration d in adl.kids) 319 foreach (Declaration d in adl.kids)
289 { 320 {
290 retstr += String.Format("{0} {1}", d.Datatype, d.Id); 321 retstr += Generate(String.Format("{0} {1}", d.Datatype, d.Id), d);
291 if (0 < comma--) 322 if (0 < comma--)
292 retstr += ", "; 323 retstr += Generate(", ");
293 } 324 }
294 325
295 return retstr; 326 return retstr;
@@ -299,7 +330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
299 /// Generates the code for an ArgumentList node. 330 /// Generates the code for an ArgumentList node.
300 /// </summary> 331 /// </summary>
301 /// <param name="al">The ArgumentList node.</param> 332 /// <param name="al">The ArgumentList node.</param>
302 /// <returns>String containing C# code for SYMBOL s.</returns> 333 /// <returns>String containing C# code for ArgumentList al.</returns>
303 private string GenerateArgumentList(ArgumentList al) 334 private string GenerateArgumentList(ArgumentList al)
304 { 335 {
305 string retstr = String.Empty; 336 string retstr = String.Empty;
@@ -310,7 +341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
310 { 341 {
311 retstr += GenerateNode(s); 342 retstr += GenerateNode(s);
312 if (0 < comma--) 343 if (0 < comma--)
313 retstr += ", "; 344 retstr += Generate(", ");
314 } 345 }
315 346
316 return retstr; 347 return retstr;
@@ -320,13 +351,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
320 /// Generates the code for a CompoundStatement node. 351 /// Generates the code for a CompoundStatement node.
321 /// </summary> 352 /// </summary>
322 /// <param name="cs">The CompoundStatement node.</param> 353 /// <param name="cs">The CompoundStatement node.</param>
323 /// <returns>String containing C# code for SYMBOL s.</returns> 354 /// <returns>String containing C# code for CompoundStatement cs.</returns>
324 private string GenerateCompoundStatement(CompoundStatement cs) 355 private string GenerateCompoundStatement(CompoundStatement cs)
325 { 356 {
326 string retstr = String.Empty; 357 string retstr = String.Empty;
327 358
328 // opening brace 359 // opening brace
329 retstr += WriteIndentedLine("{"); 360 retstr += GenerateIndentedLine("{");
330 m_braceCount++; 361 m_braceCount++;
331 362
332 foreach (SYMBOL kid in cs.kids) 363 foreach (SYMBOL kid in cs.kids)
@@ -334,7 +365,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
334 365
335 // closing brace 366 // closing brace
336 m_braceCount--; 367 m_braceCount--;
337 retstr += WriteIndentedLine("}"); 368 retstr += GenerateIndentedLine("}");
338 369
339 return retstr; 370 return retstr;
340 } 371 }
@@ -343,17 +374,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
343 /// Generates the code for a Declaration node. 374 /// Generates the code for a Declaration node.
344 /// </summary> 375 /// </summary>
345 /// <param name="d">The Declaration node.</param> 376 /// <param name="d">The Declaration node.</param>
346 /// <returns>String containing C# code for SYMBOL s.</returns> 377 /// <returns>String containing C# code for Declaration d.</returns>
347 private string GenerateDeclaration(Declaration d) 378 private string GenerateDeclaration(Declaration d)
348 { 379 {
349 return String.Format("{0} {1}", d.Datatype, d.Id); 380 return Generate(String.Format("{0} {1}", d.Datatype, d.Id), d);
350 } 381 }
351 382
352 /// <summary> 383 /// <summary>
353 /// Generates the code for a Statement node. 384 /// Generates the code for a Statement node.
354 /// </summary> 385 /// </summary>
355 /// <param name="s">The Statement node.</param> 386 /// <param name="s">The Statement node.</param>
356 /// <returns>String containing C# code for SYMBOL s.</returns> 387 /// <returns>String containing C# code for Statement s.</returns>
357 private string GenerateStatement(Statement s) 388 private string GenerateStatement(Statement s)
358 { 389 {
359 string retstr = String.Empty; 390 string retstr = String.Empty;
@@ -367,7 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
367 retstr += GenerateNode(kid); 398 retstr += GenerateNode(kid);
368 399
369 if (printSemicolon) 400 if (printSemicolon)
370 retstr += ";\n"; 401 retstr += GenerateLine(";");
371 402
372 return retstr; 403 return retstr;
373 } 404 }
@@ -376,13 +407,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
376 /// Generates the code for an Assignment node. 407 /// Generates the code for an Assignment node.
377 /// </summary> 408 /// </summary>
378 /// <param name="a">The Assignment node.</param> 409 /// <param name="a">The Assignment node.</param>
379 /// <returns>String containing C# code for SYMBOL s.</returns> 410 /// <returns>String containing C# code for Assignment a.</returns>
380 private string GenerateAssignment(Assignment a) 411 private string GenerateAssignment(Assignment a)
381 { 412 {
382 string retstr = String.Empty; 413 string retstr = String.Empty;
383 414
384 retstr += GenerateNode((SYMBOL) a.kids.Pop()); 415 retstr += GenerateNode((SYMBOL) a.kids.Pop());
385 retstr +=String.Format(" {0} ", a.AssignmentType); 416 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
386 foreach (SYMBOL kid in a.kids) 417 foreach (SYMBOL kid in a.kids)
387 retstr += GenerateNode(kid); 418 retstr += GenerateNode(kid);
388 419
@@ -393,12 +424,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
393 /// Generates the code for a ReturnStatement node. 424 /// Generates the code for a ReturnStatement node.
394 /// </summary> 425 /// </summary>
395 /// <param name="rs">The ReturnStatement node.</param> 426 /// <param name="rs">The ReturnStatement node.</param>
396 /// <returns>String containing C# code for SYMBOL s.</returns> 427 /// <returns>String containing C# code for ReturnStatement rs.</returns>
397 private string GenerateReturnStatement(ReturnStatement rs) 428 private string GenerateReturnStatement(ReturnStatement rs)
398 { 429 {
399 string retstr = String.Empty; 430 string retstr = String.Empty;
400 431
401 retstr += "return "; 432 retstr += Generate("return ", rs);
402 433
403 foreach (SYMBOL kid in rs.kids) 434 foreach (SYMBOL kid in rs.kids)
404 retstr += GenerateNode(kid); 435 retstr += GenerateNode(kid);
@@ -410,34 +441,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
410 /// Generates the code for a JumpLabel node. 441 /// Generates the code for a JumpLabel node.
411 /// </summary> 442 /// </summary>
412 /// <param name="jl">The JumpLabel node.</param> 443 /// <param name="jl">The JumpLabel node.</param>
413 /// <returns>String containing C# code for SYMBOL s.</returns> 444 /// <returns>String containing C# code for JumpLabel jl.</returns>
414 private string GenerateJumpLabel(JumpLabel jl) 445 private string GenerateJumpLabel(JumpLabel jl)
415 { 446 {
416 return String.Format("{0}:\n", jl.LabelName); 447 return Generate(String.Format("{0}:\n", jl.LabelName), jl);
417 } 448 }
418 449
419 /// <summary> 450 /// <summary>
420 /// Generates the code for a JumpStatement node. 451 /// Generates the code for a JumpStatement node.
421 /// </summary> 452 /// </summary>
422 /// <param name="js">The JumpStatement node.</param> 453 /// <param name="js">The JumpStatement node.</param>
423 /// <returns>String containing C# code for SYMBOL s.</returns> 454 /// <returns>String containing C# code for JumpStatement js.</returns>
424 private string GenerateJumpStatement(JumpStatement js) 455 private string GenerateJumpStatement(JumpStatement js)
425 { 456 {
426 return String.Format("goto {0}", js.TargetName); 457 return Generate(String.Format("goto {0}", js.TargetName), js);
427 } 458 }
428 459
429 /// <summary> 460 /// <summary>
430 /// Generates the code for a IfStatement node. 461 /// Generates the code for an IfStatement node.
431 /// </summary> 462 /// </summary>
432 /// <param name="ifs">The IfStatement node.</param> 463 /// <param name="ifs">The IfStatement node.</param>
433 /// <returns>String containing C# code for SYMBOL s.</returns> 464 /// <returns>String containing C# code for IfStatement ifs.</returns>
434 private string GenerateIfStatement(IfStatement ifs) 465 private string GenerateIfStatement(IfStatement ifs)
435 { 466 {
436 string retstr = String.Empty; 467 string retstr = String.Empty;
437 468
438 retstr += WriteIndented("if ("); 469 retstr += GenerateIndented("if (", ifs);
439 retstr += GenerateNode((SYMBOL) ifs.kids.Pop()); 470 retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
440 retstr += ")\n"; 471 retstr += GenerateLine(")");
441 472
442 // CompoundStatement handles indentation itself but we need to do it 473 // CompoundStatement handles indentation itself but we need to do it
443 // otherwise. 474 // otherwise.
@@ -448,7 +479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
448 479
449 if (0 < ifs.kids.Count) // do it again for an else 480 if (0 < ifs.kids.Count) // do it again for an else
450 { 481 {
451 retstr += WriteIndentedLine("else"); 482 retstr += GenerateIndentedLine("else", ifs);
452 483
453 indentHere = ifs.kids.Top is Statement; 484 indentHere = ifs.kids.Top is Statement;
454 if (indentHere) m_braceCount++; 485 if (indentHere) m_braceCount++;
@@ -463,24 +494,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
463 /// Generates the code for a StateChange node. 494 /// Generates the code for a StateChange node.
464 /// </summary> 495 /// </summary>
465 /// <param name="sc">The StateChange node.</param> 496 /// <param name="sc">The StateChange node.</param>
466 /// <returns>String containing C# code for SYMBOL s.</returns> 497 /// <returns>String containing C# code for StateChange sc.</returns>
467 private string GenerateStateChange(StateChange sc) 498 private string GenerateStateChange(StateChange sc)
468 { 499 {
469 return String.Format("state(\"{0}\")", sc.NewState); 500 return Generate(String.Format("state(\"{0}\")", sc.NewState), sc);
470 } 501 }
471 502
472 /// <summary> 503 /// <summary>
473 /// Generates the code for a WhileStatement node. 504 /// Generates the code for a WhileStatement node.
474 /// </summary> 505 /// </summary>
475 /// <param name="ws">The WhileStatement node.</param> 506 /// <param name="ws">The WhileStatement node.</param>
476 /// <returns>String containing C# code for SYMBOL s.</returns> 507 /// <returns>String containing C# code for WhileStatement ws.</returns>
477 private string GenerateWhileStatement(WhileStatement ws) 508 private string GenerateWhileStatement(WhileStatement ws)
478 { 509 {
479 string retstr = String.Empty; 510 string retstr = String.Empty;
480 511
481 retstr += WriteIndented("while ("); 512 retstr += GenerateIndented("while (", ws);
482 retstr += GenerateNode((SYMBOL) ws.kids.Pop()); 513 retstr += GenerateNode((SYMBOL) ws.kids.Pop());
483 retstr += ")\n"; 514 retstr += GenerateLine(")");
484 515
485 // CompoundStatement handles indentation itself but we need to do it 516 // CompoundStatement handles indentation itself but we need to do it
486 // otherwise. 517 // otherwise.
@@ -496,12 +527,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
496 /// Generates the code for a DoWhileStatement node. 527 /// Generates the code for a DoWhileStatement node.
497 /// </summary> 528 /// </summary>
498 /// <param name="dws">The DoWhileStatement node.</param> 529 /// <param name="dws">The DoWhileStatement node.</param>
499 /// <returns>String containing C# code for SYMBOL s.</returns> 530 /// <returns>String containing C# code for DoWhileStatement dws.</returns>
500 private string GenerateDoWhileStatement(DoWhileStatement dws) 531 private string GenerateDoWhileStatement(DoWhileStatement dws)
501 { 532 {
502 string retstr = String.Empty; 533 string retstr = String.Empty;
503 534
504 retstr += WriteIndentedLine("do"); 535 retstr += GenerateIndentedLine("do", dws);
505 536
506 // CompoundStatement handles indentation itself but we need to do it 537 // CompoundStatement handles indentation itself but we need to do it
507 // otherwise. 538 // otherwise.
@@ -510,9 +541,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
510 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 541 retstr += GenerateNode((SYMBOL) dws.kids.Pop());
511 if (indentHere) m_braceCount--; 542 if (indentHere) m_braceCount--;
512 543
513 retstr += WriteIndented("while ("); 544 retstr += GenerateIndented("while (", dws);
514 retstr += GenerateNode((SYMBOL) dws.kids.Pop()); 545 retstr += GenerateNode((SYMBOL) dws.kids.Pop());
515 retstr += ");\n"; 546 retstr += GenerateLine(");");
516 547
517 return retstr; 548 return retstr;
518 } 549 }
@@ -521,25 +552,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
521 /// Generates the code for a ForLoop node. 552 /// Generates the code for a ForLoop node.
522 /// </summary> 553 /// </summary>
523 /// <param name="fl">The ForLoop node.</param> 554 /// <param name="fl">The ForLoop node.</param>
524 /// <returns>String containing C# code for SYMBOL s.</returns> 555 /// <returns>String containing C# code for ForLoop fl.</returns>
525 private string GenerateForLoop(ForLoop fl) 556 private string GenerateForLoop(ForLoop fl)
526 { 557 {
527 string retstr = String.Empty; 558 string retstr = String.Empty;
528 559
529 retstr += WriteIndented("for ("); 560 retstr += GenerateIndented("for (", fl);
530 561
531 // for ( x = 0 ; x < 10 ; x++ ) 562 // for ( x = 0 ; x < 10 ; x++ )
532 // ^^^^^^^ 563 // ^^^^^^^
533 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop()); 564 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
534 retstr += "; "; 565 retstr += Generate("; ");
535 // for ( x = 0 ; x < 10 ; x++ ) 566 // for ( x = 0 ; x < 10 ; x++ )
536 // ^^^^^^^^ 567 // ^^^^^^^^
537 retstr += GenerateNode((SYMBOL) fl.kids.Pop()); 568 retstr += GenerateNode((SYMBOL) fl.kids.Pop());
538 retstr += "; "; 569 retstr += Generate("; ");
539 // for ( x = 0 ; x < 10 ; x++ ) 570 // for ( x = 0 ; x < 10 ; x++ )
540 // ^^^^^ 571 // ^^^^^
541 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop()); 572 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
542 retstr += ")\n"; 573 retstr += GenerateLine(")");
543 574
544 // CompoundStatement handles indentation itself but we need to do it 575 // CompoundStatement handles indentation itself but we need to do it
545 // otherwise. 576 // otherwise.
@@ -555,7 +586,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
555 /// Generates the code for a ForLoopStatement node. 586 /// Generates the code for a ForLoopStatement node.
556 /// </summary> 587 /// </summary>
557 /// <param name="fls">The ForLoopStatement node.</param> 588 /// <param name="fls">The ForLoopStatement node.</param>
558 /// <returns>String containing C# code for SYMBOL s.</returns> 589 /// <returns>String containing C# code for ForLoopStatement fls.</returns>
559 private string GenerateForLoopStatement(ForLoopStatement fls) 590 private string GenerateForLoopStatement(ForLoopStatement fls)
560 { 591 {
561 string retstr = String.Empty; 592 string retstr = String.Empty;
@@ -566,7 +597,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
566 { 597 {
567 retstr += GenerateNode(s); 598 retstr += GenerateNode(s);
568 if (0 < comma--) 599 if (0 < comma--)
569 retstr += ", "; 600 retstr += Generate(", ");
570 } 601 }
571 602
572 return retstr; 603 return retstr;
@@ -576,13 +607,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
576 /// Generates the code for a BinaryExpression node. 607 /// Generates the code for a BinaryExpression node.
577 /// </summary> 608 /// </summary>
578 /// <param name="be">The BinaryExpression node.</param> 609 /// <param name="be">The BinaryExpression node.</param>
579 /// <returns>String containing C# code for SYMBOL s.</returns> 610 /// <returns>String containing C# code for BinaryExpression be.</returns>
580 private string GenerateBinaryExpression(BinaryExpression be) 611 private string GenerateBinaryExpression(BinaryExpression be)
581 { 612 {
582 string retstr = String.Empty; 613 string retstr = String.Empty;
583 614
584 retstr += GenerateNode((SYMBOL) be.kids.Pop()); 615 retstr += GenerateNode((SYMBOL) be.kids.Pop());
585 retstr += String.Format(" {0} ", be.ExpressionSymbol); 616 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be);
586 foreach (SYMBOL kid in be.kids) 617 foreach (SYMBOL kid in be.kids)
587 retstr += GenerateNode(kid); 618 retstr += GenerateNode(kid);
588 619
@@ -593,12 +624,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
593 /// Generates the code for a UnaryExpression node. 624 /// Generates the code for a UnaryExpression node.
594 /// </summary> 625 /// </summary>
595 /// <param name="ue">The UnaryExpression node.</param> 626 /// <param name="ue">The UnaryExpression node.</param>
596 /// <returns>String containing C# code for SYMBOL s.</returns> 627 /// <returns>String containing C# code for UnaryExpression ue.</returns>
597 private string GenerateUnaryExpression(UnaryExpression ue) 628 private string GenerateUnaryExpression(UnaryExpression ue)
598 { 629 {
599 string retstr = String.Empty; 630 string retstr = String.Empty;
600 631
601 retstr += ue.UnarySymbol; 632 retstr += Generate(ue.UnarySymbol, ue);
602 retstr += GenerateNode((SYMBOL) ue.kids.Pop()); 633 retstr += GenerateNode((SYMBOL) ue.kids.Pop());
603 634
604 return retstr; 635 return retstr;
@@ -608,15 +639,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
608 /// Generates the code for a ParenthesisExpression node. 639 /// Generates the code for a ParenthesisExpression node.
609 /// </summary> 640 /// </summary>
610 /// <param name="pe">The ParenthesisExpression node.</param> 641 /// <param name="pe">The ParenthesisExpression node.</param>
611 /// <returns>String containing C# code for SYMBOL s.</returns> 642 /// <returns>String containing C# code for ParenthesisExpression pe.</returns>
612 private string GenerateParenthesisExpression(ParenthesisExpression pe) 643 private string GenerateParenthesisExpression(ParenthesisExpression pe)
613 { 644 {
614 string retstr = String.Empty; 645 string retstr = String.Empty;
615 646
616 retstr += "("; 647 retstr += Generate("(");
617 foreach (SYMBOL kid in pe.kids) 648 foreach (SYMBOL kid in pe.kids)
618 retstr += GenerateNode(kid); 649 retstr += GenerateNode(kid);
619 retstr += ")"; 650 retstr += Generate(")");
620 651
621 return retstr; 652 return retstr;
622 } 653 }
@@ -625,7 +656,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
625 /// Generates the code for a IncrementDecrementExpression node. 656 /// Generates the code for a IncrementDecrementExpression node.
626 /// </summary> 657 /// </summary>
627 /// <param name="ide">The IncrementDecrementExpression node.</param> 658 /// <param name="ide">The IncrementDecrementExpression node.</param>
628 /// <returns>String containing C# code for SYMBOL s.</returns> 659 /// <returns>String containing C# code for IncrementDecrementExpression ide.</returns>
629 private string GenerateIncrementDecrementExpression(IncrementDecrementExpression ide) 660 private string GenerateIncrementDecrementExpression(IncrementDecrementExpression ide)
630 { 661 {
631 string retstr = String.Empty; 662 string retstr = String.Empty;
@@ -633,10 +664,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
633 if (0 < ide.kids.Count) 664 if (0 < ide.kids.Count)
634 { 665 {
635 IdentDotExpression dot = (IdentDotExpression) ide.kids.Top; 666 IdentDotExpression dot = (IdentDotExpression) ide.kids.Top;
636 retstr += String.Format("{0}", ide.PostOperation ? dot.Name + "." + dot.Member + ide.Operation : ide.Operation + dot.Name + "." + dot.Member); 667 retstr += Generate(String.Format("{0}", ide.PostOperation ? dot.Name + "." + dot.Member + ide.Operation : ide.Operation + dot.Name + "." + dot.Member), ide);
637 } 668 }
638 else 669 else
639 retstr += String.Format("{0}", ide.PostOperation ? ide.Name + ide.Operation : ide.Operation + ide.Name); 670 retstr += Generate(String.Format("{0}", ide.PostOperation ? ide.Name + ide.Operation : ide.Operation + ide.Name), ide);
640 671
641 return retstr; 672 return retstr;
642 } 673 }
@@ -645,15 +676,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
645 /// Generates the code for a TypecastExpression node. 676 /// Generates the code for a TypecastExpression node.
646 /// </summary> 677 /// </summary>
647 /// <param name="te">The TypecastExpression node.</param> 678 /// <param name="te">The TypecastExpression node.</param>
648 /// <returns>String containing C# code for SYMBOL s.</returns> 679 /// <returns>String containing C# code for TypecastExpression te.</returns>
649 private string GenerateTypecastExpression(TypecastExpression te) 680 private string GenerateTypecastExpression(TypecastExpression te)
650 { 681 {
651 string retstr = String.Empty; 682 string retstr = String.Empty;
652 683
653 // we wrap all typecasted statements in parentheses 684 // we wrap all typecasted statements in parentheses
654 retstr += String.Format("({0}) (", te.TypecastType); 685 retstr += Generate(String.Format("({0}) (", te.TypecastType), te);
655 retstr += GenerateNode((SYMBOL) te.kids.Pop()); 686 retstr += GenerateNode((SYMBOL) te.kids.Pop());
656 retstr += ")"; 687 retstr += Generate(")");
657 688
658 return retstr; 689 return retstr;
659 } 690 }
@@ -662,17 +693,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
662 /// Generates the code for a FunctionCall node. 693 /// Generates the code for a FunctionCall node.
663 /// </summary> 694 /// </summary>
664 /// <param name="fc">The FunctionCall node.</param> 695 /// <param name="fc">The FunctionCall node.</param>
665 /// <returns>String containing C# code for SYMBOL s.</returns> 696 /// <returns>String containing C# code for FunctionCall fc.</returns>
666 private string GenerateFunctionCall(FunctionCall fc) 697 private string GenerateFunctionCall(FunctionCall fc)
667 { 698 {
668 string retstr = String.Empty; 699 string retstr = String.Empty;
669 700
670 retstr += String.Format("{0}(", fc.Id); 701 retstr += Generate(String.Format("{0}(", fc.Id), fc);
671 702
672 foreach (SYMBOL kid in fc.kids) 703 foreach (SYMBOL kid in fc.kids)
673 retstr += GenerateNode(kid); 704 retstr += GenerateNode(kid);
674 705
675 retstr += ")"; 706 retstr += Generate(")");
676 707
677 return retstr; 708 return retstr;
678 } 709 }
@@ -681,7 +712,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
681 /// Generates the code for a Constant node. 712 /// Generates the code for a Constant node.
682 /// </summary> 713 /// </summary>
683 /// <param name="c">The Constant node.</param> 714 /// <param name="c">The Constant node.</param>
684 /// <returns>String containing C# code for SYMBOL s.</returns> 715 /// <returns>String containing C# code for Constant c.</returns>
685 private string GenerateConstant(Constant c) 716 private string GenerateConstant(Constant c)
686 { 717 {
687 string retstr = String.Empty; 718 string retstr = String.Empty;
@@ -697,10 +728,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
697 728
698 // need to quote strings 729 // need to quote strings
699 if ("LSL_Types.LSLString" == c.Type) 730 if ("LSL_Types.LSLString" == c.Type)
700 retstr += "\""; 731 retstr += Generate("\"");
701 retstr += c.Value; 732 retstr += Generate(c.Value, c);
702 if ("LSL_Types.LSLString" == c.Type) 733 if ("LSL_Types.LSLString" == c.Type)
703 retstr += "\""; 734 retstr += Generate("\"");
704 735
705 return retstr; 736 return retstr;
706 } 737 }
@@ -709,18 +740,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
709 /// Generates the code for a VectorConstant node. 740 /// Generates the code for a VectorConstant node.
710 /// </summary> 741 /// </summary>
711 /// <param name="vc">The VectorConstant node.</param> 742 /// <param name="vc">The VectorConstant node.</param>
712 /// <returns>String containing C# code for SYMBOL s.</returns> 743 /// <returns>String containing C# code for VectorConstant vc.</returns>
713 private string GenerateVectorConstant(VectorConstant vc) 744 private string GenerateVectorConstant(VectorConstant vc)
714 { 745 {
715 string retstr = String.Empty; 746 string retstr = String.Empty;
716 747
717 retstr += String.Format("new {0}(", vc.Type); 748 retstr += Generate(String.Format("new {0}(", vc.Type), vc);
718 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 749 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
719 retstr += ", "; 750 retstr += Generate(", ");
720 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 751 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
721 retstr += ", "; 752 retstr += Generate(", ");
722 retstr += GenerateNode((SYMBOL) vc.kids.Pop()); 753 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
723 retstr += ")"; 754 retstr += Generate(")");
724 755
725 return retstr; 756 return retstr;
726 } 757 }
@@ -729,20 +760,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
729 /// Generates the code for a RotationConstant node. 760 /// Generates the code for a RotationConstant node.
730 /// </summary> 761 /// </summary>
731 /// <param name="rc">The RotationConstant node.</param> 762 /// <param name="rc">The RotationConstant node.</param>
732 /// <returns>String containing C# code for SYMBOL s.</returns> 763 /// <returns>String containing C# code for RotationConstant rc.</returns>
733 private string GenerateRotationConstant(RotationConstant rc) 764 private string GenerateRotationConstant(RotationConstant rc)
734 { 765 {
735 string retstr = String.Empty; 766 string retstr = String.Empty;
736 767
737 retstr += String.Format("new {0}(", rc.Type); 768 retstr += Generate(String.Format("new {0}(", rc.Type), rc);
738 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 769 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
739 retstr += ", "; 770 retstr += Generate(", ");
740 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 771 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
741 retstr += ", "; 772 retstr += Generate(", ");
742 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 773 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
743 retstr += ", "; 774 retstr += Generate(", ");
744 retstr += GenerateNode((SYMBOL) rc.kids.Pop()); 775 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
745 retstr += ")"; 776 retstr += Generate(")");
746 777
747 return retstr; 778 return retstr;
748 } 779 }
@@ -751,51 +782,155 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
751 /// Generates the code for a ListConstant node. 782 /// Generates the code for a ListConstant node.
752 /// </summary> 783 /// </summary>
753 /// <param name="lc">The ListConstant node.</param> 784 /// <param name="lc">The ListConstant node.</param>
754 /// <returns>String containing C# code for SYMBOL s.</returns> 785 /// <returns>String containing C# code for ListConstant lc.</returns>
755 private string GenerateListConstant(ListConstant lc) 786 private string GenerateListConstant(ListConstant lc)
756 { 787 {
757 string retstr = String.Empty; 788 string retstr = String.Empty;
758 789
759 retstr += String.Format("new {0}(", lc.Type); 790 retstr += Generate(String.Format("new {0}(", lc.Type), lc);
760 791
761 foreach (SYMBOL kid in lc.kids) 792 foreach (SYMBOL kid in lc.kids)
762 retstr += GenerateNode(kid); 793 retstr += GenerateNode(kid);
763 794
764 retstr += ")"; 795 retstr += Generate(")");
796
797 return retstr;
798 }
799
800 /// <summary>
801 /// Prints a newline.
802 /// </summary>
803 /// <returns>A newline.</returns>
804 private string GenerateLine()
805 {
806 return GenerateLine("");
807 }
808
809 /// <summary>
810 /// Prints text, followed by a newline.
811 /// </summary>
812 /// <param name="s">String of text to print.</param>
813 /// <returns>String s followed by newline.</returns>
814 private string GenerateLine(string s)
815 {
816 return GenerateLine(s, null);
817 }
818
819 /// <summary>
820 /// Prints text, followed by a newline.
821 /// </summary>
822 /// <param name="s">String of text to print.</param>
823 /// <param name="sym">Symbol being generated to extract original line
824 /// number and column from.</param>
825 /// <returns>String s followed by newline.</returns>
826 private string GenerateLine(string s, SYMBOL sym)
827 {
828 string retstr = Generate(s, sym) + "\n";
829
830 m_CSharpLine++;
831 m_CSharpCol = 1;
765 832
766 return retstr; 833 return retstr;
767 } 834 }
768 835
769 /// <summary> 836 /// <summary>
837 /// Prints text.
838 /// </summary>
839 /// <param name="s">String of text to print.</param>
840 /// <returns>String s.</returns>
841 private string Generate(string s)
842 {
843 return Generate(s, null);
844 }
845
846 /// <summary>
847 /// Prints text.
848 /// </summary>
849 /// <param name="s">String of text to print.</param>
850 /// <param name="sym">Symbol being generated to extract original line
851 /// number and column from.</param>
852 /// <returns>String s.</returns>
853 private string Generate(string s, SYMBOL sym)
854 {
855 if (null != sym)
856 m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position));
857
858 m_CSharpCol += s.Length;
859
860 return s;
861 }
862
863 /// <summary>
770 /// Prints text correctly indented, followed by a newline. 864 /// Prints text correctly indented, followed by a newline.
771 /// </summary> 865 /// </summary>
772 /// <param name="s">String of text to print.</param> 866 /// <param name="s">String of text to print.</param>
773 /// <returns>String containing C# code for SYMBOL s.</returns> 867 /// <returns>Properly indented string s followed by newline.</returns>
774 private string WriteIndentedLine(string s) 868 private string GenerateIndentedLine(string s)
869 {
870 return GenerateIndentedLine(s, null);
871 }
872
873 /// <summary>
874 /// Prints text correctly indented, followed by a newline.
875 /// </summary>
876 /// <param name="s">String of text to print.</param>
877 /// <param name="sym">Symbol being generated to extract original line
878 /// number and column from.</param>
879 /// <returns>Properly indented string s followed by newline.</returns>
880 private string GenerateIndentedLine(string s, SYMBOL sym)
775 { 881 {
776 return WriteIndented(s) + "\n"; 882 string retstr = GenerateIndented(s, sym) + "\n";
883
884 m_CSharpLine++;
885 m_CSharpCol = 1;
886
887 return retstr;
777 } 888 }
778 889
779 /// <summary> 890 /// <summary>
780 /// Prints text correctly indented. 891 /// Prints text correctly indented.
781 /// </summary> 892 /// </summary>
782 /// <param name="s">String of text to print.</param> 893 /// <param name="s">String of text to print.</param>
783 /// <returns>String containing C# code for SYMBOL s.</returns> 894 /// <returns>Properly indented string s.</returns>
784 private string WriteIndented(string s) 895 //private string GenerateIndented(string s)
896 //{
897 // return GenerateIndented(s, null);
898 //}
899 // THIS FUNCTION IS COMMENTED OUT TO SUPPRESS WARNINGS
900
901 /// <summary>
902 /// Prints text correctly indented.
903 /// </summary>
904 /// <param name="s">String of text to print.</param>
905 /// <param name="sym">Symbol being generated to extract original line
906 /// number and column from.</param>
907 /// <returns>Properly indented string s.</returns>
908 private string GenerateIndented(string s, SYMBOL sym)
785 { 909 {
786 return Indent() + s; 910 string retstr = Indent() + s;
911
912 if (null != sym)
913 m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position));
914
915 m_CSharpCol += s.Length;
916
917 return retstr;
787 } 918 }
788 919
789 /// <summary> 920 /// <summary>
790 /// Prints correct indentation. 921 /// Prints correct indentation.
791 /// </summary> 922 /// </summary>
792 /// <returns>String containing C# code for SYMBOL s.</returns> 923 /// <returns>Indentation based on brace count.</returns>
793 private string Indent() 924 private string Indent()
794 { 925 {
795 string retstr = String.Empty; 926 string retstr = String.Empty;
796 927
797 for (int i = 0; i < m_braceCount; i++) 928 for (int i = 0; i < m_braceCount; i++)
798 retstr += " "; 929 for (int j = 0; j < m_indentWidth; j++)
930 {
931 retstr += " ";
932 m_CSharpCol++;
933 }
799 934
800 return retstr; 935 return retstr;
801 } 936 }
diff --git a/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSLCompilerTest.cs b/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs
index 70472cb..0b07b30 100644
--- a/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/LSLCompilerTest.cs
+++ b/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGeneratorTest.cs
@@ -38,7 +38,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
38 /// The generated C# code is compared against the expected C# code. 38 /// The generated C# code is compared against the expected C# code.
39 /// </summary> 39 /// </summary>
40 [TestFixture] 40 [TestFixture]
41 public class LSLCompilerTest 41 public class CSCodeGeneratorTest
42 { 42 {
43 [Test] 43 [Test]
44 public void TestDefaultState() 44 public void TestDefaultState()
@@ -685,7 +685,7 @@ default
685 integer x = 1; 685 integer x = 1;
686 686
687 if(x) llSay(0, ""Hello""); 687 if(x) llSay(0, ""Hello"");
688 if(1) 688 if(1)
689 { 689 {
690 llSay(0, ""Hi""); 690 llSay(0, ""Hi"");
691 integer r = 3; 691 integer r = 3;
@@ -791,7 +791,7 @@ default
791 integer y = 0; 791 integer y = 0;
792 792
793 if(x && y) llSay(0, ""Hello""); 793 if(x && y) llSay(0, ""Hello"");
794 if(x || y) 794 if(x || y)
795 { 795 {
796 llSay(0, ""Hi""); 796 llSay(0, ""Hi"");
797 integer r = 3; 797 integer r = 3;
diff --git a/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CompilerTest.cs b/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CompilerTest.cs
new file mode 100644
index 0000000..7a11d33
--- /dev/null
+++ b/OpenSim/Tests/OpenSim/Region/ScriptEngine/Shared/CodeTools/CompilerTest.cs
@@ -0,0 +1,120 @@
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.IO;
29using System.CodeDom.Compiler;
30using System.Collections.Generic;
31using Microsoft.CSharp;
32using NUnit.Framework;
33using OpenSim.Region.ScriptEngine.Shared.CodeTools;
34
35namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
36{
37 /// <summary>
38 /// Tests the LSL compiler. Among other things, test that error messages
39 /// generated by the C# compiler can be mapped to prper lines/columns in
40 /// the LSL source.
41 /// </summary>
42 [TestFixture]
43 public class CompilerTest
44 {
45 private string m_testDir;
46 private CSharpCodeProvider m_CSCodeProvider;
47 private CompilerParameters m_compilerParameters;
48 private CompilerResults m_compilerResults;
49
50 /// <summary>
51 /// Creates a temporary directory where build artifacts are stored.
52 /// </summary>
53 [TestFixtureSetUp]
54 public void Init()
55 {
56 m_testDir = Path.Combine(Path.GetTempPath(), "opensim_compilerTest_" + Path.GetRandomFileName());
57
58 if (!Directory.Exists(m_testDir))
59 {
60 // Create the temporary directory for housing build artifacts.
61 Directory.CreateDirectory(m_testDir);
62 }
63
64 // Create a CSCodeProvider and CompilerParameters.
65 m_CSCodeProvider = new CSharpCodeProvider();
66 m_compilerParameters = new CompilerParameters();
67
68 string rootPath = Path.Combine(Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory), "bin");
69 m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll"));
70 m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
71 m_compilerParameters.GenerateExecutable = false;
72 }
73
74 /// <summary>
75 /// Removes the temporary build directory and any build artifacts
76 /// inside it.
77 /// </summary>
78 [TestFixtureTearDown]
79 public void CleanUp()
80 {
81 if (Directory.Exists(m_testDir))
82 {
83 // Blow away the temporary directory with artifacts.
84 Directory.Delete(m_testDir, true);
85 }
86 }
87
88 [Test]
89 /// <summary>
90 /// Test the C# compiler error message can be mapped to the correct
91 /// line/column in the LSL source when an undeclared variable is used.
92 /// </summary>
93 public void TestUseUndeclaredVariable()
94 {
95 m_compilerParameters.OutputAssembly = Path.Combine(m_testDir, Path.GetRandomFileName() + ".dll");
96
97 string input = @"default
98{
99 state_entry()
100 {
101 integer y = x + 3;
102 }
103}";
104
105 CSCodeGenerator cg = new CSCodeGenerator();
106 string output = "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\n" +
107 "namespace SecondLife { " +
108 "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass {\n" +
109 "public Script() { } " +
110 cg.Convert(input) +
111 "} }\n";
112 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap = cg.PositionMap;
113
114 m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output);
115
116 Assert.AreEqual(new KeyValuePair<int, int>(5, 21),
117 positionMap[new KeyValuePair<int, int>(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]);
118 }
119 }
120}