Initial Array Access Implementation

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-03-13 09:41:04 -04:00
parent 1982fda677
commit 0b4db34177
10 changed files with 266 additions and 11 deletions
+65 -1
View File
@@ -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))
}
}
+12 -1
View File
@@ -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)
}
}