compiler, runtime, testing, common: Centralize Execution/Evaluation
Centralize the execution of statements and evaluation of expressions so that the user can specify a debugging "callback" after every execution/evaluation. The callback can be used for myriad things, but it seems likely that it will be useful for implementing: 1. Testing 2. Debugger Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -49,7 +49,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
@@ -101,7 +101,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.reject)
|
||||
@@ -128,7 +128,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
@@ -155,7 +155,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
@@ -187,7 +187,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
@@ -216,7 +216,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
@@ -249,7 +249,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
// 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
|
||||
import Foundation
|
||||
import Macros
|
||||
import P4Runtime
|
||||
import P4Lang
|
||||
import SwiftTreeSitter
|
||||
import Testing
|
||||
import TreeSitter
|
||||
import TreeSitterP4
|
||||
|
||||
@testable import P4Compiler
|
||||
|
||||
@Test func test_statement_interloper() async throws {
|
||||
let simple_parser_declaration = """
|
||||
parser main_parser() {
|
||||
state starts {
|
||||
bool where_to = false;
|
||||
int va = 5;
|
||||
transition accept;
|
||||
}
|
||||
state start {
|
||||
bool where_to = true;
|
||||
where_to = true;
|
||||
transition select (where_to) {
|
||||
false: reject;
|
||||
true: starts;
|
||||
};
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
|
||||
|
||||
var statements_executed: [String] = Array()
|
||||
|
||||
let pe = ProgramExecution().setStatementInterloper({ (statement, cf, execution) in
|
||||
statements_executed.append("\(statement)")
|
||||
})
|
||||
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run(withArguments: ArgumentList(), inExecution: pe))
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
|
||||
#expect(statements_executed[0].hasPrefix("VariableDeclarationStatement"))
|
||||
#expect(statements_executed[1].hasPrefix("ParserAssignmentStatement"))
|
||||
// Moved into starts
|
||||
#expect(statements_executed[2].hasPrefix("VariableDeclarationStatement"))
|
||||
#expect(statements_executed[3].hasPrefix("VariableDeclarationStatement"))
|
||||
}
|
||||
|
||||
@Test func test_expression_interloper() async throws {
|
||||
let simple_parser_declaration = """
|
||||
parser main_parser() {
|
||||
state starts {
|
||||
bool where_to = false;
|
||||
int va = 5;
|
||||
transition accept;
|
||||
}
|
||||
state start {
|
||||
bool where_to = true;
|
||||
where_to = true;
|
||||
transition select (where_to) {
|
||||
false: reject;
|
||||
true: starts;
|
||||
};
|
||||
}
|
||||
};
|
||||
"""
|
||||
|
||||
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program))
|
||||
|
||||
var expressions_evaluated: [String] = Array()
|
||||
|
||||
let pe = ProgramExecution().setExpressionInterloper() { expression, result, execution in
|
||||
print("Expression: \(expression)")
|
||||
expressions_evaluated.append("\(expression)")
|
||||
}
|
||||
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run(withArguments: ArgumentList(), inExecution: pe))
|
||||
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
|
||||
#expect(expressions_evaluated[0].hasPrefix("Value: true of Boolean"))
|
||||
#expect(expressions_evaluated[1].hasPrefix("Value: true of Boolean"))
|
||||
#expect(expressions_evaluated[2].hasPrefix("where_to"))
|
||||
#expect(expressions_evaluated[3].hasPrefix("Value: false of Boolean"))
|
||||
#expect(expressions_evaluated[4].hasPrefix("KeysetExpression"))
|
||||
#expect(expressions_evaluated[5].hasPrefix("Value: true of Boolean"))
|
||||
#expect(expressions_evaluated[6].hasPrefix("KeysetExpression"))
|
||||
#expect(expressions_evaluated[7].hasPrefix("SelectCaseExpression"))
|
||||
#expect(expressions_evaluated[8].hasPrefix("SelectExpression"))
|
||||
// Moved into starts
|
||||
#expect(expressions_evaluated[9].hasPrefix("Value: false of Boolean"))
|
||||
#expect(expressions_evaluated[10].hasPrefix("Value: 5 of Int"))
|
||||
}
|
||||
@@ -57,7 +57,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
}
|
||||
@@ -151,7 +151,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.reject)
|
||||
}
|
||||
@@ -186,7 +186,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
}
|
||||
@@ -220,7 +220,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.reject)
|
||||
}
|
||||
@@ -266,7 +266,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
}
|
||||
@@ -302,7 +302,7 @@ import TreeSitterP4
|
||||
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
}
|
||||
@@ -375,7 +375,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
}
|
||||
@@ -423,7 +423,7 @@ import TreeSitterP4
|
||||
])))
|
||||
let program = try #UseOkResult(
|
||||
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withInitialValues: test_values))
|
||||
let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program, withGlobalValues: test_values))
|
||||
let (state_result, _) = try! #UseOkResult(runtime.run())
|
||||
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
|
||||
}
|
||||
|
||||
@@ -35,10 +35,15 @@ struct StringConvertible: CustomStringConvertible {
|
||||
|
||||
@Test func test_result_type_description_not_convertible() async throws {
|
||||
let result: Result<NotStringConvertible> = Result.Ok(NotStringConvertible());
|
||||
#expect(result.description == "Ok")
|
||||
#expect("\(result)" == "Ok(Tests.NotStringConvertible())")
|
||||
}
|
||||
|
||||
@Test func test_result_type_description_convertible() async throws {
|
||||
let result: Result<StringConvertible> = Result.Ok(StringConvertible());
|
||||
#expect(result.description == "CONVERTED")
|
||||
#expect("\(result)" == "Ok: CONVERTED")
|
||||
}
|
||||
|
||||
@Test func test_result_type_p4value_convertible() async throws {
|
||||
let result = Result.Ok(P4Value(P4IntValue(withValue: 5)))
|
||||
#expect("\(result)" == "Ok: Value: 5 of Int type of type Int")
|
||||
}
|
||||
Reference in New Issue
Block a user