|
|
@@ -38,13 +38,14 @@ namespace Natsu.Compiler
|
|
|
|
|
|
class Generator
|
|
|
{
|
|
|
- private readonly ModuleDef _module;
|
|
|
+ private readonly ModuleDefMD _module;
|
|
|
private readonly Dictionary<TypeDef, TypeDesc> _typeDescs = new Dictionary<TypeDef, TypeDesc>();
|
|
|
private readonly List<TypeDesc> _sortedTypeDescs = new List<TypeDesc>();
|
|
|
private readonly CorLibTypes _corLibTypes;
|
|
|
private TypeDesc _szArrayType;
|
|
|
+ private List<string> _userStrings = new List<string>();
|
|
|
|
|
|
- public Generator(ModuleDef module)
|
|
|
+ public Generator(ModuleDefMD module)
|
|
|
{
|
|
|
_module = module;
|
|
|
_corLibTypes = new CorLibTypes(module);
|
|
|
@@ -103,24 +104,44 @@ namespace Natsu.Compiler
|
|
|
writer.WriteLine();
|
|
|
}
|
|
|
|
|
|
+ using (var writerSrc = new StreamWriter(Path.Combine(outputPath, $"{_module.Assembly.Name}.cpp"), false, Encoding.UTF8))
|
|
|
+ {
|
|
|
+ writerSrc.WriteLine("// Generated by natsu clr compiler.");
|
|
|
+ writerSrc.WriteLine($"#include \"{_module.Assembly.Name}.h\"");
|
|
|
+ writerSrc.WriteLine();
|
|
|
+
|
|
|
+ writerSrc.WriteLine($"namespace {TypeUtils.EscapeModuleName(_module)}");
|
|
|
+ writerSrc.WriteLine("{");
|
|
|
+ WriteTypeMethodsBody(writerSrc, false);
|
|
|
+ WriteConstantStringFields(writerSrc);
|
|
|
+ writerSrc.WriteLine("}");
|
|
|
+ }
|
|
|
+
|
|
|
+ var hBody = new StringWriter();
|
|
|
+
|
|
|
+ hBody.WriteLine($"namespace {TypeUtils.EscapeModuleName(_module)}");
|
|
|
+ hBody.WriteLine("{");
|
|
|
+ WriteTypeMethodsBody(hBody, true);
|
|
|
+ hBody.WriteLine("}");
|
|
|
+
|
|
|
writer.WriteLine($"namespace {TypeUtils.EscapeModuleName(_module)}");
|
|
|
writer.WriteLine("{");
|
|
|
- WriteTypeMethodsBody(writer, true);
|
|
|
+ WriteUserStrings(writer);
|
|
|
writer.WriteLine("}");
|
|
|
- }
|
|
|
|
|
|
- using (var writer = new StreamWriter(Path.Combine(outputPath, $"{_module.Assembly.Name}.cpp"), false, Encoding.UTF8))
|
|
|
- {
|
|
|
- writer.WriteLine("// Generated by natsu clr compiler.");
|
|
|
- writer.WriteLine($"#include \"{_module.Assembly.Name}.h\"");
|
|
|
writer.WriteLine();
|
|
|
+ writer.WriteLine(hBody.ToString());
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- writer.WriteLine($"namespace {TypeUtils.EscapeModuleName(_module)}");
|
|
|
- writer.WriteLine("{");
|
|
|
- WriteTypeMethodsBody(writer, false);
|
|
|
- WriteConstantStringFields(writer);
|
|
|
- writer.WriteLine("}");
|
|
|
+ private void WriteUserStrings(StreamWriter writer)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < _userStrings.Count; i++)
|
|
|
+ {
|
|
|
+ writer.Ident(1).WriteLine($"static const natsu::static_object<::System_Private_CorLib::System::String, natsu::string_literal<{_userStrings[i].Length}>> user_string_{i}(uR\"NS({_userStrings[i]})NS\");");
|
|
|
}
|
|
|
+
|
|
|
+ writer.WriteLine();
|
|
|
}
|
|
|
|
|
|
private void WriteConstantStringFields(StreamWriter writer)
|
|
|
@@ -587,7 +608,7 @@ namespace Natsu.Compiler
|
|
|
writer.Ident(ident).WriteLine($"{TypeUtils.EscapeVariableTypeName(value.FieldType, value.DeclaringType)} {TypeUtils.EscapeTypeName(value.DeclaringType, hasModuleName: false)}::{TypeUtils.EscapeIdentifier(value.Name)} = ::natsu::load_string(uR\"NS({value.Constant.Value})NS\"sv);");
|
|
|
}
|
|
|
|
|
|
- private void WriteMethodDeclare(StreamWriter writer, int ident, MethodDef method)
|
|
|
+ private void WriteMethodDeclare(TextWriter writer, int ident, MethodDef method)
|
|
|
{
|
|
|
var methodGens = new List<string>();
|
|
|
|
|
|
@@ -605,7 +626,7 @@ namespace Natsu.Compiler
|
|
|
writer.WriteLine($");");
|
|
|
}
|
|
|
|
|
|
- private void WriteParameterList(StreamWriter writer, ParameterList parameters, bool hasType = true, bool isVTable = false)
|
|
|
+ private void WriteParameterList(TextWriter writer, ParameterList parameters, bool hasType = true, bool isVTable = false)
|
|
|
{
|
|
|
var index = 0;
|
|
|
var method = parameters.Method;
|
|
|
@@ -651,7 +672,7 @@ namespace Natsu.Compiler
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
- private void WriteTypeMethodsBody(StreamWriter writer, bool inHeader)
|
|
|
+ private void WriteTypeMethodsBody(TextWriter writer, bool inHeader)
|
|
|
{
|
|
|
foreach (var type in _sortedTypeDescs)
|
|
|
{
|
|
|
@@ -659,7 +680,7 @@ namespace Natsu.Compiler
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void WriteTypeMethodBody(StreamWriter writer, int ident, TypeDesc type, bool inHeader)
|
|
|
+ private void WriteTypeMethodBody(TextWriter writer, int ident, TypeDesc type, bool inHeader)
|
|
|
{
|
|
|
foreach (var method in type.TypeDef.Methods)
|
|
|
{
|
|
|
@@ -681,7 +702,7 @@ namespace Natsu.Compiler
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void WriteMethodBody(StreamWriter writer, int ident, MethodDef method)
|
|
|
+ private void WriteMethodBody(TextWriter writer, int ident, MethodDef method)
|
|
|
{
|
|
|
writer.Ident(ident);
|
|
|
var typeGens = new List<string>();
|
|
|
@@ -709,7 +730,7 @@ namespace Natsu.Compiler
|
|
|
writer.Flush();
|
|
|
}
|
|
|
|
|
|
- private void WriteVTableMethodDeclare(StreamWriter writer, int ident, MethodDef method)
|
|
|
+ private void WriteVTableMethodDeclare(TextWriter writer, int ident, MethodDef method)
|
|
|
{
|
|
|
writer.Ident(ident);
|
|
|
|
|
|
@@ -752,7 +773,7 @@ namespace Natsu.Compiler
|
|
|
writer.Flush();
|
|
|
}
|
|
|
|
|
|
- private void WriteVTableMethodBody(StreamWriter writer, int ident, MethodDef method)
|
|
|
+ private void WriteVTableMethodBody(TextWriter writer, int ident, MethodDef method)
|
|
|
{
|
|
|
writer.Ident(ident);
|
|
|
var typeGens = new List<string>();
|
|
|
@@ -791,7 +812,7 @@ namespace Natsu.Compiler
|
|
|
writer.Flush();
|
|
|
}
|
|
|
|
|
|
- private void WriteILBody(StreamWriter writer, int ident, MethodDef method)
|
|
|
+ private void WriteILBody(TextWriter writer, int ident, MethodDef method)
|
|
|
{
|
|
|
var body = method.Body;
|
|
|
|
|
|
@@ -801,12 +822,12 @@ namespace Natsu.Compiler
|
|
|
}
|
|
|
|
|
|
//Console.WriteLine(method);
|
|
|
- var importer = new ILImporter(method, writer, ident);
|
|
|
+ var importer = new ILImporter(method, writer, ident) { UserStrings = _userStrings, ModuleName = TypeUtils.EscapeModuleName(_module.Assembly) };
|
|
|
importer.ImportBlocks(body.Instructions);
|
|
|
importer.Gencode();
|
|
|
}
|
|
|
|
|
|
- private void WriteLocal(Local local, StreamWriter writer, int ident, MethodDef method)
|
|
|
+ private void WriteLocal(Local local, TextWriter writer, int ident, MethodDef method)
|
|
|
{
|
|
|
writer.Ident(ident).WriteLine($"{TypeUtils.EscapeVariableTypeName(local.Type)} _l{local.Index};");
|
|
|
}
|