public static void AssemblyFunctionEmit(ILWriter il, List <FunctionSpecialization> fss) { for (var i = 0; i < fss.Count; i++) { var f = fss[i].Body.Cast <IFunctionBody>(); var g = fss[i].GenericsMapper; var mapper = Lookup.GetTypemapper(f.SpecializationMapper, g); il.WriteLine($".method public static {GetTypeName(mapper, f.Return, g)} {EscapeILName(f.Name)}({f.Arguments.Map(a => GetTypeName(mapper[a.Name], g)).Join(", ")})"); il.WriteLine("{"); il.Indent++; if (i == 0) { il.WriteLine(".entrypoint"); } il.WriteLine(".maxstack 8"); var local_vals = mapper.Values.Where(x => x.Type == VariableType.LocalVariable && !(x.Struct is NamespaceBody)).Sort((a, b) => a.Index - b.Index).ToList(); local_vals.Each((x, i) => x.Index = i); if (local_vals.Count > 0) { il.WriteLine(".locals("); il.Indent++; local_vals.Map(x => x.Struct).By <AnonymousFunctionBody>().Each(x => CallToAddEmitFunctionList(mapper, x, fss)); il.WriteLine(local_vals.Map(x => $"[{x.Index}] {GetTypeName(x, g)} {x.Name}").Join(",\n")); il.Indent--; il.WriteLine(")"); } var labels = Lookup.AllLabels(f.Body).Zip(Lists.Sequence(1)).ToDictionary(x => x.First, x => $"_{x.First.Name}{x.Second}"); f.Body.Each(x => { if (x is Call call) { CallToAddEmitFunctionList(mapper, call, fss); } AssemblyOperandEmit(il, x, f, mapper, labels, g); }); il.WriteLine("ret"); il.Indent--; il.WriteLine("}"); } }
public static void AssemblyStructEmit(ILWriter il, StructBody body, List <FunctionSpecialization> fss) { var cache = new HashSet <string>(); body.SpecializationMapper.Each(sp => { var g = sp.Key; var mapper = sp.Value; var name = GetStructName(body.Name, body, g); if (cache.Contains(name)) { return; } cache.Add(name); il.WriteLine($".class public {name}"); il.WriteLine("{"); il.Indent++; body.Members.Each(x => il.WriteLine($".field public {GetTypeName(mapper, x.Value, g)} {EscapeILName(x.Key)}")); il.WriteLine(""); il.WriteLine($".method public void .ctor()"); il.WriteLine("{"); il.Indent++; var local_vals = mapper.Values.Where(x => x.Type == VariableType.LocalVariable && !(x.Struct is NamespaceBody)).Sort((a, b) => a.Index - b.Index).ToList(); local_vals.Each((x, i) => x.Index = i); if (local_vals.Count > 0) { il.WriteLine(".locals("); il.Indent++; il.WriteLine(local_vals.Map(x => $"[{x.Index}] {GetTypeName(x, g)} {x.Name}").Join(",\n")); il.Indent--; il.WriteLine(")"); } var labels = Lookup.AllLabels(body.Body).Zip(Lists.Sequence(1)).ToDictionary(x => x.First, x => $"_{x.First.Name}{x.Second}"); body.Body.Each(x => { if (x is Call call) { CallToAddEmitFunctionList(mapper, call, fss); } AssemblyOperandEmit(il, x, body.Namespace, mapper, labels, g); }); il.WriteLine("ret"); il.Indent--; il.WriteLine("}"); il.Indent--; il.WriteLine("}"); }); }
public static void AssemblyExternEmit(ILWriter il, Assembly[] extern_asms) => extern_asms.Each(x => il.WriteLine($".assembly extern {x.GetName().Name} {{}}"));
public static void AssemblyNameEmit(ILWriter il, string path) => il.WriteLine($".assembly {Path.GetFileNameWithoutExtension(path)} {{}}");
public static void AssemblyOperandEmit(ILWriter il, IOperand op, INamespace ns, TypeMapper m, Dictionary <LabelCode, string> labels, GenericsMapper g) { il.WriteLine(); if (op is IReturnBind prop && prop.Return is { } && m[prop.Return].Type == VariableType.Property)