Skip to content

Commit d0b7d80

Browse files
committed
DSLTree, a shared representation for compilation and printing
1 parent 6b3dff0 commit d0b7d80

File tree

14 files changed

+1264
-625
lines changed

14 files changed

+1264
-625
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ let package = Package(
6868
dependencies: [
6969
.product(name: "ArgumentParser", package: "swift-argument-parser"),
7070
"_MatchingEngine",
71+
"_StringProcessing"
7172
]),
7273

7374
// MARK: Exercises

Sources/PatternConverter/PatternConverter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import ArgumentParser
1515
import _MatchingEngine
16+
import _StringProcessing
1617

1718
@main
1819
struct PatternConverter: ParsableCommand {

Sources/_MatchingEngine/Regex/AST/AST.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extension AST {
3333
/// A node in the regex AST.
3434
@frozen
3535
public indirect enum Node:
36-
Hashable/*, _ASTPrintable ASTValue, ASTAction*/
36+
Hashable, _TreeNode //, _ASTPrintable ASTValue, ASTAction
3737
{
3838
/// ... | ... | ...
3939
case alternation(Alternation)
@@ -94,7 +94,7 @@ extension AST.Node {
9494
}
9595
}
9696

97-
func `as`<T: _ASTNode>(_ t: T.Type = T.self) -> T? {
97+
public func `as`<T: _ASTNode>(_ t: T.Type = T.self) -> T? {
9898
_associatedValue as? T
9999
}
100100

Sources/_MatchingEngine/Regex/AST/ASTProtocols.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
// MARK: - AST parent/child
2121

22-
protocol _ASTNode: _ASTPrintable {
22+
public protocol _ASTNode: _ASTPrintable {
2323
var location: SourceLocation { get }
2424
}
2525
extension _ASTNode {
@@ -41,7 +41,7 @@ extension AST.Quantification: _ASTParent {
4141
var children: [AST.Node] { [child] }
4242
}
4343
extension AST.AbsentFunction: _ASTParent {
44-
var children: [AST.Node] {
44+
public var children: [AST.Node] {
4545
switch kind {
4646
case .repeater(let a), .stopper(let a): return [a]
4747
case .expression(let a, _, let c): return [a, c]

Sources/_MatchingEngine/Regex/AST/Group.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ extension AST.Group.Kind {
112112
}
113113
}
114114

115-
extension AST.Group {
115+
extension AST.Group.Kind {
116116
/// If this group is a lookaround assertion, return its direction
117117
/// and whether it is positive or negative. Otherwise returns
118118
/// `nil`.
119119
public var lookaroundKind: (forwards: Bool, positive: Bool)? {
120-
switch self.kind.value {
120+
switch self {
121121
case .lookahead: return (true, true)
122122
case .negativeLookahead: return (true, false)
123123
case .lookbehind: return (false, true)

Sources/_MatchingEngine/Regex/Printing/PrettyPrinter.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
/// Track and handle state relevant to pretty-printing ASTs.
13-
struct PrettyPrinter {
13+
public struct PrettyPrinter {
1414
// Configuration
1515

1616
/// Cut off pattern conversion after this many levels
17-
var maxTopDownLevels: Int?
17+
public var maxTopDownLevels: Int?
1818

1919
/// Cut off pattern conversion after this tree height
20-
var minBottomUpLevels: Int?
20+
public var minBottomUpLevels: Int?
2121

2222
/// How many spaces to indent with ("tab-width")
23-
var indentWidth = 2
23+
public var indentWidth = 2
2424

2525
// Internal state
2626

@@ -38,7 +38,7 @@ struct PrettyPrinter {
3838
extension PrettyPrinter {
3939
// This might be necessary if `fileprivate` above suppresses
4040
// default struct inits.
41-
init(
41+
public init(
4242
maxTopDownLevels: Int? = nil,
4343
minBottomUpLevels: Int? = nil
4444
) {
@@ -53,32 +53,32 @@ extension PrettyPrinter {
5353
///
5454
/// NOTE: If `s` includes a newline, even at the end,
5555
/// this function will not update any tracking state.
56-
mutating func output(_ s: String) {
56+
public mutating func output(_ s: String) {
5757
result += s
5858
}
5959

6060
/// Terminate a line, updating any relevant state
61-
mutating func terminateLine() {
61+
public mutating func terminateLine() {
6262
output("\n")
6363
startOfLine = true
6464
}
6565

6666
/// Indent a new line, if at the start of a line, otherwise
6767
/// does nothing. Updates internal state.
68-
mutating func indent() {
68+
public mutating func indent() {
6969
guard startOfLine else { return }
7070
let numCols = indentLevel * indentWidth
7171
output(String(repeating: " ", count: numCols))
7272
startOfLine = false
7373
}
7474

7575
// Finish, flush, and clear. Returns the rendered output
76-
mutating func finish() -> String {
76+
public mutating func finish() -> String {
7777
defer { result = "" }
7878
return result
7979
}
8080

81-
var depth: Int { indentLevel }
81+
public var depth: Int { indentLevel }
8282
}
8383

8484
// MARK: - Pretty-print interface
@@ -87,7 +87,7 @@ extension PrettyPrinter {
8787
///
8888
/// This will property indent `s`, update any internal state,
8989
/// and will also terminate the current line.
90-
mutating func print(_ s: String) {
90+
public mutating func print(_ s: String) {
9191
indent()
9292
output("\(s)")
9393
terminateLine()
@@ -97,7 +97,7 @@ extension PrettyPrinter {
9797
///
9898
/// This will property indent, update any internal state,
9999
/// and will also terminate the current line.
100-
mutating func printLine(_ f: () -> String?) {
100+
public mutating func printLine(_ f: () -> String?) {
101101
// TODO: What should we do if `f` never returns non-nil?
102102
indent()
103103
while let s = f() {
@@ -107,7 +107,7 @@ extension PrettyPrinter {
107107
}
108108

109109
/// Execute `f` at one increased level of indentation
110-
mutating func printIndented(
110+
public mutating func printIndented(
111111
_ f: (inout Self) -> ()
112112
) {
113113
self.indentLevel += 1
@@ -117,7 +117,7 @@ extension PrettyPrinter {
117117

118118
/// Execute `f` inside an indented "block", which has a header
119119
/// and delimiters.
120-
mutating func printBlock(
120+
public mutating func printBlock(
121121
_ header: String,
122122
startDelimiter: String = "{",
123123
endDelimiter: String = "}",

Sources/_MatchingEngine/Regex/Printing/PrintAsCanonical.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension AST.Node {
4040
extension PrettyPrinter {
4141
/// Will output `ast` in canonical form, taking care to
4242
/// also indent and terminate the line (updating internal state)
43-
mutating func printAsCanonical(
43+
public mutating func printAsCanonical(
4444
_ ast: AST,
4545
delimiters: Bool = false,
4646
terminateLine terminate: Bool = true
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
3+
public protocol _TreeNode {
4+
var children: [Self]? { get }
5+
}
6+
7+
extension _TreeNode {
8+
public var height: Int {
9+
// FIXME: Is this right for custom char classes?
10+
// How do we count set operations?
11+
guard let children = self.children else {
12+
return 1
13+
}
14+
guard let max = children.lazy.map(\.height).max() else {
15+
return 1
16+
}
17+
return 1 + max
18+
}
19+
}
20+
21+
// TODO: Pretty-printing helpers, etc
22+
23+

0 commit comments

Comments
 (0)