wryun / es-shell

es: a shell with higher-order functions
http://wryun.github.io/es-shell/
Other
307 stars 25 forks source link

adventure.es example doesn't work #34

Closed pmarreck closed 2 years ago

pmarreck commented 2 years ago

Fascinated by this shell (why has this project not gotten more attention??), but afraid to mess with anything due to the lack of a real test suite ("make trip" doesn't, or shouldn't, count!)

I actually forked es-shell, fixed compiler bugs on the current gnu toolchain and merged in the job control branch (and added some homebrew-friendly config stuff for macOS devs)... but I have no idea if I broke anything other than just running the examples and seeing a success. (Which is how I found this problem. I then came back here, built it without any of my changes, and adventure.es was still broken in an endless loop... unless my tooling somehow caused a bug!)

For starters, just a way to assert on stdout, stderr (and any other fd's, I suppose) and return code, given a statement or block or what have you, would be an outstanding step towards a fundamental test suite function (I found a very hacky way to do this in bash so I could test my bash scripts, an even hackier way to do this in zsh, but I'd have no idea how to build such an assert in es!)

By day I'm an Elixir/BEAM coder (hence the "functional shell" interest) and my level of C/C++ ability is basically "given an unlimited amount of time and all the googles, can probably build anything" 😅

wryun commented 2 years ago

@pmarreck though nominally the 'owner' of this project, it only exists because I'm an es user and thought it deserved a place on the internet.

I've never quite found the enthusiasm to do serious work on it, and based on past performance am not likely to; I also haven't written any substantial amount of C in many years. If you'd like to start PR-ing then feel free, or if you feel some decent amount of work has been done on your fork I'm happy to point to it from the homepage. However, I'm going to be wary of things that change es's functionality as opposed to addressing bugs.

If you haven't seen it, you might be interested in https://github.com/TieDyedDevil/XS

If you're merging 'random useful things' in a fork you may also want to pull in the readline-history branch and clean it up. This is what I use myself.

I'm going to change this issue to 'adventure.es' is broken. Feel free to raise another issue for the test suite :)

wryun commented 2 years ago

(btw, if you wanted to start a project that would draw attention to the concepts and approach in 'es', I'd suggest rewriting it in Zig - just because doing something like that might get people excited about the shell and attract contributors)

pmarreck commented 2 years ago

All makes sense. Sorry about the wordy issue title =) Yeah, I've actually been talking to TieDyedDevil about XS offline over email with the intent of reviving it but it turns out he is porting his XS stuff over to ES and made a pretty good argument that if one had to choose between supporting XS or ES, it makes more sense to support ES currently, so I think I'm going to do that. Been playing around with it and going through the docs and wow, it's actually sane!

I recently wrote this to test my bash scripts https://github.com/pmarreck/tinytestlib , I'd like to write something like this in es to start some sort of es-driven es test suite (not just for my own es scripts but for es itself!) even though I could probably just drive es test scripts from bash using this lib and assert on those results from bash. The tricky bits I solved in Bash (but not yet in ES) involve capturing all of stdout, stderr and retcode from a single execution without making new files so that you can assert on them (without touching the filesystem, something I generally try to avoid in test suites), and doing encoding-agnostic (escapes, unicode, ANSI etc.) binary comparisons in those assertions. I'm currently having difficulty making this work in es (I'm proceeding with basically taking the core magic line of code, which you can see here https://stackoverflow.com/questions/13806626/capture-both-stdout-and-stderr-in-bash and manually transcoding bash constructs to es constructs... which is going slow, probably because I'm new to es) but I think the semantics and language features necessary to make it work are there.

If you were very good at es, this would be a huge help.

I think this would possibly support your criteria of not adding new features :) I guess I'm so used to testing my own stuff that I literally can't proceed to add anything without some sort of test suite, anyway! It's too risky! We know this!

If that was in place, it would be (almost) completely trivial to include a test of all the examples in said suite, incorporate it into a github build action, etc...

pmarreck commented 2 years ago

