<commit_before>﻿using Extensions;
using Roku.IntermediateCode;
using Roku.Manager;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Roku.Compiler
{
    public static class CodeGenerator
    {
        public static void Emit(SourceCodeBody body, string path)
        {
            var pgms = Lookup.AllPrograms(body);
            var nss = Lookup.AllNamespaces(body);
            var entrypoint = Lookup.AllFunctionBodies(pgms).FindFirst(x => x.Name == "main");
            var structs = Lookup.AllStructBodies(pgms);
            var externs = Lookup.AllExternFunctions(nss);
            var embedded = Lookup.AllEmbeddedFunctions(nss);
            var extern_structs = Lookup.AllExternStructs(Lookup.GetRootNamespace(body));
            var extern_asms = externs.Map(x => x.Assembly)
                .Concat(extern_structs.Map(x => x.Assembly))
                .By<Assembly>().Unique().ToArray();

            using (var il = new ILWriter(path))
            {
                AssemblyExternEmit(il, extern_asms);
                AssemblyNameEmit(il, path);

                var fss = new List<FunctionCaller>() { new FunctionCaller(entrypoint, new GenericsMapper()) };
                structs.Each(x => AssemblyStructEmit(il, x, fss));
                AssemblyFunctionEmit(il, fss);
            }
        }

        public static Type GetType(ExternFunction e) => e.DeclaringType ?? e.Function.DeclaringType!;

        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 AssemblyStructEmit(ILWriter il, StructBody body, List<FunctionCaller> fss)
        {
            body.SpecializationMapper.Each(sp =>
            {
                var g = sp.Key;
                var mapper = sp.Value;

                il.WriteLine($".class public {body.Name}");
                il.WriteLine("{");
                il.Indent++;
                body.Members.Each(x => il.WriteLine($".field public {GetTypeName(mapper, x.Value, g)} {x.Key}"));<commit_msg>usingを簡略化<commit_after>﻿using Extensions;
using Roku.IntermediateCode;
using Roku.Manager;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Roku.Compiler
{
    public static class CodeGenerator
    {
        public static void Emit(SourceCodeBody body, string path)
        {
            var pgms = Lookup.AllPrograms(body);
            var nss = Lookup.AllNamespaces(body);
            var entrypoint = Lookup.AllFunctionBodies(pgms).FindFirst(x => x.Name == "main");
            var structs = Lookup.AllStructBodies(pgms);
            var externs = Lookup.AllExternFunctions(nss);
            var embedded = Lookup.AllEmbeddedFunctions(nss);
            var extern_structs = Lookup.AllExternStructs(Lookup.GetRootNamespace(body));
            var extern_asms = externs.Map(x => x.Assembly)
                .Concat(extern_structs.Map(x => x.Assembly))
                .By<Assembly>().Unique().ToArray();

            using var il = new ILWriter(path);
            AssemblyExternEmit(il, extern_asms);
            AssemblyNameEmit(il, path);

            var fss = new List<FunctionCaller>() { new FunctionCaller(entrypoint, new GenericsMapper()) };
            structs.Each(x => AssemblyStructEmit(il, x, fss));
            AssemblyFunctionEmit(il, fss);
        }

        public static Type GetType(ExternFunction e) => e.DeclaringType ?? e.Function.DeclaringType!;

        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 AssemblyStructEmit(ILWriter il, StructBody body, List<FunctionCaller> fss)
        {
            body.SpecializationMapper.Each(sp =>
            {
                var g = sp.Key;
                var mapper = sp.Value;

                il.WriteLine($".class public {body.Name}");
                il.WriteLine("{");
                il.Indent++;
                body.Members.Each(x => il.WriteLine($".field public {GetTypeName(mapper, x.Value, g)} {x.Key}"));
{'fraction_non_alphanumeric': 0.1198044009779951, 'fraction_numerical': 0.0, 'mean_word_length': 2.4965034965034967, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2987629', 'n_tokens_mistral': 1293, 'n_tokens_neox': 1256, 'n_words': 269}