Search

lundi 20 mars 2017

Mutiquine: structure (3)

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.

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*/
            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);
        }
    }
}
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.

  • 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