public static void Emit(RootNamespace root, 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).Concat(Lookup.AllStructBodies(root)); 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 <FunctionSpecialization>() { new FunctionSpecialization(entrypoint, new GenericsMapper()) }; structs.Each(x => AssemblyStructEmit(il, x, fss)); AssemblyFunctionEmit(il, fss); }
public static StructBody TypeBodyDefinition(SourceCodeBody src, StructNode sn) { var body = new StructBody(src, sn.Name.Name); sn.Generics.Each(x => body.Generics.Add(new TypeGenericsParameter(x.Name))); FunctionBodyDefinition(body, sn.Statements); sn.Statements.Each(let => { switch (let) { case LetNode x: body.Members.Add(x.Var.Name, body.LexicalScope[x.Var.Name]); break; case LetTypeNode x: body.Members.Add(x.Var.Name, body.LexicalScope[x.Var.Name]); break; default: throw new Exception(); } }); if (sn.Generics.Count == 0) { body.SpecializationMapper[new GenericsMapper()] = new TypeMapper(); src.Functions.Add(new EmbeddedFunction(sn.Name.Name, sn.Name.Name) { OpCode = (args) => $"newobj instance void {sn.Name.Name}::.ctor()" }); } return(body); }
public static SourceCodeBody LoadProgram(RootNamespace root, ProgramNode pgm) { var src = new SourceCodeBody(); src.Uses.Add(root); TypeDefinition(src, pgm); FunctionDefinition(src, pgm); return(src); }
public static void TypeInference(RootNamespace root, SourceCodeBody src) { var srcs = Lookup.AllPrograms(src).ToList(); while (true) { var resolved = false; Lookup.AllStructBodies(srcs).Concat(Lookup.AllStructBodies(root)).Each(x => resolved = TypeInference(x) || resolved); Lookup.AllFunctionBodies(srcs).Concat(Lookup.AllFunctionBodies(root)).Each(x => resolved = TypeInference(x) || resolved); if (!resolved) { break; } } }
public static List <SourceCodeBody> AllPrograms(SourceCodeBody src) { var readed = new HashSet <SourceCodeBody>(); List <SourceCodeBody> use_load(SourceCodeBody source) { var xs = new List <SourceCodeBody>(); if (!readed.Contains(source)) { xs.Add(source); readed.Add(source); } xs.AddRange(source.Uses.By <SourceCodeBody>().Map(xs => use_load(xs)).Flatten()); return(xs); } return(use_load(src)); }
public static List <INamespace> AllNamespaces(SourceCodeBody src) { var readed = new HashSet <INamespace>(); List <INamespace> use_load(INamespace source) { var xs = new List <INamespace>(); if (!readed.Contains(source)) { xs.Add(source); readed.Add(source); } if (source is IUse body) { xs.AddRange(body.Uses.Map(xs => use_load(xs)).Flatten()); } return(xs); } return(use_load(src)); }
public static void TypeDefinition(SourceCodeBody src, ProgramNode pgm) { pgm.Structs.Each(x => src.Structs.Add(TypeBodyDefinition(src, x))); }