grammar,compiler: Add Support For Fixed-Width Integers
Continuous Integration / Grammar Tests (push) Successful in 4m13s
Continuous Integration / Library Format Tests (push) Successful in 5m17s
Continuous Integration / Library Tests (push) Failing after 8m34s
Continuous Integration / Cli Tests (push) Failing after 4m40s

Distinguishing between signed and unsigned fixed-width integer
types must still be done.

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-05-18 06:52:21 -04:00
parent cbebcae20a
commit a7d8fd1304
16 changed files with 328 additions and 48 deletions
+1 -1
View File
@@ -283,7 +283,7 @@ import P4Lang
#RequireErrorResult(
Error(
withMessage:
"{57, 10}: Failed to parse a statement element: {57, 1}: Cannot assign value with type Boolean to identifier z with type Int"
"{57, 10}: Failed to parse a statement element: {57, 1}: Cannot assign value with type Boolean to identifier z with type Int (width: Infinite)"
),
Program.Compile(simple_parser_declaration))
)
@@ -182,5 +182,5 @@ import TreeSitterP4
let error = try #UseErrorResult(Program.Compile(simple_parser_declaration))
#expect(error.msg().contains("{29, 12}: Type of expression in return statement (Boolean) is not compatible with function return type (Int)"))
#expect(error.msg().contains("{29, 12}: Type of expression in return statement (Boolean) is not compatible with function return type (Int (width: Infinite))"))
}
@@ -132,7 +132,7 @@ import TreeSitterP4
#RequireErrorResult(
Error(
withMessage:
"Error(s) parsing select cases: {81, 4}: Key expression of type Boolean is not compatible with selector type Int"
"Error(s) parsing select cases: {81, 4}: Key expression of type Boolean is not compatible with selector type Int (width: Infinite)"
),
Program.Compile(simple_parser_declaration)))
}
+1 -1
View File
@@ -147,7 +147,7 @@ import TreeSitterP4
#expect(
#RequireErrorResult<(InstantiatedParserState, ProgramExecution)>(
Error(withMessage: "Cannot call parser: Argument 1's type (Int) is incompatible with the parameter type (Boolean)"),
Error(withMessage: "Cannot call parser: Argument 1's type (Int (width: Infinite)) is incompatible with the parameter type (Boolean)"),
runtime.run(withArguments: args)))
}
+2 -2
View File
@@ -327,7 +327,7 @@ import TreeSitterP4
#expect(
#RequireErrorResult(
Error(
withMessage: "{49, 13}: Failed to parse a statement element: {49, 8}: Cannot assign value of type Int to field yesno of type Boolean"
withMessage: "{49, 13}: Failed to parse a statement element: {49, 8}: Cannot assign value of type Int (width: Infinite) to field yesno of type Boolean"
),
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
)
@@ -457,7 +457,7 @@ import TreeSitterP4
#expect(
#RequireErrorResult(
Error(
withMessage: "{49, 20}: Failed to parse a statement element: {49, 11}: Cannot assign value of type Boolean to field count of type Int"
withMessage: "{49, 20}: Failed to parse a statement element: {49, 11}: Cannot assign value of type Boolean to field count of type Int (width: Infinite)"
),
Program.Compile(simple_parser_declaration, withGlobalInstances: test_declarations))
)
+1 -1
View File
@@ -45,5 +45,5 @@ struct StringConvertible: CustomStringConvertible {
@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")
#expect("\(result)" == "Ok: Value: 5 of Int (width: Infinite) type of type Int (width: Infinite)")
}
+114 -20
View File
@@ -18,8 +18,8 @@
import Common
import Foundation
import Macros
import P4Runtime
import P4Lang
import P4Runtime
import SwiftTreeSitter
import Testing
import TreeSitter
@@ -36,13 +36,15 @@ import TreeSitterP4
transition reject;
}
};
""";
"""
let err = Program.Compile(simple_parser_declaration)
guard case Result.Error(let e) = err else {
assert(false, "Expected an error, but had success")
}
#expect(e.msg().contains("Failed to parse a statement element: Could not parse a P4 type from \(invalid_type_name)"))
#expect(
e.msg().contains(
"Failed to parse a statement element: Could not parse a P4 type from \(invalid_type_name)"))
}
}
@@ -62,7 +64,7 @@ import TreeSitterP4
#RequireErrorResult(
Error(
withMessage:
"{112, 16}: Failed to parse a statement element: {112, 8}: Cannot assign value with type Boolean to identifier where_to with type String"
"{112, 16}: Failed to parse a statement element: {112, 8}: Cannot assign value with type Boolean to identifier where_to with type String"
),
Program.Compile(simple_parser_declaration)))
}
@@ -83,7 +85,7 @@ import TreeSitterP4
#RequireErrorResult(
Error(
withMessage:
"{114, 22}: Failed to parse a statement element: {114, 8}: Cannot assign value with type String to identifier where_to with type Boolean"
"{114, 22}: Failed to parse a statement element: {114, 8}: Cannot assign value with type String to identifier where_to with type Boolean"
),
Program.Compile(simple_parser_declaration)))
}
@@ -128,6 +130,90 @@ import TreeSitterP4
Program.Compile(simple_parser_declaration)))
}
@Test func test_invalid_type_in_declaration3() async throws {
let simple_parser_declaration = """
parser main_parser() {
state start {
int<5> specific_width_int = 5;
int unspecific_width_int = specific_width_int;
transition reject;
}
};
"""
let error = try! #UseErrorResult(Program.Compile(simple_parser_declaration))
#expect(
error.msg().contains(
"Cannot initialize specific_width_int (with type Int (width: Width(5))) from expression with type Int (width: Infinite)"
))
}
@Test func test_valid_specific_width_int_type_in_declaration() async throws {
let simple_parser_declaration = """
parser main_parser() {
state start {
int<5> specific_width_int = 5w5;
int<5> unspecific_width_int = specific_width_int;
transition reject;
}
};
"""
#expect(#RequireOkResult(Program.Compile(simple_parser_declaration)))
}
@Test func test_expression_in_declaration_initializer_specific_width_int_type() async throws {
let simple_parser_declaration = """
parser main_parser() {
state start {
int<5> specific_width_int = 5w5;
bool where_to = 5w5 == specific_width_int == true;
transition select (where_to) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// 5w5 == specific_width_int == true
// true == true
// true
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
}
@Test func test_expression_in_declaration_initializer_specific_width_int_type2() async throws {
let simple_parser_declaration = """
parser main_parser() {
state start {
int<5> specific_width_int = 5w5;
bool where_to = 5w6 == specific_width_int == false;
transition select (where_to) {
true: accept;
false: reject;
};
}
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// 5w6 == specific_width_int == false
// false == false
// true
#expect(AsInstantiatedParserState(state_result) == P4Lang.accept)
}
@Test func test_expression_in_declaration_initializer() async throws {
let simple_parser_declaration = """
parser main_parser() {
@@ -141,7 +227,8 @@ import TreeSitterP4
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// 5 == 5 == true
@@ -163,7 +250,8 @@ import TreeSitterP4
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// 5 == 5 == true
@@ -185,7 +273,8 @@ import TreeSitterP4
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// 6 == 5 == true
@@ -207,7 +296,8 @@ import TreeSitterP4
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// 6 == 5 == false
@@ -229,7 +319,8 @@ import TreeSitterP4
};
"""
let program = try #UseOkResult(Program.Compile(simple_parser_declaration))
let runtime = try #UseOkResult(P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let runtime = try #UseOkResult(
P4Runtime.Runtime<InstantiatedParserState, P4Lang.Parser>.create(program: program))
let (state_result, _) = try! #UseOkResult(runtime.run())
// TODO: This test should throw an error.
@@ -253,29 +344,32 @@ import TreeSitterP4
};
"""
var test_types = VarTypeScopes().enter()
test_types = test_types.declare(identifier: Identifier(name: "ta"), withValue: P4QualifiedType(P4Array(withValueType: P4QualifiedType(P4Int()))))
test_types = test_types.declare(
identifier: Identifier(name: "ta"),
withValue: P4QualifiedType(P4Array(withValueType: P4QualifiedType(P4Int()))))
#expect(
#RequireErrorResult(
Error(
withMessage:
"{49, 22}: Failed to parse a statement element: Cannot initialize where_to (with type Boolean) from expression with type Int"
"{49, 22}: Failed to parse a statement element: Cannot initialize where_to (with type Boolean) from expression with type Int (width: Infinite)"
),
Program.Compile(simple_parser_declaration, withGlobalInstances: test_types)))
}
@Test func test_simple_compiler_parser_parameters_invalid_types() async throws {
let simple_parser_declaration = """
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
pmtr = 1;
transition accept;
}
};
"""
parser main_parser(bool pmtr, string smtr, int imtr) {
state start {
pmtr = 1;
transition accept;
}
};
"""
#expect(
#RequireErrorResult(
Error(
withMessage: "{85, 9}: Failed to parse a statement element: {85, 4}: Cannot assign value with type Int to identifier pmtr with type Boolean"
withMessage:
"{85, 9}: Failed to parse a statement element: {85, 4}: Cannot assign value with type Int (width: Infinite) to identifier pmtr with type Boolean"
),
Program.Compile(simple_parser_declaration)))
}