Skip to content

Conversation

@jpco
Copy link
Collaborator

@jpco jpco commented Jul 29, 2025

TL;DR, this PR:

  1. Adds %define api.pure full to parse.y. This makes the generated parsers "pure", which means they don't depend on any shared variables and multiple can run at once.
  2. Adds y.tab.c and token.h to the repo so yacc doesn't need to be invoked just to build the shell.
  3. Miscellaneous changes in other files to make the above work.

This should be a complete no-op for an es user, and a minor improvement in convenience to an es builder.

Why this change? The ultimate goal is to be able to run es code while the parser is running. Doing so would unlock more or less the entire category of "interactive features" that are either difficult or impossible to have in es today. See #178 for what one version of that might look like, and some discussion.

The major technical hurdle to this "programmable input" was fixed with #205, which made it possible to fetch shell input without disabling the GC. This PR does half the work[*] of resolving the second technical hurdle: parsing while parsing.

The problem is that running es code requires, at unpredictable times, parsing es code. For example, if you overrode %write-history in your .esrc, and you want to call %write-history for each line of input, then that means that your interactive es shell parses %write-history from the environment on the first line of input entered, which is likely to be in the middle of parsing the line of input itself.

POSIX does not specify anything about a yacc parser supporting this, and by default, yaccs don't. However, bison and byacc can both be configured to, by using the non-standard %define api.pure full directive to generate a "pure" parser. So we do that. But that makes our parse.y non-standard (and therefore considered non-portable, though I've struggled to even find alternative yaccs in reasonably common use these days). So to work around that, we just package up the generated parsers with the source code and, unless you mess around with parse.y, don't bother re-generating y.tab.c and token.h at all.

This means that folks just trying to build es on their machines don't need a yacc installed at all. This makes es even more portable than it has been :) (assuming the outputted C code is nicely standards-compliant, which all evidence thus far suggests it is).

This follows how rc is packaged up these days, so arguably this is also helping make #1 happen. :)


[*] After this, the remaining work is making any globally scoped parsing-related data per-Input.

jpco added 3 commits July 29, 2025 15:46
Doing this requires non-standard YACC, so we test for bison or byacc,
and package y.tab.c in the repo so that users don't need to generate the
parser unless they're hacking on it specifically.
@jpco jpco force-pushed the master branch 3 times, most recently from 64361a8 to a23a7a0 Compare September 19, 2025 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant