Atoms: literals, names, numbers, strings, f-strings, containers. */
(&mut self)
| 168 | |
| 169 | /* Atoms: literals, names, numbers, strings, f-strings, containers. */ |
| 170 | pub(super) fn parse_atom(&mut self) { |
| 171 | let errs_before = self.errors.len(); |
| 172 | let t = self.advance(); |
| 173 | match t.kind { |
| 174 | TokenType::Name => self.name(t), |
| 175 | TokenType::String => { |
| 176 | let mut s = parse_string(self.lexeme(&t)); |
| 177 | while matches!(self.peek(), Some(TokenType::String)) { |
| 178 | let t = self.advance(); |
| 179 | s.push_str(&parse_string(self.lexeme(&t))); |
| 180 | } |
| 181 | self.emit_const(Value::Str(s)); |
| 182 | } |
| 183 | TokenType::Bytes => { |
| 184 | // Adjacent bytes literals concat; mixing with str surfaces a diagnostic. |
| 185 | let mut buf = parse_bytes_literal(self.lexeme(&t)); |
| 186 | while matches!(self.peek(), Some(TokenType::Bytes)) { |
| 187 | let t = self.advance(); |
| 188 | buf.extend_from_slice(&parse_bytes_literal(self.lexeme(&t))); |
| 189 | } |
| 190 | self.emit_const(Value::Bytes(buf)); |
| 191 | } |
| 192 | TokenType::Int | TokenType::Float => { |
| 193 | self.parse_number(self.lexeme(&t), t.kind); |
| 194 | } |
| 195 | TokenType::True => self.chunk.emit(OpCode::LoadTrue, 0), |
| 196 | TokenType::False => self.chunk.emit(OpCode::LoadFalse, 0), |
| 197 | TokenType::None => self.chunk.emit(OpCode::LoadNone, 0), |
| 198 | TokenType::Ellipsis => self.chunk.emit(OpCode::LoadEllipsis, 0), |
| 199 | TokenType::FstringStart => self.fstring(t.start, t.end), |
| 200 | TokenType::Lbrace => self.brace_literal(), |
| 201 | TokenType::Lsqb => self.list_literal(), |
| 202 | TokenType::Lpar => { |
| 203 | if matches!(self.peek(), Some(TokenType::Rpar)) { |
| 204 | self.advance(); |
| 205 | self.chunk.emit(OpCode::BuildTuple, 0); |
| 206 | } else { |
| 207 | let elem_start = self.chunk.instructions.len(); |
| 208 | self.expr(); |
| 209 | if matches!(self.peek(), Some(TokenType::For)) { |
| 210 | let versions_before = self.ssa_versions.clone(); |
| 211 | let elem_ins: Vec<Instruction> = self.chunk.instructions.drain(elem_start..).collect(); |
| 212 | self.chunk.emit(OpCode::BuildList, 0); |
| 213 | self.comprehension_loop(&[(elem_start, elem_ins)], OpCode::ListAppend, &versions_before); |
| 214 | self.advance(); |
| 215 | } else if self.eat_if(TokenType::Comma) { |
| 216 | let mut count = 1u16; |
| 217 | while !matches!(self.peek(), Some(TokenType::Rpar) | None) { |
| 218 | self.expr(); |
| 219 | count += 1; |
| 220 | if !self.eat_if(TokenType::Comma) { break; } |
| 221 | } |
| 222 | self.eat(TokenType::Rpar); |
| 223 | self.chunk.emit(OpCode::BuildTuple, count); |
| 224 | } else { |
| 225 | self.eat(TokenType::Rpar); |
| 226 | } |
| 227 | } |
no test coverage detected