diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs | 369 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs | 357 | ||||
-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.cs | 120 |
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 | |||
28 | using System.IO; | ||
29 | using System.CodeDom.Compiler; | ||
30 | using System.Collections.Generic; | ||
31 | using Microsoft.CSharp; | ||
32 | using NUnit.Framework; | ||
33 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | ||
34 | |||
35 | namespace 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 | } | ||