// p4rse, Copyright 2026, Will Hawkins
//
// This file is part of p4rse.
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
import Common
public struct CSTVisitorDriver {
public init() {}
public func visit(
expression: any CST.AnExpression, visitor: any CSTVisitor, context: T
) -> Result {
return switch expression {
case let e as CST.BinaryOperatorExpression:
visitor.visit(node: e, driver: self, context: context)
case let e as CST.Literal: visitor.visit(node: e, driver: self, context: context)
default: .Error(Error(withMessage: "AST Expression Element Is Not Visitable"))
}
}
public func visit(
state: any CST.AnState, visitor: any CSTVisitor, context: T
) -> Result {
return switch state {
case let s as CST.ParserStateDirectTransition:
visitor.visit(node: s, driver: self, context: context)
case let s as CST.ParserStateNoTransition:
visitor.visit(node: s, driver: self, context: context)
case let s as CST.ParserStateSelectTransition:
visitor.visit(node: s, driver: self, context: context)
default: .Error(Error(withMessage: "AST State Element (\(state)) Is Not Visitable"))
}
}
public func visit(
statement: any CST.Statement, visitor: any CSTVisitor, context: T
) -> Result {
return switch statement {
case let s as CST.Parser: visitor.visit(node: s, driver: self, context: context)
default: .Error(Error(withMessage: "AST Statement Element Is Not Visitable"))
}
}
public func visit(
program: CST.Program, visitor: any CSTVisitor, context: T
) -> Result {
var context = context
for s in program.statements.statements {
switch visit(statement: s, visitor: visitor, context: context) {
case .Ok(let c): context = c
case .Error(let e): return .Error(e)
}
}
return .Ok(context)
}
}