Context
The multiquine structure is composed by the bootstrap, the data declaration and the code.
Here is a C# example.
/*BOOTSTRAP*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Multiquine
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> data = new Dictionary<string, string>();
/*DATA*/
data.Add("cs", "CS_CODE_PLACEHOLDER");
data.Add("js", "JS_CODE_PLACEHOLDER");
data.Add("bf", "BF_CODE_PLACEHOLDER");
/*CODE*/
string language = args.Length == 0 ? "cs" : args[0];
string code = data[language];
Dictionary<string, string> bootstraps = new Dictionary<string, string>();
bootstraps.Add("cs", "CS_BOOTSTRAP_PLACEHOLDER");
bootstraps.Add("js", "JS_BOOTSTRAP_PLACEHOLDER");
bootstraps.Add("bf", "BF_BOOTSTRAP_PLACEHOLDER");
Dictionary<string, string> dataAdd = new Dictionary<string, string>();
dataAdd.Add("cs", " data.Add(\"{0}\", \"{1}\");" + Environment.NewLine);
dataAdd.Add("js", " {0}: \"{1}\"," + Environment.NewLine);
string res = bootstraps[language];
if (language == "bf")
{
StringBuilder sb = new StringBuilder();
foreach (string key in data.Keys)
{
foreach (char c in key)
{
if (c == '\n') continue;
if (c == '\r')
{
sb.Append("++++++++++>");
continue;
}
sb.Append(new string('+', (int)c) + ">");
}
sb.Append(">");
foreach (char c in data[key])
{
if (c == '\n') continue;
if (c == '\r')
{
sb.Append("++++++++++>");
continue;
}
sb.Append(new string('+', (int)c) + ">");
}
sb.Append(">");
}
res += sb.ToString() + Environment.NewLine;
}
else
{
foreach (string key in data.Keys)
res += String.Format(dataAdd[language], key, data[key].Replace("\\", "\\\\").Replace("\"", "\\\"").Replace(Environment.NewLine, @"\r\n"));
}
res += code;
Console.Write(res);
}
}
}
The bootstrap
/*BOOTSTRAP*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Multiquine
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> data = new Dictionary<string, string>();
As mentionned, it's a static part, in C#, to initialize our program the way source code should be.
It also initializes the data structure, though the data themselves are not set yet.
It also initializes the data structure, though the data themselves are not set yet.
The data
/*DATA*/
data.Add("cs", "CS_CODE_PLACEHOLDER");
data.Add("js", "JS_CODE_PLACEHOLDER");
data.Add("bf", "BF_CODE_PLACEHOLDER");
In other words, for each language, add some data (we use placeholders that will be filled later)
The code
/*CODE*/Everything that arrives after data declaration is the code. And our C# code does exactly what JS code will do, or BF code as well.
string language = args.Length == 0 ? "cs" : args[0];
string code = data[language];
Dictionary<string, string> bootstraps = new Dictionary<string, string>();
bootstraps.Add("cs", "CS_BOOTSTRAP_PLACEHOLDER");
bootstraps.Add("js", "JS_BOOTSTRAP_PLACEHOLDER");
bootstraps.Add("bf", "BF_BOOTSTRAP_PLACEHOLDER");
Dictionary<string, string> dataAdd = new Dictionary<string, string>();
dataAdd.Add("cs", " data.Add(\"{0}\", \"{1}\");" + Environment.NewLine);
dataAdd.Add("js", " {0}: \"{1}\"," + Environment.NewLine);
string res = bootstraps[language];
if (language == "bf")
{
StringBuilder sb = new StringBuilder();
foreach (string key in data.Keys)
{
foreach (char c in key)
{
if (c == '\n') continue;
if (c == '\r')
{
sb.Append("++++++++++>");
continue;
}
sb.Append(new string('+', (int)c) + ">");
}
sb.Append(">");
foreach (char c in data[key])
{
if (c == '\n') continue;
if (c == '\r')
{
sb.Append("++++++++++>");
continue;
}
sb.Append(new string('+', (int)c) + ">");
}
sb.Append(">");
}
res += sb.ToString() + Environment.NewLine;
}
else
{
foreach (string key in data.Keys)
res += String.Format(dataAdd[language], key, data[key].Replace("\\", "\\\\").Replace("\"", "\\\"").Replace(Environment.NewLine, @"\r\n"));
}
res += code;
Console.Write(res);
}
}
}
- First, determine the desired output language (CS, JS or BF)
- Then, initialize the output with target language's bootstrap (again, using placeholders, as other languages' bootstrap codes are not defined yet)
- In theory, we should do the same for the 2 other languages, and only then move to the next part of the code, as it requires some knowledge about other quines' data declaration structure...
- Build BF data declaration (write language name, and then language data, for each language), just make sure line breaks are processed in a slightly different way (to be more compliant with different interpreters)
- OR build other languages data declaration (C# and JS were grouped because quite similar)
- Finally, append target language's specific code (id est, append data as it's supposed to be the code, as string)
The next post will present the 3 templates, for CS, BF and JS, and the final results.
Aucun commentaire:
Enregistrer un commentaire