1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#if swift(>=6)
public import SwiftSyntax
#else
import SwiftSyntax
#endif
/// Names a precedence group.
///
/// TODO: For now, we'll use strings, but we likely want to move this to
/// a general notion of an Identifier.
public typealias PrecedenceGroupName = String
/// The associativity of a precedence group.
public enum Associativity: String, Sendable {
/// The precedence group is nonassociative, meaning that one must
/// parenthesize when there are multiple operators in a sequence, e.g.,
/// if ^ was nonassociative, a ^ b ^ c would need to be disambiguated as
/// either (a ^ b ) ^ c or a ^ (b ^ c).
case none
/// The precedence group is left-associative, meaning that multiple operators
/// in the same sequence will be parenthesized from the left. This is typical
/// for arithmetic operators, such that a + b - c is treated as (a + b) - c.
case left
/// The precedence group is right-associative, meaning that multiple operators
/// in the same sequence will be parenthesized from the right. This is used
/// for assignments, where a = b = c is treated as a = (b = c).
case right
}
/// Describes the relationship of a precedence group to another precedence
/// group.
public struct PrecedenceRelation: Sendable {
/// Describes the kind of a precedence relation.
public enum Kind: Sendable {
case higherThan
case lowerThan
var keyword: Keyword {
switch self {
case .higherThan: return .higherThan
case .lowerThan: return .lowerThan
}
}
}
/// The relationship to the other group.
public var kind: Kind
/// The group name.
public var groupName: PrecedenceGroupName
/// The syntax that provides the relation. This specifically refers to the
/// group name itself, but one can follow the parent pointer to find its
/// position.
public var syntax: PrecedenceGroupNameSyntax?
/// Return a higher-than precedence relation.
public static func higherThan(
_ groupName: PrecedenceGroupName,
syntax: PrecedenceGroupNameSyntax? = nil
) -> PrecedenceRelation {
return .init(kind: .higherThan, groupName: groupName, syntax: syntax)
}
/// Return a lower-than precedence relation.
public static func lowerThan(
_ groupName: PrecedenceGroupName,
syntax: PrecedenceGroupNameSyntax? = nil
) -> PrecedenceRelation {
return .init(kind: .lowerThan, groupName: groupName, syntax: syntax)
}
}
/// Precedence groups are used for parsing sequences of expressions in Swift
/// source code. Each precedence group defines the associativity of the
/// operator and its precedence relative to other precedence groups:
///
/// precedencegroup MultiplicativePrecedence {
/// associativity: left
/// higherThan: AdditivePrecedence
/// }
///
/// Operator declarations then specify which precedence group describes their
/// precedence, e.g.,
///
/// infix operator *: MultiplicationPrecedence
public struct PrecedenceGroup: Sendable {
/// The name of the group, which must be unique.
public var name: PrecedenceGroupName
/// The associativity for the group.
public var associativity: Associativity = .none
/// Whether the operators in this precedence group are considered to be
/// assignment operators.
public var assignment: Bool = false
/// The set of relations to other precedence groups that are defined by
/// this precedence group.
public var relations: [PrecedenceRelation] = []
/// The syntax node that describes this precedence group.
public var syntax: PrecedenceGroupDeclSyntax? = nil
public init(
name: PrecedenceGroupName,
associativity: Associativity = .none,
assignment: Bool = false,
relations: [PrecedenceRelation] = [],
syntax: PrecedenceGroupDeclSyntax? = nil
) {
self.name = name
self.associativity = associativity
self.assignment = assignment
self.relations = relations
self.syntax = syntax
}
}
extension PrecedenceGroup: CustomStringConvertible {
/// The description of a precedence group is the source code that produces it.
public var description: String {
(syntax ?? synthesizedSyntax()).description
}
}
|