Files
gp4/Sources/P4Compiler/Types.swift
T
Will Hawkins b9ff228362
Continuous Integration / Grammar Tests (push) Successful in 3m54s
Continuous Integration / Library Format Tests (push) Failing after 4m49s
Continuous Integration / Library Tests (push) Successful in 7m40s
Start Rewrite
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
2026-06-12 06:24:53 -04:00

99 lines
3.3 KiB
Swift

// p4rse, Copyright 2026, Will Hawkins
//
// This file is part of p4rse.
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import Common
import SwiftTreeSitter
import TreeSitterExtensions
import TreeSitterP4
extension P4Boolean: MaybeCompilableType {
public static func MaybeCompileType(
type: SwiftTreeSitter.Node, withContext: ASTCompilerContext
) -> Common.Result<(AST.Tipe)?> {
return type.text == "bool" ? .Ok(AST.Tipe(P4QualifiedType(P4Boolean()))) : .Ok(.none)
}
}
extension P4Int: MaybeCompilableType {
public static func MaybeCompileType(
type: SwiftTreeSitter.Node, withContext: ASTCompilerContext
) -> Common.Result<(AST.Tipe)?> {
// Drill down, as appropriate.
let base_type_node = type.child(at: 0)!
#SkipUnlessNodeType<SwiftTreeSitter.Node>(
node: base_type_node, type: "baseType")
let type_node = base_type_node.child(at: 0)!
#SkipUnlessNodeType<SwiftTreeSitter.Node>(
node: type_node, type: "int_type")
var walker = Walker(node: type_node)
var int_node: Node? = .none
#MustOr(
result: int_node, thing: walker.getNext(),
or: Result<AST.Tipe?>.Error(
ErrorWithLocation(
sourceLocation: type_node.toSourceLocation(),
withError: "Missing elements in int type declaration")))
// Move passed the keyword.
walker.next()
if let bit_width_node = walker.getNext() {
guard let bit_width = Int(bit_width_node.child(at: 1)!.text!),
bit_width != 0
else {
return .Error(
ErrorWithLocation(
sourceLocation: bit_width_node.toSourceLocation(),
withError: "Could not parse \(bit_width_node.text!) into integer"))
}
return .Ok(AST.Tipe(P4QualifiedType(P4Int(BitWidth.Width(bit_width)))))
}
return .Ok(AST.Tipe(P4QualifiedType(P4Int(BitWidth.Infinite))))
}
}
extension P4String: MaybeCompilableType {
public static func MaybeCompileType(
type: SwiftTreeSitter.Node, withContext: ASTCompilerContext
) -> Common.Result<(AST.Tipe)?> {
return type.text == "string" ? .Ok(AST.Tipe(P4QualifiedType(P4String()))) : .Ok(.none)
}
}
extension AST.Types: CompilableType {
public static func CompileType(
type: SwiftTreeSitter.Node, withContext context: ASTCompilerContext
) -> Result<AST.Tipe> {
let type_parsers: [MaybeCompilableType.Type] = [
P4Boolean.self, P4Int.self, P4String.self, /*P4Struct.self,*/
]
for type_parser in type_parsers {
switch type_parser.MaybeCompileType(type: type, withContext: context) {
case .Ok(.some(let type)): return .Ok(type)
case .Ok(.none): continue
case .Error(let e): return .Error(e)
}
}
return Result.Error(Error(withMessage: "Type name not recognized"))
}
}