using System.Text; using CodePlay.Core.Interfaces; using CodePlay.Core.Common; namespace CodePlay.Core.Converters; public class CppCodeGenerator : ICodeGenerator { private StringBuilder _out = new(); private int _indent; public string Generate(SyntaxTree tree) { _out.Clear(); _indent = 0; _out.AppendLine("#include "); _out.AppendLine("#include "); _out.AppendLine("#include "); _out.AppendLine("#include "); _out.AppendLine("#include "); _out.AppendLine("#include "); _out.AppendLine(); GenNode(tree.Root); return _out.ToString(); } void GenNode(SyntaxNode n) { if (n.Type == SyntaxNodeType.Unknown && !string.IsNullOrWhiteSpace(n.Text)) { foreach (var line in n.Text.Split('\n')) { var t = line.Trim(); if (!string.IsNullOrEmpty(t) && !t.StartsWith("{") && !t.StartsWith("}")) _out.AppendLine(IndentLine(t)); } return; } switch (n.Type) { case SyntaxNodeType.CompilationUnit: foreach (var c in n.Children) GenNode(c); break; case SyntaxNodeType.Namespace: var ns = System.Text.RegularExpressions.Regex.Match(n.Text, @"namespace\s+([\w.]+)").Groups[1].Value; _out.AppendLine($"namespace {ns} {{"); _indent++; foreach (var c in n.Children) GenNode(c); _indent--; _out.AppendLine("}"); break; case SyntaxNodeType.Class: var cls = n.Text.Trim(); var brace = cls.IndexOf('{'); if (brace > 0) cls = cls.Substring(0, brace); _out.AppendLine(IndentLine($"class {cls.Replace("public ", "")} {{")); _out.AppendLine(IndentLine("public:")); _indent++; foreach (var c in n.Children) GenNode(c); _indent--; _out.AppendLine(IndentLine("};")); _out.AppendLine(); break; case SyntaxNodeType.Method: var sig = n.Text.Split('\n').First().Trim(); if (sig.EndsWith("{")) sig = sig[..^1].Trim(); _out.AppendLine(IndentLine($"{sig} {{")); _indent++; var body = string.Join('\n', n.Text.Split('{', '}').Skip(1)).Trim(); foreach (var l in body.Split('\n')) if (!string.IsNullOrWhiteSpace(l)) _out.AppendLine(IndentLine(l.Trim())); _indent--; _out.AppendLine(IndentLine("}")); _out.AppendLine(); break; case SyntaxNodeType.Field: case SyntaxNodeType.Property: if (!string.IsNullOrWhiteSpace(n.Text)) _out.AppendLine(IndentLine(n.Text.Trim())); break; default: if (!string.IsNullOrWhiteSpace(n.Text)) _out.AppendLine(IndentLine(n.Text.Trim())); foreach (var c in n.Children) GenNode(c); break; } } string IndentLine(string t) { var spaces = string.Concat(Enumerable.Repeat(" ", _indent * 2)); return spaces + t; } }