surrealdb_core/syn/lexer/compound/
js.rs1use crate::syn::{
2 error::{MessageKind, SyntaxError},
3 lexer::unicode::chars::JS_LINE_TERIMATORS,
4 token::{t, Token},
5};
6
7use super::Lexer;
8
9pub fn javascript(lexer: &mut Lexer, start: Token) -> Result<(), SyntaxError> {
10 assert_eq!(start.kind, t!("{"), "Invalid start of JavaScript compound token");
11 lex_js_function_body_inner(lexer)?;
12 Ok(())
13}
14
15fn lex_js_function_body_inner(lexer: &mut Lexer) -> Result<(), SyntaxError> {
17 let mut block_depth = 1;
18 loop {
19 let Some(byte) = lexer.reader.next() else {
20 let span = lexer.advance_span();
21 return Err(SyntaxError::new(format_args!(
22 "Invalid JavaScript function, encountered unexpected eof"
23 ))
24 .with_span(span, MessageKind::Error)
25 .with_data_pending());
26 };
27 match byte {
28 b'`' => lex_js_string(lexer, b'`')?,
29 b'\'' => lex_js_string(lexer, b'\'')?,
30 b'\"' => lex_js_string(lexer, b'\"')?,
31 b'/' => match lexer.reader.peek() {
32 Some(b'/') => {
33 lexer.reader.next();
34 lex_js_single_comment(lexer)?;
35 }
36 Some(b'*') => {
37 lexer.reader.next();
38 lex_js_multi_comment(lexer)?
39 }
40 _ => {}
41 },
42 b'{' => {
43 block_depth += 1;
44 }
45 b'}' => {
46 block_depth -= 1;
47 if block_depth == 0 {
48 break;
49 }
50 }
51 x if !x.is_ascii() => {
52 lexer.reader.complete_char(x)?;
53 }
54 _ => {}
55 }
56 }
57
58 Ok(())
59}
60
61fn lex_js_string(lexer: &mut Lexer, enclosing_byte: u8) -> Result<(), SyntaxError> {
63 loop {
64 let Some(byte) = lexer.reader.next() else {
65 let span = lexer.advance_span();
66 return Err(SyntaxError::new(format_args!(
67 "Invalid JavaScript function, encountered unexpected eof"
68 ))
69 .with_span(span, MessageKind::Error)
70 .with_data_pending());
71 };
72 if byte == enclosing_byte {
73 return Ok(());
74 }
75 if byte == b'\\' {
76 lexer.reader.next();
77 }
78 lexer.reader.convert_to_char(byte)?;
80 }
81}
82
83fn lex_js_single_comment(lexer: &mut Lexer) -> Result<(), SyntaxError> {
85 loop {
86 let Some(byte) = lexer.reader.next() else {
87 return Ok(());
88 };
89 let char = lexer.reader.convert_to_char(byte)?;
90 if JS_LINE_TERIMATORS.contains(&char) {
91 return Ok(());
92 }
93 }
94}
95
96fn lex_js_multi_comment(lexer: &mut Lexer) -> Result<(), SyntaxError> {
98 loop {
99 let Some(byte) = lexer.reader.next() else {
100 let span = lexer.advance_span();
101 return Err(SyntaxError::new(format_args!(
102 "Invalid JavaScript function, encountered unexpected eof"
103 ))
104 .with_span(span, MessageKind::Error)
105 .with_data_pending());
106 };
107 if byte == b'*' && lexer.reader.peek() == Some(b'/') {
108 lexer.reader.next();
109 return Ok(());
110 }
111 lexer.reader.convert_to_char(byte)?;
113 }
114}