using System; using System.IO; using System.Collections; using System.Reflection; using System.Reflection.Emit; public class emit { public MessageWriter msg; protected TextWriter w; public BuiltinTypes T; protected Hashtable map; public ModuleBuilder module; public emit(TextWriter w, MessageWriter msg, Hashtable map, ModuleBuilder module) { this.w = w; this.msg = msg; this.map = map; this.module = module; } static void init(BuiltinTypes T, Hashtable map) { map.Add(T.Bool, System.Type.GetType("System.Boolean")); map.Add(T.Byte, System.Type.GetType("System.Byte")); map.Add(T.Char, System.Type.GetType("System.Char")); map.Add(T.Decimal, System.Type.GetType("System.Decimal")); map.Add(T.Double, System.Type.GetType("System.Double")); map.Add(T.Float, System.Type.GetType("System.Single")); map.Add(T.Int, System.Type.GetType("System.Int32")); map.Add(T.Long, System.Type.GetType("System.Int64")); map.Add(T.Object, System.Type.GetType("System.Object")); map.Add(T.SByte, System.Type.GetType("System.SByte")); map.Add(T.Short, System.Type.GetType("System.Int16")); map.Add(T.String, System.Type.GetType("System.String")); map.Add(T.UInt, System.Type.GetType("System.UInt32")); map.Add(T.ULong, System.Type.GetType("System.UInt64")); map.Add(T.UShort, System.Type.GetType("System.UInt16")); map.Add(T.Void, System.Type.GetType("System.Void")); } public static object visit(object ast, TextWriter w, string[] args, MessageWriter msg) { if (msg.Count == 0) { Hashtable map = new Hashtable(); init(((compilation)ast).global.Types, map); emit1 pass1 = new emit1(w, msg, map); AssemblyBuilder asm = pass1.compilation((compilation)ast); (new emit2(w, msg, map, pass1.module)).compilation((compilation)ast); (new emit3(w, msg, map, pass1.module)).compilation((compilation)ast); return asm; } return ast; } public FieldAttributes GetFieldAttributes(stringList modifiers) { FieldAttributes attr = 0; foreach (string mod in modifiers) switch (mod) { case "private": attr |= FieldAttributes.Private; break; case "public": attr |= FieldAttributes.Public; break; case "protected": if (modifiers.Contains("internal")) attr |= FieldAttributes.FamORAssem; else attr |= FieldAttributes.Family; break; case "internal": if (modifiers.Contains("protected")) attr |= FieldAttributes.FamORAssem; else attr |= FieldAttributes.Assembly; break; case "static": attr |= FieldAttributes.Static; break; } return attr; } public MethodAttributes GetMethodAttributes(stringList modifiers) { MethodAttributes attr = 0; foreach (string mod in modifiers) switch (mod) { case "private": attr |= MethodAttributes.Private; break; case "public": attr |= MethodAttributes.Public; break; case "protected": if (modifiers.Contains("internal")) attr |= MethodAttributes.FamORAssem; else attr |= MethodAttributes.Family; break; case "internal": if (modifiers.Contains("protected")) attr |= MethodAttributes.FamORAssem; else attr |= MethodAttributes.Assembly; break; case "static": attr |= MethodAttributes.Static; break; case "override": case "virtual": attr |= MethodAttributes.Virtual; break; case "new": attr |= MethodAttributes.NewSlot; break; case "abstract": attr |= MethodAttributes.Abstract; break; case "sealed": attr |= MethodAttributes.Final; break; } return attr; } public TypeAttributes GetTypeAttributes(Type t) { TypeAttributes attr = 0; foreach (string mod in t.Modifiers) switch (mod) { case "private": attr |= t.IsNested ? TypeAttributes.NestedPrivate : TypeAttributes.NotPublic; break; case "public": attr |= t.IsNested ? TypeAttributes.NestedPublic : TypeAttributes.Public; break; case "protected": if (t.IsNested) attr |= t.Modifiers.Contains("internal") ? TypeAttributes.NestedFamORAssem : TypeAttributes.NestedFamily; break; case "internal": if (t.IsNested) attr |= t.Modifiers.Contains("protected") ? TypeAttributes.NestedFamORAssem : TypeAttributes.NestedAssembly; break; case "sealed": attr |= TypeAttributes.Sealed; break; case "abstract": attr |= TypeAttributes.Abstract; break; } return attr; } static System.Type GetTypeFromAssembly(Type ty, string assembly) { Assembly asm = Assembly.LoadFrom(assembly); // may throw System.Type type = asm.GetType(ty.RealName); Debug.Assert(type != null); return type; } public FieldInfo this[Field f] { get { FieldInfo info = (FieldInfo)map[f]; if (info == null) { Type ty = f.GetType(); System.Type type = this[ty]; BindingFlags flags = 0; flags |= f.IsStatic ? BindingFlags.Static : BindingFlags.Instance; flags |= f.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; info = type.GetField(f.Name, flags); if (info != null) map.Add(f, info); } Debug.Assert(info != null); return info; } } public ConstructorInfo this[Constructor m] { get { ConstructorInfo info = (ConstructorInfo)map[m]; if (info == null) { Type ty = m.GetType(); System.Type type = this[ty]; BindingFlags flags = m.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; System.Type[] args = new System.Type[m.ArgCount]; for (int i = 0; i < m.ArgCount; i++) args[i] = this[m[i].Type]; info = type.GetConstructor(flags|BindingFlags.Instance, null, args, null); if (info != null) map.Add(m, info); } Debug.Assert(info != null); return info; } } public MethodInfo this[Method m] { get { MethodInfo info = (MethodInfo)map[m]; if (info == null) { Type ty = m.GetType(); System.Type type = this[ty]; BindingFlags flags = 0; flags |= m.IsStatic ? BindingFlags.Static : BindingFlags.Instance; flags |= m.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; System.Type[] args = new System.Type[m.ArgCount]; for (int i = 0; i < m.ArgCount; i++) args[i] = this[m[i].Type]; info = type.GetMethod(m.Name, flags, null, args, null); if (info != null) map.Add(m, info); } Debug.Assert(info != null); return info; } } public System.Type this[PointerType ty] { get { System.Type type, etype = this[ty.elementType]; if (ty.elementType.module != null) type = GetTypeFromAssembly(ty, ty.elementType.module); else type = module.GetType(etype.FullName + "&"); Debug.Assert(type != null); return type; } } public System.Type this[ArrayType ty] { get { System.Type type, etype = this[ty.elementType]; if (ty.elementType.module != null) type = GetTypeFromAssembly(ty, ty.elementType.module); else type = module.GetType(string.Format("{0}[{1}]", etype.FullName, "".PadRight(ty.rank - 1, ','))); Debug.Assert(type != null); return type; } } public System.Type this[Type ty] { get { if (ty is ArrayType) return this[(ArrayType)ty]; else if (ty is PointerType) return this[(PointerType)ty]; System.Type type = (System.Type)map[ty]; if (type != null) return type; if (ty.module != null) return GetTypeFromAssembly(ty, ty.module); type = System.Type.GetType(ty.RealName); if (type == null) type = module.GetType(ty.RealName); if (type != null) map.Add(ty, type); if (type == null) System.Console.WriteLine(ty.RealName); Debug.Assert(type != null); return type; } } public virtual System.Type type(type ast) { return this[ast.sym]; } } public class emit1: emit { public emit1(TextWriter w, MessageWriter msg, Hashtable map) : base(w, msg, map, null) {} public virtual void class_declaration(class_declaration ast, ModuleBuilder m) { if (ast.parent is type_declaration) { TypeBuilder t = ((type_declaration)ast.parent).builder; ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym)|TypeAttributes.Class); } else ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym)|TypeAttributes.Class); map.Add(ast.sym, ast.type); foreach (declaration x in ast.body) declaration(x, m); } public virtual AssemblyBuilder compilation(compilation ast) { T = ast.global.Types; AssemblyName name = new AssemblyName(); if (ast.inputs.Count > 0 && ast.inputs[0].begin.file != null && ast.inputs[0].begin.file != "") name.Name = Path.GetFileNameWithoutExtension(ast.inputs[0].begin.file); else name.Name = Guid.NewGuid().ToString(); AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave); string oname = name.Name; foreach (string s in ast.args) if (s[0] == '/' || s[0] == '-') { string arg = s.Substring(1); if (arg.StartsWith("out:")) oname = arg.Substring(4); } foreach (compilation_unit x in ast.inputs) compilation_unit(x, asm, oname); return asm; } public virtual void compilation_unit(compilation_unit ast, AssemblyBuilder asm, string name) { module = asm.DefineDynamicModule(asm.GetName().Name, name, true); foreach (declaration x in ast.declarations) declaration(x, module); } public virtual void declaration(declaration ast, ModuleBuilder m) { if (ast is class_declaration) class_declaration((class_declaration)ast, m); else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast, m); else if (ast is enum_declaration) enum_declaration((enum_declaration)ast, m); else if (ast is interface_declaration) interface_declaration((interface_declaration)ast, m); else if (ast is namespace_declaration) namespace_declaration((namespace_declaration)ast, m); else if (ast is struct_declaration) struct_declaration((struct_declaration)ast, m); } public virtual void delegate_declaration(delegate_declaration ast, ModuleBuilder m) { if (ast.parent is type_declaration) { TypeBuilder t = ((type_declaration)ast.parent).builder; ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym)); } else ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym)); map.Add(ast.sym, ast.type); } public virtual void enum_declaration(enum_declaration ast, ModuleBuilder m) { ast.type = m.DefineEnum(ast.sym.FullName, GetTypeAttributes(ast.sym), System.Type.GetType("System.Int32")); map.Add(ast.sym, ast.type); } public virtual void interface_declaration(interface_declaration ast, ModuleBuilder m) { if (ast.parent is type_declaration) { TypeBuilder t = ((type_declaration)ast.parent).builder; ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym)|TypeAttributes.Interface|TypeAttributes.Abstract); } else ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym)|TypeAttributes.Interface|TypeAttributes.Abstract); map.Add(ast.sym, ast.type); foreach (declaration x in ast.body) declaration(x, m); } public virtual void namespace_body(namespace_body ast, ModuleBuilder m) { foreach (declaration x in ast.declarations) declaration(x, m); } public virtual void namespace_declaration(namespace_declaration ast, ModuleBuilder m) { namespace_body(ast.nb, m); } public virtual void struct_declaration(struct_declaration ast, ModuleBuilder m) { if (ast.parent is type_declaration) { TypeBuilder t = ((type_declaration)ast.parent).builder; ast.type = t.DefineNestedType(ast.sym.FullName, GetTypeAttributes(ast.sym)); } else ast.type = m.DefineType(ast.sym.FullName, GetTypeAttributes(ast.sym)); map.Add(ast.sym, ast.type); foreach (declaration x in ast.body) declaration(x, m); } } public class emit2: emit { public emit2(TextWriter w, MessageWriter msg, Hashtable map, ModuleBuilder mod) : base(w, msg, map, mod) {} public virtual void binary_declarator(binary_declarator ast, TypeBuilder t) { } public virtual void class_declaration(class_declaration ast) { TypeBuilder t = ast.builder; t.SetParent(this[ast.sym.baseClass]); foreach (Type x in ast.sym.interfaces) t.AddInterfaceImplementation(this[x]); foreach (declaration x in ast.body) declaration(x, t); } public virtual void compilation(compilation ast) { T = ast.global.Types; foreach (compilation_unit x in ast.inputs) compilation_unit(x); } public virtual void compilation_unit(compilation_unit ast) { foreach (declaration x in ast.declarations) declaration(x); } public virtual void constant_declaration(constant_declaration ast, TypeBuilder t) { foreach (const_declarator x in ast.decls) { FieldBuilder f = t.DefineField(x.sym.Name, type(ast.ty), GetFieldAttributes(x.sym.Modifiers)); f.SetConstant(x.sym.value); map.Add(x.sym, f); x.builder = f; } } public virtual void constructor_declaration(constructor_declaration ast, TypeBuilder t) { System.Type[] args = new System.Type[ast.sym.ArgCount]; for (int i = 0; i < ast.sym.ArgCount; i++) args[i]= this[ast.sym[i].Type]; ConstructorBuilder m = t.DefineConstructor(GetMethodAttributes(ast.sym.Modifiers), CallingConventions.Standard, args); for (int i = 0; i < ast.sym.ArgCount; i++) { Formal f = ast.sym[i]; m.DefineParameter(i + 1, f.modifier != null && f.modifier.str == "out" ? ParameterAttributes.Out : 0, f.Name); f.ordinal = ast.sym.IsInstance ? i + 1 : i; } map.Add(ast.sym, m); ast.builder = m; } public virtual void declaration(declaration ast, TypeBuilder t) { if (ast is class_declaration) class_declaration((class_declaration)ast); else if (ast is constant_declaration) constant_declaration((constant_declaration)ast, t); else if (ast is constructor_declaration) constructor_declaration((constructor_declaration)ast, t); else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast); else if (ast is destructor_declaration) destructor_declaration((destructor_declaration)ast, t); else if (ast is enum_declaration) enum_declaration((enum_declaration)ast); else if (ast is event_declaration1) event_declaration1((event_declaration1)ast, t); else if (ast is event_declaration2) event_declaration2((event_declaration2)ast, t); else if (ast is field_declaration) field_declaration((field_declaration)ast, t); else if (ast is indexer_declaration) indexer_declaration((indexer_declaration)ast, t); else if (ast is interface_declaration) interface_declaration((interface_declaration)ast); else if (ast is interface_event_declaration) interface_event_declaration((interface_event_declaration)ast, t); else if (ast is interface_indexer_declaration) interface_indexer_declaration((interface_indexer_declaration)ast, t); else if (ast is interface_method_declaration) interface_method_declaration((interface_method_declaration)ast, t); else if (ast is interface_property_declaration) interface_property_declaration((interface_property_declaration)ast, t); else if (ast is method_declaration) method_declaration((method_declaration)ast, t); else if (ast is operator_declaration) operator_declaration((operator_declaration)ast, t); else if (ast is property_declaration) property_declaration((property_declaration)ast, t); else if (ast is struct_declaration) struct_declaration((struct_declaration)ast); else throw new ArgumentException(); } public virtual void declaration(declaration ast) { if (ast is class_declaration) class_declaration((class_declaration)ast); else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast); else if (ast is enum_declaration) enum_declaration((enum_declaration)ast); else if (ast is interface_declaration) interface_declaration((interface_declaration)ast); else if (ast is namespace_declaration) namespace_declaration((namespace_declaration)ast); else if (ast is struct_declaration) struct_declaration((struct_declaration)ast); else throw new ArgumentException(); } public virtual MethodBuilder DefineMethod(TypeBuilder t, Method m) { return DefineMethod(t, m, GetMethodAttributes(m.Modifiers)); } public virtual MethodBuilder DefineMethod(TypeBuilder t, Method m, MethodAttributes attr) { System.Type[] args; if (m.Name == "set_Item") { args = new System.Type[m.ArgCount + 1]; args[m.ArgCount] = this[((Formal)m.locals["value"]).Type]; } else args = new System.Type[m.ArgCount]; int i; for (i = 0; i < m.ArgCount; i++) { Formal f = m[i]; if (f.modifier != null) args[i] = this[new ManagedPointerType(f.Type)]; else args[i] = this[f.Type]; } MethodBuilder mb = t.DefineMethod(m.Name, attr, this[m.Type], args); for (i = 0; i < m.ArgCount; i++) { Formal f = m[i]; mb.DefineParameter(i + 1, f.modifier != null && f.modifier.str == "out" ? ParameterAttributes.Out : 0, f.Name); f.ordinal = m.IsInstance ? i + 1 : i; } if (m.Name == "set_Item") { Formal f = (Formal)m.locals["value"]; f.ordinal = m.IsInstance ? i + 1 : i; mb.DefineParameter(f.ordinal, 0, f.Name); } if (m.interfaceMethod != null) t.DefineMethodOverride(mb, this[m.interfaceMethod]); return mb; } public virtual void delegate_declaration(delegate_declaration ast) { TypeBuilder t = ast.builder; t.SetParent(this[ast.sym.baseClass]); foreach (Symbol s in ast.sym) if (s is Constructor) { Constructor m = (Constructor)s; System.Type[] args = new System.Type[m.ArgCount]; for (int i = 0; i < m.ArgCount; i++) args[i]= this[m[i].Type]; ConstructorBuilder mb = t.DefineConstructor(GetMethodAttributes(m.Modifiers), CallingConventions.Standard, args); for (int i = 0; i < m.ArgCount; i++) { Formal f = m[i]; mb.DefineParameter(i + 1, 0, f.Name); f.ordinal = m.IsInstance ? i + 1 : i; } map.Add(m, mb); } else if (s is Method) { MethodBuilder mb = DefineMethod(t, (Method)s, GetMethodAttributes(s.Modifiers)); map.Add(s, mb); } } public virtual void destructor_declaration(destructor_declaration ast, TypeBuilder t) { ast.builder = t.DefineMethod(ast.sym.Name, MethodAttributes.Private|MethodAttributes.Final|MethodAttributes.SpecialName, this[T.Void], new System.Type[0]); } public virtual void enum_declaration(enum_declaration ast) { EnumBuilder t = (EnumBuilder)ast.type; foreach (enum_member_declaration x in ast.body) x.builder = t.DefineLiteral(x.sym.Name, x.sym.value); if (ast.sym.enclosingType == null) map[ast.sym] = t.CreateType(); } public virtual void event_declaration1(event_declaration1 ast, TypeBuilder t) { foreach (event_declarator x in ast.decls) { x.builder = t.DefineField(x.sym.Name, type(ast.ty), GetFieldAttributes(x.sym.Modifiers)); map.Add(x.sym, x.builder); x.event_builder = t.DefineEvent(x.sym.Name, EventAttributes.None, type(ast.ty)); x.add_builder = DefineMethod(t, x.sym.Add); map.Add(x.sym.Add, x.add_builder); x.remove_builder = DefineMethod(t, x.sym.Remove); map.Add(x.sym.Remove, x.remove_builder); } } public virtual void event_declaration2(event_declaration2 ast, TypeBuilder t) { EventBuilder e = t.DefineEvent(ast.sym.Name, EventAttributes.None, type(ast.ty)); foreach (event_accessor x in ast.accessors) { x.builder = DefineMethod(t, x.sym); map.Add(x.sym, x.builder); } ast.builder = e; } public virtual void explicit_declarator(explicit_declarator ast, TypeBuilder t) { } public virtual void field_declaration(field_declaration ast, TypeBuilder t) { foreach (field_declarator x in ast.decls) { FieldBuilder f = t.DefineField(x.sym.Name, type(ast.ty), GetFieldAttributes(x.sym.Modifiers)); map.Add(x.sym, f); x.builder = f; } } public virtual System.Type[] formals(formals ast) { System.Type[] args = new System.Type[ast.fixeds.Count + (ast.param != null ? 1 : 0)]; int i = 0; foreach (fixed_parameter p in ast.fixeds) args[i++] = type(p.ty); if (ast.param != null) args[i] = type(((params_parameter)ast.param).ty); // fix return args; } public virtual void implicit_declarator(implicit_declarator ast, TypeBuilder t) { } public virtual void indexer_declaration(indexer_declaration ast, TypeBuilder t) { PropertyBuilder p = t.DefineProperty("Item", PropertyAttributes.None, type(ast.i.ty), formals(ast.i.f)); foreach (accessor_declaration x in ast.accessors) { x.builder = DefineMethod(t, x.sym); map.Add(x.sym, x.builder); } ast.builder = p; } public virtual void interface_declaration(interface_declaration ast) { TypeBuilder t = ast.builder; if (ast.sym.baseClass != null) t.SetParent(this[ast.sym.baseClass]); foreach (Type x in ast.sym.interfaces) t.AddInterfaceImplementation(this[x]); foreach (declaration x in ast.body) declaration(x, t); } public virtual void interface_event_declaration(interface_event_declaration ast, TypeBuilder t) { ast.builder = t.DefineEvent(ast.sym.Name, EventAttributes.None, type(ast.ty)); map[ast.sym.Add] = DefineMethod(t, ast.sym.Add); map[ast.sym.Remove] = DefineMethod(t, ast.sym.Remove); } public virtual void interface_indexer_declaration(interface_indexer_declaration ast, TypeBuilder t) { PropertyBuilder p = t.DefineProperty("Item", PropertyAttributes.None, type(ast.ty), formals(ast.f)); foreach (accessor_declaration x in ast.accessors) { x.builder = DefineMethod(t, x.sym); map.Add(x.sym, x.builder); } ast.builder = p; } public virtual void interface_method_declaration(interface_method_declaration ast, TypeBuilder t) { ast.builder = DefineMethod(t, ast.sym); map.Add(ast.sym, ast.builder); } public virtual void interface_property_declaration(interface_property_declaration ast, TypeBuilder t) { PropertyBuilder p = t.DefineProperty(ast.sym.Name, PropertyAttributes.None, type(ast.ty), new System.Type[0]); foreach (accessor_declaration x in ast.accessors) { x.builder = DefineMethod(t, x.sym); map.Add(x.sym, x.builder); } } public virtual void method_declaration(method_declaration ast, TypeBuilder t) { ast.builder = DefineMethod(t, ast.sym); map.Add(ast.sym, ast.builder); } public virtual void namespace_declaration(namespace_declaration ast) { foreach (declaration x in ast.nb.declarations) declaration(x); } public virtual void operator_declaration(operator_declaration ast, TypeBuilder t) { } public virtual void operator_declarator(operator_declarator ast, TypeBuilder t) { if (ast is binary_declarator) binary_declarator((binary_declarator)ast, t); else if (ast is explicit_declarator) explicit_declarator((explicit_declarator)ast, t); else if (ast is implicit_declarator) implicit_declarator((implicit_declarator)ast, t); else if (ast is unary_declarator) unary_declarator((unary_declarator)ast, t); else throw new ArgumentException(); } public virtual void property_declaration(property_declaration ast, TypeBuilder t) { PropertyBuilder p = t.DefineProperty(ast.sym.Name, PropertyAttributes.None, type(ast.ty), new System.Type[0]); foreach (accessor_declaration x in ast.decls) { x.builder = DefineMethod(t, x.sym); map.Add(x.sym, x.builder); } ast.builder = p; } public virtual void struct_declaration(struct_declaration ast) { TypeBuilder t = ast.builder; t.SetParent(this[ast.sym.baseClass]); foreach (Type x in ast.sym.interfaces) t.AddInterfaceImplementation(this[x]); foreach (declaration x in ast.body) declaration(x, t); } public virtual void unary_declarator(unary_declarator ast, TypeBuilder t) { } } public class emit3: emit { public emit3(TextWriter w, MessageWriter msg, Hashtable map, ModuleBuilder mod) : base(w, msg, map, mod) {} public class ILState: gen { ILGenerator ILgen; emit map; ArrayList labels = new ArrayList(); ArrayList locals = new ArrayList(); public ILState(ILGenerator ILgen, emit map) : base(map.T, map.msg) { this.ILgen = ILgen; this.map = map; labels.Add(null); locals.Add(null); } System.Type[] arrayMethodArgs(int rank, params System.Type[] prefix) { System.Type[] args = new System.Type[rank+prefix.Length]; Array.Copy(prefix, args, prefix.Length); for (int i = 0; i < rank; i++) args[i+prefix.Length] = typeof (int); return args; } override public object BeginTry() { return ILgen.BeginExceptionBlock(); } override public object BeginFinally(object handle) { ILgen.BeginFinallyBlock(); return handle; } override public void block_statement(block_statement ast) { ILgen.BeginScope(); foreach (statement x in ast.stmts) statement(x); ILgen.EndScope(); } override public void catch_clause(Type ty, Local sym, statement block, object handle) { ILgen.BeginCatchBlock(map[ty]); base.catch_clause(ty, sym, block, handle); } override public void defLabel(int lab) { ILgen.MarkLabel(getLabel(lab)); } void Emit(OpCode op, ConstructorInfo x) { ILgen.Emit(op, x); } void Emit(OpCode op, LocalBuilder x) { ILgen.Emit(op, x); } void Emit(OpCode op, MethodInfo x) { ILgen.Emit(op, x); } void Emit(OpCode op, System.Reflection.Emit.Label x) { ILgen.Emit(op, x); } void Emit(OpCode op, System.Type x) { ILgen.Emit(op, x); } override public void Emit(OpCode op) { ILgen.Emit(op); } override public void Emit(OpCode op, double x) { ILgen.Emit(op, x); } override public void Emit(OpCode op, float x) { ILgen.Emit(op, x); } override public void Emit(OpCode op, Constructor x) { Emit(op, map[x]); } override public void Emit(OpCode op, Field x) { ILgen.Emit(op, map[x]); } override public void Emit(OpCode op, int x) { ILgen.Emit(op, x); } override public void Emit(OpCode op, Formal x) { ILgen.Emit(op, (short)x.ordinal); } override public void Emit(OpCode op, Local x) { ILgen.Emit(op, getLocal(x.ordinal)); } override public void Emit(OpCode op, Method x) { Emit(op, map[x]); } override public void Emit(OpCode op, string x) { ILgen.Emit(op, x); } override public void Emit(OpCode op, Type x) { Emit(op, map[x]); } override public void EmitCreateArray(ArrayType ty, Type ety, int rank) { ILgen.Emit(OpCodes.Newobj, GetArrayMethodToken(ty, ".ctor", null)); } override public void EmitLoad(int index) { Emit(OpCodes.Ldloc, getLocal(index)); } override public void EmitLoadAddress(int index) { Emit(OpCodes.Ldloca, getLocal(index)); } override public void EmitLoadElement(ArrayType ty, Type ety, int rank) { Emit(OpCodes.Call, GetArrayMethodToken(ty, "Get", map[ety])); } override public void EmitLoadElementAddress(ArrayType ty, Type ety, int rank) { System.Type rettype = map[new ManagedPointerType(ety)]; ILgen.Emit(OpCodes.Call, GetArrayMethodToken(ty, "Address", rettype)); } override public void EmitStore(int index) { Emit(OpCodes.Stloc, getLocal(index)); } override public void EmitStoreElement(ArrayType ty, Type ety, int rank) { ILgen.Emit(OpCodes.Call, GetArrayMethodToken(ty, "Set", null, arrayMethodArgs(rank, map[ety]))); } override public void EmitSwitch(int[] caselabels) { System.Reflection.Emit.Label[] labels = new System.Reflection.Emit.Label[caselabels.Length]; for (int i = 0; i < labels.Length; i++) labels[i] = getLabel(caselabels[i]); ILgen.Emit(OpCodes.Switch, labels); } override public void EndTry(object handle) { ILgen.EndExceptionBlock(); } override public int genLabel(int n) { for (int i = 0; i < n; i++) labels.Add(ILgen.DefineLabel()); return base.genLabel(n); } int GetArrayMethodToken(ArrayType ty, string name, System.Type rettype) { return GetArrayMethodToken(ty, name, rettype, arrayMethodArgs(ty.rank)); } int GetArrayMethodToken(ArrayType ty, string name, System.Type rettype, System.Type[] args) { System.Type t = map[ty]; MethodToken m = map.module.GetArrayMethodToken(t, name, CallingConventions.Standard|CallingConventions.HasThis, rettype, args); return m.Token; } System.Reflection.Emit.Label getLabel(int lab) { Debug.Assert(labels[lab] != null); return (System.Reflection.Emit.Label)labels[lab]; } LocalBuilder getLocal(int var) { return (LocalBuilder)locals[var]; } override public void gotoLabel(OpCode inst, int lab) { Emit(inst, getLabel(lab)); } override public int newLocal(Type ty) { locals.Add(ILgen.DeclareLocal(map[ty])); return locals.Count - 1; } override public int newLocal(Local v) { int var = base.newLocal(v); getLocal(var).SetLocalSymInfo(v.Name); return var; } } public virtual void attribute(attribute ast) { if (ast.arguments != null) attribute_arguments(ast.arguments); type(ast.name); } public virtual void attribute_arguments(attribute_arguments ast) { foreach (named_argument x in ast.namedargs) named_argument(x); } public virtual void attribute_section(attribute_section ast) { foreach (attribute x in ast.attributes) attribute(x); } public virtual void attribute_sections(attribute_sectionList attributes) { foreach (attribute_section x in attributes) attribute_section(x); } public virtual void binary_declarator(binary_declarator ast, TypeBuilder t) { } public virtual void class_declaration(class_declaration ast) { attribute_sections(ast.attrs); declarations(ast.sym, ast.body, ast.builder); } public virtual void compilation(compilation ast) { T = ast.global.Types; foreach (compilation_unit x in ast.inputs) compilation_unit(x); } public virtual void compilation_unit(compilation_unit ast) { attribute_sections(ast.attributes); foreach (declaration x in ast.declarations) declaration(x); } public virtual void constant_declaration(constant_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); } public virtual void constructor_declaration(constructor_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); ConstructorBuilder m = ast.builder; if (ast.block != null || ast.decl.init != null) { declarationList body; if (ast.parent is class_declaration) body = ((class_declaration)ast.parent).body; else body = ((struct_declaration)ast.parent).body; ILState g = new ILState(m.GetILGenerator(), this); if (ast.decl.init != null) constructor_initializer(ast.decl.init, g, body); if (ast.sym.IsStatic) foreach (declaration d in body) if (d is field_declaration) field_declaration((field_declaration)d, g, true); if (ast.block != null) g.statement(ast.block, ast.sym); else g.Emit(OpCodes.Ret); } } public virtual void constructor_initializer(constructor_initializer ast, ILState g, declarationList body) { if (ast is base_initializer) { foreach (declaration d in body) if (d is field_declaration) field_declaration((field_declaration)d, g, false); g.base_initializer((base_initializer)ast); } else if (ast is this_initializer) g.this_initializer((this_initializer)ast); else throw new ArgumentException(); } public virtual void declaration(declaration ast, TypeBuilder t) { if (ast is class_declaration) class_declaration((class_declaration)ast); else if (ast is constant_declaration) constant_declaration((constant_declaration)ast, t); else if (ast is constructor_declaration) constructor_declaration((constructor_declaration)ast, t); else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast); else if (ast is destructor_declaration) destructor_declaration((destructor_declaration)ast, t); else if (ast is enum_declaration) enum_declaration((enum_declaration)ast); else if (ast is event_declaration1) event_declaration1((event_declaration1)ast, t); else if (ast is event_declaration2) event_declaration2((event_declaration2)ast, t); else if (ast is field_declaration) return; else if (ast is indexer_declaration) indexer_declaration((indexer_declaration)ast, t); else if (ast is interface_declaration) interface_declaration((interface_declaration)ast); else if (ast is interface_event_declaration) interface_event_declaration((interface_event_declaration)ast, t); else if (ast is interface_indexer_declaration) interface_indexer_declaration((interface_indexer_declaration)ast, t); else if (ast is interface_method_declaration) interface_method_declaration((interface_method_declaration)ast, t); else if (ast is interface_property_declaration) interface_property_declaration((interface_property_declaration)ast, t); else if (ast is method_declaration) method_declaration((method_declaration)ast, t); else if (ast is operator_declaration) operator_declaration((operator_declaration)ast, t); else if (ast is property_declaration) property_declaration((property_declaration)ast, t); else if (ast is struct_declaration) struct_declaration((struct_declaration)ast); else throw new ArgumentException(); } public virtual void declaration(declaration ast) { if (ast is class_declaration) class_declaration((class_declaration)ast); else if (ast is delegate_declaration) delegate_declaration((delegate_declaration)ast); else if (ast is enum_declaration) enum_declaration((enum_declaration)ast); else if (ast is interface_declaration) interface_declaration((interface_declaration)ast); else if (ast is namespace_declaration) namespace_declaration((namespace_declaration)ast); else if (ast is struct_declaration) struct_declaration((struct_declaration)ast); else throw new ArgumentException(); } public virtual void declarations(Type ty, declarationList decls, TypeBuilder t) { foreach (declaration x in decls) declaration(x, t); if (ty.enclosingType == null) map[ty] = t.CreateType(); foreach (declaration x in decls) if (x is type_declaration) { type_declaration d = (type_declaration)x; map[d.typ] = d.builder.CreateType(); } } public virtual void delegate_declaration(delegate_declaration ast) { attribute_sections(ast.attrs); TypeBuilder t = ast.builder; foreach (Symbol s in ast.sym) if (s is Constructor) { ConstructorBuilder m = (ConstructorBuilder)this[(Constructor)s]; m.SetImplementationFlags(MethodImplAttributes.Runtime); } else if (s is Method) { MethodBuilder m = (MethodBuilder)this[(Method)s]; m.SetImplementationFlags(MethodImplAttributes.Runtime); m.CreateMethodBody(new Byte[]{}, 0); } if (ast.sym.enclosingType == null) map[ast.sym] = t.CreateType(); } public virtual void destructor_declaration(destructor_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); if (ast.block != null) EmitMethodBody(ast.sym, ast.block, ast.builder); } public virtual void EmitMethodBody(Method m, statement body, MethodBuilder mb) { EmitMethodBody(m, body, new ILState(mb.GetILGenerator(), this)); } public virtual void EmitMethodBody(Method m, statement body, ILState g) { g.statement(body, m); } public virtual void enum_declaration(enum_declaration ast) { attribute_sections(ast.attrs); } public virtual void event_declaration1(event_declaration1 ast, TypeBuilder t) { attribute_sections(ast.attrs); foreach (event_declarator x in ast.decls) { ILState g = new ILState(x.add_builder.GetILGenerator(), this); g.EmitDefaultAccessor(x.sym, x.sym.Add); g = new ILState(x.remove_builder.GetILGenerator(), this); g.EmitDefaultAccessor(x.sym, x.sym.Remove); x.event_builder.SetAddOnMethod(x.add_builder); x.event_builder.SetRemoveOnMethod(x.remove_builder); } } public virtual void event_declaration2(event_declaration2 ast, TypeBuilder t) { attribute_sections(ast.attrs); EventBuilder e = ast.builder; foreach (event_accessor x in ast.accessors) { attribute_sections(x.attrs); MethodBuilder m = x.builder; EmitMethodBody(x.sym, x.block, m); if (x.id.str == "add") e.SetAddOnMethod(m); else e.SetRemoveOnMethod(m); } } public virtual void explicit_declarator(explicit_declarator ast, TypeBuilder t) { } public virtual void field_declaration(field_declaration ast, ILState g, bool doStatic) { attribute_sections(ast.attrs); foreach (field_declarator x in ast.decls) if (x.init != null) if (doStatic && x.sym.IsStatic) { g.variable_initializer(x.init); g.Emit(OpCodes.Stsfld, x.sym); } else if (!doStatic && !x.sym.IsStatic) { g.this_access(); g.variable_initializer(x.init); g.Emit(OpCodes.Stfld, x.sym); } } public virtual void implicit_declarator(implicit_declarator ast, TypeBuilder t) { } public virtual void indexer_declaration(indexer_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); PropertyBuilder p = ast.builder; foreach (accessor_declaration x in ast.accessors) { MethodBuilder m = x.builder; if (x.body != null) EmitMethodBody(x.sym, x.body, m); if (x.id.str == "get") p.SetGetMethod(m); else p.SetSetMethod(m); } } public virtual void interface_declaration(interface_declaration ast) { attribute_sections(ast.attrs); declarations(ast.sym, ast.body, ast.builder); } public virtual void interface_event_declaration(interface_event_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); } public virtual void interface_indexer_declaration(interface_indexer_declaration ast, TypeBuilder t) { msg.Error("Interface indexers not yet implemented"); } public virtual void interface_method_declaration(interface_method_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); } public virtual void interface_property_declaration(interface_property_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); foreach (accessor_declaration x in ast.accessors) attribute_sections(x.attrs); } public virtual void method_declaration(method_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); if (ast.body != null) EmitMethodBody(ast.sym, ast.body, ast.builder); if (ast.sym.Name == "Main" && ast.sym.IsStatic && ast.sym.IsPublic) ((AssemblyBuilder)t.Assembly).SetEntryPoint(ast.builder, PEFileKinds.ConsoleApplication); } public virtual void named_argument(named_argument ast) { //expression(ast.expr, null); // InputElement ast.id } public virtual void namespace_declaration(namespace_declaration ast) { foreach (declaration x in ast.nb.declarations) declaration(x); } public virtual void operator_declaration(operator_declaration ast, TypeBuilder t) { msg.Error("Operator declarations not yet implemented"); } public virtual void operator_declarator(operator_declarator ast, TypeBuilder t) { if (ast is binary_declarator) binary_declarator((binary_declarator)ast, t); else if (ast is explicit_declarator) explicit_declarator((explicit_declarator)ast, t); else if (ast is implicit_declarator) implicit_declarator((implicit_declarator)ast, t); else if (ast is unary_declarator) unary_declarator((unary_declarator)ast, t); else throw new ArgumentException(); } public virtual void property_declaration(property_declaration ast, TypeBuilder t) { attribute_sections(ast.attrs); PropertyBuilder p = ast.builder; foreach (accessor_declaration x in ast.decls) { attribute_sections(x.attrs); MethodBuilder m = x.builder; if (x.body != null) EmitMethodBody(x.sym, x.body, m); if (x.id.str == "get") p.SetGetMethod(m); else p.SetSetMethod(m); } } public virtual void struct_declaration(struct_declaration ast) { attribute_sections(ast.attrs); declarations(ast.sym, ast.body, ast.builder); } public virtual void unary_declarator(unary_declarator ast, TypeBuilder t) { } }