diff --git a/Sources/Common/ProgramTypes.swift b/Sources/Common/ProgramTypes.swift index 03ce4f1..c691ea0 100644 --- a/Sources/Common/ProgramTypes.swift +++ b/Sources/Common/ProgramTypes.swift @@ -186,23 +186,25 @@ public class P4StructValue: P4Value { // Note: Because the number of values _always_ matches the number of fields, there // is no need to check there! - for xx in zip(zip(lhs.stype.fields, lhs.values), zip(rhs.stype.fields, rhs.values)) { - let left = xx.0 - let right = xx.1 + for fields_to_compare in zip( + zip(lhs.stype.fields, lhs.values), zip(rhs.stype.fields, rhs.values)) + { + let left_field_and_value = fields_to_compare.0 + let right_field_and_value = fields_to_compare.1 - let left_field = left.0 - let left_value = left.1 + let left_field_name = left_field_and_value.0 + let left_field_value = left_field_and_value.1 - let right_field = right.0 - let right_value = right.1 + let right_field_name = right_field_and_value.0 + let right_field_value = right_field_and_value.1 // If the field names do not match, then there is a problem. - if left_field != right_field { + if left_field_name != right_field_name { return false } // Now that we know that the field names match, do the values match? - if !op(left_value, right_value) { + if !op(left_field_value, right_field_value) { return false } } @@ -296,17 +298,21 @@ public class P4StructValue: P4Value { } public let stype: P4Struct - public let values: [P4Value?] + public let values: [P4Value] public convenience init(withType type: P4Struct) { self.init(withType: type, andInitializers: []) } public init(withType type: P4Struct, andInitializers initializers: [P4Value?]) { - var values: [P4Value?] = Array(repeating: .none, count: type.fields.count()) - - for i in 0.. SelectExpression { diff --git a/Sources/P4Runtime/Expressions.swift b/Sources/P4Runtime/Expressions.swift index 27aff88..6b16ec7 100644 --- a/Sources/P4Runtime/Expressions.swift +++ b/Sources/P4Runtime/Expressions.swift @@ -33,11 +33,11 @@ extension SelectExpression: EvaluatableExpression { public func evaluate(execution: Common.ProgramExecution) -> Common.Result { switch self.selector.evaluate(execution: execution) { case .Ok(let selector_value): - for kse in self.select_expressions { - if case .Ok(let kse_key) = kse.key.evaluate(execution: execution), - kse_key.eq(rhs: selector_value) + for sce in self.select_expressions { + if case .Ok(let kse) = sce.key.evaluate(execution: execution), + kse.eq(rhs: selector_value) { - let result = kse.evaluate(execution: execution) + let result = sce.evaluate(execution: execution) return result } } diff --git a/Tests/p4rseTests/Declarations.swift b/Tests/p4rseTests/Declarations.swift index 08c71d1..c7206ef 100644 --- a/Tests/p4rseTests/Declarations.swift +++ b/Tests/p4rseTests/Declarations.swift @@ -50,4 +50,99 @@ import TreeSitterP4 let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program)) let (state_result, _) = try! #UseOkResult(runtime.run()) #expect(state_result == P4Lang.accept) -} \ No newline at end of file +} + +@Test func test_struct_declaration_and_field_write_field_read() async throws { + let simple_parser_declaration = """ + struct Testing { + bool yesno; + int count; + }; + parser main_parser() { + state start { + Testing ts; + ts.yesno = true; + ts.count = 5; + transition select (ts.count == 5) { + true: accept; + false: reject; + }; + } + }; + """ + let program = try #UseOkResult( + Program.Compile(simple_parser_declaration)) + let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program)) + let (state_result, _) = try! #UseOkResult(runtime.run()) + #expect(state_result == P4Lang.accept) +} + +@Test func test_struct_declaration_and_field_read_defaults() async throws { + let simple_parser_declaration = """ + struct Testing { + bool yesno; + int count; + }; + parser main_parser() { + state start { + Testing ts; + transition select (ts.count == 0) { + true: accept; + false: reject; + }; + } + }; + """ + let program = try #UseOkResult( + Program.Compile(simple_parser_declaration)) + let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program)) + let (state_result, _) = try! #UseOkResult(runtime.run()) + #expect(state_result == P4Lang.accept) +} + +@Test func test_struct_declaration_and_field_read_defaults_sc() async throws { + let simple_parser_declaration = """ + struct Testing { + bool yesno; + int count; + }; + parser main_parser() { + state start { + Testing ts; + transition select (ts.count) { + 0: accept; + _: reject; + }; + } + }; + """ + let program = try #UseOkResult( + Program.Compile(simple_parser_declaration)) + let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program)) + let (state_result, _) = try! #UseOkResult(runtime.run()) + #expect(state_result == P4Lang.accept) +} + +@Test func test_struct_declaration_and_field_read_defaults_sc2() async throws { + let simple_parser_declaration = """ + struct Testing { + bool yesno; + int count; + }; + parser main_parser() { + state start { + Testing ts; + ts.count = 1; + transition select (ts.count) { + 0: accept; + _: reject; + }; + } + }; + """ + let program = try #UseOkResult( + Program.Compile(simple_parser_declaration)) + let runtime = try #UseOkResult(P4Runtime.ParserRuntime.create(program: program)) + let (state_result, _) = try! #UseOkResult(runtime.run()) + #expect(state_result == P4Lang.reject) +}