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:
@@ -24,30 +24,30 @@ import TreeSitterP4
|
||||
|
||||
func parameter_list_compiler(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(ParameterList, CompilerContext)> {
|
||||
) -> Common.Result<ParameterList> {
|
||||
|
||||
var walker = Walker(node: node)
|
||||
var current_node: Node? = .none
|
||||
|
||||
if node.text == ")" {
|
||||
// There are no parameters!
|
||||
return Result.Ok((ParameterList([]), context))
|
||||
return Result.Ok(ParameterList([]))
|
||||
}
|
||||
|
||||
#RequireNodeType<Node, (ParameterList, CompilerContext)>(
|
||||
#RequireNodeType<Node, ParameterList>(
|
||||
node: node, type: "parameter_list", nice_type_name: "Parameter List")
|
||||
|
||||
var parameters: ParameterList = ParameterList([])
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ParameterList, CompilerContext)>.Error(
|
||||
or: Result<ParameterList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing parameter list component")))
|
||||
|
||||
if current_node?.nodeType == "parameter_list" {
|
||||
switch parameter_list_compiler(node: current_node!, withContext: context) {
|
||||
case .Ok(let (ps, _)):
|
||||
case .Ok(let ps):
|
||||
parameters = ps
|
||||
case .Error(let e): return Result.Error(e)
|
||||
}
|
||||
@@ -56,13 +56,13 @@ func parameter_list_compiler(
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ParameterList, CompilerContext)>.Error(
|
||||
or: Result<ParameterList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing parameter list component")))
|
||||
|
||||
// If this is a ')', we are done.
|
||||
if current_node?.text == ")" {
|
||||
return Result.Ok((parameters, context))
|
||||
return Result.Ok(parameters)
|
||||
}
|
||||
|
||||
// If this is a comma, we skip it!
|
||||
@@ -72,26 +72,26 @@ func parameter_list_compiler(
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ParameterList, CompilerContext)>.Error(
|
||||
or: Result<ParameterList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing parameter list component")))
|
||||
|
||||
// Otherwise, there should be one parameter left!
|
||||
switch Parameter.Compile(node: current_node!, withContext: context) {
|
||||
case .Ok(let (parsed_parameter, updated_context)):
|
||||
return Result.Ok((parameters.addParameter(parsed_parameter), updated_context))
|
||||
case .Ok(let parsed_parameter):
|
||||
return Result.Ok(parameters.addParameter(parsed_parameter))
|
||||
case .Error(let e): return Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
extension ParameterList: Compilable {
|
||||
public typealias T = ParameterList
|
||||
public typealias C = ParameterList
|
||||
public static func Compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(ParameterList, CompilerContext)> {
|
||||
) -> Common.Result<ParameterList> {
|
||||
|
||||
let parameter_node = node
|
||||
#RequireNodeType<Node, (ParameterList, CompilerContext)>(
|
||||
#RequireNodeType<Node, ParameterList>(
|
||||
node: parameter_node, type: "parameters", nice_type_name: "Parameters")
|
||||
|
||||
var walker = Walker(node: parameter_node)
|
||||
@@ -100,7 +100,7 @@ extension ParameterList: Compilable {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ParameterList, CompilerContext)>.Error(
|
||||
or: Result<ParameterList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing '(' in parameter list component")))
|
||||
@@ -108,7 +108,7 @@ extension ParameterList: Compilable {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ParameterList, CompilerContext)>.Error(
|
||||
or: Result<ParameterList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing parameter list component")))
|
||||
|
||||
@@ -117,12 +117,12 @@ extension ParameterList: Compilable {
|
||||
}
|
||||
|
||||
extension Direction: Compilable {
|
||||
public typealias T = Direction
|
||||
public typealias C = Direction
|
||||
public static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<(Direction, CompilerContext)> {
|
||||
) -> Result<Direction> {
|
||||
let direction_node = node
|
||||
#RequireNodeType<Node, (Direction, CompilerContext)>(
|
||||
#RequireNodeType<Node, Direction>(
|
||||
node: direction_node, type: "direction", nice_type_name: "direction")
|
||||
let directions = [
|
||||
"in": Direction.In,
|
||||
@@ -137,17 +137,17 @@ extension Direction: Compilable {
|
||||
withError: "\(direction_node.text!) is not a valid direction"))
|
||||
}
|
||||
|
||||
return .Ok((parsed_direction, context))
|
||||
return .Ok(parsed_direction)
|
||||
}
|
||||
}
|
||||
|
||||
extension Parameter: Compilable {
|
||||
public typealias T = Parameter
|
||||
public typealias C = Parameter
|
||||
public static func Compile(
|
||||
node: Node, withContext context: CompilerContext
|
||||
) -> Result<(Parameter, CompilerContext)> {
|
||||
) -> Result<Parameter> {
|
||||
|
||||
#RequireNodeType<Node, (EvaluatableStatement, CompilerContext)>(
|
||||
#RequireNodeType<Node, P4Statement>(
|
||||
node: node, type: "parameter", nice_type_name: "parameter")
|
||||
|
||||
var walker = Walker(node: node)
|
||||
@@ -155,7 +155,7 @@ extension Parameter: Compilable {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(Parameter, CompilerContext)>.Error(
|
||||
or: Result<Parameter>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing parameter declaration component")))
|
||||
@@ -171,7 +171,7 @@ extension Parameter: Compilable {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(Parameter, CompilerContext)>.Error(
|
||||
or: Result<Parameter>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing parameter declaration component")))
|
||||
@@ -181,7 +181,7 @@ extension Parameter: Compilable {
|
||||
if current_node!.nodeType == "direction" {
|
||||
|
||||
let maybe_parsed_direction = Direction.Compile(node: current_node!, withContext: context)
|
||||
guard case .Ok((let parsed_direction, _)) = maybe_parsed_direction else {
|
||||
guard case .Ok(let parsed_direction) = maybe_parsed_direction else {
|
||||
return .Error(maybe_parsed_direction.error()!)
|
||||
}
|
||||
direction = parsed_direction
|
||||
@@ -191,7 +191,7 @@ extension Parameter: Compilable {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(Parameter, CompilerContext)>.Error(
|
||||
or: Result<Parameter>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing parameter declaration component")))
|
||||
@@ -213,7 +213,7 @@ extension Parameter: Compilable {
|
||||
walker.next()
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(Parameter, CompilerContext)>.Error(
|
||||
or: Result<Parameter>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing parameter declaration component")))
|
||||
@@ -233,43 +233,41 @@ extension Parameter: Compilable {
|
||||
}
|
||||
|
||||
return Result.Ok(
|
||||
(
|
||||
Parameter(
|
||||
identifier: parameter_name,
|
||||
withType: direction != nil
|
||||
? parameter_type.update(addAttribute: P4TypeQualifier.Direction(direction!))
|
||||
: parameter_type),
|
||||
context
|
||||
))
|
||||
Parameter(
|
||||
identifier: parameter_name,
|
||||
withType: direction != nil
|
||||
? parameter_type.update(addAttribute: P4TypeQualifier.Direction(direction!))
|
||||
: parameter_type),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func argument_list_compiler(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(ArgumentList, CompilerContext)> {
|
||||
) -> Common.Result<ArgumentList> {
|
||||
|
||||
var walker = Walker(node: node)
|
||||
var current_node: Node? = .none
|
||||
|
||||
if node.text == ")" {
|
||||
// There are no arguments!
|
||||
return Result.Ok((ArgumentList([]), context))
|
||||
return Result.Ok(ArgumentList([]))
|
||||
}
|
||||
|
||||
#RequireNodeType<Node, (ArgumentList, CompilerContext)>(
|
||||
#RequireNodeType<Node, ArgumentList>(
|
||||
node: node, type: "argument_list", nice_type_name: "argument List")
|
||||
|
||||
var arguments: ArgumentList = ArgumentList([])
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ArgumentList, CompilerContext)>.Error(
|
||||
or: Result<ArgumentList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing argument list component")))
|
||||
|
||||
if current_node?.nodeType == "argument_list" {
|
||||
switch argument_list_compiler(node: current_node!, withContext: context) {
|
||||
case .Ok(let (ps, _)):
|
||||
case .Ok(let ps):
|
||||
arguments = ps
|
||||
case .Error(let e): return Result.Error(e)
|
||||
}
|
||||
@@ -280,13 +278,13 @@ func argument_list_compiler(
|
||||
// We may have moved nodes, check/reset current_node.
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ArgumentList, CompilerContext)>.Error(
|
||||
or: Result<ArgumentList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing argument list component")))
|
||||
|
||||
// If this is a ')', we are done.
|
||||
if current_node?.text == ")" {
|
||||
return Result.Ok((arguments, context))
|
||||
return Result.Ok(arguments)
|
||||
}
|
||||
|
||||
// If this is a comma, we skip it!
|
||||
@@ -296,27 +294,27 @@ func argument_list_compiler(
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ArgumentList, CompilerContext)>.Error(
|
||||
or: Result<ArgumentList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing argument list component")))
|
||||
|
||||
// Otherwise, there should be one argument left!
|
||||
switch Argument.Compile(node: current_node!, withContext: context) {
|
||||
case .Ok(let (ce, updated_context)):
|
||||
case .Ok(let ce):
|
||||
return Result.Ok(
|
||||
(arguments.addArgument(Argument(ce, atIndex: arguments.count() + 1)), updated_context))
|
||||
arguments.addArgument(Argument(ce, atIndex: arguments.count() + 1)))
|
||||
case .Error(let e): return Result.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
extension ArgumentList: Compilable {
|
||||
public typealias T = ArgumentList
|
||||
public typealias C = ArgumentList
|
||||
public static func Compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(ArgumentList, CompilerContext)> {
|
||||
) -> Common.Result<ArgumentList> {
|
||||
|
||||
let argument_node = node
|
||||
#RequireNodeType<Node, (ArgumentList, CompilerContext)>(
|
||||
#RequireNodeType<Node, ArgumentList>(
|
||||
node: argument_node, type: "arguments", nice_type_name: "arguments")
|
||||
|
||||
var walker = Walker(node: argument_node)
|
||||
@@ -324,7 +322,7 @@ extension ArgumentList: Compilable {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ArgumentList, CompilerContext)>.Error(
|
||||
or: Result<ArgumentList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(),
|
||||
withError: "Missing '(' in argument list component")))
|
||||
@@ -333,7 +331,7 @@ extension ArgumentList: Compilable {
|
||||
|
||||
#MustOr(
|
||||
result: current_node, thing: walker.getNext(),
|
||||
or: Result<(ArgumentList, CompilerContext)>.Error(
|
||||
or: Result<ArgumentList>.Error(
|
||||
ErrorWithLocation(
|
||||
sourceLocation: node.toSourceLocation(), withError: "Missing argument list component")))
|
||||
|
||||
@@ -342,25 +340,25 @@ extension ArgumentList: Compilable {
|
||||
}
|
||||
|
||||
extension Argument: Compilable {
|
||||
public typealias T = EvaluatableExpression
|
||||
public typealias C = P4Expression
|
||||
public static func Compile(
|
||||
node: SwiftTreeSitter.Node, withContext context: CompilerContext
|
||||
) -> Common.Result<(EvaluatableExpression, CompilerContext)> {
|
||||
) -> Common.Result<P4Expression> {
|
||||
let argument_node = node
|
||||
#RequireNodeType<Node, (EvaluatableExpression, CompilerContext)>(
|
||||
#RequireNodeType<Node, P4Expression>(
|
||||
node: argument_node, type: "argument", nice_type_name: "argument")
|
||||
|
||||
let expression_node = node.child(at: 0)!
|
||||
|
||||
return switch Expression.Compile(node: expression_node, withContext: context) {
|
||||
case .Ok(let compiled_expression): .Ok((compiled_expression, context))
|
||||
case .Ok(let compiled_expression): .Ok(compiled_expression)
|
||||
case .Error(let e): .Error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ContainsInvalidStatements(
|
||||
statement: EvaluatableStatement, invalids: [EvaluatableStatement.Type]
|
||||
statement: P4Statement, invalids: [P4Statement.Type]
|
||||
) -> Bool {
|
||||
for es in invalids {
|
||||
if type(of: statement) == es {
|
||||
@@ -370,8 +368,7 @@ func ContainsInvalidStatements(
|
||||
return false
|
||||
}
|
||||
|
||||
func ContainsInvalidStatements(block: BlockStatement, invalids: [EvaluatableStatement.Type]) -> Bool
|
||||
{
|
||||
func ContainsInvalidStatements(block: BlockStatement, invalids: [P4Statement.Type]) -> Bool {
|
||||
return block.statements.contains { statement in
|
||||
for es in invalids {
|
||||
if type(of: statement) == es {
|
||||
|
||||
Reference in New Issue
Block a user