compiler, runtime: Begin Runtime Refactor
Ultimately, the goal is to completely separate the compilation from the runtime to make it possible to have the interpreter/evaluator be "just another" entity that can perform meaningful work when given a parsed GP4 program. Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -21,22 +21,10 @@ import P4Runtime
|
||||
import SwiftTreeSitter
|
||||
import TreeSitterP4
|
||||
|
||||
protocol CompilableExpression {
|
||||
static func compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?>
|
||||
}
|
||||
|
||||
protocol CompilableLValueExpression {
|
||||
static func compile_as_lvalue(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableLValueExpression?>
|
||||
}
|
||||
|
||||
extension TypedIdentifier: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
|
||||
let node = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<SwiftTreeSitter.Node>(
|
||||
@@ -57,9 +45,9 @@ extension TypedIdentifier: CompilableExpression {
|
||||
}
|
||||
|
||||
extension TypedIdentifier: CompilableLValueExpression {
|
||||
static func compile_as_lvalue(
|
||||
public static func compile_as_lvalue(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableLValueExpression?> {
|
||||
) -> Result<P4LValueExpression?> {
|
||||
|
||||
let expression = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<SwiftTreeSitter.Node>(
|
||||
@@ -77,9 +65,9 @@ extension TypedIdentifier: CompilableLValueExpression {
|
||||
}
|
||||
|
||||
extension P4BooleanValue: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
let node = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<SwiftTreeSitter.Node>(
|
||||
node: node, type: "booleanLiteralExpression")
|
||||
@@ -98,9 +86,9 @@ extension P4BooleanValue: CompilableExpression {
|
||||
}
|
||||
|
||||
extension P4IntValue: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
let node = node.child(at: 0)!
|
||||
|
||||
#SkipUnlessNodesTypes<SwiftTreeSitter.Node>(
|
||||
@@ -147,9 +135,9 @@ extension P4IntValue: CompilableExpression {
|
||||
}
|
||||
|
||||
extension P4StringValue: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext scopes: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
let node = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<SwiftTreeSitter.Node>(
|
||||
node: node, type: "string_literal")
|
||||
@@ -158,12 +146,12 @@ extension P4StringValue: CompilableExpression {
|
||||
}
|
||||
|
||||
extension KeysetExpression: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(any Common.EvaluatableExpression)?> {
|
||||
) -> Result<P4Expression?> {
|
||||
let keyset_expression_node = node.child(at: 0)!
|
||||
|
||||
#RequireNodesType<Node, EvaluatableExpression>(
|
||||
#RequireNodesType<Node, P4Expression>(
|
||||
nodes: keyset_expression_node, type: ["expression", "default_keyset"],
|
||||
nice_type_names: ["expression", "default keyset"])
|
||||
|
||||
@@ -186,12 +174,12 @@ extension KeysetExpression: CompilableExpression {
|
||||
struct Expression {
|
||||
public static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression> {
|
||||
#RequireNodeType<Node, EvaluatableExpression>(
|
||||
) -> Result<P4Expression> {
|
||||
#RequireNodeType<Node, P4Expression>(
|
||||
node: node, type: "expression", nice_type_name: "expression")
|
||||
|
||||
let expression_node = node.child(at: 0)!
|
||||
#RequireNodesType<Node, EvaluatableExpression>(
|
||||
#RequireNodesType<Node, P4Expression>(
|
||||
nodes: expression_node, type: ["grouped_expression", "simple_expression"],
|
||||
nice_type_names: ["grouped expression", "simple expression"])
|
||||
|
||||
@@ -223,12 +211,12 @@ struct Expression {
|
||||
struct LValue {
|
||||
public static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableLValueExpression> {
|
||||
#RequireNodeType<Node, EvaluatableExpression>(
|
||||
) -> Result<P4LValueExpression> {
|
||||
#RequireNodeType<Node, P4Expression>(
|
||||
node: node, type: "expression", nice_type_name: "expression")
|
||||
|
||||
let expression_node = node.child(at: 0)!
|
||||
#RequireNodesType<Node, EvaluatableExpression>(
|
||||
#RequireNodesType<Node, P4Expression>(
|
||||
nodes: expression_node, type: ["grouped_expression", "simple_expression"],
|
||||
nice_type_names: ["grouped expression", "simple expression"])
|
||||
|
||||
@@ -268,9 +256,9 @@ struct Identifier {
|
||||
}
|
||||
|
||||
extension SelectExpression: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
#RequireNodeType<Node, (SelectExpression, CompilerContext)>(
|
||||
node: node, type: "selectExpression", nice_type_name: "parser select expression")
|
||||
|
||||
@@ -330,9 +318,9 @@ extension SelectExpression: CompilableExpression {
|
||||
}
|
||||
|
||||
extension SelectCaseExpression: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
if node.nodeType != "selectCase" {
|
||||
return Result.Error(Error(withMessage: "Expected select case not found"))
|
||||
}
|
||||
@@ -383,10 +371,35 @@ extension SelectCaseExpression: CompilableExpression {
|
||||
}
|
||||
}
|
||||
|
||||
// swift-format-ignore
|
||||
public typealias BinaryOperatorChecker = (P4Expression, P4Expression) -> Result<()>
|
||||
|
||||
public func binary_and_or_operator_checker(
|
||||
left: P4Expression, right: P4Expression
|
||||
) -> Result<()> {
|
||||
// Check that both are Boolean-typed things!
|
||||
if !(left.type().baseType().eq(rhs: P4Boolean()) && right.type().baseType().eq(rhs: P4Boolean()))
|
||||
{
|
||||
return .Error(Error(withMessage: "And/Or on operands with non-bool type is not allowed"))
|
||||
}
|
||||
return .Ok(())
|
||||
}
|
||||
|
||||
public func binary_int_math_operator_checker(
|
||||
left: P4Expression, right: P4Expression
|
||||
) -> Result<()> {
|
||||
// Check that both are int-typed things!
|
||||
if !(left.type().baseType().eq(rhs: P4Int()) && right.type().baseType().eq(rhs: P4Int())) {
|
||||
return .Error(
|
||||
Error(withMessage: "Mathematical operation on operands with non-int type is not allowed"))
|
||||
}
|
||||
return .Ok(())
|
||||
}
|
||||
|
||||
extension BinaryOperatorExpression: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<(EvaluatableExpression)?> {
|
||||
) -> Result<(P4Expression)?> {
|
||||
let expression = node.child(at: 0)!
|
||||
|
||||
#SkipUnlessNodeType<Node>(
|
||||
@@ -398,20 +411,20 @@ extension BinaryOperatorExpression: CompilableExpression {
|
||||
var current_node: Node? = .none
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Malformed binary operator expression"
|
||||
)))
|
||||
|
||||
/// TODO: This macro cannot handle new lines in the arrays
|
||||
// swift-format-ignore
|
||||
#RequireNodesType<Node, EvaluatableExpression?>(
|
||||
#RequireNodesType<Node, P4Expression?>(
|
||||
nodes: binary_operator_expression_node,
|
||||
type: ["binaryEqualOperatorExpression", "binaryLessThanOperatorExpression", "binaryLessThanEqualOperatorExpression", "binaryGreaterThanOperatorExpression", "binaryGreaterThanEqualOperatorExpression", "binaryAndOperatorExpression", "binaryOrOperatorExpression", "binaryAddOperatorExpression", "binarySubtractOperatorExpression", "binaryMultiplyOperatorExpression", "binaryDivideOperatorExpression"],
|
||||
nice_type_names: [ "binary equal operator", "binary less than operator", "binary less than or equal to operator", "binary greater than operator", "binary greater than or equal to operator", "binary and operator", "binary or operator", "binary add operator", "binary subtract operator", "binary multiply operator", "binary divide operator"])
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing LHS for binary operator expression")))
|
||||
@@ -421,7 +434,7 @@ extension BinaryOperatorExpression: CompilableExpression {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing binary operator for binary operator expression")))
|
||||
@@ -429,7 +442,7 @@ extension BinaryOperatorExpression: CompilableExpression {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing RHS for binary operator expression")))
|
||||
@@ -520,9 +533,9 @@ extension BinaryOperatorExpression: CompilableExpression {
|
||||
}
|
||||
|
||||
extension ArrayAccessExpression: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
let expression = node.child(at: 0)!
|
||||
|
||||
#SkipUnlessNodeType<Node>(
|
||||
@@ -535,11 +548,11 @@ extension ArrayAccessExpression: CompilableExpression {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Malformed array access expression")))
|
||||
|
||||
#RequireNodeType<Node, EvaluatableExpression?>(
|
||||
#RequireNodeType<Node, P4Expression?>(
|
||||
node: current_node!, type: "expression",
|
||||
nice_type_name: "array identifier expression")
|
||||
let array_access_identifier_node = current_node!
|
||||
@@ -547,7 +560,7 @@ extension ArrayAccessExpression: CompilableExpression {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing [ for array access expression")))
|
||||
@@ -556,12 +569,12 @@ extension ArrayAccessExpression: CompilableExpression {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing indexor expression for array access expression")))
|
||||
|
||||
#RequireNodeType<Node, EvaluatableExpression?>(
|
||||
#RequireNodeType<Node, P4Expression?>(
|
||||
node: current_node!, type: "expression",
|
||||
nice_type_name: "array indexor expression")
|
||||
|
||||
@@ -595,9 +608,9 @@ extension ArrayAccessExpression: CompilableExpression {
|
||||
}
|
||||
|
||||
extension FieldAccessExpression: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(any Common.EvaluatableExpression)?> {
|
||||
) -> Result<P4Expression?> {
|
||||
let expression = node.child(at: 0)!
|
||||
|
||||
#SkipUnlessNodeType<Node>(
|
||||
@@ -610,11 +623,11 @@ extension FieldAccessExpression: CompilableExpression {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Malformed field access expression")))
|
||||
|
||||
#RequireNodeType<Node, EvaluatableExpression?>(
|
||||
#RequireNodeType<Node, P4Expression?>(
|
||||
node: current_node!, type: "expression",
|
||||
nice_type_name: "struct identifier expression")
|
||||
let struct_identifier_node = current_node!
|
||||
@@ -622,7 +635,7 @@ extension FieldAccessExpression: CompilableExpression {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing . for field access expression")))
|
||||
@@ -630,12 +643,12 @@ extension FieldAccessExpression: CompilableExpression {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing field name for field access expression")))
|
||||
|
||||
#RequireNodeType<Node, EvaluatableExpression?>(
|
||||
#RequireNodeType<Node, P4Expression?>(
|
||||
node: current_node!, type: "identifier",
|
||||
nice_type_name: "field name")
|
||||
|
||||
@@ -677,9 +690,9 @@ extension FieldAccessExpression: CompilableExpression {
|
||||
}
|
||||
|
||||
extension FieldAccessExpression: CompilableLValueExpression {
|
||||
static func compile_as_lvalue(
|
||||
public static func compile_as_lvalue(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableLValueExpression?> {
|
||||
) -> Result<P4LValueExpression?> {
|
||||
let expression = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<Node>(
|
||||
node: expression, type: "fieldAccessExpression")
|
||||
@@ -696,9 +709,9 @@ extension FieldAccessExpression: CompilableLValueExpression {
|
||||
}
|
||||
|
||||
extension ArrayAccessExpression: CompilableLValueExpression {
|
||||
static func compile_as_lvalue(
|
||||
public static func compile_as_lvalue(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableLValueExpression?> {
|
||||
) -> Result<P4LValueExpression?> {
|
||||
let expression = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<Node>(
|
||||
node: expression, type: "arrayAccessExpression")
|
||||
@@ -715,9 +728,9 @@ extension ArrayAccessExpression: CompilableLValueExpression {
|
||||
}
|
||||
|
||||
extension FunctionCall: CompilableExpression {
|
||||
static func compile(
|
||||
public static func compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<EvaluatableExpression?> {
|
||||
) -> Result<P4Expression?> {
|
||||
|
||||
let expression = node.child(at: 0)!
|
||||
#SkipUnlessNodeType<Node>(
|
||||
@@ -728,7 +741,7 @@ extension FunctionCall: CompilableExpression {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing function call component")))
|
||||
|
||||
@@ -780,13 +793,13 @@ extension FunctionCall: CompilableExpression {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<EvaluatableExpression?>.Error(
|
||||
or: Result<P4Expression?>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing function call component")))
|
||||
|
||||
let maybe_argument_list = ArgumentList.Compile(node: current_node!, withContext: context)
|
||||
|
||||
guard case .Ok((let arguments, _)) = maybe_argument_list else {
|
||||
guard case .Ok(let arguments) = maybe_argument_list else {
|
||||
return .Error(maybe_argument_list.error()!)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user