patterncsharpModerate
Interpreting Brainfuck code to C#, then compiling to a .exe
Viewed 0 times
exeinterpretingcodecompilingthenbrainfuck
Problem
This is a C# programme to convert Brainfuck to C#, then convert that C# to a .exe. So basically, it's a Brainfuck to Windows exe file converter/compiler.
This requires any of:
Just specify
Do note that this uses classes from my Framework library. If you wish to run it you'll need to download the
It's also on GitHub.
```
class Program
{
static string AddExtension(string data, string extension)
{
if (data.IndexOf('.') == -1)
{
data += extension;
}
return data;
}
static void AcquireInput(ILogger logger, out string sourceFile, out string programName, out string destinationFile, out string executableFile, out int bufferSize, out string dotNetVersion)
{
ConsolePrompt prompt = new ConsolePrompt(new EmptyLogger());
logger.LogVerbose("Prompting for input...");
sourceFile = AddExtension(prompt.Prompt("Enter the source filename (.bf)", PromptOptions.Required), ".bf");
programName = sourceFile.Substring(0, sourceFile.LastIndexOf('.'));
destinationFile = AddExtension(prompt.Prompt("Enter the destination filename (.cs)", PromptOptions.Optional, programName + ".cs"), ".cs");
executableFile = AddExtension(prompt.Prompt("Enter the destination executable (.exe)", PromptOptions.Optional, programName + ".exe"), ".exe");
bufferSize = prompt.Prompt("Enter buffer size", PromptOptions.Optional, 2048);
dotNetVersion = prompt.Prompt("Enter .NET version to compile with", PromptOptions.Optional, "4.0", "Version can be any of: 2.0, 3.5, 4.0", x => _dotNetFolders.ContainsKey(x));
logger.LogVerbose("Input acqu
This requires any of:
- .NET 2.0 in C:\Windows\Microsoft.NET\Framework\v2.0.50727
- .NET 3.5 in C:\Windows\Microsoft.NET\Framework\v3.5
- .NET 4.0 in C:\Windows\Microsoft.NET\Framework\v4.0.30319
Just specify
2.0, 3.5, or 4.0 at the appropriate prompt.Do note that this uses classes from my Framework library. If you wish to run it you'll need to download the
Evbpc.Framework project there and compile it. (Or remove all of the ConsolePrompt, ConsoleLogger, and IPrompt stuff.)It's also on GitHub.
```
class Program
{
static string AddExtension(string data, string extension)
{
if (data.IndexOf('.') == -1)
{
data += extension;
}
return data;
}
static void AcquireInput(ILogger logger, out string sourceFile, out string programName, out string destinationFile, out string executableFile, out int bufferSize, out string dotNetVersion)
{
ConsolePrompt prompt = new ConsolePrompt(new EmptyLogger());
logger.LogVerbose("Prompting for input...");
sourceFile = AddExtension(prompt.Prompt("Enter the source filename (.bf)", PromptOptions.Required), ".bf");
programName = sourceFile.Substring(0, sourceFile.LastIndexOf('.'));
destinationFile = AddExtension(prompt.Prompt("Enter the destination filename (.cs)", PromptOptions.Optional, programName + ".cs"), ".cs");
executableFile = AddExtension(prompt.Prompt("Enter the destination executable (.exe)", PromptOptions.Optional, programName + ".exe"), ".exe");
bufferSize = prompt.Prompt("Enter buffer size", PromptOptions.Optional, 2048);
dotNetVersion = prompt.Prompt("Enter .NET version to compile with", PromptOptions.Optional, "4.0", "Version can be any of: 2.0, 3.5, 4.0", x => _dotNetFolders.ContainsKey(x));
logger.LogVerbose("Input acqu
Solution
Dayum, there's some
Why not make it an instance class?
What you have here is a workflow, where methods have a specific order. This is clearly seen in your
Doing this would also mean you wouldn't need all those dirty
as class members, which would make sense. This would also let you inject the dependancies of your logger at one place, instead of having it as a parameter for each of your methods.
You didn't specify your access modifier, you should. It's always easier if they're there, this way you don't have to wonder "Did I forget to make it
Your
Finally, you've made a method for every step of your "workflow" except for the one where you replace your placeholders with actual values. You could argue 2-3 lines of code don't deserve a method, but I think they do!
In the best case scenario, you should have something like this in your
By retyping this, I realized you have a constant in your code that isn't a..
I figured I didn't need to retype all the methods as you probably get my point, but if there's something not clear about the workflow process and you'd like me to write it all, I'll do it!
static around here.Why not make it an instance class?
What you have here is a workflow, where methods have a specific order. This is clearly seen in your
Main method. The workflow usually have a state, and static stuff is supposed to be stateless. So I really think an instance class would be good!Doing this would also mean you wouldn't need all those dirty
out parameters, nobody loves them anyway! You could keep these ->string sourceFile = string.Empty;
string programName = string.Empty;
string destinationFile = string.Empty;
string executableFile = string.Empty;
string dotNetVersion = string.Empty;as class members, which would make sense. This would also let you inject the dependancies of your logger at one place, instead of having it as a parameter for each of your methods.
You didn't specify your access modifier, you should. It's always easier if they're there, this way you don't have to wonder "Did I forget to make it
[internal,private,public] or was private intended?"Your
static Dictionary should be at the top of your class, in order to follow conventions about the file template!Finally, you've made a method for every step of your "workflow" except for the one where you replace your placeholders with actual values. You could argue 2-3 lines of code don't deserve a method, but I think they do!
In the best case scenario, you should have something like this in your
Main method (which, btw, would be named something else if it was in an instance class)//All the initialization that was here is now in the constructor
AcquireInput();
string brainfuck = LoadBrainfuckCode();
string result = AcquireTemplate("CompiledTemplate.cs");
string brainfuckCode = InterpretBrainfuck(brainfuck);
result = ReplacePlaceHolders(result,brainfuckCode);
WriteToCsFile(_logger, _destinationFile, result);
CompileCsFile(_logger, _dotNetFolders[dotNetVersion], _destinationFile, _executableFile);
_logger.LogInformation("Launching programme...");
Process.Start(_executableFile);
_logger.LogInformation("Programme launched.");
Console.WriteLine("Press enter key to exit...");
Console.ReadLine();By retyping this, I realized you have a constant in your code that isn't a..
const. You should really extract it, so it's clear does "CompiledTemplate.cs" means.I figured I didn't need to retype all the methods as you probably get my point, but if there's something not clear about the workflow process and you'd like me to write it all, I'll do it!
Code Snippets
string sourceFile = string.Empty;
string programName = string.Empty;
string destinationFile = string.Empty;
string executableFile = string.Empty;
string dotNetVersion = string.Empty;//All the initialization that was here is now in the constructor
AcquireInput();
string brainfuck = LoadBrainfuckCode();
string result = AcquireTemplate("CompiledTemplate.cs");
string brainfuckCode = InterpretBrainfuck(brainfuck);
result = ReplacePlaceHolders(result,brainfuckCode);
WriteToCsFile(_logger, _destinationFile, result);
CompileCsFile(_logger, _dotNetFolders[dotNetVersion], _destinationFile, _executableFile);
_logger.LogInformation("Launching programme...");
Process.Start(_executableFile);
_logger.LogInformation("Programme launched.");
Console.WriteLine("Press enter key to exit...");
Console.ReadLine();Context
StackExchange Code Review Q#107713, answer score: 11
Revisions (0)
No revisions yet.