Issues with regexp in multiplatform projects

My project is multiplatform, compiling to JVM, Native and JS. The application is a programming language interpreter, so the multiplatform aspect has been quite useful.

One feature I’m implementing at the moment is a regexp API that is accessible to the interpreted programs. In doing so, I’ve come across two issues that are somewhat difficult to work around.

Problem 1: Exceptions when parsing illegal regexps

Since I am unable to control the content of a regexp that I pass to the toRegexp() function, I need to report back to the user that there was a parse error. The problem is that the Kotlin API does not provide a standard way to catch this error. The three platforms do this in different ways:

  • JVM: The function throws a PatternSyntaxException
  • Native: The function throws an exception of a type which is an internal class, so I need to catch Exception
  • JS: The function throws an internal exception which is actually a Throwable.

The cases of native and JS are really ugly, and in particular the JS one, since there is no way for me to distinguish between an incorrectly formatted regexp and an internal error.

For now I have created platform-specific functions that do its best to determine whether the error is caused by a formatting error or something else, and throw a more appropriate exception.

I believe that the lack of a defined error state is an oversight in the regexp API and probably deserves being looked at.

Problem 2: Indexes to match groups

This problem is much more severe than the previous one as I have yet to find a workaround.

The JVM and native API’s provide a range value on the MatchGroup implementation that allows me to read the indexes in the source string of the specific match. The problem is that the JS implementation doesn’t, and I have no found any way to retrieve these values. For technical reasons, I really need to expose these values to the user, and I haven’t been able to find any workaround so far.

At this point I’m willing to dig into the underlying JS with some native JS code just to get this to work, and I would be thankful if someone could give me some hints.

1 Like