/src/IronLua/IronLua/Ast/LuaPrinter.cs
http://ironlua.googlecode.com/ · C# · 429 lines · 366 code · 63 blank · 0 comment · 17 complexity · 2aa490d57e8b9506c4315a131626dda2 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using Dlr = Microsoft.Scripting;
- namespace IronLua.Ast {
- public class LuaPrinter : BaseAstVisitor {
- public static void PrintCode (TextWriter writer, LuaNode node)
- {
- var printer = new LuaPrinter (writer);
- node.Accept (printer);
- }
- public static string ToCodeString (LuaNode node)
- {
- var writer = new StringWriter ();
- PrintCode (writer, node);
- return writer.ToString ();
- }
- const string ListSeparator = ", ";
- TextWriter writer;
- bool write_indent;
- int indent;
- private LuaPrinter (TextWriter writer)
- {
- this.writer = writer;
- }
- void WriteIndent ()
- {
- if (!write_indent)
- return;
- for (int i = 0; i < indent; i++)
- writer.Write ("\t");
- }
- void Write (object o)
- {
- WriteIndent ();
- writer.Write (o);
- write_indent = false;
- }
- void Write (string s)
- {
- WriteIndent ();
- writer.Write (s);
- write_indent = false;
- }
- void Write (string s, params object [] objs)
- {
- WriteIndent ();
- writer.Write (s, objs);
- write_indent = false;
- }
- void WriteLine ()
- {
- writer.WriteLine ();
- write_indent = true;
- }
- void WriteLine (string s)
- {
- WriteIndent ();
- writer.WriteLine (s);
- write_indent = true;
- }
- void WriteLine (string s, params object [] objs)
- {
- WriteIndent ();
- writer.WriteLine (s, objs);
- write_indent = true;
- }
- void Indent ()
- {
- indent++;
- write_indent = true;
- }
- void Dedent ()
- {
- indent--;
- }
- void WriteIndented (Action action)
- {
- Indent ();
- action ();
- Dedent ();
- }
- void WriteDoBlock (Action action)
- {
- WriteLine ("do");
- WriteIndented (action);
- WriteLine ("end");
- }
- void WriteBetweenSpaces (Action action)
- {
- Write (" ");
- action ();
- Write (" ");
- }
- void WriteBetweenSpaces (string s)
- {
- Write (" ");
- Write (s);
- Write (" ");
- }
- void WriteBetweenParenthesis (Action action)
- {
- Write ("(");
- action ();
- Write (")");
- }
- void WriteBetweenBrackets (Action action)
- {
- Write ("[");
- action ();
- Write ("]");
- }
- void WriteSpace ()
- {
- Write (" ");
- }
- void VisitList<TElement> (IEnumerable<TElement> list, string separator) where TElement : LuaNode
- {
- int i = 0;
- foreach (var e in list) {
- if (i > 0)
- Write (separator);
- e.Accept (this);
- i++;
- }
- }
- public override void VisitList<TElement> (IEnumerable<TElement> list)
- {
- VisitList (list, ListSeparator);
- }
- public override void VisitBlockStatement (BlockStatement node)
- {
- VisitList (node.Statements, string.Empty);
- }
- public override void VisitAssignStatement (AssignStatement node)
- {
- VisitList (node.Left);
- WriteBetweenSpaces ("=");
- VisitList (node.Right);
- WriteLine ();
- }
- public override void VisitDoStatement (DoStatement node)
- {
- WriteDoBlock (() => node.Body.Accept (this));
- }
- public override void VisitWhileStatement (WhileStatement node)
- {
- Write ("while");
- WriteBetweenSpaces (() => node.Condition.Accept (this));
- WriteDoBlock (() => node.Body.Accept (this));
- }
- public override void VisitRepeatStatement (RepeatStatement node)
- {
- WriteLine ("repeat");
- WriteIndented (() => node.Body.Accept (this));
- Write ("until");
- WriteSpace ();
- node.Until.Accept (this);
- WriteLine ();
- }
- public override void VisitIfStatement (IfStatement node)
- {
- Write ("if");
- WriteBetweenSpaces (() => node.Condition.Accept (this));
- WriteLine ("then");
- WriteIndented (() => node.Then.Accept (this));
- VisitList (node.ElseIfs, string.Empty);
- if (node.Else != null) {
- WriteLine ("else");
- WriteIndented (() => node.Else.Accept (this));
- }
- WriteLine ("end");
- }
- public override void VisitElseIfClause (ElseIfClause node)
- {
- Write ("elseif");
- WriteBetweenSpaces (() => node.Condition.Accept (this));
- WriteLine ("then");
- WriteIndented (() => node.Then.Accept (this));
- }
- public override void VisitReturnStatement (ReturnStatement node)
- {
- Write ("return");
- WriteSpace ();
- VisitList (node.Expressions);
- WriteLine ();
- }
- public override void VisitBreakStatement (BreakStatement node)
- {
- WriteLine ("break");
- }
- public override void VisitExpressionStatement (ExpressionStatement node)
- {
- node.Expression.Accept (this);
- WriteLine ();
- }
- public override void VisitCommentStatement (CommentStatement node)
- {
- Write ("--");
- WriteSpace ();
- WriteLine (node.Comment);
- }
- public override void VisitForStatement (ForStatement node)
- {
- Write ("for");
- WriteBetweenSpaces (() => node.Variable.Accept (this));
- Write ("=");
- WriteSpace ();
- node.Initializer.Accept (this);
- Write (ListSeparator);
- node.Limit.Accept (this);
- if (node.Step != null) {
- Write (ListSeparator);
- node.Step.Accept (this);
- }
- WriteSpace ();
- WriteDoBlock (() => node.Body.Accept (this));
- }
- public override void VisitForEachStatement (ForEachStatement node)
- {
- Write ("for");
- WriteBetweenSpaces (() => VisitList (node.Variables));
- Write ("in");
- WriteBetweenSpaces (() => VisitList (node.Expressions));
- WriteDoBlock (() => node.Body.Accept (this));
- }
- public override void VisitLocalStatement (LocalStatement node)
- {
- Write ("local");
- WriteBetweenSpaces (() => VisitList (node.Variables));
- Write ("=");
- WriteSpace ();
- VisitList (node.Expressions);
- WriteLine ();
- }
- static string OperatorToString (UnaryOperatorType op)
- {
- switch (op) {
- case UnaryOperatorType.Length:
- return "#";
- case UnaryOperatorType.Negation:
- return "-";
- case UnaryOperatorType.Not:
- return "not";
- default:
- throw new NotSupportedException ();
- }
- }
- public override void VisitUnaryExpression (UnaryExpression node)
- {
- Write (OperatorToString (node.Operator));
- WriteBetweenParenthesis (() => node.Expression.Accept (this));
- }
- static string OperatorToString (BinaryOperatorType op)
- {
- switch (op) {
- case BinaryOperatorType.Add:
- return "+";
- case BinaryOperatorType.And:
- return "and";
- case BinaryOperatorType.Divide:
- return "/";
- case BinaryOperatorType.Equal:
- return "==";
- case BinaryOperatorType.GreaterThan:
- return ">";
- case BinaryOperatorType.GreaterThanOrEqual:
- return ">=";
- case BinaryOperatorType.LessThan:
- return "<";
- case BinaryOperatorType.LessThanOrEqual:
- return "<=";
- case BinaryOperatorType.Modulo:
- return "%";
- case BinaryOperatorType.Multiply:
- return "*";
- case BinaryOperatorType.NotEqual:
- return "~=";
- case BinaryOperatorType.Or:
- return "or";
- case BinaryOperatorType.Power:
- return "^";
- case BinaryOperatorType.Subtract:
- return "-";
- case BinaryOperatorType.Concat:
- return "..";
- default:
- throw new InvalidOperationException ();
- }
- }
- public override void VisitBinaryExpression (BinaryExpression node)
- {
- WriteBetweenParenthesis (() => {
- node.Left.Accept (this);
- WriteBetweenSpaces (OperatorToString (node.Operator));
- node.Right.Accept (this);
- });
- }
- public override void VisitLiteralExpression (LiteralExpression node)
- {
- Write (FormatLiteral (node.Value));
- }
- string FormatLiteral (object obj)
- {
- if (obj == null)
- return "nil";
- if (obj == Dlr.Runtime.RuntimeHelpers.True)
- return "true";
- if (obj == Dlr.Runtime.RuntimeHelpers.False)
- return "false";
- if (obj is string)
- return "\"" + obj + "\"";
- if (obj is double)
- return ((double) obj).ToString (NumberFormatInfo.InvariantInfo);
- return obj.ToString ();
- }
- public override void VisitTableCreationExpression (TableCreationExpression node)
- {
- Write ("{}");
- }
- public override void VisitVariableExpression (VariableExpression node)
- {
- Write (node.Name);
- }
- public override void VisitSlotExpression (SlotExpression node)
- {
- node.Target.Accept (this);
- WriteSpace ();
- WriteBetweenBrackets (() => node.Expression.Accept (this));
- }
- public override void VisitMemberExpression (MemberExpression node)
- {
- node.Target.Accept (this);
- Write (".");
- Write (node.Name);
- }
- public override void VisitFunctionCallExpression (FunctionCallExpression node)
- {
- node.Target.Accept (this);
- WriteSpace ();
- WriteBetweenParenthesis (() => VisitList (node.Arguments));
- }
- public override void VisitMethodCallExpression (MethodCallExpression node)
- {
- node.Target.Accept (this);
- Write (":");
- Write (node.Name);
- WriteSpace ();
- WriteBetweenParenthesis (() => VisitList (node.Arguments));
- }
- public override void VisitFunctionExpression (FunctionExpression node)
- {
- Write ("function");
- WriteSpace ();
- WriteBetweenParenthesis (() => VisitList (node.Parameters));
- WriteLine ();
- WriteIndented (() => node.Body.Accept (this));
- Write ("end");
- }
- public override void VisitVarArgExpression (VarArgExpression node)
- {
- Write ("...");
- }
- }
- }