1- import { RangeArithmetic } from '../RangeArithmetic' ;
2- import type { Node , CheckOverlap } from '../utils' ;
1+ import { CoreFactory } from '../CoreFactory' ;
2+ import type { Node } from '../nodeTypings' ;
3+ import type { CheckOverlap } from '../utils' ;
34import type { GeneratorFromRules , GenRuleMap , GenRulesToObject , GenNamesFromList } from './builderTypes' ;
45import type { GeneratorRule , RuleDefArg } from './generatorTypes' ;
56
@@ -179,21 +180,21 @@ export class GeneratorBuilder<Context, Names extends string, RuleDefs extends Ge
179180}
180181
181182export class Generator < Context , Names extends string , RuleDefs extends GenRuleMap < Names > > {
183+ protected readonly factory = new CoreFactory ( ) ;
182184 protected __context : Context | undefined = undefined ;
183- protected readonly sourceStack : { source : string ; generatedUntil : number ; allowedRanges : RangeArithmetic } [ ] = [ ] ;
185+ protected origSource = '' ;
186+ protected generatedUntil = 0 ;
184187 protected readonly stringBuilder : string [ ] = [ ] ;
185- protected readonly skipRanges : [ number , number ] [ ] = [ ] ;
186188
187189 public constructor ( protected rules : RuleDefs ) {
188190 // eslint-disable-next-line ts/no-unnecessary-type-assertion
189191 for ( const rule of < GeneratorRule [ ] > Object . values ( rules ) ) {
190192 // Define function implementation
191193 this [ < keyof ( typeof this ) > rule . name ] =
192- < any > ( ( input : any , context : Context & { skipRanges : [ number , number ] [ ] } , args : any ) => {
194+ < any > ( ( input : any , context : Context & { origSource : string ; offset ?: number } , args : any ) => {
193195 this . stringBuilder . length = 0 ;
194- this . sourceStack . length = 0 ;
195- this . skipRanges . length = 0 ;
196- this . skipRanges . push ( ...context . skipRanges ) ;
196+ this . origSource = context . origSource ;
197+ this . generatedUntil = context ?. offset ?? 0 ;
197198 this . setContext ( context ) ;
198199
199200 this . subrule ( rule , input , args ) ;
@@ -216,56 +217,41 @@ export class Generator<Context, Names extends string, RuleDefs extends GenRuleMa
216217 if ( ! def ) {
217218 throw new Error ( `Rule ${ cstDef . name } not found` ) ;
218219 }
219- if ( ast . loc && ast . loc . noStringManifestation ) {
220+ if ( this . factory . isSourceLocationNoMaterialize ( ast . loc ) ) {
220221 return ;
221222 }
222- if ( ast . loc ?. source ) {
223- this . pushSource ( ast . loc . source ) ;
223+ if ( this . factory . isSourceLocationStringReplace ( ast . loc ) ) {
224+ this . catchup ( ast . loc . start ) ;
225+ this . print ( ast . loc . newSource ) ;
226+ this . generatedUntil = ast . loc . end ;
227+ return ;
224228 }
225- if ( ast . loc ) {
229+ if ( this . factory . isSourceLocationNodeReplace ( ast . loc ) || this . factory . isSourceLocationSource ( ast . loc ) ) {
226230 this . catchup ( ast . loc . start ) ;
227231 }
232+ // If autoGenerate - do nothing
233+
234+ // Do call generation
228235 def . gImpl ( {
229236 SUBRULE : this . subrule ,
230237 PRINT : this . print ,
231238 PRINT_WORD : this . printWord ,
232239 CATCHUP : this . catchup ,
233- PUSH_SOURCE : this . pushSource ,
234- POP_SOURCE : this . popSource ,
235240 } ) ( ast , this . getSafeContext ( ) , arg ) ;
236- // TODO: You cannot close at end because scopes dont work like that for blankNodes like `[ ... ]`
237- // That than gives errors since you don't close at the time you will insert something new.
238- // if (ast.loc) {
239- // this.catchup(ast.loc.end);
240- // }
241- if ( ast . loc ?. source ) {
242- this . popSource ( ) ;
243- }
244- } ;
245241
246- protected readonly catchup : RuleDefArg [ 'CATCHUP' ] = ( until ) => {
247- const currentSource = this . sourceStack . at ( - 1 ) ;
248- if ( ! currentSource ) {
249- throw new Error ( 'No source to catchup to' ) ;
250- }
251- const { source, generatedUntil, allowedRanges } = currentSource ;
252- for ( const range of allowedRanges . projection ( generatedUntil , until ) ) {
253- this . stringBuilder . push ( source . slice ( ...range ) ) ;
242+ if ( this . factory . isSourceLocationNodeReplace ( ast . loc ) ) {
243+ this . generatedUntil = ast . loc . end ;
244+ } else if ( this . factory . isSourceLocationSource ( ast . loc ) ) {
245+ this . catchup ( ast . loc . end ) ;
254246 }
255- currentSource . generatedUntil = Math . max ( generatedUntil , until ) ;
256247 } ;
257248
258- protected readonly pushSource : RuleDefArg [ 'PUSH_SOURCE ' ] = ( source ) => {
259- const allowedRanges = new RangeArithmetic ( 0 , source . length ) ;
260- for ( const skip of this . skipRanges ) {
261- allowedRanges . subtract ( ... skip ) ;
249+ protected readonly catchup : RuleDefArg [ 'CATCHUP ' ] = ( until ) => {
250+ const start = this . generatedUntil ;
251+ if ( start < until ) {
252+ this . stringBuilder . push ( this . origSource . slice ( start , until ) ) ;
262253 }
263- this . sourceStack . push ( { source, generatedUntil : 0 , allowedRanges } ) ;
264- } ;
265-
266- protected readonly popSource : RuleDefArg [ 'POP_SOURCE' ] = ( ) => {
267- this . catchup ( Number . MAX_VALUE ) ;
268- this . sourceStack . pop ( ) ;
254+ this . generatedUntil = Math . max ( this . generatedUntil , until ) ;
269255 } ;
270256
271257 protected readonly print : RuleDefArg [ 'PRINT' ] = ( ...args ) => {
0 commit comments