using System; using System.Collections; using System.CodeDom; public class AST2CodeDom2 { private class Unsupported : Exception { public Unsupported(string s) : base(s) { } } public static compilation visit(compilation ast, System.IO.TextWriter w, string[] args, MessageWriter msg) { if (msg.Count > 0) return ast; System.CodeDom.Compiler.CodeDomProvider cdp = new Microsoft.CSharp.CSharpCodeProvider(); System.CodeDom.Compiler.ICodeGenerator icg = cdp.CreateGenerator(); System.CodeDom.Compiler.CodeGeneratorOptions cgo = new System.CodeDom.Compiler.CodeGeneratorOptions(); foreach (compilation_unit cu in ast.inputs) { CodeCompileUnit cd = emit_compilation_unit(cu); icg.GenerateCodeFromCompileUnit(cd, System.Console.Out, cgo); } return ast; } public static CodeCompileUnit Compile(compilation_unit cu) { return emit_compilation_unit(cu); } private static CodeTypeReference emit_name_type(name_type p) { string t0 = dotted2string(p.name); CodeTypeReference c = new CodeTypeReference(t0); c.UserData["AST"] = p; return c; } // emit_name_type private static CodeExpression emit_simple_name_expr(simple_name p) { return (CodeExpression) emit_simple_name(p); } private static bool isInsideAccessor(AST p) { for (AST a = p; a != null; a = a.parent) { if (a is accessor_declaration) { accessor_declaration ad = (accessor_declaration) a; if (ad.id.str == "set") { return true; } } } return false; } private static CodeObject emit_simple_name(simple_name p) { CodeObject o = null; CodeThisReferenceExpression self = null; if (p.sym.IsInstance) { self = new CodeThisReferenceExpression(); self.UserData["AST"] = p; } if (p.sym is MethodSuite) { if (p.sym.IsInstance) { CodeMethodReferenceExpression mr = new CodeMethodReferenceExpression(); mr.UserData["AST"] = p; mr.MethodName = p.id.str; mr.TargetObject = self; o = mr; } else { throw new Unsupported("unhandled sym type"); } } else if (p.sym is Formal) { if (p.id.str == "value" && isInsideAccessor(p)) { CodePropertySetValueReferenceExpression psvre = new CodePropertySetValueReferenceExpression(); psvre.UserData["AST"] = p; return psvre; } CodeArgumentReferenceExpression ar = new CodeArgumentReferenceExpression(); ar.UserData["AST"] = p; ar.ParameterName = p.id.str; o = ar; } else if (p.sym is Local) { CodeVariableReferenceExpression lr = new CodeVariableReferenceExpression(); lr.UserData["AST"] = p; lr.VariableName = p.id.str; o = lr; } else if (p.sym is Field) { if (p.sym.IsInstance) { CodeFieldReferenceExpression fr = new CodeFieldReferenceExpression(); fr.UserData["AST"] = p; fr.FieldName = p.id.str; fr.TargetObject = self; o = fr; } else { throw new Unsupported("unhandled sym type"); } } else if (p.sym is Property) { if (p.sym.IsInstance) { CodePropertyReferenceExpression pr = new CodePropertyReferenceExpression(); pr.UserData["AST"] = p; pr.PropertyName = p.id.str; pr.TargetObject = self; o = pr; } else { throw new Unsupported("unhandled sym type"); } } else if (p.sym is Event) { if (p.sym.IsInstance) { CodeEventReferenceExpression er = new CodeEventReferenceExpression(); er.UserData["AST"] = p; er.EventName = p.id.str; er.TargetObject = self; o = er; } else { throw new Unsupported("unhandled sym type"); } } else { throw new Unsupported("unhandled sym type: " + p.sym.ToString()); } return o; } // emit_simple_name private static CodeStatement emit_expression_statement(expression_statement p) { if (p.expr is assignment_expression) { return emit_assignment_statement((assignment_expression)p.expr); } if (p.expr is compound_assignment_expression) { return emit_compound_assignment_statement((compound_assignment_expression)p.expr); } CodeExpressionStatement es = new CodeExpressionStatement(); es.UserData["AST"] = es; CodeExpression t0 = emit_expression(p.expr); es.Expression = t0; return es; } // emit_expression_statement private static string get_member_name(member_name p) { string name = p.id.str; if (p.ty != null) { // WARNING: unimplemented interface names: member_name.ty } return name; } // get_member_name private static CodeCompileUnit emit_compilation(compilation p) { // WARNING: need to fix this foreach (compilation_unit x in p.inputs) { return emit_compilation_unit(x); } return null; } private static CodeAttributeDeclarationCollection emit_attribute_sections(attribute_sectionList attrs) { CodeAttributeDeclarationCollection adc = new CodeAttributeDeclarationCollection(); foreach (attribute_section attr_section in attrs) { emit_attribute_section(attr_section, adc); } return adc; } private static void emit_attribute_section(attribute_section p, CodeAttributeDeclarationCollection cadc) { foreach (attribute attr in p.attributes) { CodeAttributeDeclaration ad = emit_attribute(attr); cadc.Add(ad); } } private static CodeCompileUnit emit_compilation_unit(compilation_unit p) { CodeCompileUnit cu = new CodeCompileUnit(); try { emit_compilation_unit0(p, cu); } catch (Unsupported u) { cu.Namespaces[0].Comments.Add(new CodeCommentStatement("CodeDom Error: " + u.Message)); } return cu; } private static CodeCompileUnit emit_compilation_unit0(compilation_unit p, CodeCompileUnit cu) { CodeNamespace globals = new CodeNamespace(); globals.UserData["AST"] = p; cu.Namespaces.Add(globals); cu.UserData["AST"] = p; foreach (using_directive k in p.using_directives) { CodeNamespaceImport s = emit_using_directive(k); globals.Imports.Add(s); } cu.AssemblyCustomAttributes.AddRange(emit_attribute_sections(p.attributes)); foreach (declaration k in p.declarations) { if (k is namespace_declaration) { CodeNamespace ns = emit_namespace_declaration((namespace_declaration) k); cu.Namespaces.Add(ns); } else { CodeTypeDeclaration td = (CodeTypeDeclaration) emit_declaration(k); globals.Types.Add(td); } } return cu; } // emit_compilation_unit private static string dotted2string(dotted_name p) { return ((p.left != null) ? dotted2string(p.left) + "." : "") + p.right.str; } // dotted2string private static CodeTypeReference emit_type(type p) { if (p is name_type) return emit_name_type((name_type) p); if (p is bool_type) return emit_bool_type((bool_type) p); if (p is decimal_type) return emit_decimal_type((decimal_type) p); if (p is sbyte_type) return emit_sbyte_type((sbyte_type) p); if (p is byte_type) return emit_byte_type((byte_type) p); if (p is short_type) return emit_short_type((short_type) p); if (p is ushort_type) return emit_ushort_type((ushort_type) p); if (p is int_type) return emit_int_type((int_type) p); if (p is uint_type) return emit_uint_type((uint_type) p); if (p is long_type) return emit_long_type((long_type) p); if (p is ulong_type) return emit_ulong_type((ulong_type) p); if (p is char_type) return emit_char_type((char_type) p); if (p is float_type) return emit_float_type((float_type) p); if (p is double_type) return emit_double_type((double_type) p); if (p is object_type) return emit_object_type((object_type) p); if (p is string_type) return emit_string_type((string_type) p); if (p is array_type) return emit_array_type((array_type) p); if (p is void_type) return emit_void_type((void_type) p); if (p is pointer_type) return emit_pointer_type((pointer_type) p); if (p is void_pointer_type) return emit_void_pointer_type((void_pointer_type) p); throw new Unsupported(p.ToString()); } // emit_type private static CodeTypeReference emit_bool_type(bool_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(bool)); tr.UserData["AST"] = p; return tr; } // emit_bool_type private static CodeTypeReference emit_decimal_type(decimal_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(decimal)); tr.UserData["AST"] = p; return tr; } // emit_decimal_type private static CodeTypeReference emit_sbyte_type(sbyte_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(sbyte)); tr.UserData["AST"] = p; return tr; } // emit_sbyte_type private static CodeTypeReference emit_byte_type(byte_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(byte)); tr.UserData["AST"] = p; return tr; } // emit_byte_type private static CodeTypeReference emit_short_type(short_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(short)); tr.UserData["AST"] = p; return tr; } // emit_short_type private static CodeTypeReference emit_ushort_type(ushort_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(ushort)); tr.UserData["AST"] = p; return tr; } // emit_ushort_type private static CodeTypeReference emit_int_type(int_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(int)); tr.UserData["AST"] = p; return tr; } // emit_int_type private static CodeTypeReference emit_uint_type(uint_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(uint)); tr.UserData["AST"] = p; return tr; } // emit_uint_type private static CodeTypeReference emit_long_type(long_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(long)); tr.UserData["AST"] = p; return tr; } // emit_long_type private static CodeTypeReference emit_ulong_type(ulong_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(ulong)); tr.UserData["AST"] = p; return tr; } // emit_ulong_type private static CodeTypeReference emit_char_type(char_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(char)); tr.UserData["AST"] = p; return tr; } // emit_char_type private static CodeTypeReference emit_float_type(float_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(float)); tr.UserData["AST"] = p; return tr; } // emit_float_type private static CodeTypeReference emit_double_type(double_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(double)); tr.UserData["AST"] = p; return tr; } // emit_double_type private static CodeTypeReference emit_object_type(object_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(object)); tr.UserData["AST"] = p; return tr; } // emit_object_type private static CodeTypeReference emit_string_type(string_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(string)); tr.UserData["AST"] = p; return tr; } // emit_string_type private static CodeTypeReference emit_array_type(array_type p) { CodeTypeReference t0 = emit_type(p.ty); CodeTypeReference tr = new CodeTypeReference(t0, p.rank_specifier); tr.UserData["AST"] = p; return tr; } // emit_array_type private static CodeExpression emit_argument(argument p) { CodeExpression e = emit_expression(p.expr); if (p.kind != null) { switch (p.kind.tag) { case "ref": e = new CodeDirectionExpression(FieldDirection.Ref, e); e.UserData["AST"] = p; break; case "out": e = new CodeDirectionExpression(FieldDirection.Out, e); e.UserData["AST"] = p; break; default: throw new Unsupported("CodeDOM does not support: " + p.kind.tag); } } return e; } // emit_argument private static CodeExpression emit_expression(expression p) { if (p is simple_name) return emit_simple_name_expr((simple_name) p); if (p is literal) return emit_literal((literal) p); if (p is member_access) return emit_member_access((member_access) p); if (p is invocation_expression) return emit_invocation_expression((invocation_expression) p); if (p is element_access) return emit_element_access((element_access) p); if (p is this_access) return emit_this_access((this_access) p); if (p is base_access) return emit_base_access((base_access) p); if (p is post_expression) return emit_post_expression((post_expression) p); if (p is new_expression) return emit_new_expression((new_expression) p); if (p is array_creation_expression1) return emit_array_creation_expression1((array_creation_expression1) p); if (p is array_creation_expression2) return emit_array_creation_expression2((array_creation_expression2) p); if (p is typeof_expression) return emit_typeof_expression((typeof_expression) p); if (p is checked_expression) return emit_checked_expression((checked_expression) p); if (p is unchecked_expression) return emit_unchecked_expression((unchecked_expression) p); if (p is unary_expression) return emit_unary_expression((unary_expression) p); if (p is pre_expression) return emit_pre_expression((pre_expression) p); if (p is cast_expression) return emit_cast_expression((cast_expression) p); if (p is binary_expression) return emit_binary_expression((binary_expression) p); if (p is is_expression) return emit_is_expression((is_expression) p); if (p is as_expression) return emit_as_expression((as_expression) p); if (p is cond_expression) return emit_cond_expression((cond_expression) p); if (p is assignment_expression) return emit_assignment_expression((assignment_expression) p); if (p is compound_assignment_expression) return emit_compound_assignment_expression((compound_assignment_expression) p); if (p is sizeof_expression) return emit_sizeof_expression((sizeof_expression) p); if (p is implicit_cast_expression) return emit_implicit_cast_expression((implicit_cast_expression) p); throw new Unsupported(p.ToString()); } // emit_expression private static CodeExpression emit_literal(literal p) { if (p is integer_literal) return emit_integer_literal((integer_literal) p); if (p is real_literal) return emit_real_literal((real_literal) p); if (p is character_literal) return emit_character_literal((character_literal) p); if (p is string_literal) return emit_string_literal((string_literal) p); if (p is boolean_literal) return emit_boolean_literal((boolean_literal) p); if (p is null_literal) return emit_null_literal((null_literal) p); throw new Unsupported(p.ToString()); } // emit_literal private static CodePrimitiveExpression emit_integer_literal(integer_literal p) { CodePrimitiveExpression pe = new CodePrimitiveExpression(p.value); pe.UserData["AST"] = p; return pe; } // emit_integer_literal private static CodePrimitiveExpression emit_real_literal(real_literal p) { CodePrimitiveExpression pe = new CodePrimitiveExpression(p.value); pe.UserData["AST"] = p; return pe; } // emit_real_literal private static CodePrimitiveExpression emit_character_literal(character_literal p) { CodePrimitiveExpression pe = new CodePrimitiveExpression(p.value); pe.UserData["AST"] = p; return pe; } // emit_character_literal private static CodePrimitiveExpression emit_string_literal(string_literal p) { CodePrimitiveExpression pe = new CodePrimitiveExpression(p.value); pe.UserData["AST"] = p; return pe; } // emit_string_literal private static CodePrimitiveExpression emit_boolean_literal(boolean_literal p) { CodePrimitiveExpression pe = new CodePrimitiveExpression(p.value); pe.UserData["AST"] = p; return pe; } // emit_boolean_literal private static CodePrimitiveExpression emit_null_literal(null_literal p) { CodePrimitiveExpression pe = new CodePrimitiveExpression(p.value); pe.UserData["AST"] = p; return pe; } // emit_null_literal private static CodeExpression emit_member_access(member_access p) { if (p is expr_access) return emit_expr_access((expr_access) p); if (p is pointer_access) return emit_pointer_access((pointer_access) p); if (p is predefined_access) return emit_predefined_access((predefined_access) p); throw new Unsupported(p.ToString()); } // emit_member_access private static CodeExpression emit_expr_access(expr_access p) { CodeExpression e; // //string ns = null; //Type lhsType = null; //if (p.expr is simple_name) { // simple_name s = (simple_name) p.expr; // if (s.sym is NameSpace) { // NameSpace n = (NameSpace) s.sym; // ns = n.FullName; // } else if (s.sym is Type) { // lhsType = (Type) s.sym; // } //} else if (p.expr is expr_access) { // expr_access ea = (expr_access) p.expr; // if (ea.sym is NameSpace) { // NameSpace n = (NameSpace) ea.sym; // ns = n.FullName; // } else if (ea.sym is Type) { // lhsType = (Type) ea.sym; // } //} // CodeExpression t0 = emit_expression(p.expr); string id = p.id.str; if (p.sym is ClassType) { throw new Unsupported("unhandled ClassType in expr access"); } else if (p.sym is MethodSuite) { e = t0; } else if (p.sym is Field) { CodeFieldReferenceExpression fre = new CodeFieldReferenceExpression(); fre.UserData["AST"] = p; fre.FieldName = id; fre.TargetObject = t0; e = fre; } else if (p.sym is Property) { CodePropertyReferenceExpression pre = new CodePropertyReferenceExpression(); pre.UserData["AST"] = p; pre.PropertyName = id; pre.TargetObject = t0; e = pre; } else { throw new Unsupported("unhandled sym type in expr_access"); } return e; } // emit_expr_access private static CodeExpression emit_pointer_access(pointer_access p) { throw new Unsupported("pointer access not handled"); } // emit_pointer_access private static CodeExpression emit_predefined_access(predefined_access p) { throw new Unsupported("predefined access not handled"); } // emit_predefined_access private static CodeExpression emit_invocation_expression(invocation_expression p) { CodeExpression e = null; if (p.method != null) { CodeExpression target = null; if (p.method.IsInstance) { target = emit_expression(p.expr); } CodeExpressionCollection ec; if (p.expr.typ is DelegateType) { CodeDelegateInvokeExpression die = new CodeDelegateInvokeExpression(); die.UserData["AST"] = p; die.TargetObject = target; ec = die.Parameters; e = die; } else { CodeMethodReferenceExpression mre = new CodeMethodReferenceExpression(); mre.UserData["AST"] = p; mre.TargetObject = target; mre.MethodName = p.method.id.str; CodeMethodInvokeExpression mie = new CodeMethodInvokeExpression(); mie.UserData["AST"] = p; mie.Method = mre; ec = mie.Parameters; e = mie; } emit_argumentList(p.args, ec); } return e; } // emit_invocation_expression private static CodeExpression emit_element_access(element_access p) { CodeExpression t0 = emit_expression(p.expr); if (p.expr.typ is ArrayType) { CodeArrayIndexerExpression aie = new CodeArrayIndexerExpression(); aie.UserData["AST"] = p; aie.TargetObject = t0; emit_argumentList(p.exprs, aie.Indices); return aie; } else { CodeIndexerExpression aie = new CodeIndexerExpression(); aie.UserData["AST"] = p; aie.TargetObject = t0; emit_argumentList(p.exprs, aie.Indices); return aie; } } // emit_element_access private static void emit_argumentList(argumentList aList, CodeExpressionCollection ec) { foreach (argument k in aList) { CodeExpression s = emit_argument(k); ec.Add(s); } } private static CodeThisReferenceExpression emit_this_access(this_access p) { CodeThisReferenceExpression tre = new CodeThisReferenceExpression(); tre.UserData["AST"] = p; return tre; } // emit_this_access private static CodeBaseReferenceExpression emit_base_access(base_access p) { CodeBaseReferenceExpression bre = new CodeBaseReferenceExpression(); bre.UserData["AST"] = p; return bre; } // emit_base_access private static CodeExpression emit_post_expression(post_expression p) { throw new Unsupported("post expression not handled"); } // emit_post_expression private static CodeExpression emit_new_expression(new_expression p) { CodeTypeReference t0 = emit_type(p.ty); CodeExpression e; if (p.typ is DelegateType) { CodeDelegateCreateExpression dce = new CodeDelegateCreateExpression(); dce.UserData["AST"] = p; dce.DelegateType = t0; argument a = p.args[0]; if (a.expr is expr_access) { expr_access ea = (expr_access) a.expr; CodeExpression o = emit_expression(ea.expr); dce.TargetObject = o; dce.MethodName = ea.id.str; e = dce; } else { throw new Unsupported("unknown expr in new_expression: " + a.expr.ToString()); } } else if (p.typ is ClassType || p.typ is StructType) { CodeObjectCreateExpression oce = new CodeObjectCreateExpression(); oce.UserData["AST"] = p; oce.CreateType = t0; emit_argumentList(p.args, oce.Parameters); e = oce; } else { throw new Unsupported("unknown type in new_expression: " + p.typ.ToString()); } return e; } // emit_new_expression private static CodeExpression emit_array_creation_expression1(array_creation_expression1 p) { if (p.exprs.Count > 1) { throw new Unsupported("cannot handle multi-dimension arrays"); } if (p.ranks.Count > 0) { throw new Unsupported("cannot handle high-rank arrays"); } CodeArrayCreateExpression ace = new CodeArrayCreateExpression(); ace.UserData["AST"] = p; CodeTypeReference t0 = emit_type(p.ty); ace.CreateType = t0; if (p.init != null) { emit_array_initializer(p.init, ace.Initializers); } else { CodeExpression expr = emit_expression(p.exprs[0]); ace.SizeExpression = expr; } return ace; } // emit_array_creation_expression1 private static CodeArrayCreateExpression emit_array_creation_expression2(array_creation_expression2 p) { CodeArrayCreateExpression ace = new CodeArrayCreateExpression(); ace.UserData["AST"] = p; CodeTypeReference t0 = emit_type(p.ty); ace.CreateType = t0; emit_array_initializer(p.init, ace.Initializers); return ace; } // emit_array_creation_expression2 private static CodeExpression emit_typeof_expression(typeof_expression p) { CodeTypeOfExpression toe = new CodeTypeOfExpression(); toe.UserData["AST"] = p; CodeTypeReference t0 = emit_type(p.ty); toe.Type = t0; return toe; } // emit_typeof_expression private static CodeExpression emit_checked_expression(checked_expression p) { throw new Unsupported("unhandled checked expression"); } // emit_checked_expression private static CodeExpression emit_unchecked_expression(unchecked_expression p) { throw new Unsupported("unhandled unchecked expression"); } // emit_unchecked_expression private static CodeExpression emit_unary_expression(unary_expression p) { throw new Unsupported("unhandled unary expression"); } // emit_unary_expression private static CodeExpression emit_pre_expression(pre_expression p) { throw new Unsupported("unhandled prefix expression"); } // emit_pre_expression private static CodeCastExpression emit_cast_expression(cast_expression p) { CodeCastExpression ce = new CodeCastExpression(); ce.UserData["AST"] = p; CodeTypeReference t0 = emit_type(p.ty); ce.TargetType = t0; CodeExpression t1 = emit_expression(p.expr); ce.Expression = t1; return ce; } // emit_cast_expression private static CodeExpression emit_implicit_cast_expression(implicit_cast_expression p) { throw new Unsupported("unhandled implicit cast expression"); } private static CodeExpression emit_binary_expression(binary_expression p) { CodeBinaryOperatorExpression boe = new CodeBinaryOperatorExpression(); boe.UserData["AST"] = p; CodeExpression t0 = emit_expression(p.e1); boe.Left = t0; CodeBinaryOperatorType op; switch (p.op.tag) { case "+": op = CodeBinaryOperatorType.Add; break; case "=": op = CodeBinaryOperatorType.Assign; break; case "&": op = CodeBinaryOperatorType.BitwiseAnd; break; case "|": op = CodeBinaryOperatorType.BitwiseOr; break; case "&&": op = CodeBinaryOperatorType.BooleanAnd; break; case "||": op = CodeBinaryOperatorType.BooleanOr; break; case "/": op = CodeBinaryOperatorType.Divide; break; case ">": op = CodeBinaryOperatorType.GreaterThan; break; case ">=": op = CodeBinaryOperatorType.GreaterThanOrEqual; break; case "==": op = CodeBinaryOperatorType.IdentityEquality; break; case "!=": op = CodeBinaryOperatorType.IdentityInequality; break; case "<": op = CodeBinaryOperatorType.LessThan; break; case "<=": op = CodeBinaryOperatorType.LessThanOrEqual; break; case "%": op = CodeBinaryOperatorType.Modulus; break; case "*": op = CodeBinaryOperatorType.Multiply; break; case "-": op = CodeBinaryOperatorType.Subtract; break; default: throw new Unsupported("unhandled binary operator " + p.op.str); } boe.Operator = op; if (p.op.tag == "==") { // WARNING: Could be CodeBinaryOperatorType.ValueEquality } CodeExpression t2 = emit_expression(p.e2); boe.Right = t2; return boe; } // emit_binary_expression private static CodeExpression emit_is_expression(is_expression p) { throw new Unsupported("unhandled 'is' expression"); } // emit_is_expression private static CodeExpression emit_as_expression(as_expression p) { throw new Unsupported("unhandled 'as' expression"); } // emit_as_expression private static CodeExpression emit_cond_expression(cond_expression p) { throw new Unsupported("unhandled cond expression"); } // emit_cond_expression private static CodeExpression emit_compound_assignment_expression(compound_assignment_expression p) { throw new Unsupported("unhandled compound_assignment as expression"); } private static CodeStatement emit_compound_assignment_statement(compound_assignment_expression p) { if (!(p.typ is DelegateType)) { throw new Unsupported("unhandled compound assignment expression " + p.op.str); } CodeEventReferenceExpression eventRef = (CodeEventReferenceExpression) emit_expression(p.e1); eventRef.UserData["AST"] = p; CodeExpression listener = emit_expression(p.e2); if (p.op.str[0] == '+') { CodeAttachEventStatement aes = new CodeAttachEventStatement(eventRef, listener); aes.UserData["AST"] = p; return aes; } else if (p.op.str[0] == '-') { CodeRemoveEventStatement res = new CodeRemoveEventStatement(eventRef, listener); res.UserData["AST"] = p; return res; } else { throw new Unsupported("unknown op: " + p.op.str); } } // emit_compound_assignment_expression private static CodeExpression emit_assignment_expression(assignment_expression p) { throw new Unsupported("unhandled: assignments as expressions"); } private static CodeStatement emit_assignment_statement(assignment_expression p) { CodeAssignStatement a = new CodeAssignStatement(); a.UserData["AST"] = p; CodeExpression t0 = emit_expression(p.e1); a.Left = t0; CodeExpression t2 = emit_expression(p.e2); a.Right = t2; return a; } // emit_assignment_expression private static void emit_statement(statement p, CodeStatementCollection sc) { sc.Add(emit_statement(p)); } private static CodeStatement emit_statement(statement p) { try { return emit_statement0(p); } catch (Unsupported u) { CodeStatement s = new CodeCommentStatement("CodeDom Error: " + u.Message); s.UserData["AST"] = p; return s; } } private static CodeStatement emit_statement0(statement p) { if (p is expression_statement) return emit_expression_statement((expression_statement) p); if (p is block_statement) return emit_block_statement((block_statement) p); if (p is empty_statement) return emit_empty_statement((empty_statement) p); if (p is labeled_statement) return emit_labeled_statement((labeled_statement) p); if (p is local_statement) return emit_local_statement((local_statement) p); if (p is const_statement) return emit_const_statement((const_statement) p); if (p is if_statement) return emit_if_statement((if_statement) p); if (p is switch_statement) return emit_switch_statement((switch_statement) p); if (p is while_statement) return emit_while_statement((while_statement) p); if (p is do_statement) return emit_do_statement((do_statement) p); if (p is for_statement) return emit_for_statement((for_statement) p); if (p is foreach_statement) return emit_foreach_statement((foreach_statement) p); if (p is break_statement) return emit_break_statement((break_statement) p); if (p is continue_statement) return emit_continue_statement((continue_statement) p); if (p is goto_default_statement) return emit_goto_default_statement((goto_default_statement) p); if (p is goto_statement) return emit_goto_statement((goto_statement) p); if (p is goto_case_statement) return emit_goto_case_statement((goto_case_statement) p); if (p is return_statement) return emit_return_statement((return_statement) p); if (p is throw_statement) return emit_throw_statement((throw_statement) p); if (p is try_statement) return emit_try_statement((try_statement) p); if (p is checked_statement) return emit_checked_statement((checked_statement) p); if (p is unchecked_statement) return emit_unchecked_statement((unchecked_statement) p); if (p is lock_statement) return emit_lock_statement((lock_statement) p); if (p is using_statement) return emit_using_statement((using_statement) p); if (p is fixed_statement) return emit_fixed_statement((fixed_statement) p); throw new Unsupported(p.ToString()); } // emit_statement private static CodeStatement emit_block_statement(block_statement p) { throw new Unsupported("unhandled block statement"); } // emit_block_statement private static void emit_block_statement(block_statement p, CodeStatementCollection sc) { foreach (statement k in p.stmts) { emit_statement(k, sc); } } // emit_block_statement private static CodeStatement emit_empty_statement(empty_statement p) { CodeCommentStatement cs = new CodeCommentStatement("empty statement"); cs.UserData["AST"] = p; return cs; } // emit_empty_statement private static CodeLabeledStatement emit_labeled_statement(labeled_statement p) { CodeLabeledStatement ls = new CodeLabeledStatement(); ls.UserData["AST"] = p; ls.Label = p.label.str; CodeStatement t1 = emit_statement0(p.stmt); ls.Statement = t1; return ls; } // emit_labeled_statement private static CodeStatement emit_local_statement(local_statement p) { if (p.vars.Count > 1) { throw new Unsupported("cannot handle multiple declarations"); } CodeTypeReference t2 = emit_type(p.ty); var_declarator k = (var_declarator)p.vars[0]; CodeVariableDeclarationStatement vds = new CodeVariableDeclarationStatement(); vds.UserData["AST"] = p; vds.Type = t2; vds.Name = k.id.str; if (k.init != null) { CodeExpression t4 = emit_variable_initializer(k.init); vds.InitExpression = t4; } return vds; } // emit_local_statement private static CodeStatement emit_var_decl(var_declarator p) { throw new Unsupported("unhandled var_declarator"); } // emit_var_decl private static CodeStatement emit_const_statement(const_statement p) { throw new Unsupported("unhandled const_statement"); } // emit_const_statement private static CodeStatement emit_const_decl(const_declarator p) { throw new Unsupported("unhandled const_declarator expression"); } // emit_const_decl private static CodeConditionStatement emit_if_statement(if_statement p) { CodeConditionStatement cs = new CodeConditionStatement(); cs.UserData["AST"] = p; CodeExpression t0 = emit_expression(p.expr); cs.Condition = t0; emit_statement(p.thenpart, cs.TrueStatements); if (p.elsepart != null) { emit_statement(p.elsepart, cs.FalseStatements); } return cs; } // emit_if_statement private static CodeStatement emit_switch_statement(switch_statement p) { throw new Unsupported("unhandled switch statement"); } // emit_switch_statement private static CodeStatement emit_switch_section(switch_section p) { throw new Unsupported("unhandled switch_section"); } // emit_switch_section private static CodeObject emit_switch_label(switch_label p) { if (p is switch_expression) return emit_switch_expression((switch_expression) p); if (p is switch_default) return emit_switch_default((switch_default) p); throw new Unsupported(p.ToString()); } // emit_switch_label private static CodeObject emit_switch_expression(switch_expression p) { throw new Unsupported("unhandled switch expression"); } // emit_switch_expression private static CodeObject emit_switch_default(switch_default p) { throw new Unsupported("unhandled switch default"); } // emit_switch_default private static CodeIterationStatement emit_while_statement(while_statement p) { CodeIterationStatement iter = new CodeIterationStatement(); iter.UserData["AST"] = p; iter.TestExpression = emit_expression(p.expr); emit_statement(p.body, iter.Statements); return iter; } // emit_while_statement private static CodeIterationStatement emit_do_statement(do_statement p) { throw new Unsupported("unhandled 'do' loop statement"); } // emit_do_statement private static CodeIterationStatement emit_for_statement(for_statement p) { throw new Unsupported("unhandled 'for' loop"); } // emit_for_statement private static CodeObject emit_for_init(for_init p) { if (p is for_decl) return emit_for_decl((for_decl) p); if (p is for_list) return emit_for_list((for_list) p); throw new Unsupported(p.ToString()); } // emit_for_init private static CodeObject emit_for_decl(for_decl p) { throw new Unsupported("unhandled 'for' decl"); } // emit_for_decl private static CodeObject emit_for_list(for_list p) { throw new Unsupported("unhandled 'for' list"); } // emit_for_list private static CodeStatement emit_foreach_statement(foreach_statement p) { throw new Unsupported("unhandled 'foreach' loop"); } // emit_foreach_statement private static CodeStatement emit_break_statement(break_statement p) { throw new Unsupported("unhandled break statement"); } // emit_break_statement private static CodeStatement emit_continue_statement(continue_statement p) { throw new Unsupported("unhandled continue statement"); } // emit_continue_statement private static CodeStatement emit_goto_default_statement(goto_default_statement p) { throw new Unsupported("unhandled goto default"); } // emit_goto_default_statement private static CodeGotoStatement emit_goto_statement(goto_statement p) { return new CodeGotoStatement(p.id.str); } // emit_goto_statement private static CodeStatement emit_goto_case_statement(goto_case_statement p) { throw new Unsupported("unhandled goto case"); } // emit_goto_case_statement private static CodeMethodReturnStatement emit_return_statement(return_statement p) { CodeMethodReturnStatement mrs = new CodeMethodReturnStatement(); mrs.UserData["AST"] = p; if (p.expr != null) { mrs.Expression = emit_expression(p.expr); } return mrs; } // emit_return_statement private static CodeThrowExceptionStatement emit_throw_statement(throw_statement p) { CodeThrowExceptionStatement tes = new CodeThrowExceptionStatement(); tes.UserData["AST"] = p; tes.ToThrow = emit_expression(p.expr); return tes; } // emit_throw_statement private static CodeTryCatchFinallyStatement emit_try_statement(try_statement p) { CodeTryCatchFinallyStatement tcfs = new CodeTryCatchFinallyStatement(); tcfs.UserData["AST"] = p; emit_block_statement((block_statement)p.block, tcfs.TryStatements); if (p.catches != null) { CodeCatchClauseCollection ccc = emit_catch_clauses(p.catches); tcfs.CatchClauses.AddRange(ccc); } if (p.finally_block != null) { emit_block_statement((block_statement)p.finally_block.block, tcfs.FinallyStatements); } return tcfs; } // emit_try_statement private static CodeCatchClause emit_catch_clause(catch_clause p) { return emit_specific_catch_clause(p); } // emit_catch_clause private static CodeCatchClause emit_specific_catch_clause(catch_clause p) { CodeCatchClause cc = new CodeCatchClause(); // Why doesn't this have UserData["AST"]???? cc.CatchExceptionType = emit_type(p.ty); if (p.id != null) { cc.LocalName = p.id.str; } emit_block_statement((block_statement) p.block, cc.Statements); return cc; } // emit_specific_catch_clause private static CodeCatchClause emit_general_catch_clause(statement p) { CodeCatchClause cc = new CodeCatchClause(); emit_statement(p, cc.Statements); return cc; } // emit_general_catch_clause private static CodeCatchClauseCollection emit_catch_clauses(catch_clauses p) { CodeCatchClauseCollection ccc = new CodeCatchClauseCollection(); foreach (catch_clause k in p.specifics) { CodeCatchClause s = emit_catch_clause(k); ccc.Add(s); } if (p.general != null) { CodeCatchClause t1 = emit_general_catch_clause(p.general); ccc.Add(t1); } return ccc; } // emit_catch_clauses private static CodeStatement emit_checked_statement(checked_statement p) { throw new Unsupported("unhandled checked statement"); } // emit_checked_statement private static CodeStatement emit_unchecked_statement(unchecked_statement p) { throw new Unsupported("unhandled unchecked statement"); } // emit_unchecked_statement private static CodeStatement emit_lock_statement(lock_statement p) { throw new Unsupported("unhandled lock statement"); } // emit_lock_statement private static CodeStatement emit_using_statement(using_statement p) { throw new Unsupported("unhandled using statement"); } // emit_using_statement private static CodeObject emit_resource(resource p) { if (p is resource_expr) return emit_resource_expr((resource_expr) p); if (p is resource_decl) return emit_resource_decl((resource_decl) p); throw new Unsupported(p.ToString()); } // emit_resource private static CodeExpression emit_resource_expr(resource_expr p) { throw new Unsupported("unhandled 'resource expression"); } // emit_resource_expr private static CodeExpression emit_resource_decl(resource_decl p) { throw new Unsupported("unhandled resource decl"); } // emit_resource_decl private static CodeTypeMember emit_declaration(declaration p) { if (p is constant_declaration) return emit_constant_declaration((constant_declaration) p); if (p is field_declaration) return emit_field_declaration((field_declaration) p); if (p is method_declaration) return emit_method_declaration((method_declaration) p); if (p is property_declaration) return emit_property_declaration((property_declaration) p); if (p is event_declaration1) return emit_event_declaration1((event_declaration1) p); if (p is event_declaration2) return emit_event_declaration2((event_declaration2) p); if (p is indexer_declaration) return emit_indexer_declaration((indexer_declaration) p); if (p is operator_declaration) return emit_operator_declaration((operator_declaration) p); if (p is constructor_declaration) return emit_constructor_declaration((constructor_declaration) p); if (p is destructor_declaration) return emit_destructor_declaration((destructor_declaration) p); if (p is struct_declaration) return emit_struct_declaration((struct_declaration) p); if (p is interface_declaration) return emit_interface_declaration((interface_declaration) p); if (p is interface_method_declaration) return emit_interface_method_declaration((interface_method_declaration) p); if (p is interface_property_declaration) return emit_interface_property_declaration((interface_property_declaration) p); if (p is interface_event_declaration) return emit_interface_event_declaration((interface_event_declaration) p); if (p is interface_indexer_declaration) return emit_interface_indexer_declaration((interface_indexer_declaration) p); if (p is enum_declaration) return emit_enum_declaration((enum_declaration) p); if (p is class_declaration) return emit_class_declaration((class_declaration) p); if (p is delegate_declaration) return emit_delegate_declaration((delegate_declaration) p); throw new Unsupported(p.ToString()); } // emit_declaration private static CodeNamespace emit_namespace_declaration(namespace_declaration p) { CodeNamespace n = new CodeNamespace(); n.UserData["AST"] = p; string t0 = dotted2string(p.id); n.Name = t0; emit_namespace_body(p.nb, n); return n; } // emit_namespace_declaration private static void emit_namespace_body(namespace_body p, CodeNamespace n) { foreach (using_directive k in p.ud) { CodeNamespaceImport s = emit_using_directive(k); n.Imports.Add(s); } foreach (declaration k in p.declarations) { if (k is namespace_declaration) { throw new Unsupported("nested namespace declarations unallowed"); } else { CodeTypeDeclaration s = (CodeTypeDeclaration) emit_declaration(k); n.Types.Add(s); } } } // emit_namespace_body private static CodeNamespaceImport emit_using_directive(using_directive p) { if (p is alias_directive) return emit_alias_directive((alias_directive) p); if (p is namespace_directive) return emit_namespace_directive((namespace_directive) p); throw new Unsupported(p.ToString()); } // emit_using_directive private static CodeNamespaceImport emit_alias_directive(alias_directive p) { throw new Unsupported("\t// ERROR: CodeDOM does not support: \"using A=B;\"\n"); } // emit_alias_directive private static CodeNamespaceImport emit_namespace_directive(namespace_directive p) { CodeNamespaceImport ni = new CodeNamespaceImport(); ni.UserData["AST"] = p; string t0 = dotted2string(p.name); ni.Namespace = t0; return ni; } // emit_namespace_directive private static CodeTypeDeclaration emit_constant_declaration(constant_declaration p) { throw new Unsupported("unhandled const declaration"); } // emit_constant_declaration private static CodeMemberField emit_field_declaration(field_declaration p) { if (p.decls.Count > 1) { throw new Unsupported("cannot handle compound field declarations"); } System.Collections.Queue t3 = new System.Collections.Queue(); field_declarator k = (field_declarator) p.decls[0]; CodeMemberField mf = new CodeMemberField(); mf.UserData["AST"] = p; mf.CustomAttributes = emit_attribute_sections(p.attrs); CodeTypeReference t2 = emit_type(p.ty); mf.Type = t2; mf.Name = k.id.str; if (k.init != null) { CodeExpression t4 = emit_variable_initializer(k.init); mf.InitExpression = t4; } mf.Attributes = emit_CodeDomAttributes(p.mods); return mf; } // emit_field_declaration private static CodeMemberMethod emit_method_declaration(method_declaration p) { CodeMemberMethod mm = new CodeMemberMethod(); mm.UserData["AST"] = p; mm.Attributes = emit_CodeDomAttributes(p.mods); mm.CustomAttributes = emit_attribute_sections(p.attrs); mm.ReturnType = emit_type(p.ty); // WARNING: unimplemented Interface name: method_declaration.name mm.Name = p.name.id.str; mm.Parameters.AddRange(emit_formals(p.parms)); if (p.body != null) { emit_block_statement((block_statement)p.body, mm.Statements); } else { // WARNING: unimplemented null check: method_declaration.body } return mm; } // emit_method_declaration private static CodeTypeReference emit_void_type(void_type p) { CodeTypeReference tr = new CodeTypeReference(typeof(void)); tr.UserData["AST"] = p; return tr; } // emit_void_type private static CodeParameterDeclarationExpressionCollection emit_formals(formals p) { CodeParameterDeclarationExpressionCollection pdec = new CodeParameterDeclarationExpressionCollection(); foreach (parameter k in p.fixeds) { CodeParameterDeclarationExpression s = emit_parameter(k); pdec.Add(s); } if (p.param != null) { CodeParameterDeclarationExpression s = emit_parameter(p.param); pdec.Add(s); } return pdec; } // emit_formals private static CodeParameterDeclarationExpression emit_parameter(parameter p) { if (p is fixed_parameter) return emit_fixed_parameter((fixed_parameter) p); if (p is params_parameter) return emit_params_parameter((params_parameter) p); if (p is arglist_parameter) return emit_arglist_parameter((arglist_parameter) p); throw new Unsupported(p.ToString()); } // emit_parameter private static CodeParameterDeclarationExpression emit_fixed_parameter(fixed_parameter p) { CodeParameterDeclarationExpression pde = new CodeParameterDeclarationExpression(); pde.UserData["AST"] = p; pde.Name = p.id.str; pde.CustomAttributes = emit_attribute_sections(p.attrs); if (p.mod != null) { switch (p.mod.str) { case "ref": pde.Direction = FieldDirection.Ref; break; case "out": pde.Direction = FieldDirection.Out; break; default: throw new Unsupported("unhandled modifier " + p.mod.str); } } pde.Type = emit_type(p.ty); return pde; } // emit_fixed_parameter private static CodeParameterDeclarationExpression emit_params_parameter(params_parameter p) { throw new Unsupported("unhandled params declaration"); } // emit_params_parameter private static CodeParameterDeclarationExpression emit_arglist_parameter(arglist_parameter p) { throw new Unsupported("unhandled arglist declaration"); } // emit_arglist_parameter private static CodeMemberProperty emit_property_declaration(property_declaration p) { CodeMemberProperty mp = new CodeMemberProperty(); mp.UserData["AST"] = p; mp.CustomAttributes = emit_attribute_sections(p.attrs); // need to fix this all over the place mp.Attributes = emit_CodeDomAttributes(p.mods); mp.Type = emit_type(p.ty); mp.Name = get_member_name(p.name); foreach (accessor_declaration k in p.decls) { if (k != null) { emit_accessor_declaration(k, mp); } } return mp; } // emit_property_declaration private static void emit_accessor_declaration(accessor_declaration p, CodeMemberProperty mp) { if (p.attrs.Count > 0) { throw new Unsupported("cannot handle attributes"); } switch (p.id.str) { default: throw new Unsupported("unknown accessor: " + p.id.str); case "get": mp.HasGet = true; if (p.body != null) { emit_block_statement((block_statement)p.body, mp.GetStatements); } break; case "set": mp.HasSet = true; if (p.body != null) { emit_block_statement((block_statement)p.body, mp.SetStatements); } break; } } // emit_accessor_declaration private static string emit_event_declarator(event_declarator p) { return p.id.str; } private static CodeMemberEvent emit_event_declaration1(event_declaration1 p) { if (p.decls.Count > 1) { // WARNING: cannot handle multiple comma-separated events } declarator d = p.decls[0]; CodeMemberEvent me = new CodeMemberEvent(); me.UserData["AST"] = p; me.CustomAttributes = emit_attribute_sections(p.attrs); me.Type = emit_type(p.ty); me.Name = d.id.str; me.Attributes = emit_CodeDomAttributes(p.mods); return me; } // emit_event_declaration1 private static CodeMemberEvent emit_event_declaration2(event_declaration2 p) { if (p.accessors.Count > 0) { throw new Unsupported("cannot handle event accessors"); } CodeMemberEvent me = new CodeMemberEvent(); me.UserData["AST"] = p; me.CustomAttributes = emit_attribute_sections(p.attrs); me.Attributes = emit_CodeDomAttributes(p.mods); me.Type = emit_type(p.ty); me.Name = p.name.id.str; // handle accessors here. return me; } // emit_event_declaration2 private static CodeObject emit_event_accessor(event_accessor p) { throw new Unsupported("cannot handle event accessors"); } // emit_event_accessor private static CodeTypeMember emit_indexer_declaration(indexer_declaration p) { throw new Unsupported("unhandled indexer declaration"); } // emit_indexer_declaration private static CodeObject emit_indexer(indexer p) { throw new Unsupported("unhandled indexer"); } // emit_indexer private static CodeTypeMember emit_operator_declaration(operator_declaration p) { throw new Unsupported("unhandled operator declaration"); } // emit_operator_declaration private static CodeTypeMember emit_operator_declarator(operator_declarator p) { if (p is unary_declarator) return emit_unary_declarator((unary_declarator) p); if (p is binary_declarator) return emit_binary_declarator((binary_declarator) p); if (p is implicit_declarator) return emit_implicit_declarator((implicit_declarator) p); if (p is explicit_declarator) return emit_explicit_declarator((explicit_declarator) p); throw new Unsupported(p.ToString()); } // emit_operator_declarator private static CodeTypeMember emit_unary_declarator(unary_declarator p) { throw new Unsupported("unhandled unary declaration"); } // emit_unary_declarator private static CodeTypeMember emit_binary_declarator(binary_declarator p) { throw new Unsupported("unhandled binary declaration"); } // emit_binary_declarator private static CodeTypeMember emit_implicit_declarator(implicit_declarator p) { throw new Unsupported("unhandled implicit declaration"); } // emit_implicit_declarator private static CodeTypeMember emit_explicit_declarator(explicit_declarator p) { throw new Unsupported("unhandled explicit declaration"); } // emit_explicit_declarator private static CodeMemberMethod emit_constructor_declaration(constructor_declaration p) { CodeMemberMethod c; if (p.sym.IsStatic) { CodeTypeConstructor ctc = new CodeTypeConstructor(); ctc.UserData["AST"] = p; c = ctc; emit_constructor_declarator(p.decl, ctc); } else { CodeConstructor cc = new CodeConstructor(); cc.UserData["AST"] = p; c = cc; emit_constructor_declarator(p.decl, cc); } c.CustomAttributes = emit_attribute_sections(p.attrs); c.Attributes = emit_CodeDomAttributes(p.mods); if (p.block != null) { emit_block_statement((block_statement)p.block, c.Statements); } else { // WARNING: unimplemented null check: constructor_declaration.block } return c; } // emit_constructor_declaration private static MemberAttributes emit_CodeDomAttributes(System.Collections.IList a) { MemberAttributes ma = 0; foreach (InputElement e in a) { ma |= emit_CodeDomAttribute(e.tag); } return ma; } private static MemberAttributes emit_CodeDomAttribute(string modifier) { switch (modifier) { case "public": return MemberAttributes.Public; case "abstract": return MemberAttributes.Abstract; case "final": return MemberAttributes.Final; case "override": return MemberAttributes.Override; case "private": return MemberAttributes.Private; case "static": return MemberAttributes.Static; default: throw new Unsupported("unhandled non-CodeDOM modifier: " + modifier); } } private static void emit_constructor_declarator(constructor_declarator p, CodeTypeConstructor c) { c.Name = p.id.str; c.Parameters.AddRange(emit_formals(p.f)); // assert(p.init == null) } // emit_constructor_declarator private static void emit_constructor_declarator(constructor_declarator p, CodeConstructor c) { c.Name = p.id.str; c.Parameters.AddRange(emit_formals(p.f)); if (p.init != null) { emit_constructor_initializer(p.init, c); } } // emit_constructor_declarator private static void emit_constructor_initializer(constructor_initializer p, CodeConstructor c) { if (p is base_initializer) { emit_base_initializer((base_initializer) p, c); return; } if (p is this_initializer) { emit_this_initializer((this_initializer) p, c); return; } throw new Unsupported(p.ToString()); } // emit_constructor_initializer private static void emit_base_initializer(base_initializer p, CodeConstructor c) { emit_argumentList(p.args, c.BaseConstructorArgs); } // emit_base_initializer private static void emit_this_initializer(this_initializer p, CodeConstructor c) { emit_argumentList(p.args, c.ChainedConstructorArgs); } // emit_this_initializer private static CodeTypeMember emit_destructor_declaration(destructor_declaration p) { throw new Unsupported("unhandled destructor declaration"); } // emit_destructor_declaration private static CodeTypeDeclaration emit_struct_declaration(struct_declaration p) { CodeTypeDeclaration td = new CodeTypeDeclaration(); td.UserData["AST"] = p; td.IsStruct = true; td.CustomAttributes = emit_attribute_sections(p.attrs); td.Attributes = emit_CodeDomAttributes(p.mods); td.Name = p.id.str; foreach (type k in p.interfaces) { td.BaseTypes.Add(emit_type(k)); } foreach (declaration k in p.body) { td.Members.Add(emit_declaration(k)); } return td; } // emit_struct_declaration private static CodeTypeDeclaration emit_interface_declaration(interface_declaration p) { CodeTypeDeclaration td = new CodeTypeDeclaration(); td.UserData["AST"] = p; td.IsInterface = true; td.CustomAttributes = emit_attribute_sections(p.attrs); td.Attributes = emit_CodeDomAttributes(p.mods); td.Name = p.id.str; foreach (type k in p.interfaces) { td.BaseTypes.Add(emit_type(k)); } foreach (declaration k in p.body) { td.Members.Add(emit_declaration(k)); } return td; } // emit_interface_declaration private static CodeMemberMethod emit_interface_method_declaration(interface_method_declaration p) { throw new Unsupported("unhandled interface method declaration"); } // emit_interface_method_declaration private static CodeMemberProperty emit_interface_property_declaration(interface_property_declaration p) { throw new Unsupported("unhandled interface property declaration"); } // emit_interface_property_declaration private static CodeMemberEvent emit_interface_event_declaration(interface_event_declaration p) { throw new Unsupported("unhandled interface event declaration"); } // emit_interface_event_declaration private static CodeTypeMember emit_interface_indexer_declaration(interface_indexer_declaration p) { throw new Unsupported("unhandled interface indexer declaration"); } // emit_interface_indexer_declaration private static CodeTypeMember emit_enum_declaration(enum_declaration p) { throw new Unsupported("unhandled interface enum declaration"); } // emit_enum_declaration private static CodeTypeDeclaration emit_class_declaration(class_declaration p) { CodeTypeDeclaration td = new CodeTypeDeclaration(); td.UserData["AST"] = p; td.IsClass = true; td.CustomAttributes.AddRange(emit_attribute_sections(p.attrs)); td.Attributes = emit_CodeDomAttributes(p.mods); td.Name = p.id.str; foreach (type k in p.bases) { td.BaseTypes.Add(emit_type(k)); } foreach (declaration k in p.body) { td.Members.Add(emit_declaration(k)); } return td; } // emit_class_declaration private static CodeTypeMember emit_enum_member_declaration(enum_member_declaration p) { throw new Unsupported("unhandled enum member declaration"); } // emit_enum_member_declaration private static CodeTypeDelegate emit_delegate_declaration(delegate_declaration p) { CodeTypeDelegate td = new CodeTypeDelegate(); td.UserData["AST"] = p; td.CustomAttributes.AddRange(emit_attribute_sections(p.attrs)); td.Attributes = emit_CodeDomAttributes(p.mods); td.ReturnType = emit_type(p.ty); td.Name = p.id.str; td.Parameters.AddRange(emit_formals(p.f)); return td; } // emit_delegate_declaration private static CodeAttributeDeclarationCollection emit_attribute_section(attribute_section p) { CodeAttributeDeclarationCollection adc = new CodeAttributeDeclarationCollection(); if (p.target != null) { // WARNING: unimplemented target: attribute_section.target } else { // WARNING: unimplemented null check: attribute_section.target } foreach (attribute k in p.attributes) { adc.Add(emit_attribute(k)); } return adc; } // emit_attribute_section private static CodeAttributeDeclaration emit_attribute(attribute p) { CodeAttributeDeclaration ad = new CodeAttributeDeclaration(); // Why doesn't CodeAttributeDeclaration have UserData["AST"]? CodeTypeReference t0 = emit_type(p.name); ad.Name = t0.BaseType; // WARNING: Is this correct? foreach (expression k in p.arguments.args) { CodeAttributeArgument aa = new CodeAttributeArgument(); // UserData["AST"]? aa.Value = emit_expression(k); ad.Arguments.Add(aa); } // p.arguments.namedargs foreach (named_argument s in p.arguments.namedargs) { CodeAttributeArgument aa = emit_named_argument(s); ad.Arguments.Add(aa); } return ad; } // emit_attribute private static CodeAttributeArgument emit_named_argument(named_argument p) { CodeAttributeArgument aa = new CodeAttributeArgument(); // UserData["AST"]? aa.Value = emit_expression(p.expr); aa.Name = p.id.str; return aa; } private static CodeTypeReference emit_pointer_type(pointer_type p) { throw new Unsupported("unhandled pointer type"); } // emit_pointer_type private static CodeTypeReference emit_void_pointer_type(void_pointer_type p) { throw new Unsupported("unhandled void pointer type"); } // emit_void_pointer_type private static CodeExpression emit_sizeof_expression(sizeof_expression p) { throw new Unsupported("unhandled sizeof expression"); } // emit_sizeof_expression private static CodeStatement emit_fixed_statement(fixed_statement p) { throw new Unsupported("unhandled fixed statement"); } // emit_fixed_statement private static string emit_fixed_declarator(fixed_declarator p) { throw new Unsupported("unhandled fixed declarator"); } // emit_fixed_declarator private static CodeExpression emit_stackalloc_initializer(stackalloc_initializer p) { throw new Unsupported("unhandled stackalloc initializer"); } // emit_stackalloc_initializer private static CodeExpression emit_variable_initializer(variable_initializer p) { if (p is stackalloc_initializer) return emit_stackalloc_initializer((stackalloc_initializer) p); if (p is expr_initializer) return emit_expr_initializer((expr_initializer) p); if (p is array_initializer) throw new Unsupported("should be handled elsewhere"); //return emit_array_initializer((array_initializer) p); throw new Unsupported(p.ToString()); } // emit_variable_initializer private static CodeExpression emit_expr_initializer(expr_initializer p) { return emit_expression(p.expr); } // emit_expr_initializer private static void emit_array_initializer(array_initializer p, CodeExpressionCollection ec) { foreach (variable_initializer k in p.a) { CodeExpression s = emit_variable_initializer(k); ec.Add(s); } } // emit_array_initializer } // class AST2CodeDom