Initial Support For If Statements

Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
This commit is contained in:
Will Hawkins
2026-02-24 04:38:05 -05:00
parent 3752dd01ab
commit a2335a01ed
9 changed files with 541 additions and 46 deletions
+164
View File
@@ -22,6 +22,142 @@ import SwiftTreeSitter
import TreeSitterExtensions
import TreeSitterP4
extension BlockStatement: ParseableStatement {
public static func Parse(
node: Node, inTree tree: MutableTree, withScopes scopes: LexicalScopes
) -> Result<(EvaluatableStatement?, LexicalScopes)> {
// TODO: Make sure that this works.
// (And apply in other places!)
guard
let block_statement_query = try? SwiftTreeSitter.Query(
language: p4lang,
data: String(
"(statement . (blockStatement . (statements . ((statement) @astatement (semicolon))*) @statements) @block-statement) @statement"
).data(using: String.Encoding.utf8)!)
else {
return Result.Ok((.none, scopes))
}
let qr = block_statement_query.execute(node: node, in: tree)
guard let variable_declaration = qr.next() else {
return .Ok((.none, scopes))
}
let statement_capture = variable_declaration.captures(named: "statement")
let blockstatement_capture = variable_declaration.captures(named: "block-statement")
let astatement_capture = variable_declaration.captures(named: "astatement")
let statements_capture = variable_declaration.captures(named: "statements")
if statement_capture.isEmpty || blockstatement_capture.isEmpty {
return .Error(Error(withMessage: "Could not parse a block statement"))
}
let statement_node = statement_capture[0].node
let blockstatement_capture_node = blockstatement_capture[0].node
let statements_capture_node = statements_capture[0].node
/*
if statement_node.parent != node.parent
{
return .Ok((.none, scopes))
}
*/
var statements: [EvaluatableStatement] = Array()
var parse_err: Error? = .none
for statement in astatement_capture {
if let statement_node = statement.node.child(
at: 0) /*
let statement_node_parent = statement_node.parent,
statement_node_parent.parent == statements_capture_node
*/
{
switch P4Parser.Parser.Statements.Parse(
node: statement_node, inTree: tree, withScope: scopes.enter())
{
case .Ok((let parsed_statement, _)): statements.append(parsed_statement)
case .Error(let e):
parse_err = e
break
}
}
}
if let err = parse_err {
return .Error(err)
}
return .Ok((BlockStatement(statements), scopes))
}
}
extension ConditionalStatement: ParseableStatement {
public static func Parse(
node: Node, inTree tree: MutableTree, withScopes scopes: LexicalScopes
) -> Result<(EvaluatableStatement?, LexicalScopes)> {
guard let node_type = node.nodeType,
node_type == "conditionalStatement"
else {
return Result.Ok((.none, scopes))
}
let maybe_condition_expression = node.child(at: 2)
guard let condition_expression = maybe_condition_expression,
condition_expression.nodeType == "expression"
else {
return Result.Ok((.none, scopes))
}
let maybe_thens = node.child(at: 4)
guard let thens = maybe_thens,
thens.nodeType == "statement"
else {
return Result.Ok((.none, scopes))
}
guard
case .Ok(let condition) = Expression.Parse(
node: condition_expression, inTree: tree, withScopes: scopes.enter())
else {
return Result.Error(
Error(withMessage: "Could not parse a conditional expression in a conditional statement"))
}
guard
case .Ok((let thenns, _)) = Parser.Statements.Parse(
node: thens, inTree: tree, withScope: scopes.enter())
else {
return Result.Error(
Error(
withMessage:
"Could not parse the then block in a conditional statement"))
}
let optional_elss: Result<(any EvaluatableStatement, LexicalScopes)>? =
if let elss = node.child(at: 6) {
.some(
Parser.Statements.Parse(
node: elss, inTree: tree, withScope: scopes.enter()))
} else {
.none
}
if let parsed_elss = optional_elss {
guard
case .Ok((let elss, _)) = parsed_elss
else {
return Result.Error(
Error(
withMessage:
"Could not parse the else block in a conditional statement"))
}
return .Ok(
(ConditionalStatement(condition: condition, withThen: thenns, andElse: elss), scopes))
}
return .Ok((ConditionalStatement(condition: condition, withThen: thenns), scopes))
}
}
extension VariableDeclarationStatement: ParseableStatement {
public static func Parse(
node: Node, inTree tree: MutableTree, withScopes scopes: LexicalScopes
@@ -86,3 +222,31 @@ extension VariableDeclarationStatement: ParseableStatement {
}
}
}
extension ExpressionStatement: ParseableStatement {
public static func Parse(
node: Node, inTree tree: MutableTree, withScopes scopes: LexicalScopes
) -> Result<(EvaluatableStatement?, LexicalScopes)> {
guard
let expression_statement_query = try? SwiftTreeSitter.Query(
language: p4lang,
data: String(
"(expressionStatement (expression) @expression)"
).data(using: String.Encoding.utf8)!)
else {
return Result.Ok((.none, scopes))
}
let qr = expression_statement_query.execute(node: node, in: tree)
guard let query_result = qr.next() else {
return Result.Ok((.none, scopes))
}
let expression_capture = query_result.captures(named: "expression")
if !expression_capture.isEmpty {
// TODO: Actually create an ExpressionStatement
return Result.Ok((ExpressionStatement(), scopes))
}
return Result.Ok((.none, scopes))
}
}