Initial Array Access Implementation
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
@@ -110,7 +110,7 @@ struct Expression {
|
||||
|
||||
let localElementsParsers: [CompilableExpression.Type] = [
|
||||
P4BooleanValue.self, P4StringValue.self, P4IntValue.self, TypedIdentifier.self,
|
||||
BinaryOperatorExpression.self,
|
||||
BinaryOperatorExpression.self, ArrayAccessExpression.self
|
||||
]
|
||||
|
||||
for le_parser in localElementsParsers {
|
||||
@@ -311,3 +311,67 @@ extension BinaryOperatorExpression: CompilableExpression {
|
||||
withLhs: left_hand_side, withRhs: right_hand_side))
|
||||
}
|
||||
}
|
||||
|
||||
extension ArrayAccessExpression: CompilableExpression {
|
||||
static func compile(node: SwiftTreeSitter.Node, withContext context: CompilerContext) -> Common.Result<(any Common.EvaluatableExpression)?> {
|
||||
let expression = node.child(at: 0)!
|
||||
|
||||
#SkipUnlessNodeType<Node, EvaluatableExpression?>(
|
||||
node: expression, type: "arrayAccessExpression")
|
||||
|
||||
let array_access_expression_node = expression
|
||||
|
||||
var currentChildIdx = 0
|
||||
var currentChildIdxSafe = 1
|
||||
var currentChild: Node? = .none
|
||||
|
||||
// What is the "name" of the array?
|
||||
if array_access_expression_node.childCount < currentChildIdxSafe {
|
||||
return Result.Error(
|
||||
ErrorOnNode(node: node, withError: "Malformed array access expression"))
|
||||
}
|
||||
currentChild = expression.child(at: currentChildIdx)
|
||||
|
||||
#RequireNodeType<Node, EvaluatableExpression?>(
|
||||
node: currentChild!, type: "expression",
|
||||
nice_type_name: "array identifier expression")
|
||||
let array_access_identifier_node = currentChild!
|
||||
|
||||
// Check for the [
|
||||
currentChildIdx = currentChildIdx + 1
|
||||
currentChildIdxSafe = currentChildIdxSafe + 1
|
||||
if array_access_expression_node.childCount < currentChildIdxSafe {
|
||||
return Result.Error(
|
||||
ErrorOnNode(node: node, withError: "Missing [ for array access expression")
|
||||
)
|
||||
}
|
||||
|
||||
// What is the indexor of the array?
|
||||
currentChildIdx = currentChildIdx + 1
|
||||
currentChildIdxSafe = currentChildIdxSafe + 1
|
||||
if array_access_expression_node.childCount < currentChildIdxSafe {
|
||||
return Result.Error(
|
||||
ErrorOnNode(node: node, withError: "Missing indexor expression for array access expression")
|
||||
)
|
||||
}
|
||||
currentChild = array_access_expression_node.child(at: currentChildIdx)
|
||||
|
||||
#RequireNodeType<Node, EvaluatableExpression?>(
|
||||
node: currentChild!, type: "expression",
|
||||
nice_type_name: "array indexor expression")
|
||||
|
||||
let array_access_indexor_node = currentChild!
|
||||
|
||||
let maybe_array_identifier = Expression.Compile(node: array_access_identifier_node, withContext: context)
|
||||
guard case Result.Ok(let array_identifier) = maybe_array_identifier else {
|
||||
return Result.Error(maybe_array_identifier.error()!)
|
||||
}
|
||||
|
||||
let maybe_array_indexor = Expression.Compile(node: array_access_indexor_node, withContext: context)
|
||||
guard case Result.Ok(let array_indexor) = maybe_array_indexor else {
|
||||
return Result.Error(maybe_array_indexor.error()!)
|
||||
}
|
||||
|
||||
return .Ok(ArrayAccessExpression(withName: array_identifier, withIndexor: array_indexor))
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,10 @@ import TreeSitterP4
|
||||
|
||||
public struct Program {
|
||||
public static func Compile(_ source: String) -> Result<P4Lang.Program> {
|
||||
return Program.Compile(source, withGlobalTypes: .none)
|
||||
}
|
||||
|
||||
public static func Compile(_ source: String, withGlobalTypes globalTypes: LexicalScopes?) -> Result<P4Lang.Program> {
|
||||
|
||||
let maybe_parser = ConfigureP4Parser()
|
||||
guard case .Ok(let p) = maybe_parser else {
|
||||
@@ -45,6 +49,11 @@ public struct Program {
|
||||
|
||||
var errors: [Error] = Array()
|
||||
|
||||
// If the caller gave any global types, add them here.
|
||||
if let globalTypes = globalTypes {
|
||||
compilation_context = compilation_context.update(newNames: globalTypes)
|
||||
}
|
||||
|
||||
result?.rootNode?.enumerateNamedChildren { declaration_node in
|
||||
if declaration_node.nodeType != "declaration" {
|
||||
return
|
||||
@@ -185,7 +194,9 @@ public struct Program {
|
||||
}
|
||||
|
||||
// Any of the types that are in the top-level scope should go into the program!
|
||||
program.types = Array(compilation_context.names)
|
||||
program.types = Array(compilation_context.names.map() { (_, v) in
|
||||
v
|
||||
})
|
||||
return Result.Ok(program)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user