Skip to content

Commit a06648e

Browse files
committed
commit stmts
1 parent d5cfe24 commit a06648e

16 files changed

Lines changed: 277 additions & 3 deletions

Sources/Compiler/Compiler.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,16 @@ extension CompilerWithSource: StmtSyntaxVisitor {
258258
mutating func visit(_ stmt: DropTriggerStmtSyntax) -> (Statement, Diagnostics)? {
259259
return typeCheck(stmt, isReadOnly: false)
260260
}
261+
262+
mutating func visit(_ stmt: BeginStmtSyntax) -> (Statement, Diagnostics)? { nil }
263+
264+
mutating func visit(_ stmt: CommitStmtSyntax) -> (Statement, Diagnostics)? { nil }
265+
266+
mutating func visit(_ stmt: RollbackStmtSyntax) -> (Statement, Diagnostics)? { nil }
267+
268+
mutating func visit(_ stmt: SavepointStmtSyntax) -> (Statement, Diagnostics)? { nil }
269+
270+
mutating func visit(_ stmt: ReleaseStmtSyntax) -> (Statement, Diagnostics)? { nil }
261271
}
262272

263273
/// Used to validate whether a statement syntax is valid for use in migrations
@@ -280,6 +290,11 @@ struct IsValidForMigrations: StmtSyntaxVisitor {
280290
func visit(_ stmt: CreateVirtualTableStmtSyntax) -> Bool { true }
281291
func visit(_ stmt: CreateTriggerStmtSyntax) -> Bool { true }
282292
func visit(_ stmt: DropTriggerStmtSyntax) -> Bool { true }
293+
func visit(_ stmt: BeginStmtSyntax) -> Bool { false }
294+
func visit(_ stmt: CommitStmtSyntax) -> Bool { false }
295+
func visit(_ stmt: RollbackStmtSyntax) -> Bool { false }
296+
func visit(_ stmt: SavepointStmtSyntax) -> Bool { false }
297+
func visit(_ stmt: ReleaseStmtSyntax) -> Bool { false }
283298
}
284299

285300
/// Used to validate whether a statement syntax is valid for use in queries
@@ -302,6 +317,11 @@ struct IsValidForQueries: StmtSyntaxVisitor {
302317
func visit(_ stmt: CreateVirtualTableStmtSyntax) -> Bool { false }
303318
func visit(_ stmt: CreateTriggerStmtSyntax) -> Bool { false }
304319
func visit(_ stmt: DropTriggerStmtSyntax) -> Bool { false }
320+
func visit(_ stmt: BeginStmtSyntax) -> Bool { false }
321+
func visit(_ stmt: CommitStmtSyntax) -> Bool { false }
322+
func visit(_ stmt: RollbackStmtSyntax) -> Bool { false }
323+
func visit(_ stmt: SavepointStmtSyntax) -> Bool { false }
324+
func visit(_ stmt: ReleaseStmtSyntax) -> Bool { false }
305325
}
306326

307327
// Mainly used in tests, since they are usually a mix of migrations and queries
@@ -324,4 +344,9 @@ struct IsAlwaysValid: StmtSyntaxVisitor {
324344
func visit(_ stmt: CreateVirtualTableStmtSyntax) -> Bool { true }
325345
func visit(_ stmt: CreateTriggerStmtSyntax) -> Bool { true }
326346
func visit(_ stmt: DropTriggerStmtSyntax) -> Bool { true }
347+
func visit(_ stmt: BeginStmtSyntax) -> Bool { true }
348+
func visit(_ stmt: CommitStmtSyntax) -> Bool { true }
349+
func visit(_ stmt: RollbackStmtSyntax) -> Bool { true }
350+
func visit(_ stmt: SavepointStmtSyntax) -> Bool { true }
351+
func visit(_ stmt: ReleaseStmtSyntax) -> Bool { true }
327352
}

