DiscreteTom/retsac

Clone lexer's context?

DiscreteTom opened this issue · 2 comments

Usually lexer should be stateless. But sometimes lexer actions can depend on external states using closure. When we use parser the inner lexer may be cloned many times and thus the external states will be messed up.

So we should add a state/context for lexer (maybe also in parser), which should implement a LexerContext interface, and access it in actions.

interface LexerContext {
  clone(): this
}

// inject context in builder.
// the context type should be a part of the lexer's generic type.
// the builder should clone the context value and store as the default context value.
builder.context(...).define(...).build()

// access the context in actions
Lexer.Action.simple((input) => {
  console.log(input.context);
  return 0;
});

Usually the context is an object, maybe we also should implement a default clone method.

The clone-able state can also fix lexer state when parser re-lex.

Besides, user shouldn't update lexer's context in action's exec. The context value should be updated in action's callback.

When peek, action's callback should not be executed.

Currently the state can only be updated in action.then and never in peek.

Pass peek to action so the action can handle whether to change the state by themselves?