Skip to content

Commit

Permalink
delay regex flag parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Dec 25, 2023
1 parent 9f57c14 commit 8e092ad
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 16 deletions.
10 changes: 7 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/dash_lexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ edition = "2021"
[dependencies]
either = "1.6.1"
dash_middle = { path = "../dash_middle" }
dash_regex = { path = "../dash_regex" }
15 changes: 7 additions & 8 deletions crates/dash_lexer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::borrow::Cow;
use std::ops::Range;

use dash_middle::interner::{StringInterner, Symbol};
use dash_middle::interner::{sym, StringInterner, Symbol};
use dash_middle::lexer::token::{as_token, Token, TokenType};
use dash_middle::parser::error::Error;
use dash_middle::sourcemap::Span;
use dash_middle::util;
use dash_regex::flags::Flags;

/// A JavaScript source code lexer
#[derive(Debug)]
Expand Down Expand Up @@ -400,7 +399,7 @@ impl<'a, 'interner> Lexer<'a, 'interner> {
}

/// Assumes one character has already been read.
fn read_identifier_raw(&mut self) -> &'a str {
fn read_identifier_raw(&mut self) -> Symbol {
let start = self.idx - 1;
while !self.is_eof() {
let cur = self.current_real();
Expand All @@ -412,13 +411,13 @@ impl<'a, 'interner> Lexer<'a, 'interner> {
self.advance();
}

self.subslice(start..self.idx)
let slice = self.subslice(start..self.idx);
self.interner.intern(slice)
}

/// Reads an identifier and returns it as a node
fn read_identifier(&mut self) {
let ident = self.read_identifier_raw();
let sym = self.interner.intern(ident);
let sym = self.read_identifier_raw();
self.create_contextified_token(as_token(sym));
}

Expand All @@ -440,9 +439,9 @@ impl<'a, 'interner> Lexer<'a, 'interner> {

let flags = if self.current().is_some_and(util::is_alpha) {
self.advance(); // identifier reading requires one character to be read
self.read_identifier_raw().parse::<Flags>().unwrap() // TODO: handle error
self.read_identifier_raw()
} else {
Flags::empty()
sym::EMPTY
};

self.create_contextified_token(TokenType::RegexLiteral {
Expand Down
2 changes: 1 addition & 1 deletion crates/dash_middle/src/lexer/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ pub enum TokenType {

/// Regex literal: /a+b/g
#[display(fmt = "<regex literal>")]
RegexLiteral { literal: Symbol, flags: Flags },
RegexLiteral { literal: Symbol, flags: Symbol },

#[display(fmt = "0x")]
NumberHex(Symbol),
Expand Down
11 changes: 9 additions & 2 deletions crates/dash_parser/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use dash_middle::parser::statement::{
BlockStatement, FunctionDeclaration, FunctionKind, Parameter, ReturnStatement, Statement, StatementKind,
};
use dash_middle::sourcemap::Span;
use dash_regex::Flags;

use crate::Parser;

Expand Down Expand Up @@ -692,8 +693,14 @@ impl<'a, 'interner> Parser<'a, 'interner> {
// Trim / prefix and suffix
let full = self.interner.resolve(literal);
let full = &full[1..full.len() - 1];
let nodes = match dash_regex::Parser::new(full.as_bytes()).parse_all() {
Ok(nodes) => nodes,
let (nodes, flags) = match dash_regex::Parser::new(full.as_bytes()).parse_all().and_then(|node| {
self.interner
.resolve(flags)
.parse::<Flags>()
.map_err(Into::into)
.map(|flags| (node, flags))
}) {
Ok((nodes, flags)) => (nodes, flags),
Err(err) => {
let tok = self.previous().unwrap().clone();
self.create_error(Error::RegexSyntaxError(tok, err));
Expand Down
5 changes: 5 additions & 0 deletions crates/dash_regex/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use thiserror::Error;

use crate::flags;

#[derive(Error, Debug)]
pub enum Error {
#[error("unexpected end of file")]
UnexpectedEof,

#[error("unexpected character: {}", *.0 as char)]
UnexpectedChar(u8),

#[error("{0}")]
Flags(#[from] flags::Error),
}
4 changes: 3 additions & 1 deletion crates/dash_regex/src/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::str::FromStr;

use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use thiserror::Error;

bitflags! {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
Expand All @@ -12,8 +13,9 @@ bitflags! {
}
}

#[derive(Debug)]
#[derive(Debug, Error)]
pub enum Error {
#[error("unknown flag: {0}")]
UnknownFlag(char),
}

Expand Down

0 comments on commit 8e092ad

Please sign in to comment.