Sources/Compiler/Gen/Rewriter.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,14 @@ extension Rewriter: StmtSyntaxVisitor {
164164
func visit(_ stmt: CreateTriggerStmtSyntax) -> [Range<Substring.Index>] { [] }
165165

166166
func visit(_ stmt: DropTriggerStmtSyntax) -> [Range<Substring.Index>] { [] }
167+
168+
func visit(_ stmt: BeginStmtSyntax) -> [Range<Substring.Index>] { [] }
169+
170+
func visit(_ stmt: CommitStmtSyntax) -> [Range<Substring.Index>] { [] }
171+
172+
func visit(_ stmt: RollbackStmtSyntax) -> [Range<Substring.Index>] { [] }
173+
174+
func visit(_ stmt: SavepointStmtSyntax) -> [Range<Substring.Index>] { [] }
175+
176+
func visit(_ stmt: ReleaseStmtSyntax) -> [Range<Substring.Index>] { [] }
167177
}

Sources/Compiler/Parse/ParserState.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ struct ParserState {
108108
skip()
109109
}
110110

111+
mutating func skip(if kind: Token.Kind) {
112+
guard current.kind == kind else { return }
113+
skip()
114+
}
115+
111116
mutating func skip() {
112117
previous = current
113118
current = peek

Sources/Compiler/Parse/Parsers.swift

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,83 @@ enum Parsers {
9797
state.diagnostics.add(.unexpectedToken(of: state.current.kind, at: state.location))
9898
return EmptyStmtSyntax(id: state.nextId(), location: state.current.location)
9999
}
100+
case (.begin, _):
101+
return begin(state: &state)
102+
case (.commit, _), (.end, _):
103+
return commit(state: &state)
104+
case (.savepoint, _):
105+
return savepoint(state: &state)
106+
case (.release, _):
107+
return release(state: &state)
108+
case (.rollback, _):
109+
return rollback(state: &state)
100110
case (.semiColon, _), (.eof, _):
101111
state.skip()
102112
return EmptyStmtSyntax(id: state.nextId(), location: state.current.location)
103113
default:
104-
state.diagnostics.add(.unexpectedToken(of: state.current.kind, at: state.location))
105-
return EmptyStmtSyntax(id: state.nextId(), location: state.current.location)
114+
let token = state.take()
115+
state.diagnostics.add(.unexpectedToken(of: token.kind, at: token.location))
116+
return EmptyStmtSyntax(id: state.nextId(), location: token.location)
117+
}
118+
}
119+
120+
static func begin(state: inout ParserState) -> BeginStmtSyntax {
121+
let start = state.take()
122+
123+
let kind: BeginStmtSyntax.Kind? = if state.take(if: .deferred) {
124+
.deferred
125+
} else if state.take(if: .immediate) {
126+
.immediate
127+
} else if state.take(if: .exclusive) {
128+
.exclusive
129+
} else {
130+
nil
131+
}
132+
133+
state.skip(if: .transaction)
134+
return BeginStmtSyntax(id: state.nextId(), location: state.location(from: start), kind: kind)
135+
}
136+
137+
static func commit(state: inout ParserState) -> CommitStmtSyntax {
138+
let start = state.take()
139+
state.skip(if: .transaction)
140+
return CommitStmtSyntax(id: state.nextId(), location: state.location(from: start))
141+
}
142+
143+
static func savepoint(state: inout ParserState) -> SavepointStmtSyntax {
144+
let start = state.take()
145+
let name = identifier(state: &state)
146+
return SavepointStmtSyntax(
147+
id: state.nextId(),
148+
location: state.location(from: start),
149+
name: name
150+
)
151+
}
152+
153+
static func release(state: inout ParserState) -> ReleaseStmtSyntax {
154+
let start = state.take()
155+
let name = identifier(state: &state)
156+
return ReleaseStmtSyntax(
157+
id: state.nextId(),
158+
location: state.location(from: start),
159+
name: name
160+
)
161+
}
162+
163+
static func rollback(state: inout ParserState) -> RollbackStmtSyntax {
164+
let start = state.take()
165+
let savepoint: IdentifierSyntax?
166+
if state.take(if: .to) {
167+
state.skip(if: .savepoint)
168+
savepoint = identifier(state: &state)
169+
} else {
170+
savepoint = nil
106171
}
172+
return RollbackStmtSyntax(
173+
id: state.nextId(),
174+
location: state.location(from: start),
175+
savepoint: savepoint
176+
)
107177
}
108178

