aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs946
1 files changed, 0 insertions, 946 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs
deleted file mode 100644
index c4b0fd4..0000000
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/CSCodeGenerator.cs
+++ /dev/null
@@ -1,946 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Collections.Generic;
31using Tools;
32
33namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
34{
35 public class CSCodeGenerator
36 {
37 private SYMBOL m_astRoot = null;
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
43
44 /// <summary>
45 /// Creates an 'empty' CSCodeGenerator instance.
46 /// </summary>
47 public CSCodeGenerator()
48 {
49 ResetCounters();
50 }
51
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; }
68 }
69
70 /// <summary>
71 /// Resets various counters and metadata.
72 /// </summary>
73 private void ResetCounters()
74 {
75 m_braceCount = 0;
76 m_CSharpLine = 0;
77 m_CSharpCol = 1;
78 m_positionMap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
79 m_astRoot = null;
80 }
81
82 /// <summary>
83 /// Generate the code from the AST we have.
84 /// </summary>
85 /// <param name="script">The LSL source as a string.</param>
86 /// <returns>String containing the generated C# code.</returns>
87 public string Convert(string script)
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
95 string retstr = String.Empty;
96
97 // standard preamble
98 //retstr = GenerateLine("using OpenSim.Region.ScriptEngine.Common;");
99 //retstr += GenerateLine("using System.Collections.Generic;");
100 //retstr += GenerateLine("");
101 //retstr += GenerateLine("namespace SecondLife");
102 //retstr += GenerateLine("{");
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;
110
111 // here's the payload
112 retstr += GenerateLine();
113 foreach (SYMBOL s in m_astRoot.kids)
114 retstr += GenerateNode(s);
115
116 // close braces!
117 m_braceCount--;
118 //retstr += GenerateIndentedLine("}");
119 m_braceCount--;
120 //retstr += GenerateLine("}");
121
122 return retstr;
123 }
124
125 /// <summary>
126 /// Recursively called to generate each type of node. Will generate this
127 /// node, then all it's children.
128 /// </summary>
129 /// <param name="s">The current node to generate code for.</param>
130 /// <returns>String containing C# code for SYMBOL s.</returns>
131 private string GenerateNode(SYMBOL s)
132 {
133 string retstr = String.Empty;
134
135 // make sure to put type lower in the inheritance hierarchy first
136 // ie: since IdentArgument and ExpressionArgument inherit from
137 // Argument, put IdentArgument and ExpressionArgument before Argument
138 if (s is GlobalFunctionDefinition)
139 retstr += GenerateGlobalFunctionDefinition((GlobalFunctionDefinition) s);
140 else if (s is GlobalVariableDeclaration)
141 retstr += GenerateGlobalVariableDeclaration((GlobalVariableDeclaration) s);
142 else if (s is State)
143 retstr += GenerateState((State) s);
144 else if (s is CompoundStatement)
145 retstr += GenerateCompoundStatement((CompoundStatement) s);
146 else if (s is Declaration)
147 retstr += GenerateDeclaration((Declaration) s);
148 else if (s is Statement)
149 retstr += GenerateStatement((Statement) s);
150 else if (s is ReturnStatement)
151 retstr += GenerateReturnStatement((ReturnStatement) s);
152 else if (s is JumpLabel)
153 retstr += GenerateJumpLabel((JumpLabel) s);
154 else if (s is JumpStatement)
155 retstr += GenerateJumpStatement((JumpStatement) s);
156 else if (s is StateChange)
157 retstr += GenerateStateChange((StateChange) s);
158 else if (s is IfStatement)
159 retstr += GenerateIfStatement((IfStatement) s);
160 else if (s is WhileStatement)
161 retstr += GenerateWhileStatement((WhileStatement) s);
162 else if (s is DoWhileStatement)
163 retstr += GenerateDoWhileStatement((DoWhileStatement) s);
164 else if (s is ForLoop)
165 retstr += GenerateForLoop((ForLoop) s);
166 else if (s is ArgumentList)
167 retstr += GenerateArgumentList((ArgumentList) s);
168 else if (s is Assignment)
169 retstr += GenerateAssignment((Assignment) s);
170 else if (s is BinaryExpression)
171 retstr += GenerateBinaryExpression((BinaryExpression) s);
172 else if (s is ParenthesisExpression)
173 retstr += GenerateParenthesisExpression((ParenthesisExpression) s);
174 else if (s is UnaryExpression)
175 retstr += GenerateUnaryExpression((UnaryExpression) s);
176 else if (s is IncrementDecrementExpression)
177 retstr += GenerateIncrementDecrementExpression((IncrementDecrementExpression) s);
178 else if (s is TypecastExpression)
179 retstr += GenerateTypecastExpression((TypecastExpression) s);
180 else if (s is FunctionCall)
181 retstr += GenerateFunctionCall((FunctionCall) s);
182 else if (s is VectorConstant)
183 retstr += GenerateVectorConstant((VectorConstant) s);
184 else if (s is RotationConstant)
185 retstr += GenerateRotationConstant((RotationConstant) s);
186 else if (s is ListConstant)
187 retstr += GenerateListConstant((ListConstant) s);
188 else if (s is Constant)
189 retstr += GenerateConstant((Constant) s);
190 else if (s is IdentDotExpression)
191 retstr += Generate(((IdentDotExpression) s).Name + "." + ((IdentDotExpression) s).Member, s);
192 else if (s is IdentExpression)
193 retstr += Generate(((IdentExpression) s).Name, s);
194 else if (s is IDENT)
195 retstr += Generate(((TOKEN) s).yytext, s);
196 else
197 {
198 foreach (SYMBOL kid in s.kids)
199 retstr += GenerateNode(kid);
200 }
201
202 return retstr;
203 }
204
205 /// <summary>
206 /// Generates the code for a GlobalFunctionDefinition node.
207 /// </summary>
208 /// <param name="gf">The GlobalFunctionDefinition node.</param>
209 /// <returns>String containing C# code for GlobalFunctionDefinition gf.</returns>
210 private string GenerateGlobalFunctionDefinition(GlobalFunctionDefinition gf)
211 {
212 string retstr = String.Empty;
213
214 // we need to separate the argument declaration list from other kids
215 List<SYMBOL> argumentDeclarationListKids = new List<SYMBOL>();
216 List<SYMBOL> remainingKids = new List<SYMBOL>();
217
218 foreach (SYMBOL kid in gf.kids)
219 if (kid is ArgumentDeclarationList)
220 argumentDeclarationListKids.Add(kid);
221 else
222 remainingKids.Add(kid);
223
224 retstr += GenerateIndented(String.Format("{0} {1}(", gf.ReturnType, gf.Name), gf);
225
226 // print the state arguments, if any
227 foreach (SYMBOL kid in argumentDeclarationListKids)
228 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
229
230 retstr += GenerateLine(")");
231
232 foreach (SYMBOL kid in remainingKids)
233 retstr += GenerateNode(kid);
234
235 return retstr;
236 }
237
238 /// <summary>
239 /// Generates the code for a GlobalVariableDeclaration node.
240 /// </summary>
241 /// <param name="gv">The GlobalVariableDeclaration node.</param>
242 /// <returns>String containing C# code for GlobalVariableDeclaration gv.</returns>
243 private string GenerateGlobalVariableDeclaration(GlobalVariableDeclaration gv)
244 {
245 string retstr = String.Empty;
246
247 foreach (SYMBOL s in gv.kids)
248 {
249 retstr += Indent();
250 retstr += GenerateNode(s);
251 retstr += GenerateLine(";");
252 }
253
254 return retstr;
255 }
256
257 /// <summary>
258 /// Generates the code for a State node.
259 /// </summary>
260 /// <param name="s">The State node.</param>
261 /// <returns>String containing C# code for State s.</returns>
262 private string GenerateState(State s)
263 {
264 string retstr = String.Empty;
265
266 foreach (SYMBOL kid in s.kids)
267 if (kid is StateEvent)
268 retstr += GenerateStateEvent((StateEvent) kid, s.Name);
269
270 return retstr;
271 }
272
273 /// <summary>
274 /// Generates the code for a StateEvent node.
275 /// </summary>
276 /// <param name="se">The StateEvent node.</param>
277 /// <param name="parentStateName">The name of the parent state.</param>
278 /// <returns>String containing C# code for StateEvent se.</returns>
279 private string GenerateStateEvent(StateEvent se, string parentStateName)
280 {
281 string retstr = String.Empty;
282
283 // we need to separate the argument declaration list from other kids
284 List<SYMBOL> argumentDeclarationListKids = new List<SYMBOL>();
285 List<SYMBOL> remainingKids = new List<SYMBOL>();
286
287 foreach (SYMBOL kid in se.kids)
288 if (kid is ArgumentDeclarationList)
289 argumentDeclarationListKids.Add(kid);
290 else
291 remainingKids.Add(kid);
292
293 // "state" (function) declaration
294 retstr += GenerateIndented(String.Format("public void {0}_event_{1}(", parentStateName, se.Name), se);
295
296 // print the state arguments, if any
297 foreach (SYMBOL kid in argumentDeclarationListKids)
298 retstr += GenerateArgumentDeclarationList((ArgumentDeclarationList) kid);
299
300 retstr += GenerateLine(")");
301
302 foreach (SYMBOL kid in remainingKids)
303 retstr += GenerateNode(kid);
304
305 return retstr;
306 }
307
308 /// <summary>
309 /// Generates the code for an ArgumentDeclarationList node.
310 /// </summary>
311 /// <param name="adl">The ArgumentDeclarationList node.</param>
312 /// <returns>String containing C# code for ArgumentDeclarationList adl.</returns>
313 private string GenerateArgumentDeclarationList(ArgumentDeclarationList adl)
314 {
315 string retstr = String.Empty;
316
317 int comma = adl.kids.Count - 1; // tells us whether to print a comma
318
319 foreach (Declaration d in adl.kids)
320 {
321 retstr += Generate(String.Format("{0} {1}", d.Datatype, d.Id), d);
322 if (0 < comma--)
323 retstr += Generate(", ");
324 }
325
326 return retstr;
327 }
328
329 /// <summary>
330 /// Generates the code for an ArgumentList node.
331 /// </summary>
332 /// <param name="al">The ArgumentList node.</param>
333 /// <returns>String containing C# code for ArgumentList al.</returns>
334 private string GenerateArgumentList(ArgumentList al)
335 {
336 string retstr = String.Empty;
337
338 int comma = al.kids.Count - 1; // tells us whether to print a comma
339
340 foreach (SYMBOL s in al.kids)
341 {
342 retstr += GenerateNode(s);
343 if (0 < comma--)
344 retstr += Generate(", ");
345 }
346
347 return retstr;
348 }
349
350 /// <summary>
351 /// Generates the code for a CompoundStatement node.
352 /// </summary>
353 /// <param name="cs">The CompoundStatement node.</param>
354 /// <returns>String containing C# code for CompoundStatement cs.</returns>
355 private string GenerateCompoundStatement(CompoundStatement cs)
356 {
357 string retstr = String.Empty;
358
359 // opening brace
360 retstr += GenerateIndentedLine("{");
361 m_braceCount++;
362
363 foreach (SYMBOL kid in cs.kids)
364 retstr += GenerateNode(kid);
365
366 // closing brace
367 m_braceCount--;
368 retstr += GenerateIndentedLine("}");
369
370 return retstr;
371 }
372
373 /// <summary>
374 /// Generates the code for a Declaration node.
375 /// </summary>
376 /// <param name="d">The Declaration node.</param>
377 /// <returns>String containing C# code for Declaration d.</returns>
378 private string GenerateDeclaration(Declaration d)
379 {
380 return Generate(String.Format("{0} {1}", d.Datatype, d.Id), d);
381 }
382
383 /// <summary>
384 /// Generates the code for a Statement node.
385 /// </summary>
386 /// <param name="s">The Statement node.</param>
387 /// <returns>String containing C# code for Statement s.</returns>
388 private string GenerateStatement(Statement s)
389 {
390 string retstr = String.Empty;
391 bool printSemicolon = true;
392
393 retstr += Indent();
394
395 if (0 < s.kids.Count)
396 {
397 // Jump label prints its own colon, we don't need a semicolon.
398 printSemicolon = !(s.kids.Top is JumpLabel);
399
400 foreach (SYMBOL kid in s.kids)
401 retstr += GenerateNode(kid);
402 }
403
404 if (printSemicolon)
405 retstr += GenerateLine(";");
406
407 return retstr;
408 }
409
410 /// <summary>
411 /// Generates the code for an Assignment node.
412 /// </summary>
413 /// <param name="a">The Assignment node.</param>
414 /// <returns>String containing C# code for Assignment a.</returns>
415 private string GenerateAssignment(Assignment a)
416 {
417 string retstr = String.Empty;
418
419 retstr += GenerateNode((SYMBOL) a.kids.Pop());
420 retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
421 foreach (SYMBOL kid in a.kids)
422 retstr += GenerateNode(kid);
423
424 return retstr;
425 }
426
427 /// <summary>
428 /// Generates the code for a ReturnStatement node.
429 /// </summary>
430 /// <param name="rs">The ReturnStatement node.</param>
431 /// <returns>String containing C# code for ReturnStatement rs.</returns>
432 private string GenerateReturnStatement(ReturnStatement rs)
433 {
434 string retstr = String.Empty;
435
436 retstr += Generate("return ", rs);
437
438 foreach (SYMBOL kid in rs.kids)
439 retstr += GenerateNode(kid);
440
441 return retstr;
442 }
443
444 /// <summary>
445 /// Generates the code for a JumpLabel node.
446 /// </summary>
447 /// <param name="jl">The JumpLabel node.</param>
448 /// <returns>String containing C# code for JumpLabel jl.</returns>
449 private string GenerateJumpLabel(JumpLabel jl)
450 {
451 return Generate(String.Format("{0}:\n", jl.LabelName), jl);
452 }
453
454 /// <summary>
455 /// Generates the code for a JumpStatement node.
456 /// </summary>
457 /// <param name="js">The JumpStatement node.</param>
458 /// <returns>String containing C# code for JumpStatement js.</returns>
459 private string GenerateJumpStatement(JumpStatement js)
460 {
461 return Generate(String.Format("goto {0}", js.TargetName), js);
462 }
463
464 /// <summary>
465 /// Generates the code for an IfStatement node.
466 /// </summary>
467 /// <param name="ifs">The IfStatement node.</param>
468 /// <returns>String containing C# code for IfStatement ifs.</returns>
469 private string GenerateIfStatement(IfStatement ifs)
470 {
471 string retstr = String.Empty;
472
473 retstr += GenerateIndented("if (", ifs);
474 retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
475 retstr += GenerateLine(")");
476
477 // CompoundStatement handles indentation itself but we need to do it
478 // otherwise.
479 bool indentHere = ifs.kids.Top is Statement;
480 if (indentHere) m_braceCount++;
481 retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
482 if (indentHere) m_braceCount--;
483
484 if (0 < ifs.kids.Count) // do it again for an else
485 {
486 retstr += GenerateIndentedLine("else", ifs);
487
488 indentHere = ifs.kids.Top is Statement;
489 if (indentHere) m_braceCount++;
490 retstr += GenerateNode((SYMBOL) ifs.kids.Pop());
491 if (indentHere) m_braceCount--;
492 }
493
494 return retstr;
495 }
496
497 /// <summary>
498 /// Generates the code for a StateChange node.
499 /// </summary>
500 /// <param name="sc">The StateChange node.</param>
501 /// <returns>String containing C# code for StateChange sc.</returns>
502 private string GenerateStateChange(StateChange sc)
503 {
504 return Generate(String.Format("state(\"{0}\")", sc.NewState), sc);
505 }
506
507 /// <summary>
508 /// Generates the code for a WhileStatement node.
509 /// </summary>
510 /// <param name="ws">The WhileStatement node.</param>
511 /// <returns>String containing C# code for WhileStatement ws.</returns>
512 private string GenerateWhileStatement(WhileStatement ws)
513 {
514 string retstr = String.Empty;
515
516 retstr += GenerateIndented("while (", ws);
517 retstr += GenerateNode((SYMBOL) ws.kids.Pop());
518 retstr += GenerateLine(")");
519
520 // CompoundStatement handles indentation itself but we need to do it
521 // otherwise.
522 bool indentHere = ws.kids.Top is Statement;
523 if (indentHere) m_braceCount++;
524 retstr += GenerateNode((SYMBOL) ws.kids.Pop());
525 if (indentHere) m_braceCount--;
526
527 return retstr;
528 }
529
530 /// <summary>
531 /// Generates the code for a DoWhileStatement node.
532 /// </summary>
533 /// <param name="dws">The DoWhileStatement node.</param>
534 /// <returns>String containing C# code for DoWhileStatement dws.</returns>
535 private string GenerateDoWhileStatement(DoWhileStatement dws)
536 {
537 string retstr = String.Empty;
538
539 retstr += GenerateIndentedLine("do", dws);
540
541 // CompoundStatement handles indentation itself but we need to do it
542 // otherwise.
543 bool indentHere = dws.kids.Top is Statement;
544 if (indentHere) m_braceCount++;
545 retstr += GenerateNode((SYMBOL) dws.kids.Pop());
546 if (indentHere) m_braceCount--;
547
548 retstr += GenerateIndented("while (", dws);
549 retstr += GenerateNode((SYMBOL) dws.kids.Pop());
550 retstr += GenerateLine(");");
551
552 return retstr;
553 }
554
555 /// <summary>
556 /// Generates the code for a ForLoop node.
557 /// </summary>
558 /// <param name="fl">The ForLoop node.</param>
559 /// <returns>String containing C# code for ForLoop fl.</returns>
560 private string GenerateForLoop(ForLoop fl)
561 {
562 string retstr = String.Empty;
563
564 retstr += GenerateIndented("for (", fl);
565
566 // for ( x = 0 ; x < 10 ; x++ )
567 // ^^^^^^^
568 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
569 retstr += Generate("; ");
570 // for ( x = 0 ; x < 10 ; x++ )
571 // ^^^^^^^^
572 retstr += GenerateNode((SYMBOL) fl.kids.Pop());
573 retstr += Generate("; ");
574 // for ( x = 0 ; x < 10 ; x++ )
575 // ^^^^^
576 retstr += GenerateForLoopStatement((ForLoopStatement) fl.kids.Pop());
577 retstr += GenerateLine(")");
578
579 // CompoundStatement handles indentation itself but we need to do it
580 // otherwise.
581 bool indentHere = fl.kids.Top is Statement;
582 if (indentHere) m_braceCount++;
583 retstr += GenerateNode((SYMBOL) fl.kids.Pop());
584 if (indentHere) m_braceCount--;
585
586 return retstr;
587 }
588
589 /// <summary>
590 /// Generates the code for a ForLoopStatement node.
591 /// </summary>
592 /// <param name="fls">The ForLoopStatement node.</param>
593 /// <returns>String containing C# code for ForLoopStatement fls.</returns>
594 private string GenerateForLoopStatement(ForLoopStatement fls)
595 {
596 string retstr = String.Empty;
597
598 int comma = fls.kids.Count - 1; // tells us whether to print a comma
599
600 foreach (SYMBOL s in fls.kids)
601 {
602 retstr += GenerateNode(s);
603 if (0 < comma--)
604 retstr += Generate(", ");
605 }
606
607 return retstr;
608 }
609
610 /// <summary>
611 /// Generates the code for a BinaryExpression node.
612 /// </summary>
613 /// <param name="be">The BinaryExpression node.</param>
614 /// <returns>String containing C# code for BinaryExpression be.</returns>
615 private string GenerateBinaryExpression(BinaryExpression be)
616 {
617 string retstr = String.Empty;
618
619 retstr += GenerateNode((SYMBOL) be.kids.Pop());
620 retstr += Generate(String.Format(" {0} ", be.ExpressionSymbol), be);
621 foreach (SYMBOL kid in be.kids)
622 retstr += GenerateNode(kid);
623
624 return retstr;
625 }
626
627 /// <summary>
628 /// Generates the code for a UnaryExpression node.
629 /// </summary>
630 /// <param name="ue">The UnaryExpression node.</param>
631 /// <returns>String containing C# code for UnaryExpression ue.</returns>
632 private string GenerateUnaryExpression(UnaryExpression ue)
633 {
634 string retstr = String.Empty;
635
636 retstr += Generate(ue.UnarySymbol, ue);
637 retstr += GenerateNode((SYMBOL) ue.kids.Pop());
638
639 return retstr;
640 }
641
642 /// <summary>
643 /// Generates the code for a ParenthesisExpression node.
644 /// </summary>
645 /// <param name="pe">The ParenthesisExpression node.</param>
646 /// <returns>String containing C# code for ParenthesisExpression pe.</returns>
647 private string GenerateParenthesisExpression(ParenthesisExpression pe)
648 {
649 string retstr = String.Empty;
650
651 retstr += Generate("(");
652 foreach (SYMBOL kid in pe.kids)
653 retstr += GenerateNode(kid);
654 retstr += Generate(")");
655
656 return retstr;
657 }
658
659 /// <summary>
660 /// Generates the code for a IncrementDecrementExpression node.
661 /// </summary>
662 /// <param name="ide">The IncrementDecrementExpression node.</param>
663 /// <returns>String containing C# code for IncrementDecrementExpression ide.</returns>
664 private string GenerateIncrementDecrementExpression(IncrementDecrementExpression ide)
665 {
666 string retstr = String.Empty;
667
668 if (0 < ide.kids.Count)
669 {
670 IdentDotExpression dot = (IdentDotExpression) ide.kids.Top;
671 retstr += Generate(String.Format("{0}", ide.PostOperation ? dot.Name + "." + dot.Member + ide.Operation : ide.Operation + dot.Name + "." + dot.Member), ide);
672 }
673 else
674 retstr += Generate(String.Format("{0}", ide.PostOperation ? ide.Name + ide.Operation : ide.Operation + ide.Name), ide);
675
676 return retstr;
677 }
678
679 /// <summary>
680 /// Generates the code for a TypecastExpression node.
681 /// </summary>
682 /// <param name="te">The TypecastExpression node.</param>
683 /// <returns>String containing C# code for TypecastExpression te.</returns>
684 private string GenerateTypecastExpression(TypecastExpression te)
685 {
686 string retstr = String.Empty;
687
688 // we wrap all typecasted statements in parentheses
689 retstr += Generate(String.Format("({0}) (", te.TypecastType), te);
690 retstr += GenerateNode((SYMBOL) te.kids.Pop());
691 retstr += Generate(")");
692
693 return retstr;
694 }
695
696 /// <summary>
697 /// Generates the code for a FunctionCall node.
698 /// </summary>
699 /// <param name="fc">The FunctionCall node.</param>
700 /// <returns>String containing C# code for FunctionCall fc.</returns>
701 private string GenerateFunctionCall(FunctionCall fc)
702 {
703 string retstr = String.Empty;
704
705 retstr += Generate(String.Format("{0}(", fc.Id), fc);
706
707 foreach (SYMBOL kid in fc.kids)
708 retstr += GenerateNode(kid);
709
710 retstr += Generate(")");
711
712 return retstr;
713 }
714
715 /// <summary>
716 /// Generates the code for a Constant node.
717 /// </summary>
718 /// <param name="c">The Constant node.</param>
719 /// <returns>String containing C# code for Constant c.</returns>
720 private string GenerateConstant(Constant c)
721 {
722 string retstr = String.Empty;
723
724 // Supprt LSL's weird acceptance of floats with no trailing digits
725 // after the period. Turn float x = 10.; into float x = 10.0;
726 if ("LSL_Types.LSLFloat" == c.Type)
727 {
728 int dotIndex = c.Value.IndexOf('.') + 1;
729 if (0 < dotIndex && (dotIndex == c.Value.Length || !Char.IsDigit(c.Value[dotIndex])))
730 c.Value = c.Value.Insert(dotIndex, "0");
731 c.Value = "new LSL_Types.LSLFloat("+c.Value+")";
732 }
733 else if ("LSL_Types.LSLInteger" == c.Type)
734 {
735 c.Value = "new LSL_Types.LSLInteger("+c.Value+")";
736 }
737 else if ("LSL_Types.LSLString" == c.Type)
738 {
739 c.Value = "new LSL_Types.LSLString(\""+c.Value+"\")";
740 }
741
742 retstr += Generate(c.Value, c);
743
744 return retstr;
745 }
746
747 /// <summary>
748 /// Generates the code for a VectorConstant node.
749 /// </summary>
750 /// <param name="vc">The VectorConstant node.</param>
751 /// <returns>String containing C# code for VectorConstant vc.</returns>
752 private string GenerateVectorConstant(VectorConstant vc)
753 {
754 string retstr = String.Empty;
755
756 retstr += Generate(String.Format("new {0}(", vc.Type), vc);
757 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
758 retstr += Generate(", ");
759 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
760 retstr += Generate(", ");
761 retstr += GenerateNode((SYMBOL) vc.kids.Pop());
762 retstr += Generate(")");
763
764 return retstr;
765 }
766
767 /// <summary>
768 /// Generates the code for a RotationConstant node.
769 /// </summary>
770 /// <param name="rc">The RotationConstant node.</param>
771 /// <returns>String containing C# code for RotationConstant rc.</returns>
772 private string GenerateRotationConstant(RotationConstant rc)
773 {
774 string retstr = String.Empty;
775
776 retstr += Generate(String.Format("new {0}(", rc.Type), rc);
777 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
778 retstr += Generate(", ");
779 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
780 retstr += Generate(", ");
781 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
782 retstr += Generate(", ");
783 retstr += GenerateNode((SYMBOL) rc.kids.Pop());
784 retstr += Generate(")");
785
786 return retstr;
787 }
788
789 /// <summary>
790 /// Generates the code for a ListConstant node.
791 /// </summary>
792 /// <param name="lc">The ListConstant node.</param>
793 /// <returns>String containing C# code for ListConstant lc.</returns>
794 private string GenerateListConstant(ListConstant lc)
795 {
796 string retstr = String.Empty;
797
798 retstr += Generate(String.Format("new {0}(", lc.Type), lc);
799
800 foreach (SYMBOL kid in lc.kids)
801 retstr += GenerateNode(kid);
802
803 retstr += Generate(")");
804
805 return retstr;
806 }
807
808 /// <summary>
809 /// Prints a newline.
810 /// </summary>
811 /// <returns>A newline.</returns>
812 private string GenerateLine()
813 {
814 return GenerateLine("");
815 }
816
817 /// <summary>
818 /// Prints text, followed by a newline.
819 /// </summary>
820 /// <param name="s">String of text to print.</param>
821 /// <returns>String s followed by newline.</returns>
822 private string GenerateLine(string s)
823 {
824 return GenerateLine(s, null);
825 }
826
827 /// <summary>
828 /// Prints text, followed by a newline.
829 /// </summary>
830 /// <param name="s">String of text to print.</param>
831 /// <param name="sym">Symbol being generated to extract original line
832 /// number and column from.</param>
833 /// <returns>String s followed by newline.</returns>
834 private string GenerateLine(string s, SYMBOL sym)
835 {
836 string retstr = Generate(s, sym) + "\n";
837
838 m_CSharpLine++;
839 m_CSharpCol = 1;
840
841 return retstr;
842 }
843
844 /// <summary>
845 /// Prints text.
846 /// </summary>
847 /// <param name="s">String of text to print.</param>
848 /// <returns>String s.</returns>
849 private string Generate(string s)
850 {
851 return Generate(s, null);
852 }
853
854 /// <summary>
855 /// Prints text.
856 /// </summary>
857 /// <param name="s">String of text to print.</param>
858 /// <param name="sym">Symbol being generated to extract original line
859 /// number and column from.</param>
860 /// <returns>String s.</returns>
861 private string Generate(string s, SYMBOL sym)
862 {
863 if (null != sym)
864 m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position));
865
866 m_CSharpCol += s.Length;
867
868 return s;
869 }
870
871 /// <summary>
872 /// Prints text correctly indented, followed by a newline.
873 /// </summary>
874 /// <param name="s">String of text to print.</param>
875 /// <returns>Properly indented string s followed by newline.</returns>
876 private string GenerateIndentedLine(string s)
877 {
878 return GenerateIndentedLine(s, null);
879 }
880
881 /// <summary>
882 /// Prints text correctly indented, followed by a newline.
883 /// </summary>
884 /// <param name="s">String of text to print.</param>
885 /// <param name="sym">Symbol being generated to extract original line
886 /// number and column from.</param>
887 /// <returns>Properly indented string s followed by newline.</returns>
888 private string GenerateIndentedLine(string s, SYMBOL sym)
889 {
890 string retstr = GenerateIndented(s, sym) + "\n";
891
892 m_CSharpLine++;
893 m_CSharpCol = 1;
894
895 return retstr;
896 }
897
898 /// <summary>
899 /// Prints text correctly indented.
900 /// </summary>
901 /// <param name="s">String of text to print.</param>
902 /// <returns>Properly indented string s.</returns>
903 //private string GenerateIndented(string s)
904 //{
905 // return GenerateIndented(s, null);
906 //}
907 // THIS FUNCTION IS COMMENTED OUT TO SUPPRESS WARNINGS
908
909 /// <summary>
910 /// Prints text correctly indented.
911 /// </summary>
912 /// <param name="s">String of text to print.</param>
913 /// <param name="sym">Symbol being generated to extract original line
914 /// number and column from.</param>
915 /// <returns>Properly indented string s.</returns>
916 private string GenerateIndented(string s, SYMBOL sym)
917 {
918 string retstr = Indent() + s;
919
920 if (null != sym)
921 m_positionMap.Add(new KeyValuePair<int, int>(m_CSharpLine, m_CSharpCol), new KeyValuePair<int, int>(sym.Line, sym.Position));
922
923 m_CSharpCol += s.Length;
924
925 return retstr;
926 }
927
928 /// <summary>
929 /// Prints correct indentation.
930 /// </summary>
931 /// <returns>Indentation based on brace count.</returns>
932 private string Indent()
933 {
934 string retstr = String.Empty;
935
936 for (int i = 0; i < m_braceCount; i++)
937 for (int j = 0; j < m_indentWidth; j++)
938 {
939 retstr += " ";
940 m_CSharpCol++;
941 }
942
943 return retstr;
944 }
945 }
946}