compiler, runtime, common, documentation: Refactor Type System
The type system (and the value system) now include attributes for each type (things like direction, const-ness). Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -226,7 +226,10 @@ extension Parameter: Compilable {
|
||||
return Result.Ok(
|
||||
(
|
||||
Parameter(
|
||||
identifier: parameter_name, withType: parameter_type, withDirection: direction),
|
||||
identifier: parameter_name,
|
||||
withType: direction != nil
|
||||
? parameter_type.update(addAttribute: P4TypeAttribute.Direction(direction!))
|
||||
: parameter_type),
|
||||
context
|
||||
))
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import TreeSitterP4
|
||||
extension Declaration: CompilableDeclaration {
|
||||
public static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<(P4Type, CompilerContext)?> {
|
||||
) -> Result<(P4DataType, CompilerContext)?> {
|
||||
|
||||
let declaration_compilers: [String: CompilableDeclaration.Type] = [
|
||||
"function_declaration": FunctionDeclaration.self,
|
||||
@@ -44,7 +44,7 @@ extension Declaration: CompilableDeclaration {
|
||||
extension FunctionDeclaration: CompilableDeclaration {
|
||||
public static func Compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(any Common.P4Type, CompilerContext)?> {
|
||||
) -> Common.Result<(any Common.P4DataType, CompilerContext)?> {
|
||||
let function_declaration_node = node
|
||||
#RequireNodeType<Node, (ParameterList, CompilerContext)>(
|
||||
node: function_declaration_node, type: "function_declaration",
|
||||
@@ -109,7 +109,7 @@ extension FunctionDeclaration: CompilableDeclaration {
|
||||
var function_scope = context.instances.enter()
|
||||
for parameter in function_parameters.parameters {
|
||||
function_scope = function_scope.declare(
|
||||
identifier: parameter.name, withValue: parameter.attributedType())
|
||||
identifier: parameter.name, withValue: parameter.type)
|
||||
}
|
||||
|
||||
let maybe_function_body = Parser.Statement.Compile(
|
||||
@@ -141,7 +141,7 @@ struct StructDeclaration {}
|
||||
extension StructDeclaration: CompilableDeclaration {
|
||||
static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<(P4Type, CompilerContext)?> {
|
||||
) -> Result<(P4DataType, CompilerContext)?> {
|
||||
|
||||
let struct_declaration_node = node.child(at: 0)!
|
||||
var currentChildIdx = 0
|
||||
@@ -249,9 +249,9 @@ extension StructDeclaration: CompilableDeclaration {
|
||||
extension P4Lang.Parser: CompilableDeclaration {
|
||||
public static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<(P4Type, CompilerContext)?> {
|
||||
) -> Result<(P4DataType, CompilerContext)?> {
|
||||
let parser_node = node
|
||||
#SkipUnlessNodeType<Node, (P4Type, CompilerContext)?>(
|
||||
#SkipUnlessNodeType<Node, (P4DataType, CompilerContext)?>(
|
||||
node: parser_node, type: "parserDeclaration")
|
||||
|
||||
var current_context = context
|
||||
@@ -332,7 +332,7 @@ extension P4Lang.Parser: CompilableDeclaration {
|
||||
for parameter in parameter_list.parameters {
|
||||
current_context = current_context.update(
|
||||
newInstances: current_context.instances.declare(
|
||||
identifier: parameter.name, withValue: parameter.attributedType()))
|
||||
identifier: parameter.name, withValue: parameter.type))
|
||||
}
|
||||
|
||||
currentChildIdx += 1
|
||||
@@ -375,7 +375,7 @@ extension P4Lang.Parser: CompilableDeclaration {
|
||||
parser,
|
||||
context.update(
|
||||
newInstances: updated_context.instances.declare(
|
||||
identifier: parser.name, withValue: P4TypeAttributed(parser, [])))
|
||||
identifier: parser.name, withValue: P4Type(parser)))
|
||||
))
|
||||
case Result.Error(let error): return .Error(error)
|
||||
}
|
||||
@@ -385,9 +385,9 @@ extension P4Lang.Parser: CompilableDeclaration {
|
||||
extension Control: CompilableDeclaration {
|
||||
public static func Compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(any Common.P4Type, CompilerContext)?> {
|
||||
) -> Common.Result<(any Common.P4DataType, CompilerContext)?> {
|
||||
|
||||
#SkipUnlessNodeType<Node, (P4Type, CompilerContext)?>(
|
||||
#SkipUnlessNodeType<Node, (P4DataType, CompilerContext)?>(
|
||||
node: node, type: "control_declaration")
|
||||
|
||||
var currentChildIdx = 0
|
||||
@@ -438,7 +438,7 @@ extension Control: CompilableDeclaration {
|
||||
var control_scope = local_context.instances.enter()
|
||||
for parameter in control_parameters.parameters {
|
||||
control_scope = control_scope.declare(
|
||||
identifier: parameter.name, withValue: parameter.attributedType())
|
||||
identifier: parameter.name, withValue: parameter.type)
|
||||
}
|
||||
local_context = local_context.update(newInstances: control_scope)
|
||||
|
||||
@@ -498,7 +498,7 @@ extension Control: CompilableDeclaration {
|
||||
(Control(
|
||||
named: control_name, withParameters: control_parameters, withTable: tables[0],
|
||||
withActions: Actions(withActions: actions))
|
||||
as P4Type)
|
||||
as P4DataType)
|
||||
|
||||
// Don't forget to add the newly declared Control to the instance that we were given
|
||||
// (and not the one that we entered to do the parsing of this Control).
|
||||
@@ -507,7 +507,7 @@ extension Control: CompilableDeclaration {
|
||||
declared_control,
|
||||
context.update(
|
||||
newInstances: context.instances.declare(
|
||||
identifier: control_name, withValue: P4TypeAttributed(declared_control, [])))
|
||||
identifier: control_name, withValue: P4Type(declared_control)))
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -517,7 +517,7 @@ extension Action: Compilable {
|
||||
public static func Compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(P4Lang.Action, CompilerContext)> {
|
||||
#RequireNodeType<Node, (P4Type, CompilerContext)>(
|
||||
#RequireNodeType<Node, (P4DataType, CompilerContext)>(
|
||||
node: node, type: "action_declaration", nice_type_name: "Action Declaration")
|
||||
|
||||
var currentChildIdx = 1
|
||||
@@ -569,7 +569,7 @@ extension Action: Compilable {
|
||||
var function_scope = context.instances.enter()
|
||||
for parameter in action_parameters.parameters {
|
||||
function_scope = function_scope.declare(
|
||||
identifier: parameter.name, withValue: parameter.attributedType())
|
||||
identifier: parameter.name, withValue: parameter.type)
|
||||
}
|
||||
|
||||
let maybe_action_body = Parser.Statement.Compile(
|
||||
@@ -592,7 +592,7 @@ extension TableKeyEntry: Compilable {
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(P4Lang.TableKeyEntry, CompilerContext)> {
|
||||
|
||||
#RequireNodeType<Node, (P4Type, CompilerContext)>(
|
||||
#RequireNodeType<Node, (P4DataType, CompilerContext)>(
|
||||
node: node, type: "table_key_entry", nice_type_name: "Table Key Entry")
|
||||
|
||||
var currentChildIdx = 0
|
||||
@@ -701,7 +701,7 @@ extension TablePropertyList: Compilable {
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(P4Lang.TablePropertyList, CompilerContext)> {
|
||||
|
||||
#RequireNodeType<Node, (P4Type, CompilerContext)>(
|
||||
#RequireNodeType<Node, (P4DataType, CompilerContext)>(
|
||||
node: node, type: "table_property_list", nice_type_name: "Table Property List")
|
||||
|
||||
var current_context = context
|
||||
@@ -756,7 +756,7 @@ extension Table: Compilable {
|
||||
) -> Common.Result<(P4Lang.Table, CompilerContext)> {
|
||||
|
||||
let table_declaration_node = node
|
||||
#RequireNodeType<Node, (P4Type, CompilerContext)>(
|
||||
#RequireNodeType<Node, (P4DataType, CompilerContext)>(
|
||||
node: table_declaration_node, type: "table_declaration", nice_type_name: "Table Declaration")
|
||||
|
||||
var currentChildIdx = 1
|
||||
|
||||
@@ -43,13 +43,13 @@ extension TypedIdentifier: CompilableExpression {
|
||||
node: node, type: "identifier")
|
||||
|
||||
guard
|
||||
case Result.Ok(let attributed_type) = context.instances.lookup(
|
||||
case Result.Ok(let type) = context.instances.lookup(
|
||||
identifier: Common.Identifier(name: node.text!))
|
||||
else {
|
||||
return .Error(ErrorOnNode(node: node, withError: "Cannot find \(node.text!) in scope"))
|
||||
}
|
||||
|
||||
return .Ok(TypedIdentifier(name: node.text!, withType: attributed_type.type))
|
||||
return .Ok(TypedIdentifier(name: node.text!, withType: type))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,9 +82,9 @@ extension P4BooleanValue: CompilableExpression {
|
||||
node: node, type: "booleanLiteralExpression")
|
||||
|
||||
if node.text == "false" {
|
||||
return .Ok(P4BooleanValue(withValue: false))
|
||||
return .Ok(P4Value(P4BooleanValue(withValue: false)))
|
||||
} else if node.text == "true" {
|
||||
return .Ok(P4BooleanValue(withValue: true))
|
||||
return .Ok(P4Value(P4BooleanValue(withValue: true)))
|
||||
}
|
||||
|
||||
return .Error(
|
||||
@@ -99,7 +99,7 @@ extension P4IntValue: CompilableExpression {
|
||||
let node = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<SwiftTreeSitter.Node, EvaluatableExpression?>(node: node, type: "integer")
|
||||
if let parsed_int = Int(node.text!) {
|
||||
return .Ok(P4IntValue(withValue: parsed_int))
|
||||
return .Ok(P4Value(P4IntValue(withValue: parsed_int)))
|
||||
} else {
|
||||
return .Error(ErrorOnNode(node: node, withError: "Failed to parse integer: \(node.text!)"))
|
||||
}
|
||||
@@ -113,7 +113,7 @@ extension P4StringValue: CompilableExpression {
|
||||
let node = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<SwiftTreeSitter.Node, EvaluatableExpression?>(
|
||||
node: node, type: "string_literal")
|
||||
return .Ok(P4StringValue(withValue: node.text!))
|
||||
return .Ok(P4Value(P4StringValue(withValue: node.text!)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ extension KeysetExpression: CompilableExpression {
|
||||
|
||||
// If there is a default keyset, that's easy!
|
||||
if keyset_expression_node.nodeType == "default_keyset" {
|
||||
return .Ok(KeysetExpression(P4SetDefaultValue(withType: context.expected_type!)))
|
||||
return .Ok(KeysetExpression(P4Value(P4SetDefaultValue(withType: context.expected_type!))))
|
||||
}
|
||||
|
||||
// Compile the expression:
|
||||
@@ -399,44 +399,48 @@ extension BinaryOperatorExpression: CompilableExpression {
|
||||
|
||||
let evaluators: [String: (String, P4Type, BinaryOperatorChecker?, BinaryOperatorEvaluator)] = [
|
||||
"binaryEqualOperatorExpression": (
|
||||
"Binary Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||
"Binary Equal", P4Type(P4Boolean()), Optional<BinaryOperatorChecker>.none,
|
||||
binary_equal_operator_evaluator
|
||||
),
|
||||
"binaryLessThanOperatorExpression": (
|
||||
"Binary Less Than", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||
"Binary Less Than", P4Type(P4Boolean()), Optional<BinaryOperatorChecker>.none,
|
||||
binary_lt_operator_evaluator
|
||||
),
|
||||
"binaryLessThanEqualOperatorExpression": (
|
||||
"Binary Less Than Or Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||
"Binary Less Than Or Equal", P4Type(P4Boolean()), Optional<BinaryOperatorChecker>.none,
|
||||
binary_lte_operator_evaluator
|
||||
),
|
||||
"binaryGreaterThanOperatorExpression": (
|
||||
"Binary Greater Than", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||
"Binary Greater Than", P4Type(P4Boolean()), Optional<BinaryOperatorChecker>.none,
|
||||
binary_gt_operator_evaluator
|
||||
),
|
||||
"binaryGreaterThanEqualOperatorExpression": (
|
||||
"Binary Greater Than Or Equal", P4Boolean(), Optional<BinaryOperatorChecker>.none,
|
||||
"Binary Greater Than Or Equal", P4Type(P4Boolean()), Optional<BinaryOperatorChecker>.none,
|
||||
binary_gte_operator_evaluator
|
||||
),
|
||||
"binaryAndOperatorExpression": (
|
||||
"Binary Or", P4Boolean(), binary_and_or_operator_checker, binary_and_operator_evaluator
|
||||
"Binary Or", P4Type(P4Boolean()), binary_and_or_operator_checker,
|
||||
binary_and_operator_evaluator
|
||||
),
|
||||
"binaryOrOperatorExpression": (
|
||||
"Binary And", P4Boolean(), binary_and_or_operator_checker, binary_or_operator_evaluator
|
||||
"Binary And", P4Type(P4Boolean()), binary_and_or_operator_checker,
|
||||
binary_or_operator_evaluator
|
||||
),
|
||||
"binaryAddOperatorExpression": (
|
||||
"Binary Add", P4Int(), binary_int_math_operator_checker, binary_add_operator_evaluator
|
||||
"Binary Add", P4Type(P4Int()), binary_int_math_operator_checker,
|
||||
binary_add_operator_evaluator
|
||||
),
|
||||
"binarySubtractOperatorExpression": (
|
||||
"Binary Subtract", P4Int(), binary_int_math_operator_checker,
|
||||
"Binary Subtract", P4Type(P4Int()), binary_int_math_operator_checker,
|
||||
binary_subtract_operator_evaluator
|
||||
),
|
||||
"binaryMultiplyOperatorExpression": (
|
||||
"Binary Multiply", P4Int(), binary_int_math_operator_checker,
|
||||
"Binary Multiply", P4Type(P4Int()), binary_int_math_operator_checker,
|
||||
binary_multiply_operator_evaluator
|
||||
),
|
||||
"binaryDivideOperatorExpression": (
|
||||
"Binary Divide", P4Int(), binary_int_math_operator_checker, binary_divide_operator_evaluator
|
||||
"Binary Divide", P4Type(P4Int()), binary_int_math_operator_checker,
|
||||
binary_divide_operator_evaluator
|
||||
),
|
||||
]
|
||||
|
||||
@@ -517,7 +521,7 @@ extension ArrayAccessExpression: CompilableExpression {
|
||||
}
|
||||
|
||||
let maybe_array_type = array_identifier.type()
|
||||
guard let array_type = maybe_array_type as? P4Array else {
|
||||
guard let array_type = maybe_array_type.dataType() as? P4Array else {
|
||||
return Result.Error(
|
||||
ErrorOnNode(
|
||||
node: array_access_identifier_node,
|
||||
@@ -595,7 +599,7 @@ extension FieldAccessExpression: CompilableExpression {
|
||||
guard case Result.Ok(let struct_identifier) = maybe_struct_identifier else {
|
||||
return Result.Error(maybe_struct_identifier.error()!)
|
||||
}
|
||||
guard let struct_type = struct_identifier.type() as? P4Struct else {
|
||||
guard let struct_type = struct_identifier.type().dataType() as? P4Struct else {
|
||||
return .Error(
|
||||
ErrorOnNode(
|
||||
node: struct_identifier_node,
|
||||
|
||||
@@ -29,19 +29,19 @@ public protocol CompilableStatement {
|
||||
}
|
||||
|
||||
public protocol CompilableValue {
|
||||
static func CompileValue(withValue value: String) -> Result<P4Value>
|
||||
static func CompileValue(withValue value: String) -> Result<P4DataValue>
|
||||
}
|
||||
|
||||
public protocol CompilableType {
|
||||
static func CompileType(
|
||||
type: SwiftTreeSitter.Node, withContext: CompilerContext
|
||||
) -> Result<P4Type?>
|
||||
) -> Result<P4DataType?>
|
||||
}
|
||||
|
||||
public protocol CompilableDeclaration {
|
||||
static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<(P4Type, CompilerContext)?>
|
||||
) -> Result<(P4DataType, CompilerContext)?>
|
||||
}
|
||||
|
||||
public protocol Compilable<T> {
|
||||
|
||||
@@ -214,7 +214,7 @@ extension VariableDeclarationStatement: CompilableStatement {
|
||||
return .Error(maybe_parsed_rvalue.error()!)
|
||||
}
|
||||
|
||||
if parsed_rvalue.type().eq(rhs: declaration_p4_type) {
|
||||
if parsed_rvalue.type().eq(declaration_p4_type) {
|
||||
initializer = parsed_rvalue
|
||||
} else {
|
||||
return Result.Error(
|
||||
@@ -231,8 +231,9 @@ extension VariableDeclarationStatement: CompilableStatement {
|
||||
// Context with updated names to include the newly declared name.
|
||||
context.update(
|
||||
newInstances: context.instances.declare(
|
||||
identifier: parsed_variablename, withValue: P4TypeAttributed(declaration_p4_type, [])))
|
||||
))
|
||||
identifier: parsed_variablename, withValue: declaration_p4_type))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +312,7 @@ extension ReturnStatement: CompilableStatement {
|
||||
|
||||
return switch Expression.Compile(node: expression_node, withContext: context) {
|
||||
case .Ok(let result):
|
||||
if result.type().eq(rhs: context.expected_type!) {
|
||||
if result.type().eq(context.expected_type!) {
|
||||
.Ok((ReturnStatement(result), context))
|
||||
} else {
|
||||
.Error(
|
||||
|
||||
@@ -25,7 +25,7 @@ import TreeSitterP4
|
||||
extension P4Boolean: CompilableType {
|
||||
public static func CompileType(
|
||||
type: SwiftTreeSitter.Node, withContext: CompilerContext
|
||||
) -> Common.Result<(any Common.P4Type)?> {
|
||||
) -> Common.Result<(any Common.P4DataType)?> {
|
||||
return type.text == "bool" ? .Ok(P4Boolean()) : .Ok(.none)
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ extension P4Boolean: CompilableType {
|
||||
extension P4Int: CompilableType {
|
||||
public static func CompileType(
|
||||
type: SwiftTreeSitter.Node, withContext: CompilerContext
|
||||
) -> Common.Result<(any Common.P4Type)?> {
|
||||
) -> Common.Result<(any Common.P4DataType)?> {
|
||||
return type.text == "int" ? .Ok(P4Int()) : .Ok(.none)
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ extension P4Int: CompilableType {
|
||||
extension P4String: CompilableType {
|
||||
public static func CompileType(
|
||||
type: SwiftTreeSitter.Node, withContext: CompilerContext
|
||||
) -> Common.Result<(any Common.P4Type)?> {
|
||||
) -> Common.Result<(any Common.P4DataType)?> {
|
||||
return type.text == "string" ? .Ok(P4String()) : .Ok(.none)
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ extension P4String: CompilableType {
|
||||
extension P4Struct: CompilableType {
|
||||
public static func CompileType(
|
||||
type: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(any Common.P4Type)?> {
|
||||
) -> Common.Result<(any Common.P4DataType)?> {
|
||||
|
||||
let maybe_parsed_type_id = Identifier.Compile(node: type, withContext: context)
|
||||
guard case .Ok(let parsed_type_id) = maybe_parsed_type_id else {
|
||||
@@ -74,7 +74,7 @@ public struct Types {
|
||||
]
|
||||
for type_parser in type_parsers {
|
||||
switch type_parser.CompileType(type: type, withContext: context) {
|
||||
case .Ok(.some(let type)): return .Ok(type)
|
||||
case .Ok(.some(let type)): return .Ok(P4Type(type))
|
||||
case .Ok(.none): continue
|
||||
case .Error(let e): return .Error(e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user