export type Mapper = { destCol : number ; srcCol : number ; srcLine : number ; } [ ] ; type Point = { line : number ; column : number ; } ; export function getLoc ( mapper , destCol ) { let previousAnchor = { destCol : 1 , srcCol : 1 , srcLine : 1 } ; mapper . forEach ( anchor => { if ( anchor . destCol > destCol ) { return ; } previousAnchor = anchor ; } ) ; const remainingColumns = destCol - previousAnchor . destCol ; return { column : previousAnchor . srcCol + remainingColumns , line : previousAnchor . srcLine , } ; } export function preProcess ( src ) { const mapper = [ ] ; let srcLine = 1 ; let dest = "" ; let lineStart = 0 ; let inlineComment = false ; let blockComment = false ; let emitAnchor = false ; for ( let i = 0 ; i < src . length ; i ++ ) { const char = src [ i ] ; if ( emitAnchor ) { const destCol = dest . length + 1 ; const srcCol = i - lineStart + 1 ; mapper . push ( { destCol , srcCol , srcLine } ) ; emitAnchor = false ; } if ( char === "\n" ) { inlineComment = false ; srcLine ++ ; lineStart = i + 1 ; emitAnchor = true ; } else if ( char === "\r" && src [ i + 1 ] === "\n" ) { i ++ ; inlineComment = false ; srcLine ++ ; lineStart = i + 1 ; emitAnchor = true ; } else if ( blockComment && char === "*" && src [ i + 1 ] === "/" ) { blockComment = false ; i ++ ; emitAnchor = true ; } else if ( ( char === "\\" && src [ i + 1 ] === "\\" ) || ( char === "/" && src [ i + 1 ] === "/" ) ) { inlineComment = true ; i ++ ; } else if ( char === "/" && src [ i + 1 ] === "*" ) { blockComment = true ; i ++ ; } else if ( ! inlineComment && ! blockComment ) { dest += char ; } } return [ dest , mapper ] ; }