Add translator from poyo

This commit is contained in:
2025-05-16 14:07:02 +02:00
parent f83f59c05a
commit f39d936024
3 changed files with 219 additions and 75 deletions

View File

@@ -7,8 +7,19 @@ Console.OutputEncoding = Encoding.UTF8;
var text = "Immutable abstract representation of a span of text. For example, in an error diagnostic that reports a location, it could come from a parsed string, text from a tool editor buffer, etc.";
Console.WriteLine("Original:");
Console.WriteLine(text);
Console.WriteLine();
var translator = new PoyoLangTranslator();
var translated = translator.TranslateToPoyo(text);
Console.WriteLine("Translated to Poyo:");
Console.WriteLine(translated);
Console.WriteLine();
var original = translator.TranslateFromPoyo(translated);
Console.WriteLine("Translated back from Poyo:");
Console.WriteLine(original);

View File

@@ -26,16 +26,22 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
var formattedDictionaries = parsedDictionaries
.Select(static (dictionary, _) =>
{
// Reverse dictionary order to have ngrams first
return dictionary!.OrderBy(p => p.Value).ToDictionary(p => p.Value, p => p.Key);
// Return normal and reverse dictionary order to have ngrams first
return (
Normal: dictionary,
Reversed: dictionary!.OrderBy(p => p.Value).ToDictionary(p => p.Value, p => p.Key)
);
});
var prefixTrees = formattedDictionaries
.Select(static (formattedDictionary, _) => BuildPrefixTree(formattedDictionary));
.Select(static (dictionaries, _) => (
Dictionary: dictionaries.Normal,
PrefixTree: BuildPrefixTree(dictionaries.Reversed)
));
context.RegisterSourceOutput(prefixTrees, static (sourceProductionContext, prefixTree) =>
context.RegisterSourceOutput(prefixTrees, static (sourceProductionContext, data) =>
{
sourceProductionContext.AddSource("PoyoLangTranslator.g.cs", GenerateSource(prefixTree));
sourceProductionContext.AddSource("PoyoLangTranslator.g.cs", GenerateSource(data.Dictionary, data.PrefixTree));
});
}
@@ -103,7 +109,7 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
}
}
private static string GenerateSource(List<Node> rootNodes)
private static string GenerateSource(Dictionary<string, string> dictionary, List<Node> rootNodes)
{
var source = new StringBuilder();
@@ -128,6 +134,22 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
"""
);
GenerateNextLetterMethod(rootNodes, source);
GenerateFromPoyoMethod(dictionary, source);
// Partial class end
source.Append(
"""
}
"""
);
return source.ToString();
}
private static void GenerateNextLetterMethod(List<Node> rootNodes, StringBuilder source)
{
// Next letter method definition
source.Append(
"""
@@ -151,7 +173,7 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
"""
);
GenerateSwitchCases(rootNodes, depth: 0, source: source);
GenerateSwitchCases(rootNodes, depth: 0);
// Next letter method end
source.Append(
@@ -166,17 +188,9 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
"""
);
// Partial class end
source.Append(
"""
}
"""
);
return;
return source.ToString();
}
private static void GenerateSwitchCases(List<Node> nodes, int depth, StringBuilder source)
void GenerateSwitchCases(List<Node> nodes, int depth)
{
var indent = Indent(depth * 3);
@@ -216,7 +230,7 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
);
// Sub nodes
GenerateSwitchCases(node.Nodes, depth + 1, source);
GenerateSwitchCases(node.Nodes, depth + 1);
source.Append(
$$"""
@@ -249,6 +263,110 @@ public class PoyoLangTranslatorGenerator : IIncrementalGenerator
"""
);
}
}
private static void GenerateFromPoyoMethod(Dictionary<string, string> dictionary, StringBuilder source)
{
// From Poyo method definition
source.Append(
"""
private void FromPoyo(ref ReadOnlySpan<char> text, StringBuilder output)
{
"""
);
// Initial cases
source.Append(
"""
if (text.Length < 1)
{
return;
}
// This happens if the end of the text is not a poyo letter (punctuation for ex)
if (text.Length < 4)
{
output.Append(text);
text = text[^0..];
return;
}
var letter = text[..4];
"""
);
GenerateReverseSwitchCases();
// From Poyo method end
source.Append(
"""
// Advance in text
text = text[4..];
}
"""
);
return;
void GenerateReverseSwitchCases()
{
// Switch start
source.Append(
"""
switch (letter)
{
"""
);
foreach (var pair in dictionary)
{
// Non-caps case
source.Append(
$$"""
case "{{pair.Key}}":
output.Append("{{pair.Value}}");
break;
"""
);
// Caps case
source.Append(
$$"""
case "{{ToTitleCase(pair.Key)}}":
output.Append("{{ToTitleCase(pair.Value)}}");
break;
"""
);
}
// Switch end
source.Append(
"""
default:
// Not a poyo letter, only read 1 character (could be punctuation for ex)
output.Append(text[0]);
text = text[1..];
return;
}
"""
);
}
}
private static string ToTitleCase(string text)
{

View File

@@ -21,4 +21,19 @@ public partial class PoyoLangTranslator
return output.ToString();
}
public string TranslateFromPoyo(ReadOnlySpan<char> text)
{
var output = new StringBuilder(text.Length);
while (text.Length > 0)
{
// Skip spaces (those are not used in this language)
text = text.TrimStart(' ');
FromPoyo(ref text, output);
}
return output.ToString();
}
}