예제 #1
0
        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("}");
            }
        }
예제 #2
0
        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("}");
            });
        }
예제 #3
0
 public static void AssemblyExternEmit(ILWriter il, Assembly[] extern_asms) => extern_asms.Each(x => il.WriteLine($".assembly extern {x.GetName().Name} {{}}"));
예제 #4
0
 public static void AssemblyNameEmit(ILWriter il, string path) => il.WriteLine($".assembly {Path.GetFileNameWithoutExtension(path)} {{}}");
예제 #5
0
 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)