109179
static func insertStmt(state: inout ParserState) throws -> InsertStmtSyntax {

Sources/Compiler/Sema/CardinalityInferrer.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,16 @@ extension CardinalityInferrer: StmtSyntaxVisitor {
149149
mutating func visit(_ stmt: CreateTriggerStmtSyntax) -> Cardinality { .many }
150150

151151
mutating func visit(_ stmt: DropTriggerStmtSyntax) -> Cardinality { .many }
152+
153+
mutating func visit(_ stmt: BeginStmtSyntax) -> Cardinality { .many }
154+
155+
mutating func visit(_ stmt: CommitStmtSyntax) -> Cardinality { .many }
156+
157+
mutating func visit(_ stmt: RollbackStmtSyntax) -> Cardinality { .many }
158+
159+
mutating func visit(_ stmt: SavepointStmtSyntax) -> Cardinality { .many }
160+
161+
mutating func visit(_ stmt: ReleaseStmtSyntax) -> Cardinality { .many }
152162
}
153163

154164
/// We need to look for a `primaryKey = value`. This can get complicated since

Sources/Compiler/Sema/StmtTypeChecker.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,26 @@ extension StmtTypeChecker: StmtSyntaxVisitor {
407407
schema[trigger: name] = nil
408408
return .empty
409409
}
410+
411+
mutating func visit(_ stmt: BeginStmtSyntax) -> ResultColumns {
412+
return .empty
413+
}
414+
415+
mutating func visit(_ stmt: CommitStmtSyntax) -> ResultColumns {
416+
return .empty
417+
}
418+
419+
mutating func visit(_ stmt: SavepointStmtSyntax) -> ResultColumns {
420+
return .empty
421+
}
422+
423+
mutating func visit(_ stmt: ReleaseStmtSyntax) -> ResultColumns {
424+
return .empty
425+
}
426+
427+
mutating func visit(_ stmt: RollbackStmtSyntax) -> ResultColumns {
428+
return .empty
429+
}
410430
}
411431

412432
extension StmtTypeChecker {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// BeginStmtSyntax.swift
3+
// Feather
4+
//
5+
// Created by Wes Wickwire on 6/14/25.
6+
//
7+
8+
struct BeginStmtSyntax: StmtSyntax {
9+
let id: SyntaxId
10+
let location: SourceLocation
11+
let kind: Kind?
12+
13+
enum Kind {
14+
case deferred
15+
case immediate
16+
case exclusive
17+
}
18+
19+
func accept<V>(visitor: inout V) -> V.StmtOutput where V : StmtSyntaxVisitor {
20+
visitor.visit(self)
21+
}
22+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// CommitStmtSyntax.swift
3+
// Feather
4+
//
5+
// Created by Wes Wickwire on 6/14/25.
6+
//
7+
8+
struct CommitStmtSyntax: StmtSyntax {
9+
let id: SyntaxId
10+
let location: SourceLocation
11+
12+
func accept<V>(visitor: inout V) -> V.StmtOutput where V : StmtSyntaxVisitor {
13+
visitor.visit(self)
14+
}
15+
}

Sources/Compiler/Syntax/CreateTriggerStmtSyntax.swift renamed to Sources/Compiler/Syntax/Statements/CreateTriggerStmtSyntax.swift

File renamed without changes.

Sources/Compiler/Syntax/DropTriggerStmtSyntax.swift renamed to Sources/Compiler/Syntax/Statements/DropTriggerStmtSyntax.swift

File renamed without changes.

0 commit comments

Comments
 (0)