Skip to content

Commit 69ce866

Browse files
committed
Extended parser bootstrap with managed visitors.
1 parent 831cea9 commit 69ce866

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/CppParser/Bootstrap/Bootstrap.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ private void GenerateStmt(BindingContext ctx)
185185
managedCodeGen.GenerateDeclarations();
186186
WriteFile(managedCodeGen, Path.Combine("AST", "Stmt.cs"));
187187

188+
managedCodeGen = new ManagedVisitorCodeGenerator(ctx, decls.Union(ExprClasses));
189+
managedCodeGen.Process();
190+
WriteFile(managedCodeGen, Path.Combine("AST", "StmtVisitor.cs"));
191+
188192
managedCodeGen = new StmtASTConverterCodeGenerator(ctx, decls, stmtClassEnum);
189193
managedCodeGen.Process();
190194
WriteFile(managedCodeGen, Path.Combine("Parser", "ASTConverter.Stmt.cs"));
@@ -267,6 +271,9 @@ public override bool VisitClassDecl(Class @class)
267271
// Statements
268272
//
269273

274+
if (CodeGeneratorHelpers.IsAbstractStmt(@class))
275+
@class.IsAbstract = true;
276+
270277
if (@class.Name.EndsWith("Bitfields"))
271278
@class.ExplicitlyIgnore();
272279

@@ -529,11 +536,32 @@ public override bool VisitClassDecl(Class @class)
529536
WriteLine($"public {typeName} {propertyName} {{ get; set; }}");
530537
}
531538

539+
var rootBase = @class.GetNonIgnoredRootBase();
540+
var isStmt = rootBase != null && rootBase.Name == "Stmt";
541+
542+
if (isStmt && !(@class.IsAbstract && @class.Name != "Stmt"))
543+
{
544+
NewLine();
545+
GenerateVisitMethod(@class);
546+
}
547+
532548
UnindentAndWriteCloseBrace();
533549

534550
return true;
535551
}
536552

553+
private void GenerateVisitMethod(Class @class)
554+
{
555+
if (@class.IsAbstract)
556+
{
557+
WriteLine("public abstract T Visit<T>(IStmtVisitor<T> visitor);");
558+
return;
559+
}
560+
561+
WriteLine("public override T Visit<T>(IStmtVisitor<T> visitor) =>");
562+
WriteLineIndent("visitor.Visit{0}(this);", @class.Name);
563+
}
564+
537565
public override string GetBaseClassTypeName(BaseClassSpecifier @base)
538566
{
539567
var type = base.GetBaseClassTypeName(@base);
@@ -563,6 +591,77 @@ public override void GenerateNamespaceFunctionsAndVariables(
563591
}
564592
}
565593

594+
class ManagedVisitorCodeGenerator : ManagedParserCodeGenerator
595+
{
596+
public ManagedVisitorCodeGenerator(BindingContext context,
597+
IEnumerable<Declaration> declarations)
598+
: base(context, declarations)
599+
{
600+
}
601+
602+
public override void Process()
603+
{
604+
GenerateFilePreamble(CommentKind.BCPL);
605+
NewLine();
606+
607+
WriteLine("namespace CppSharp.AST");
608+
WriteOpenBraceAndIndent();
609+
610+
GenerateVisitor();
611+
NewLine();
612+
613+
GenerateVisitorInterface();
614+
615+
UnindentAndWriteCloseBrace();
616+
}
617+
618+
private void GenerateVisitor()
619+
{
620+
WriteLine($"public abstract partial class AstVisitor");
621+
WriteOpenBraceAndIndent();
622+
623+
foreach (var @class in Declarations.OfType<Class>())
624+
{
625+
if (@class.Name == "Stmt") continue;
626+
627+
PushBlock();
628+
var paramName = "stmt";
629+
WriteLine("public virtual bool Visit{0}({0} {1})",
630+
@class.Name, paramName);
631+
WriteOpenBraceAndIndent();
632+
633+
var visitName = @class.BaseClass != null ?
634+
@class.BaseClass.Name : "Stmt";
635+
636+
WriteLine($"if (!Visit{@class.BaseClass.Name}({paramName}))");
637+
WriteLineIndent("return false;");
638+
NewLine();
639+
640+
WriteLine("return true;");
641+
642+
UnindentAndWriteCloseBrace();
643+
PopBlock(NewLineKind.BeforeNextBlock);
644+
}
645+
646+
UnindentAndWriteCloseBrace();
647+
}
648+
649+
private void GenerateVisitorInterface()
650+
{
651+
WriteLine($"public interface IStmtVisitor<out T>");
652+
WriteOpenBraceAndIndent();
653+
654+
foreach (var @class in Declarations.OfType<Class>())
655+
{
656+
var paramName = "stmt";
657+
WriteLine("T Visit{0}({0} {1});",
658+
@class.Name, paramName);
659+
}
660+
661+
UnindentAndWriteCloseBrace();
662+
}
663+
}
664+
566665
class ASTConverterCodeGenerator : ManagedParserCodeGenerator
567666
{
568667
readonly Enumeration StmtClassEnum;

0 commit comments

Comments
 (0)