compiler, runtime: Begin Runtime Refactor
Continuous Integration / Grammar Tests (push) Failing after 39s
Continuous Integration / Library Format Tests (push) Successful in 1m46s
Continuous Integration / Library Tests (push) Successful in 4m38s

Ultimately, the goal is to completely separate the compilation from
the runtime to make it possible to have the interpreter/evaluator
be "just another" entity that can perform meaningful work when
given a parsed GP4 program.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-05-29 08:41:49 -04:00
parent 18461a9215
commit 44e93e4cda
30 changed files with 1264 additions and 854 deletions
-95
View File
@@ -1,95 +0,0 @@
// 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 <https://www.gnu.org/licenses/>.
import Common
public protocol Visitable {
}
public protocol LanguageVisitor<Context> {
associatedtype Context
// Program
func visit(_ program: Program, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
// Parser
func visit(_ parser: Parser, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(
_ parser_state: InstantiatedParserState, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Statements
func visit(
_ variable_declaration: VariableDeclarationStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ conditional: ConditionalStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ block: BlockStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ rtn: ReturnStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ apply: ApplyStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Expressions
func visit(
_ keyset: KeysetExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ select_case: SelectCaseExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ select: SelectExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ array_access: ArrayAccessExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ field_access: FieldAccessExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ function_call: FunctionCall, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ binary_operator: BinaryOperatorExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Declarations
func visit(_ decl: Declaration, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(
_ extern_decl: ExternDeclaration, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ func_decl: FunctionDeclaration, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Control
func visit(_ action: Action, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(
_ table_key_entry: TableKeyEntry, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ table_property_list: TablePropertyList, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(_ table: Table, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(_ control: Control, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
}
+13 -1
View File
@@ -52,7 +52,7 @@ public struct Declaration: P4Type {
return self
}
public var description: String {
return "Extern \(self.identifier)"
return self.extern ? "Extern " : "" + "\(self.identifier)"
}
}
@@ -130,3 +130,15 @@ public struct FunctionDeclaration: P4Type, P4DataValue {
self.body = body
}
}
public struct Instantiation {
public let name: Identifier
public let tipe: P4Type
public let arguments: ArgumentList
public init(named name: Identifier, ofType tipe: P4Type, withArguments arguments: ArgumentList) {
self.name = name
self.tipe = tipe
self.arguments = arguments
}
}
+10 -10
View File
@@ -18,9 +18,9 @@
import Common
public struct KeysetExpression {
public let key: EvaluatableExpression
public let key: P4Expression
public init(_ key: EvaluatableExpression) {
public init(_ key: P4Expression) {
self.key = key
}
@@ -65,11 +65,11 @@ public struct SelectCaseExpression {
}
public struct SelectExpression {
public let selector: EvaluatableExpression
public let selector: P4Expression
public let case_expressions: [SelectCaseExpression]
public init(
withSelector selector: EvaluatableExpression,
withSelector selector: P4Expression,
withSelectCaseExpressions sces: [SelectCaseExpression]
) {
self.selector = selector
@@ -105,13 +105,13 @@ public struct BinaryOperatorExpression {
}
public struct ArrayAccessExpression {
public let indexor: EvaluatableExpression
public let name: EvaluatableExpression
public let indexor: P4Expression
public let name: P4Expression
public let type: P4Array
public init(
withName name: EvaluatableExpression, withType type: P4Array,
withIndexor indexor: EvaluatableExpression
withName name: P4Expression, withType type: P4Array,
withIndexor indexor: P4Expression
) {
self.name = name
self.type = type
@@ -121,9 +121,9 @@ public struct ArrayAccessExpression {
public struct FieldAccessExpression {
public let field: P4StructFieldIdentifier
public let strct: EvaluatableExpression
public let strct: P4Expression
public init(withStruct strct: EvaluatableExpression, withField field: P4StructFieldIdentifier) {
public init(withStruct strct: P4Expression, withField field: P4StructFieldIdentifier) {
self.strct = strct
self.field = field
}
+10 -13
View File
@@ -22,11 +22,11 @@ public struct LocalElements {}
public struct LocalElement {}
public struct ParserAssignmentStatement {
public let lvalue: EvaluatableLValueExpression
public let value: EvaluatableExpression
public let lvalue: P4LValueExpression
public let value: P4Expression
public init(
withLValue lvalue: EvaluatableLValueExpression, withValue value: EvaluatableExpression
withLValue lvalue: P4LValueExpression, withValue value: P4Expression
) {
self.lvalue = lvalue
self.value = value
@@ -34,12 +34,9 @@ public struct ParserAssignmentStatement {
}
/// A P4 Parser State
///
/// Note: A P4 Parser State is both a type and a value.
/// This "bare" parser state represents the state more as a type than a value.
public class ParserState: P4Type, Equatable, CustomStringConvertible {
let name: Identifier
public let statements: [EvaluatableStatement]
public let statements: [P4Statement]
public static func == (lhs: ParserState, rhs: ParserState) -> Bool {
return lhs.eq(rhs: rhs)
@@ -60,12 +57,12 @@ public class ParserState: P4Type, Equatable, CustomStringConvertible {
return self.name
}
public func getStatements() -> [EvaluatableStatement] {
public func getStatements() -> [P4Statement] {
return self.statements
}
/// Construct a ParserState
public init(_ name: Identifier, _ statements: [EvaluatableStatement] = Array()) {
public init(_ name: Identifier, _ statements: [P4Statement] = Array()) {
self.name = name
self.statements = statements
}
@@ -100,7 +97,7 @@ public class ParserStateDirectTransition: ParserState {
/// Construct a ParserState
public init(
name: Identifier, withNextState next_state: InstantiatedParserState,
withStatements stmts: [EvaluatableStatement] = Array(),
withStatements stmts: [P4Statement] = Array(),
) {
self.next_state = next_state
self.next_state_identifier = .none
@@ -109,7 +106,7 @@ public class ParserStateDirectTransition: ParserState {
public init(
name: Identifier, withNextStateIdentifier next_state_id: Identifier,
withStatements stmts: [EvaluatableStatement] = Array(),
withStatements stmts: [P4Statement] = Array(),
) {
self.next_state = .none
self.next_state_identifier = next_state_id
@@ -129,7 +126,7 @@ public class ParserStateDirectTransition: ParserState {
public class ParserStateNoTransition: ParserState {
/// Construct a ParserState
public init(
name: Identifier, withStatements stmts: [EvaluatableStatement] = Array(),
name: Identifier, withStatements stmts: [P4Statement] = Array(),
) {
super.init(name, stmts)
}
@@ -145,7 +142,7 @@ public class ParserStateSelectTransition: ParserState {
public init(
name: Identifier, withTransitionExpression te: SelectExpression,
withStatements stmts: [EvaluatableStatement] = Array()
withStatements stmts: [P4Statement] = Array()
) {
self.te = te
super.init(name, stmts)
+2 -2
View File
@@ -18,9 +18,9 @@
import Common
public struct ExpressionStatement {
public let expression: EvaluatableExpression
public let expression: P4Expression
public init(_ expr: EvaluatableExpression) {
public init(_ expr: P4Expression) {
self.expression = expr
}
}
+95
View File
@@ -0,0 +1,95 @@
// 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 <https://www.gnu.org/licenses/>.
import Common
public protocol Visitable {
}
public protocol LanguageVisitor<Context> {
associatedtype Context
// Program
func visit(_ program: Program, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
// Parser
func visit(_ parser: Parser, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(
_ parser_state: InstantiatedParserState, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Statements
func visit(
_ variable_declaration: VariableDeclarationStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ conditional: ConditionalStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ block: BlockStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ rtn: ReturnStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ apply: ApplyStatement, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Expressions
func visit(
_ keyset: KeysetExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ select_case: SelectCaseExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ select: SelectExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ array_access: ArrayAccessExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ field_access: FieldAccessExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ function_call: FunctionCall, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ binary_operator: BinaryOperatorExpression, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Declarations
func visit(_ decl: Declaration, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(
_ extern_decl: ExternDeclaration, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ func_decl: FunctionDeclaration, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
// Control
func visit(_ action: Action, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(
_ table_key_entry: TableKeyEntry, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(
_ table_property_list: TablePropertyList, _ c: VisitorContext<Context>
) -> Result<VisitorContext<Context>>
func visit(_ table: Table, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
func visit(_ control: Control, _ c: VisitorContext<Context>) -> Result<VisitorContext<Context>>
}
+13 -13
View File
@@ -20,28 +20,28 @@ import Common
public struct Statement {}
public struct VariableDeclarationStatement {
public var initializer: EvaluatableExpression
public var identifier: Identifier
public init(identifier: Identifier, withInitializer initializer: EvaluatableExpression) {
public var initializer: P4Expression
public var identifier: TypedIdentifier
public init(identifier: TypedIdentifier, withInitializer initializer: P4Expression) {
self.identifier = identifier
self.initializer = initializer
}
}
public struct ConditionalStatement {
public var condition: EvaluatableExpression
public var thenn: EvaluatableStatement
public var elss: EvaluatableStatement?
public var condition: P4Expression
public var thenn: P4Statement
public var elss: P4Statement?
public init(condition: EvaluatableExpression, withThen thenn: EvaluatableStatement) {
public init(condition: P4Expression, withThen thenn: P4Statement) {
self.condition = condition
self.thenn = thenn
self.elss = .none
}
public init(
condition: EvaluatableExpression, withThen thenn: EvaluatableStatement,
andElse elss: EvaluatableStatement
condition: P4Expression, withThen thenn: P4Statement,
andElse elss: P4Statement
) {
self.condition = condition
self.thenn = thenn
@@ -50,18 +50,18 @@ public struct ConditionalStatement {
}
public struct BlockStatement {
public var statements: [EvaluatableStatement]
public var statements: [P4Statement]
public init(_ statements: [EvaluatableStatement]) {
public init(_ statements: [P4Statement]) {
self.statements = statements
}
}
public struct ReturnStatement {
public let value: EvaluatableExpression
public let value: P4Expression
public init(_ value: EvaluatableExpression) {
public init(_ value: P4Expression) {
self.value = value
}
}