Skip to content
This repository was archived by the owner on Jul 27, 2023. It is now read-only.

Commit c645115

Browse files
committed
Lex Jupyter Magic in assignment value position
1 parent db04fd4 commit c645115

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

parser/src/lexer.rs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ pub struct Lexer<T: Iterator<Item = char>> {
175175
pending: Vec<Spanned>,
176176
// The current location.
177177
location: TextSize,
178+
// The last emitted token.
179+
last_emitted: Option<Tok>,
178180
// Lexer mode.
179181
mode: Mode,
180182
}
@@ -233,6 +235,7 @@ where
233235
pending: Vec::with_capacity(5),
234236
location: start,
235237
window: CharWindow::new(input),
238+
last_emitted: None,
236239
mode,
237240
};
238241
// Fill the window.
@@ -945,15 +948,22 @@ where
945948
}
946949
}
947950
'%' => {
948-
let tok_start = self.get_pos();
949-
self.next_char();
950-
if let Some('=') = self.window[0] {
951-
self.next_char();
952-
let tok_end = self.get_pos();
953-
self.emit((Tok::PercentEqual, TextRange::new(tok_start, tok_end)));
951+
if self.mode == Mode::Jupyter
952+
&& self.nesting == 0
953+
&& matches!(self.last_emitted, Some(Tok::Equal))
954+
{
955+
self.lex_and_emit_magic_command();
954956
} else {
955-
let tok_end = self.get_pos();
956-
self.emit((Tok::Percent, TextRange::new(tok_start, tok_end)));
957+
let tok_start = self.get_pos();
958+
self.next_char();
959+
if let Some('=') = self.window[0] {
960+
self.next_char();
961+
let tok_end = self.get_pos();
962+
self.emit((Tok::PercentEqual, TextRange::new(tok_start, tok_end)));
963+
} else {
964+
let tok_end = self.get_pos();
965+
self.emit((Tok::Percent, TextRange::new(tok_start, tok_end)));
966+
}
957967
}
958968
}
959969
'|' => {
@@ -1025,17 +1035,24 @@ where
10251035
}
10261036
}
10271037
'!' => {
1028-
let tok_start = self.get_pos();
1029-
self.next_char();
1030-
if let Some('=') = self.window[0] {
1031-
self.next_char();
1032-
let tok_end = self.get_pos();
1033-
self.emit((Tok::NotEqual, TextRange::new(tok_start, tok_end)));
1038+
if self.mode == Mode::Jupyter
1039+
&& self.nesting == 0
1040+
&& matches!(self.last_emitted, Some(Tok::Equal))
1041+
{
1042+
self.lex_and_emit_magic_command();
10341043
} else {
1035-
return Err(LexicalError {
1036-
error: LexicalErrorType::UnrecognizedToken { tok: '!' },
1037-
location: tok_start,
1038-
});
1044+
let tok_start = self.get_pos();
1045+
self.next_char();
1046+
if let Some('=') = self.window[0] {
1047+
self.next_char();
1048+
let tok_end = self.get_pos();
1049+
self.emit((Tok::NotEqual, TextRange::new(tok_start, tok_end)));
1050+
} else {
1051+
return Err(LexicalError {
1052+
error: LexicalErrorType::UnrecognizedToken { tok: '!' },
1053+
location: tok_start,
1054+
});
1055+
}
10391056
}
10401057
}
10411058
'~' => {
@@ -1292,6 +1309,7 @@ where
12921309

12931310
// Helper function to emit a lexed token to the queue of tokens.
12941311
fn emit(&mut self, spanned: Spanned) {
1312+
self.last_emitted = Some(spanned.0.clone());
12951313
self.pending.push(spanned);
12961314
}
12971315
}

0 commit comments

Comments
 (0)