(btw, if you wanted to start a project that would draw attention to the concepts and approach in 'es', I'd suggest rewriting it in Zig - just because doing something like that might get people excited about the shell and attract contributors)

Zig looks interesting, I was actually unfamiliar with it but it looks superior to C on first glance, while also (I think?) allowing you to compile C.

I don't know if I have the bandwidth to rewrite es in Zig though, I'm not a C coder by day... Ironically, this was another reason why I wanted a good test suite before I attempted anything crazy

pmarreck commented 2 years ago

I merged in the readline-history branch as suggested, so now my fork has both the jobcontrol stuff and the readline stuff (in theory... If only there was a mechanism to assert these things...) https://github.com/pmarreck/es-shell/ So far it's running existing things fine.

The only conflicts were in input.c but I think I managed to clean it up without disturbing the logic and eliminate any compiler warnings as well.

I also started a new ticket for a test suite (as you probably saw)

wryun commented 2 years ago

@pmarreck I pulled a very slightly improved readline thing into master and released 0.9.2

I couldn't see the bug with adventure.es. What output do you get when you try to run it? I get something like:

; ./es examples/adventure.es 
You found a discarded empty knapsack.
Welcome to the Adventure shell!  Do you need instructions?[y/n] y

                  Instructions for the Adventure shell

  Welcome to the Adventure shell!  In this exploration of the UNIX file
  system, I will act as your eyes and hands.  As you move around, I will
  describe whatever is visible and will carry out your commands.  The
  general form of a command is
          Verb Object Extra_stuff.
  Most commands pay no attention to the "Extra_stuff", and many do not
  need an "Object".  A typical command is
          get all
  which picks up all files in the current "room" (directory).  You can
  find out what you are carrying by typing the command
          inventory
  The command "help" results in a full description of all commands that I
  understand.  To quit the Adventure shell, type
          quit

  There are UNIX monsters lurking in the background.  These are also
  known as "commands with arguments".

  Good luck!
Type a newline to continue: 
You are in your own home.
This room contains:
progs.tgz
There are exits labeled:
a          Desktop        Downloads      Pictures       Templates
builds         Documents      Music      Public     Videos
as well as a passage overhead.
-advsh> help
I understand the following commands synonyms in parentheses :

change OBJECT to NEW_NAME changes the name of the object
clone OBJECT as NEW_NAME duplicates the object
drop OBJECTS leaves the objects in the room
enter go PASSAGE takes the labeled passage
examine OBJECTS describes the objects in detail
feed OBJECT to MONSTER stuffs the object into a UNIX monster
get take OBJECTS picks up the specified objects
gripe bug report a problem with the Adventure shell
help prints this summary
inventory i tells what you are carrying
kill destroy OBJECTS destroys the objects
look l describes the room, including hidden objects
open read OBJECT shows the contents of an object
quit exit leaves the Adventure shell
resurrect OBJECTS attempts to restore dead objects
steal OBJECT from MONSTER obtains the object from a UNIX monster
throw OBJECT at daemon feeds the object to the printer daemon
up takes the overhead passage
wake MONSTER awakens a UNIX monster
where w tells you where you are
xyzzy moves you to your home
memreflect commented 2 years ago

es < adventure.es appears to print -advsh> Do you really want to quit now?[y/n] infinitely. Using something similar to the following line before anything is executed would prevent this from happening:

test -t 0 || throw error adventure 'usage: es adventure.es'
pmarreck commented 2 years ago

@wryun I get the error @memreflect is seeing, basically.

wryun commented 2 years ago

i.e. if you try to execute it with es < adventure.es it fails? Is there a reason to do this?

pmarreck commented 2 years ago

Yes, that's when it fails. I guess there's no particular reason to execute it that way instead of ./es examples/adventure.es except that I thought their effects were equivalent most of the time (such as with ./es < examples/99bottles.es despite the fact that < is a pipe to stdin while passing it in as an argument treats it as a file.

And suddenly I realize the problem. Since adventure.es accepts user input at runtime (and 99bottles.es doesn't), piping to es's stdin probably feeds the program itself to itself or something odd like that, which makes it more of a behavior idiosyncrasy to be aware of, than a bug, I guess. I've honestly not tried to run a bash script that requests user input by piping it to bash's stdin, maybe it behaves similarly...

wryun commented 2 years ago

I'm going to close this as 'potentially confusing, but working as intended'.