diff --git a/Sources/Common/DataTypes.swift b/Sources/Common/DataTypes.swift index be94e7f..6b27f95 100644 --- a/Sources/Common/DataTypes.swift +++ b/Sources/Common/DataTypes.swift @@ -162,7 +162,7 @@ public struct P4Struct: P4Type { } } - public func def() -> any P4DataValue { + public func def() -> P4DataValue? { return P4StructValue(withType: self) } } @@ -203,7 +203,7 @@ public class P4StructValue: P4DataValue { } // Now that we know that the field names match, do the values match? - if !op(left_field_value.dataValue(), right_field_value.dataValue()) { + if !op(left_field_value?.dataValue(), right_field_value?.dataValue()) { return false } } @@ -297,19 +297,21 @@ public class P4StructValue: P4DataValue { } 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?]) { - let values = zip(0.. any P4DataValue { + public func def() -> P4DataValue? { return P4BooleanValue(withValue: false) } } @@ -434,7 +436,7 @@ public struct P4Int: P4Type { default: false } } - public func def() -> any P4DataValue { + public func def() -> P4DataValue? { return P4IntValue(withValue: 0) } } @@ -506,7 +508,7 @@ public struct P4String: P4Type { default: false } } - public func def() -> any P4DataValue { + public func def() -> P4DataValue? { return P4StringValue(withValue: "") } } @@ -587,7 +589,7 @@ public struct P4Array: P4Type { } } - public func def() -> P4DataValue { + public func def() -> P4DataValue? { return P4ArrayValue(withType: self.vtype, withValue: []) } } @@ -686,8 +688,11 @@ public struct P4Set: P4Type { } } - public func def() -> P4DataValue { - return P4SetValue(withValue: P4Value(self.stype.baseType().def(), self.stype)) + public func def() -> P4DataValue? { + if let base_type_default = self.stype.baseType().def() { + return P4SetValue(withValue: P4Value(base_type_default, self.stype)) + } + return .none } } @@ -784,7 +789,7 @@ public struct P4HitMiss: P4Type { } } - public func def() -> any P4DataValue { + public func def() -> P4DataValue? { return P4TableHitMissValue.Miss } diff --git a/Sources/Common/P4Types.swift b/Sources/Common/P4Types.swift index ff91952..0d515ae 100644 --- a/Sources/Common/P4Types.swift +++ b/Sources/Common/P4Types.swift @@ -141,8 +141,11 @@ public struct P4QualifiedType: CustomStringConvertible { return self.base_type } - public func def() -> P4Value { - return P4Value(self.base_type.def(), self) + public func def() -> P4Value? { + if let default_value = self.base_type.def() { + return P4Value(default_value, self) + } + return .none } public func eq(_ rhs: P4QualifiedType) -> Bool { diff --git a/Sources/Common/Protocols.swift b/Sources/Common/Protocols.swift index c5b3f28..d28b43c 100644 --- a/Sources/Common/Protocols.swift +++ b/Sources/Common/Protocols.swift @@ -36,7 +36,7 @@ public protocol EvaluatableStatement { public protocol P4Type: CustomStringConvertible { func eq(rhs: any P4Type) -> Bool - func def() -> P4DataValue + func def() -> P4DataValue? } public protocol P4DataValue: CustomStringConvertible { diff --git a/Sources/P4Compiler/Statement.swift b/Sources/P4Compiler/Statement.swift index 87c42a1..7e1d386 100644 --- a/Sources/P4Compiler/Statement.swift +++ b/Sources/P4Compiler/Statement.swift @@ -194,17 +194,18 @@ extension VariableDeclarationStatement: CompilableStatement { Error(withMessage: "Could not parse a P4 type from \(typeref.text!)")) } - var initializer: EvaluatableExpression = declaration_p4_type.def() + var initializer: EvaluatableExpression? = .none + // If there is an initializer, it must be an expression. - if let rvalue = maybe_rvalue { - guard rvalue.nodeType == "expression" else { + if let initializer_expression = maybe_rvalue { + guard initializer_expression.nodeType == "expression" else { return Result.Error( ErrorOnNode( node: node, withError: "initial value for declaration statement is not an expression")) } - let maybe_parsed_rvalue = Expression.Compile(node: rvalue, withContext: context) + let maybe_parsed_rvalue = Expression.Compile(node: initializer_expression, withContext: context) guard case .Ok(let parsed_rvalue) = maybe_parsed_rvalue else { @@ -217,10 +218,22 @@ extension VariableDeclarationStatement: CompilableStatement { return Result.Error( Error( withMessage: - "Cannot initialize \(parsed_variablename) (with type \(declaration_p4_type)) from rvalue with type \(parsed_rvalue.type())" + "Cannot initialize \(parsed_variablename) (with type \(declaration_p4_type)) from expression with type \(parsed_rvalue.type())" )) } } + + // If there is no initializer, then it must be defaultable. + + if initializer == nil { + initializer = declaration_p4_type.def() + } + + guard let initializer = initializer else { + return Result.Error( + ErrorOnNode(node: node, withError: "No initializer for declaration")) + } + return Result.Ok( ( VariableDeclarationStatement( diff --git a/Sources/P4Lang/Control.swift b/Sources/P4Lang/Control.swift index 6796ae1..f47d125 100644 --- a/Sources/P4Lang/Control.swift +++ b/Sources/P4Lang/Control.swift @@ -64,8 +64,8 @@ public struct Action: CustomStringConvertible, P4Type, P4DataValue { } } - public func def() -> any Common.P4DataValue { - return Action() + public func def() -> P4DataValue? { + return .none } public var description: String { @@ -284,15 +284,8 @@ public struct Control: P4Type, P4DataValue, Equatable, CustomStringConvertible { withActions: self.actions, withApply: self.apply) } - public func def() -> any P4DataValue { - return Control( - named: Identifier(name: ""), - withParameters: ParameterList(), - withTable: Table( - withName: Identifier(name: "empty"), - withPropertyList: TablePropertyList( - withActions: TableActionsProperty(), withKeys: TableKeys())), - withActions: Actions(withActions: []), withApply: ApplyStatement()) + public func def() -> P4DataValue? { + return .none } } diff --git a/Sources/P4Lang/Declarations.swift b/Sources/P4Lang/Declarations.swift index 3fd37e1..0e1c59d 100644 --- a/Sources/P4Lang/Declarations.swift +++ b/Sources/P4Lang/Declarations.swift @@ -43,7 +43,7 @@ public struct Declaration: P4Type { } } - public func def() -> any Common.P4DataValue { + public func def() -> P4DataValue? { /// TODO: Is a default of the extern'd type the right way to go? return self.identifier.type.baseType().def() } @@ -107,11 +107,8 @@ public struct FunctionDeclaration: P4Type, P4DataValue { } } - public func def() -> any Common.P4DataValue { - return FunctionDeclaration( - named: Identifier(name: ""), ofType: P4QualifiedType(P4Boolean()), - withParameters: ParameterList([]), - withBody: .none) + public func def() -> P4DataValue? { + return .none } public var description: String { diff --git a/Sources/P4Lang/Parser.swift b/Sources/P4Lang/Parser.swift index b213a50..e56b353 100644 --- a/Sources/P4Lang/Parser.swift +++ b/Sources/P4Lang/Parser.swift @@ -101,8 +101,8 @@ public class ParserState: P4Type, P4DataValue, Equatable, CustomStringConvertibl /// Construct a ParserState public init() {} - public func def() -> any P4DataValue { - return ParserState() + public func def() -> P4DataValue? { + return .none } } @@ -353,8 +353,8 @@ public struct Parser: P4Type, P4DataValue { return "Parser \(self.name) with parameters: \(parameters) and states: \(self.states)" } - public func def() -> any P4DataValue { - return Parser(withName: Identifier(name: "")) + public func def() -> P4DataValue? { + return .none } } diff --git a/Tests/p4rseTests/ValueTypeParserTests.swift b/Tests/p4rseTests/ValueTypeParserTests.swift index cd8dbae..fd99d36 100644 --- a/Tests/p4rseTests/ValueTypeParserTests.swift +++ b/Tests/p4rseTests/ValueTypeParserTests.swift @@ -103,7 +103,7 @@ import TreeSitterP4 #RequireErrorResult( Error( withMessage: - "{86, 27}: Failed to parse a statement element: Cannot initialize where_to (with type Boolean) from rvalue with type String" + "{86, 27}: Failed to parse a statement element: Cannot initialize where_to (with type Boolean) from expression with type String" ), Program.Compile(simple_parser_declaration))) } @@ -123,7 +123,7 @@ import TreeSitterP4 #RequireErrorResult( Error( withMessage: - "{77, 29}: Failed to parse a statement element: Cannot initialize where_from (with type String) from rvalue with type Boolean" + "{77, 29}: Failed to parse a statement element: Cannot initialize where_from (with type String) from expression with type Boolean" ), Program.Compile(simple_parser_declaration))) } @@ -258,7 +258,7 @@ import TreeSitterP4 #RequireErrorResult( Error( withMessage: - "{49, 22}: Failed to parse a statement element: Cannot initialize where_to (with type Boolean) from rvalue with type Int" + "{49, 22}: Failed to parse a statement element: Cannot initialize where_to (with type Boolean) from expression with type Int" ), Program.Compile(simple_parser_declaration, withGlobalInstances: test_types))) }