956 lines
39 KiB
C#
956 lines
39 KiB
C#
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 != "<stream>")
|
|
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) {
|
|
}
|
|
}
|