JITCompiler.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using NTERA.Engine.Compiler;
  9. namespace NTERA.Engine.Runtime
  10. {
  11. public class JITCompiler : IExecutionProvider
  12. {
  13. public ICollection<FunctionDefinition> DefinedProcedures { get; protected set; }
  14. public ICollection<FunctionDefinition> DefinedFunctions { get; protected set; }
  15. public ICollection<FunctionVariable> DefinedConstants { get; protected set; }
  16. public CSVDefinition CSVDefinition { get; protected set; }
  17. public Dictionary<FunctionDefinition, ExecutionNode[]> CompiledProcedures { get; protected set; } = new Dictionary<FunctionDefinition, ExecutionNode[]>();
  18. public string InputDirectory { get; }
  19. public static int Threads = 4;
  20. public JITCompiler(string path)
  21. {
  22. InputDirectory = path;
  23. Compile();
  24. }
  25. protected void Compile()
  26. {
  27. string csvPath = Path.Combine(InputDirectory, "CSV");
  28. string erbPath = Path.Combine(InputDirectory, "ERB");
  29. var csvDefinition = new CSVDefinition();
  30. Console.WriteLine("Preprocessing CSV files...");
  31. foreach (var file in Directory.EnumerateFiles(csvPath, "*.csv", SearchOption.AllDirectories))
  32. {
  33. string path = Path.GetFileNameWithoutExtension(file);
  34. if (path.EndsWith("_TR"))
  35. continue;
  36. Preprocessor.ProcessCSV(csvDefinition, path, File.ReadLines(file, Encoding.UTF8));
  37. }
  38. Console.WriteLine("Preprocessing header files...");
  39. ConcurrentBag<FunctionVariable> preprocessedConstants = new ConcurrentBag<FunctionVariable>();
  40. #if DEBUG
  41. foreach (var file in Directory.EnumerateFiles(erbPath, "*.erh", SearchOption.AllDirectories))
  42. #else
  43. Parallel.ForEach(Directory.EnumerateFiles(erbPath, "*.erh", SearchOption.AllDirectories), new ParallelOptions
  44. {
  45. MaxDegreeOfParallelism = Threads
  46. }, file =>
  47. #endif
  48. {
  49. foreach (var variable in Preprocessor.PreprocessHeaderFile(File.ReadAllText(file)))
  50. preprocessedConstants.Add(variable);
  51. #if DEBUG
  52. }
  53. #else
  54. });
  55. #endif
  56. Console.WriteLine("Preprocessing functions...");
  57. ConcurrentDictionary<FunctionDefinition, string> preprocessedFunctions = new ConcurrentDictionary<FunctionDefinition, string>();
  58. #if DEBUG
  59. foreach (var file in Directory.EnumerateFiles(erbPath, "*.erb", SearchOption.AllDirectories))
  60. #else
  61. Parallel.ForEach(Directory.EnumerateFiles(erbPath, "*.erb", SearchOption.AllDirectories), new ParallelOptions
  62. {
  63. MaxDegreeOfParallelism = Threads
  64. }, file =>
  65. #endif
  66. {
  67. foreach (var kv in Preprocessor.PreprocessCodeFile(File.ReadAllText(file), Path.GetFileName(file), preprocessedConstants.ToArray()))
  68. preprocessedFunctions[kv.Key] = kv.Value;
  69. #if DEBUG
  70. }
  71. #else
  72. });
  73. #endif
  74. DefinedProcedures = preprocessedFunctions.Select(kv => kv.Key).ToArray();
  75. var DeclaredProcedures = preprocessedFunctions.ToDictionary(kv => kv.Key, kv => kv.Value);
  76. var declaredFunctions = BaseDefinitions.DefaultGlobalFunctions.ToList();
  77. declaredFunctions.AddRange(DeclaredProcedures.Keys.Where(x => x.IsReturnFunction));
  78. var procedures = DeclaredProcedures.Keys.Where(x => !x.IsReturnFunction).ToList();
  79. Console.WriteLine("Compiling functions...");
  80. #if DEBUG
  81. foreach (var kv in DeclaredProcedures)
  82. #else
  83. Parallel.ForEach(DeclaredProcedures, new ParallelOptions
  84. {
  85. MaxDegreeOfParallelism = Threads
  86. }, kv =>
  87. #endif
  88. {
  89. Parser parser = new Parser(kv.Value, kv.Key, declaredFunctions, procedures, BaseDefinitions.DefaultGlobalVariables, kv.Key.Variables, BaseDefinitions.DefaultKeywords, csvDefinition, preprocessedConstants.ToArray());
  90. var nodes = parser.Parse(out var localErrors, out var localWarnings);
  91. if (localErrors.Count > 0)
  92. throw new ParserException($"Failed to compile '{kv.Key.Name}'");
  93. CompiledProcedures.Add(kv.Key, nodes.ToArray());
  94. #if DEBUG
  95. }
  96. #else
  97. });
  98. #endif
  99. }
  100. public IEnumerable<ExecutionNode> GetExecutionNodes(FunctionDefinition function)
  101. {
  102. return CompiledProcedures[function];
  103. }
  104. }
  105. }