aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-01 09:58:19 +0100
committerAleksey Kladov <[email protected]>2018-08-01 09:58:19 +0100
commitecd5da5b0cae5b3af95f5b86a8157a1f57a944c5 (patch)
treeeb14d6c340e2ee96666c90637c1ca3fc7ba1b5ea /src
parent37e1625f0139da07c2690b6ee6ca7eae5ebb061a (diff)
Introduce drop-bomb
Diffstat (limited to 'src')
-rw-r--r--src/drop_bomb.rs21
-rw-r--r--src/lib.rs1
-rw-r--r--src/parser_api.rs41
3 files changed, 43 insertions, 20 deletions
diff --git a/src/drop_bomb.rs b/src/drop_bomb.rs
new file mode 100644
index 000000000..750904a01
--- /dev/null
+++ b/src/drop_bomb.rs
@@ -0,0 +1,21 @@
1use std::borrow::Cow;
2
3pub struct DropBomb {
4 msg: Cow<'static, str>,
5 defused: bool,
6}
7
8impl DropBomb {
9 pub fn new(msg: impl Into<Cow<'static, str>>) -> DropBomb {
10 DropBomb { msg: msg.into(), defused: false }
11 }
12 pub fn defuse(&mut self) { self.defused = true }
13}
14
15impl Drop for DropBomb {
16 fn drop(&mut self) {
17 if !self.defused && !::std::thread::panicking() {
18 panic!("{}", self.msg)
19 }
20 }
21}
diff --git a/src/lib.rs b/src/lib.rs
index 1cd45690a..d9572912c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,6 +31,7 @@ mod lexer;
31mod parser_api; 31mod parser_api;
32mod grammar; 32mod grammar;
33mod parser_impl; 33mod parser_impl;
34mod drop_bomb;
34 35
35mod syntax_kinds; 36mod syntax_kinds;
36/// Utilities for simple uses of the parser. 37/// Utilities for simple uses of the parser.
diff --git a/src/parser_api.rs b/src/parser_api.rs
index d12f773b2..3cad91976 100644
--- a/src/parser_api.rs
+++ b/src/parser_api.rs
@@ -1,6 +1,7 @@
1use { 1use {
2 parser_impl::ParserImpl, 2 parser_impl::ParserImpl,
3 SyntaxKind::{self, ERROR}, 3 SyntaxKind::{self, ERROR},
4 drop_bomb::DropBomb,
4}; 5};
5 6
6#[derive(Clone, Copy)] 7#[derive(Clone, Copy)]
@@ -76,7 +77,7 @@ impl<'t> Parser<'t> {
76 /// consumed between the `start` and the corresponding `Marker::complete` 77 /// consumed between the `start` and the corresponding `Marker::complete`
77 /// belong to the same node. 78 /// belong to the same node.
78 pub(crate) fn start(&mut self) -> Marker { 79 pub(crate) fn start(&mut self) -> Marker {
79 Marker(self.0.start()) 80 Marker::new(self.0.start())
80 } 81 }
81 82
82 /// Advances the parser by one token. 83 /// Advances the parser by one token.
@@ -131,31 +132,31 @@ impl<'t> Parser<'t> {
131} 132}
132 133
133/// See `Parser::start`. 134/// See `Parser::start`.
134pub(crate) struct Marker(u32); 135pub(crate) struct Marker {
136 pos: u32,
137 bomb: DropBomb,
138}
135 139
136impl Marker { 140impl Marker {
141 fn new(pos: u32) -> Marker {
142 Marker {
143 pos,
144 bomb: DropBomb::new("Marker must be either completed or abandoned")
145 }
146 }
147
137 /// Finishes the syntax tree node and assigns `kind` to it. 148 /// Finishes the syntax tree node and assigns `kind` to it.
138 pub(crate) fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { 149 pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
139 let pos = self.0; 150 self.bomb.defuse();
140 ::std::mem::forget(self); 151 p.0.complete(self.pos, kind);
141 p.0.complete(pos, kind); 152 CompletedMarker(self.pos)
142 CompletedMarker(pos)
143 } 153 }
144 154
145 /// Abandons the syntax tree node. All its children 155 /// Abandons the syntax tree node. All its children
146 /// are attached to its parent instead. 156 /// are attached to its parent instead.
147 pub(crate) fn abandon(self, p: &mut Parser) { 157 pub(crate) fn abandon(mut self, p: &mut Parser) {
148 let pos = self.0; 158 self.bomb.defuse();
149 ::std::mem::forget(self); 159 p.0.abandon(self.pos);
150 p.0.abandon(pos);
151 }
152}
153
154impl Drop for Marker {
155 fn drop(&mut self) {
156 if !::std::thread::panicking() {
157 panic!("Marker must be either completed or abandoned");
158 }
159 } 160 }
160} 161}
161 162
@@ -170,6 +171,6 @@ impl CompletedMarker {
170 /// `B` before starting `A`. `precede` allows to do exactly 171 /// `B` before starting `A`. `precede` allows to do exactly
171 /// that. See also docs about `forward_parent` in `Event::Start`. 172 /// that. See also docs about `forward_parent` in `Event::Start`.
172 pub(crate) fn precede(self, p: &mut Parser) -> Marker { 173 pub(crate) fn precede(self, p: &mut Parser) -> Marker {
173 Marker(p.0.precede(self.0)) 174 Marker::new(p.0.precede(self.0))
174 } 175 }
175} 176}