<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
using Mono.Cecil.Cil;
using Mono.Cecil;
using VCSFramework.Assembly;
using System.Collections.Immutable;
using System.Reflection;

namespace VCSCompiler
{
    internal class CilCompiler
    {
		public static IEnumerable<AssemblyLine> CompileMethod(MethodDefinition definition, IImmutableDictionary<string, ProcessedType> types, Assembly frameworkAssembly)
		{
			// TODO - If this is the entry point, automatically initialize memory and invoke static constructor.
			var instructionCompiler = new CilInstructionCompiler(definition, types);
			var instructions = definition.Body.Instructions;
			var compilationActions = ProcessInstructions(instructions, types, frameworkAssembly);
			var instructionsToLabel = GetInstructionsToEmitLabelsFor(instructions).ToArray();
			var compiledBody = new List<AssemblyLine>();
			// Iterate over Instruction::Next so we can rewrite instructions while processing.
			for(var instruction = instructions.First(); instruction != null; instruction = instruction.Next)
			{
				Console.WriteLine($"{instruction}  -->");
				if (instructionsToLabel.Contains(instruction))
				{
					compiledBody.Add(AssemblyFactory.Label(LabelGenerator.GetFromInstruction(instruction)));
				}
				var vcsInstructions = instructionCompiler.CompileInstruction(instruction).ToArray();
				compiledBody.AddRange(vcsInstructions);
				foreach(var vcsInstruction in vcsInstructions)
				{
					Console.WriteLine($"  {vcsInstruction}");
				}
			}
			compiledBody = OptimizeMethod(compiledBody).ToList();
			return compiledBody;
		}

		private static IEnumerable<ICompilationAction> ProcessInstructions(IEnumerable<Instruction> instructions, IImmutableDictionary<string, ProcessedType> types, Assembly frameworkAssembly)
		{
			var actions = new List<ICompilationAction>();

			foreach(var instruction in instructions.Reverse())
			{
				if (actions.Any(a => a.ConsumedInstructions.Contains(instruction)))
				{
					continue;
				}

				if (instruction.OpCode == OpCodes.Call && IsCompileTimeExecutable((MethodReference)instruction.Operand))
				{
					actions.Add(CreateExecuteCommand(instruction, types, frameworkAssembly));
				}
				else
				{
					actions.Add(new CompileCompilationAction(instruction));<commit_msg>Replace Instruction-based loop with ICompilationAction-based loop, unfortunately this breaks the behavior of inline assembly skipping the subsequent pop instruction.<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
using Mono.Cecil.Cil;
using Mono.Cecil;
using VCSFramework.Assembly;
using System.Collections.Immutable;
using System.Reflection;

namespace VCSCompiler
{
    internal class CilCompiler
    {
		public static IEnumerable<AssemblyLine> CompileMethod(MethodDefinition definition, IImmutableDictionary<string, ProcessedType> types, Assembly frameworkAssembly)
		{
			// TODO - If this is the entry point, automatically initialize memory and invoke static constructor.
			var instructionCompiler = new CilInstructionCompiler(definition, types);
			var instructions = definition.Body.Instructions;
			var compilationActions = ProcessInstructions(instructions, types, frameworkAssembly);
			var instructionsToLabel = GetInstructionsToEmitLabelsFor(instructions).ToArray();
			var compiledBody = new List<AssemblyLine>();
			var compilationContext = new CompilationContext(instructionCompiler);
			foreach (var action in compilationActions)
			{
				var needLabel = action.ConsumedInstructions.Where(i => instructionsToLabel.Contains(i)).ToArray();
				foreach (var toLabel in needLabel)
				{
					compiledBody.Add(AssemblyFactory.Label(LabelGenerator.GetFromInstruction(toLabel)));
				}

				compiledBody.AddRange(action.Execute(compilationContext));
			}

			compiledBody = OptimizeMethod(compiledBody).ToList();
			return compiledBody;
		}

		private static IEnumerable<ICompilationAction> ProcessInstructions(IEnumerable<Instruction> instructions, IImmutableDictionary<string, ProcessedType> types, Assembly frameworkAssembly)
		{
			var actions = new List<ICompilationAction>();

			foreach(var instruction in instructions.Reverse())
			{
				if (actions.Any(a => a.ConsumedInstructions.Contains(instruction)))
				{
					continue;
				}

				if (instruction.OpCode == OpCodes.Call && IsCompileTimeExecutable((MethodReference)instruction.Operand))
				{
					actions.Add(CreateExecuteCommand(instruction, types, frameworkAssembly));
				}
				else
				{
					actions.Add(new CompileCompilationAction(instruction));
{'fraction_non_alphanumeric': 0.08957795004306632, 'fraction_numerical': 0.0, 'mean_word_length': 5.345628415300546, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, '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': '3484547', 'n_tokens_mistral': 1403, 'n_tokens_neox': 1183, 'n_words': 278}