aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/CodeTools
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/CodeTools')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs77
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs1
3 files changed, 99 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
index 71e88e3..880ba4a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs
@@ -40,6 +40,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
40 private int m_braceCount; // for indentation 40 private int m_braceCount; // for indentation
41 private int m_CSharpLine; // the current line of generated C# code 41 private int m_CSharpLine; // the current line of generated C# code
42 private int m_CSharpCol; // the current column of generated C# code 42 private int m_CSharpCol; // the current column of generated C# code
43 private List<string> m_warnings = new List<string>();
43 44
44 /// <summary> 45 /// <summary>
45 /// Creates an 'empty' CSCodeGenerator instance. 46 /// Creates an 'empty' CSCodeGenerator instance.
@@ -153,6 +154,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
153 } 154 }
154 155
155 /// <summary> 156 /// <summary>
157 /// Get the set of warnings generated during compilation.
158 /// </summary>
159 /// <returns></returns>
160 public string[] GetWarnings()
161 {
162 return m_warnings.ToArray();
163 }
164
165 private void AddWarning(string warning)
166 {
167 if (!m_warnings.Contains(warning))
168 {
169 m_warnings.Add(warning);
170 }
171 }
172
173 /// <summary>
156 /// Recursively called to generate each type of node. Will generate this 174 /// Recursively called to generate each type of node. Will generate this
157 /// node, then all it's children. 175 /// node, then all it's children.
158 /// </summary> 176 /// </summary>
@@ -446,6 +464,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
446 { 464 {
447 string retstr = String.Empty; 465 string retstr = String.Empty;
448 466
467 List<string> identifiers = new List<string>();
468 checkForMultipleAssignments(identifiers, a);
469
449 retstr += GenerateNode((SYMBOL) a.kids.Pop()); 470 retstr += GenerateNode((SYMBOL) a.kids.Pop());
450 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a); 471 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
451 foreach (SYMBOL kid in a.kids) 472 foreach (SYMBOL kid in a.kids)
@@ -454,6 +475,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
454 return retstr; 475 return retstr;
455 } 476 }
456 477
478 // This code checks for LSL of the following forms, and generates a
479 // warning if it finds them.
480 //
481 // list l = [ "foo" ];
482 // l = (l=[]) + l + ["bar"];
483 // (produces l=["foo","bar"] in SL but l=["bar"] in OS)
484 //
485 // integer i;
486 // integer j;
487 // i = (j = 3) + (j = 4) + (j = 5);
488 // (produces j=3 in SL but j=5 in OS)
489 //
490 // Without this check, that code passes compilation, but does not do what
491 // the end user expects, because LSL in SL evaluates right to left instead
492 // of left to right.
493 //
494 // The theory here is that producing an error and alerting the end user that
495 // something needs to change is better than silently generating incorrect code.
496 private void checkForMultipleAssignments(List<string> identifiers, SYMBOL s)
497 {
498 if (s is Assignment)
499 {
500 Assignment a = (Assignment)s;
501 string newident = null;
502
503 if (a.kids[0] is Declaration)
504 {
505 newident = ((Declaration)a.kids[0]).Id;
506 }
507 else if (a.kids[0] is IDENT)
508 {
509 newident = ((IDENT)a.kids[0]).yytext;
510 }
511 else if (a.kids[0] is IdentDotExpression)
512 {
513 newident = ((IdentDotExpression)a.kids[0]).Name; // +"." + ((IdentDotExpression)a.kids[0]).Member;
514 }
515 else
516 {
517 AddWarning(String.Format("Multiple assignments checker internal error '{0}' at line {1} column {2}.", a.kids[0].GetType(), ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position));
518 }
519
520 if (identifiers.Contains(newident))
521 {
522 AddWarning(String.Format("Multiple assignments to '{0}' at line {1} column {2}; results may differ between LSL and OSSL.", newident, ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position));
523 }
524 identifiers.Add(newident);
525 }
526
527 int index;
528 for (index = 0; index < s.kids.Count; index++)
529 {
530 checkForMultipleAssignments(identifiers, (SYMBOL) s.kids[index]);
531 }
532 }
533
457 /// <summary> 534 /// <summary>
458 /// Generates the code for a ReturnStatement node. 535 /// Generates the code for a ReturnStatement node.
459 /// </summary> 536 /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 03b2ab3..59d862d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -76,6 +76,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
76 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap; 76 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap;
77 private ICodeConverter LSL_Converter; 77 private ICodeConverter LSL_Converter;
78 78
79 private List<string> m_warnings = new List<string>();
80
79 // private object m_syncy = new object(); 81 // private object m_syncy = new object();
80 82
81 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); 83 private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
@@ -336,6 +338,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
336 LSL_Converter = (ICodeConverter)new CSCodeGenerator(); 338 LSL_Converter = (ICodeConverter)new CSCodeGenerator();
337 compileScript = LSL_Converter.Convert(Script); 339 compileScript = LSL_Converter.Convert(Script);
338 340
341 // copy converter warnings into our warnings.
342 foreach(string warning in LSL_Converter.GetWarnings())
343 {
344 AddWarning(warning);
345 }
346
339 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap; 347 m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
340 } 348 }
341 349
@@ -373,6 +381,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
373 return CompileFromDotNetText(compileScript, l, asset); 381 return CompileFromDotNetText(compileScript, l, asset);
374 } 382 }
375 383
384 public string[] GetWarnings()
385 {
386 return m_warnings.ToArray();
387 }
388
389 private void AddWarning(string warning)
390 {
391 if (!m_warnings.Contains(warning))
392 {
393 m_warnings.Add(warning);
394 }
395 }
396
376 private static string CreateJSCompilerScript(string compileScript) 397 private static string CreateJSCompilerScript(string compileScript)
377 { 398 {
378 compileScript = String.Empty + 399 compileScript = String.Empty +
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs
index 28e42da..917000e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/ICodeConverter.cs
@@ -33,5 +33,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
33 public interface ICodeConverter 33 public interface ICodeConverter
34 { 34 {
35 string Convert(string script); 35 string Convert(string script);
36 string[] GetWarnings();
36 } 37 }
37} 38}