using System; using System.Collections; using System.IO; using System.Diagnostics; using System.Reflection; public class source { public static compilation visit(compilation ast, TextWriter w, string[] args, MessageWriter msg) { if (msg.Count == 0) new source(w).visit((AST)ast); return ast; } const int topprec = 16; public TextWriter wr; public source(TextWriter w) { wr = w; } public static string ToString(AST ast) { source src = new source(new StringWriter()); src.visit(ast); string result = ((StringWriter)src.wr).ToString(); src.wr.Close(); return result; } virtual public void accessor_declaration(accessor_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); if (ast.body != null) { Write("{0}", ast.id.str); statement(ast.body, indent + 1); } else WriteLine("{0};", ast.id.str); } virtual public void alias_directive(alias_directive ast, int indent) { Write("using {0} = ", indent, ast.id.str); visit(ast.name); WriteLine(""); } virtual public void anonymous_method_expression(anonymous_method_expression ast, int indent) { Write("delegate "); if (ast.formals.Count > 0) { EmitParameters(ast.formals, null); Write(" "); } Write("{{"); foreach (statement s in ((block_statement)ast.block).stmts) { Write(" "); visit(s); } Write(" }}"); } virtual public void arglist_parameter(arglist_parameter ast, int indent) { Write("__arglist", indent); } virtual public void array_creation_expression1(array_creation_expression1 ast, int parent) { Write("new "); visit(ast.ty); Write("["); EmitexpressionList(ast.exprs); Write("]"); if (ast.ranks != null) foreach (int rank in ast.ranks) Write("[{0}]", "".PadRight(rank, ',')); if (ast.init != null) visit(ast.init); } virtual public void array_creation_expression2(array_creation_expression2 ast, int parent) { Write("new "); visit(ast.ty); Write(" "); visit(ast.init); } virtual public void array_initializer(array_initializer ast, int indent) { Write("{{ "); for (int i = 0; i < ast.a.Count; i++) { if (i > 0) Write(", "); visit(ast.a[i]); } Write(" }}"); } virtual public void array_type(array_type ast, int indent) { visit(ast.ty, indent); Write("[{0}]", "".PadRight(ast.rank_specifier, ',')); } virtual public void as_expression(as_expression ast, int parent) { int myprec = prec("as"); if (myprec <= parent) parenexpr(ast, 0); else { visit(ast.expr, myprec); Write(" as "); visit(ast.ty); } } virtual public void assignment_expression(assignment_expression ast, int parent) { int myprec = prec("="); if (myprec <= parent) parenexpr(ast); else { visit(ast.e1, myprec); Write(" = "); visit(ast.e2, myprec); } } virtual public void attribute(attribute ast, int indent) { visit(ast.name); if (ast.arguments != null) { Write("("); EmitargumentList(ast.arguments.args); if (ast.arguments.namedargs.Count > 0) { if (ast.arguments.args.Count > 0) Write(", "); for (int i = 0; i < ast.arguments.namedargs.Count; i++) { if (i > 0) Write(", "); Write("{0}=", ast.arguments.namedargs[i].id.str); visit(ast.arguments.namedargs[i].expr); } } Write(")"); } } virtual public void attribute_section(attribute_section ast, int indent) { Write("[", indent); if (ast.target != null) Write("{0}: ", ast.target.str); foreach (attribute a in ast.attributes) visit(a); WriteLine("]"); } virtual public void base_access(base_access ast, int parent) { Write("base"); } virtual public void base_initializer(base_initializer ast, int indent) { if (ast.args.Count > 0) { Write(" : base"); EmitargumentList(ast.args); } } virtual public void binary_declarator(binary_declarator ast, int indent) { visit(ast.ty, indent); Write(" operator {0}(", ast.op.str); visit(ast.t1); Write(" {0}, ", ast.id1.str); visit(ast.t2); Write(" {0})", ast.id2.str); } virtual public void binary_expression(binary_expression ast, int parent) { int myprec = prec(ast.op); if (myprec <= parent) parenexpr(ast); else { visit(ast.e1, myprec); Write(" {0} ", ast.op.str); visit(ast.e2, myprec); } } virtual public void block(block_statement ast, int indent) { WriteLine("{{"); foreach (statement s in ast.stmts) visit(s, indent); Write("}}", indent - 1); } virtual public void block_statement(block_statement ast, int indent) { block(ast, indent); if (indent > 0) WriteLine(""); } virtual public void bool_type(type ast, int indent) { Write("bool", indent); } virtual public void break_statement(break_statement ast, int indent) { Write("break", indent); Semicolon(indent); } virtual public void byte_type(type ast, int indent) { Write("byte", indent); } virtual public void cast_expression(cast_expression ast, int parent) { int myprec = prec("cast"); if (myprec <= parent) parenexpr(ast); else { Write("("); visit(ast.ty); Write(")"); visit(ast.expr, myprec); } } virtual public void catch_clause(catch_clause ast, int indent) { Write("catch (", indent); visit(ast.ty); if (ast.id != null) Write(" {0}", ast.id.str); Write(")"); statement(ast.block, indent + 1); } virtual public void catch_clauses(catch_clauses ast, int indent) { foreach (catch_clause c in ast.specifics) visit(c, indent); if (ast.general != null) { WriteLine("catch", indent); visit(ast.general, indent + 1); } } virtual public void char_type(type ast, int indent) { Write("char", indent); } virtual public void checked_expression(checked_expression ast, int parent) { Write("checked ("); visit(ast.expr, topprec); Write(")"); } virtual public void checked_statement(checked_statement ast, int indent) { Write("checked", indent); statement(ast.stmt, indent + 1); } virtual public void class_declaration(class_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("class {0}", ast.id.str); EmitTypeList(ast.typeparams); if (ast.bases.Count > 0) { Write(": "); visit(ast.bases[(0)]); for (int i = 1; i < ast.bases.Count; i++) { Write(", "); visit(ast.bases[(i)]); } } EmitTypeConstraints(ast.constraints, indent + 1); WriteLine(" {{"); foreach (declaration d in ast.body) visit(d, indent + 1); WriteLine("}}", indent); } protected void compilation(compilation ast, int indent) { foreach (compilation_unit x in ast.inputs) compilation_unit(x, indent); } virtual public void compilation_unit(compilation_unit ast, int indent) { foreach (using_directive u in ast.using_directives) visit(u, indent); EmitattributeSectionList(ast.attributes, indent); foreach (declaration d in ast.declarations) { WriteLine(""); visit(d, indent); } } virtual public void compound_assignment_expression(compound_assignment_expression ast, int parent) { int myprec = prec("="); if (myprec <= parent) parenexpr(ast); else { visit(ast.e1, myprec); Write(" {0} ", ast.op.str); visit(ast.e2, myprec); } } virtual public void cond_expression(cond_expression ast, int parent) { int myprec = prec("?:"); if (myprec <= parent) parenexpr(ast); else { visit(ast.cond, myprec); Write(" ? "); visit(ast.success, myprec); Write(" : "); visit(ast.failure, myprec); } } virtual public void const_declarator(const_declarator ast, int indent) { Write(" = "); visit(ast.expr); } virtual public void const_statement(const_statement ast, int indent) { Write("const ", indent); EmitdeclaratorList(ast.ty, ast.consts); Semicolon(indent); } virtual public void constant_declaration(constant_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("const "); EmitdeclaratorList(ast.ty, ast.decls); WriteLine(";"); } virtual public void constructor_constraint(constructor_constraint ast, int indent) { Write("new ()"); } virtual public void constructor_declaration(constructor_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("{0}", ast.decl.id.str); EmitParameters(ast.decl.f.fixeds, ast.decl.f.param); if (ast.decl.init != null) visit(ast.decl.init); if (ast.block != null) statement(ast.block, indent + 1); else WriteLine(";"); } virtual public void continue_statement(continue_statement ast, int indent) { Write("continue", indent); Semicolon(indent); } virtual public void decimal_type(type ast, int indent) { Write("decimal", indent); } virtual public void delegate_declaration(delegate_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("delegate "); visit(ast.ty); Write(" {0}", ast.id.str); EmitTypeList(ast.typeparams); EmitParameters(ast.f.fixeds, ast.f.param); EmitTypeConstraints(ast.constraints, indent + 1); WriteLine(";"); } virtual public void destructor_declaration(destructor_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write(" ~{0}()", ast.id.str); if (ast.block != null) { WriteLine(""); visit(ast.block, indent + 1); } else WriteLine(";"); } virtual public void do_statement(do_statement ast, int indent) { Write("do", indent); statement(ast.body, indent + 1, false); if (ast.body is block_statement) Write(" while ("); else Write("while (", indent); visit(ast.expr); Write(")"); Semicolon(indent); } virtual public void double_type(type ast, int indent) { Write("double", indent); } virtual public void element_access(element_access ast, int parent) { visit(ast.expr, topprec); EmitargumentList(ast.exprs, "[", "]"); } protected void EmitargumentList(argumentList args) { EmitargumentList(args, "(", ")"); } protected void EmitargumentList(argumentList args, string lparen, string rparen) { Write(lparen); for (int i = 0; i < args.Count; i++) { if (i > 0) Write(", "); if (args[i].kind != null) Write("{0} ", args[i].kind.str); visit(args[i].expr); } Write(rparen); } protected void EmitattributeSectionList(attribute_sectionList attrs, int indent) { foreach (attribute_section s in attrs) attribute_section(s, indent); } protected void EmitdeclaratorList(type ty, declaratorList decls) { visit(ty); Write(" "); for (int i = 0; i < decls.Count; i++) { if (i > 0) Write(", "); Write(decls[i].id.str); visit(decls[i]); } } protected void EmitexpressionList(expressionList exprs) { for (int i = 0; i < exprs.Count; i++) { if (i > 0) Write(", "); visit(exprs[i]); } } protected void EmitindexerParameters(parameterList fixeds, parameter param) { Write("this["); for (int i = 0; i < fixeds.Count; i++) { if (i > 0) Write(", "); visit(fixeds[i]); } if (param != null) { if (fixeds.Count > 0) Write(", "); visit(param); } Write("]"); } protected void EmitModifiers(InputElementList mods, int indent, string suffix) { Indent(indent); if (mods.Count > 0) { bool partial = false; int n = 0; foreach (InputElement e in mods) if (e.str == "partial") partial = true; else Write(n++ > 0 ? " {0}" : "{0}", e.str); if (partial) Write(n++ > 0 ? " partial" : "partial"); Write("{0}", suffix); } } protected void EmitParameters(parameterList fixeds, parameter param) { Write("("); for (int i = 0; i < fixeds.Count; i++) { if (i > 0) Write(", "); visit(fixeds[i]); } if (param != null) { if (fixeds.Count > 0) Write(", "); visit(param); } Write(")"); } protected void EmitTypeConstraints(IList constraints, int indent) { for (int i = 0; i < constraints.Count; i++) { WriteLine(""); Indent(indent); visit((AST)constraints[i]); } } protected void EmitTypeList(IList types) { if (types != null && types.Count > 0) { Write("<"); for (int i = 0; i < types.Count; i++) { if (i > 0) Write(", "); visit((AST)types[i]); } Write(">"); } } virtual public void empty_statement(empty_statement ast, int indent) { Semicolon(indent); } virtual public void enum_declaration(enum_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("enum {0} ", ast.id.str); if (ast.ty != null) { Write(": "); visit(ast.ty); } WriteLine(" {{"); foreach (enum_member_declaration d in ast.body) { EmitattributeSectionList(d.attrs, indent + 1); Write("{0}", indent + 1, d.id.str); if (d.expr != null) { Write("="); visit(d.expr); } WriteLine(","); } WriteLine("}};", indent); } virtual public void event_declaration1(event_declaration1 ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("event "); EmitdeclaratorList(ast.ty, ast.decls); WriteLine(";"); } virtual public void event_declaration2(event_declaration2 ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("event "); visit(ast.ty); Write(" "); visit(ast.name); WriteLine(" {{"); foreach (event_accessor a in ast.accessors) { EmitattributeSectionList(a.attrs, indent + 1); Write("{0}", indent + 1, a.id.str); statement(a.block, indent + 2); } WriteLine("}}", indent); } virtual public void event_declarator(event_declarator ast, int indent) { if (ast.init != null) { Write(" = "); visit(ast.init); } } virtual public void explicit_declarator(explicit_declarator ast, int indent) { Write("explicit operator ", indent); visit(ast.ty); Write("("); visit(ast.t1); Write(" {0})", ast.id1.str); } virtual public void expr_access(expr_access ast, int parent) { visit(ast.expr, topprec); Write(".{0}", ast.id.str); EmitTypeList(ast.typeargs); } virtual public void expr_initializer(expr_initializer ast, int indent) { visit(ast.expr); } virtual public void expression_statement(expression_statement ast, int indent) { Indent(indent); visit(ast.expr); Semicolon(indent); } virtual public void field_declaration(field_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); EmitdeclaratorList(ast.ty, ast.decls); WriteLine(";"); } virtual public void field_declarator(field_declarator ast, int indent) { if (ast.init != null) { Write(" = "); visit(ast.init); } } virtual public void fixed_declarator(fixed_declarator ast, int indent) { Write(" = ", indent); visit(ast.expr); } virtual public void fixed_parameter(fixed_parameter ast, int indent) { EmitattributeSectionList(ast.attrs, indent); if (ast.mod != null) { Write("{0} ", indent, ast.mod.str); visit(ast.ty); } else visit(ast.ty, indent); Write(" {0}", ast.id.str); } virtual public void fixed_statement(fixed_statement ast, int indent) { Write("fixed (", indent); EmitdeclaratorList(ast.ty, ast.declarators); Write(")"); statement(ast.body, indent + 1); } virtual public void float_type(type ast, int indent) { Write("float", indent); } virtual public void for_decl(for_decl ast, int indent) { EmitdeclaratorList(ast.decl.ty, ast.decl.vars); } virtual public void for_list(for_list ast, int indent) { EmitexpressionList(ast.exprs); } virtual public void for_statement(for_statement ast, int indent) { Write("for (", indent); if (ast.init != null) visit(ast.init); Write("; "); if (ast.cond != null) visit(ast.cond); Write("; "); EmitexpressionList(ast.iterators); Write(")"); statement(ast.body, indent + 1); } virtual public void foreach_statement(foreach_statement ast, int indent) { Write("foreach (", indent); visit(ast.ty); Write(" {0} in ", ast.id.str); visit(ast.expr); Write(")"); statement(ast.body, indent + 1); } virtual public void generic_interface_method_declaration(generic_interface_method_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" {0} ", ast.id.str); EmitTypeList(ast.typeparams); EmitParameters(ast.f.fixeds, ast.f.param); EmitTypeConstraints(ast.constraints, indent + 1); WriteLine(";"); } virtual public void generic_method_declaration(generic_method_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" "); visit(ast.name); EmitTypeList(ast.typeparams); EmitParameters(ast.parms.fixeds, ast.parms.param); EmitTypeConstraints(ast.constraints, indent + 1); if (ast.body != null) statement(ast.body, indent + 1); else WriteLine(";"); } virtual public void goto_case_statement(goto_case_statement ast, int indent) { Write("goto case ", indent); visit(ast.expr); Semicolon(indent); } virtual public void goto_default_statement(goto_default_statement ast, int indent) { Write("goto default", indent); Semicolon(indent); } virtual public void goto_statement(goto_statement ast, int indent) { Write("goto {0}", indent, ast.id.str); Semicolon(indent); } virtual public void if_statement(if_statement ast, int indent) { Indent(indent); ifstmt(ast, indent); } virtual public void ifstmt(if_statement ast, int indent) { Write("if ("); visit(ast.expr); Write(")"); if (ast.elsepart != null) { statement(ast.thenpart, indent + 1, false); if (ast.thenpart is block_statement) Write(" else"); else Write("else", indent); if (ast.elsepart is if_statement) { Write(" "); ifstmt((if_statement)ast.elsepart, indent); } else statement(ast.elsepart, indent + 1); } else statement(ast.thenpart, indent + 1); } virtual public void implicit_cast_expression(implicit_cast_expression ast, int parent) { visit(ast.expr, parent); } virtual public void implicit_declarator(implicit_declarator ast, int indent) { Write("implicit operator ", indent); visit(ast.ty); Write("("); visit(ast.t1); Write(" {0})", ast.id1.str); } protected void Indent(int n) { if (n > 0) wr.Write("{0}", "".PadRight(n, '\t')); } virtual public void indexer_declaration(indexer_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.i.ty); Write(" "); if (ast.i.interfacename != null) { visit(ast.i.interfacename); Write("."); } EmitindexerParameters(ast.i.f.fixeds, ast.i.f.param); WriteLine(" {{", indent); foreach (declaration d in ast.accessors) visit(d, indent + 1); WriteLine("}}", indent); } virtual public void int_type(type ast, int indent) { Write("int", indent); } virtual public void interface_declaration(interface_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("interface {0}", ast.id.str); EmitTypeList(ast.typeparams); if (ast.interfaces.Count > 0) { Write(": "); visit(ast.interfaces[0]); for (int i = 1; i < ast.interfaces.Count; i++) { Write(", "); visit(ast.interfaces[i]); } } EmitTypeConstraints(ast.constraints, indent + 1); WriteLine(" {{"); foreach (declaration d in ast.body) visit(d, indent + 1); WriteLine("}}", indent); } virtual public void interface_event_declaration(interface_event_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("event "); visit(ast.ty); WriteLine(" {0};", ast.id.str); } virtual public void interface_indexer_declaration(interface_indexer_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" "); EmitindexerParameters(ast.f.fixeds, ast.f.param); WriteLine(" {{"); foreach (accessor_declaration a in ast.accessors) visit(a, indent + 1); WriteLine("}}", indent); } virtual public void interface_method_declaration(interface_method_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" {0}", ast.id.str); EmitParameters(ast.f.fixeds, ast.f.param); WriteLine(";"); } virtual public void interface_property_declaration(interface_property_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" {0} {{", ast.id.str); foreach (accessor_declaration a in ast.accessors) visit(a, indent + 1); WriteLine("}}", indent); } virtual public void invocation_expression(invocation_expression ast, int parent) { visit(ast.expr, topprec); EmitargumentList(ast.args); } virtual public void is_expression(is_expression ast, int parent) { int myprec = prec("is"); if (myprec <= parent) parenexpr(ast, 0); else { visit(ast.expr, myprec); Write(" is "); visit(ast.ty); } } virtual public void labeled_statement(labeled_statement ast, int indent) { WriteLine("{0}:", ast.label.str); visit(ast.stmt, indent); } virtual public void literal(literal ast, int parent) { Write("{0}", ast.token.str); } virtual public void local_expression(local_expression ast, int indent) { visit(ast.expr); } virtual public void local_statement(local_statement ast, int indent) { Indent(indent); EmitdeclaratorList(ast.ty, ast.vars); Semicolon(indent); } virtual public void lock_statement(lock_statement ast, int indent) { Write("lock (", indent); visit(ast.expr); Write(")"); statement(ast.body, indent + 1); } virtual public void long_type(type ast, int indent) { Write("long", indent); } virtual public void member_name(member_name ast, int indent) { if (ast.ty != null) { visit(ast.ty, indent); Write(".{0}", ast.id.str); } else Write("{0}", indent, ast.id.str); } virtual public void method_declaration(method_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" "); visit(ast.name); EmitParameters(ast.parms.fixeds, ast.parms.param); if (ast.body != null) statement(ast.body, indent + 1); else WriteLine(";"); } virtual public void dotted_name(dotted_name ast, int indent) { if (ast.left != null) { visit(ast.left); Write("."); } Write("{0}", ast.right.str); EmitTypeList(ast.typeargs); } virtual public void name_type(name_type ast, int indent) { Indent(indent); visit(ast.name); } virtual public void namespace_declaration(namespace_declaration ast, int indent) { WriteLine("namespace {0} {{", indent, ast.id); foreach (using_directive ud in ast.nb.ud) visit(ud, indent + 1); foreach (declaration d in ast.nb.declarations) visit(d, indent + 1); WriteLine("}}", indent); } virtual public void namespace_directive(namespace_directive ast, int indent) { WriteLine("using {0};", indent, ast.name); } virtual public void new_expression(new_expression ast, int parent) { Write("new "); visit(ast.ty); EmitargumentList(ast.args); } virtual public void object_type(type ast, int indent) { Write("object", indent); } virtual public void operator_declaration(operator_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.op); if (ast.block != null) statement(ast.block, indent + 1); } virtual public void params_parameter(params_parameter ast, int indent) { EmitattributeSectionList(ast.attrs, indent); Write("params ", indent); visit(ast.ty); Write(" {0}", ast.id.str); } virtual public void parenexpr(expression ast) { parenexpr(ast, 0); } virtual public void parenexpr(expression ast, int parent) { Write("("); visit(ast, parent); Write(")"); } virtual public void pointer_access(pointer_access ast, int parent) { visit(ast.expr, topprec); Write("->{0}", ast.id.str); } virtual public void pointer_type(pointer_type ast, int indent) { visit(ast.ty, indent); Write("*"); } virtual public void post_expression(post_expression ast, int parent) { visit(ast.expr, topprec); Write("{0}", ast.op.str); } virtual public void pre_expression(pre_expression ast, int parent) { int myprec = prec(ast.op.str + "e"); if (myprec <= parent) parenexpr(ast); else { Write("{0}", ast.op.str); visit(ast.expr, myprec); } } public static int prec(string op) { switch (op) { case "=": return 1; case "?:": return 2; case "||": return 3; case "&&": return 4; case "|": return 5; case "^": return 6; case "&": return 7; case "==": case "!=": return 8; case "is": case "as": case ">=": case "<=": case "<": case ">": return 9; case ">>": case "<<": return 10; case "+": case "-": return 11; case "*": case "/": case "%": return 12; case "cast": return 13; case "--e": case "++e": return 14; case "-e": case "+e": case "*e": case "~e": case "!e": case "&e": return 15; default: Debug.Assert(false); return 0; } } public static int prec(InputElement op) { return prec(op.str); } virtual public void predefined_access(predefined_access ast, int indent) { Write("{0}.{1}", ast.predefined.str, ast.id.str); EmitTypeList(ast.typeargs); } virtual public void property_declaration(property_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); visit(ast.ty); Write(" "); visit(ast.name); WriteLine(" {{"); foreach (accessor_declaration d in ast.decls) visit(d, indent + 1); WriteLine("}}", indent); } virtual public void qualified_alias_member(qualified_alias_member ast, int indent) { Write("{0}::", indent, ast.qualifier.str); dotted_name(ast, 0); } virtual public void qualified_name(qualified_name ast, int indent) { Write("{0}::", indent, ast.qualifier.str); simple_name(ast, 0); } virtual public void resource_decl(resource_decl ast, int indent) { Indent(indent); EmitdeclaratorList(ast.local.ty, ast.local.vars); } virtual public void resource_expr(resource_expr ast, int indent) { visit(ast.expr, indent); } virtual public void return_statement(return_statement ast, int indent) { Write("return", indent); if (ast.expr != null) { Write(" "); visit(ast.expr); } Semicolon(indent); } virtual public void sbyte_type(type ast, int indent) { Write("sbyte", indent); } protected void Semicolon(int indent) { if (indent > 0) WriteLine(";"); else Write(";"); } virtual public void short_type(type ast, int indent) { Write("short", indent); } virtual public void simple_name(simple_name ast, int parent) { Write("{0}", ast.id.str); EmitTypeList(ast.typeargs); } virtual public void sizeof_expression(sizeof_expression ast, int parent) { Write("sizeof ("); visit(ast.ty); Write(")"); } virtual public void stackalloc_initializer(stackalloc_initializer ast, int indent) { Write("stackalloc ", indent); visit(ast.ty); Write("["); visit(ast.expr); Write("]"); } virtual public void statement(statement ast, int indent) { statement(ast, indent, true); } virtual public void statement(statement ast, int indent, bool newline) { if (ast is block_statement) { Write(" "); block((block_statement)ast, indent); if (newline) WriteLine(""); } else { WriteLine(""); visit(ast, indent); } } virtual public void string_type(type ast, int indent) { Write("string", indent); } virtual public void struct_declaration(struct_declaration ast, int indent) { EmitattributeSectionList(ast.attrs, indent); EmitModifiers(ast.mods, indent, " "); Write("struct {0}", ast.id.str); EmitTypeList(ast.typeparams); if (ast.interfaces.Count > 0) { Write(": "); visit(ast.interfaces[0]); for (int i = 1; i < ast.interfaces.Count; i++) { Write(", "); visit(ast.interfaces[i]); } } EmitTypeConstraints(ast.constraints, indent + 1); WriteLine(" {{"); foreach (declaration d in ast.body) visit(d, indent + 1); WriteLine("}}", indent); } virtual public void switch_default(switch_default ast, int indent) { Write("default:", indent); } virtual public void switch_expression(switch_expression ast, int indent) { Write("case ", indent); visit(ast.expr); Write(":"); } virtual public void switch_label(switch_label ast, int indent) { visit(ast, indent); WriteLine(""); } virtual public void switch_statement(switch_statement ast, int indent) { Write("switch (", indent); visit(ast.expr); WriteLine(") {{"); foreach (switch_section s in ast.sections) { foreach (switch_label l in s.labels) switch_label(l, indent); foreach (statement st in s.stmts) visit(st, indent + 1); } WriteLine("}}", indent); } virtual public void this_access(this_access ast, int parent) { Write("this"); } virtual public void this_initializer(this_initializer ast, int indent) { Write(" : this"); EmitargumentList(ast.args); } virtual public void throw_statement(throw_statement ast, int indent) { Write("throw", indent); if (ast.expr != null) { Write(" "); visit(ast.expr); } Semicolon(indent); } virtual public void try_statement(try_statement ast, int indent) { Write("try", indent); statement(ast.block, indent + 1); if (ast.catches != null) visit(ast.catches, indent); if (ast.finally_block != null) { Write("finally", indent); statement(ast.finally_block.block, indent + 1); } } virtual public void type_parameter(type_parameter ast, int indent) { EmitattributeSectionList(ast.attrs, indent); Write("{0}", ast.id.str); } virtual public void type_parameter_constraints_clause(type_parameter_constraints_clause ast, int indent) { Write("where {0}: ", ast.id.str); for (int i = 0; i < ast.constraints.Count; i++) { if (i > 0) Write(", "); visit(ast.constraints[i]); } } virtual public void typeof_expression(typeof_expression ast, int parent) { Write("typeof ("); visit(ast.ty); Write(")"); } virtual public void uint_type(type ast, int indent) { Write("uint", indent); } virtual public void ulong_type(type ast, int indent) { Write("ulong", indent); } virtual public void unary_declarator(unary_declarator ast, int indent) { visit(ast.ty, indent); Write(" operator {0}(", ast.op.str); visit(ast.t1); Write(" {0})", ast.id1.str); } virtual public void unary_expression(unary_expression ast, int parent) { int myprec = prec(ast.op.str + "e"); if (myprec <= parent) parenexpr(ast); else { Write("{0}", ast.op.str); visit(ast.expr, myprec); } } virtual public void unchecked_expression(unchecked_expression ast, int parent) { Write("unchecked ("); visit(ast.expr, topprec); Write(")"); } virtual public void unchecked_statement(unchecked_statement ast, int indent) { Write("unchecked", indent); statement(ast.stmt, indent + 1); } virtual public void unsafe_statement(unsafe_statement ast, int indent) { Write("unsafe", indent); statement(ast.block, indent + 1); } virtual public void ushort_type(type ast, int indent) { Write("ushort", indent); } virtual public void using_statement(using_statement ast, int indent) { Write("using (", indent); visit(ast.r); Write(")"); statement(ast.body, indent + 1); } virtual public void var_declarator(var_declarator ast, int indent) { if (ast.init != null) { Write(" = "); visit(ast.init); } } virtual public void visit(AST ast) { visit(ast, 0); } virtual public void visit(AST ast, int indent) { const BindingFlags bindingFlags = BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic; System.Type t = ast.GetType(); Debug.Assert(t.IsClass); MethodInfo m; do { m = this.GetType().GetMethod(t.Name, bindingFlags); if (m != null) break; t = t.BaseType; } while (t != null); if (m != null) m.Invoke(this, new object[] { ast, indent }); else if (indent == 0) Write("<{0}>", ast.GetType().Name); else WriteLine("<{0}>", indent, ast.GetType().Name); } virtual public void void_pointer_type(void_pointer_type ast, int indent) { Write("void*", indent); } virtual public void void_type(type ast, int indent) { Write("void", indent); } virtual public void while_statement(while_statement ast, int indent) { Write("while (", indent); visit(ast.expr); Write(")"); statement(ast.body, indent + 1); } protected void Write(string fmt, int indent, params object[] args) { Indent(indent); wr.Write(fmt, args); } protected void Write(string fmt, params object[] args) { wr.Write(fmt, args); } protected void WriteLine(string fmt, int indent, params object[] args) { Indent(indent); wr.WriteLine(fmt, args); } protected void WriteLine(string fmt, params object[] args) { wr.WriteLine(fmt, args); } virtual public void yield_return_statement(yield_return_statement ast, int indent) { Write("yield return ", indent); visit(ast.expr); Semicolon(indent); } virtual public void yield_break_statement(yield_break_statement ast, int indent) { Write("yield break", indent); Semicolon(indent); } }