| Hello, everyone. I would have responded sooner but I spend most of my workday in a closed network for security reasons (defense contractor), and don't have much internet access over the course of the day. There is nothing stopping Forsh from being used that way. The convenience words from the README use a global variable to tell them where to build commands and overwrite the memory for every new command because the common case is that you as a user don't really care much about having arbitrary history (In any case, gforth already uses readline, so I get history for free). The words underneath all take that location as an argument on the stack. You could write some words that allocate space for each new command without changing the underlying libraries. The key to thinking about pipe words in Forsh is that they execute a given command and consume and/or leave a file pointer to a command's stdout on the stack. This is why there are multiple pipe words. They have different stack effects. `>|` (begin pipeline) only leaves a file pointer.
`|` (continue pipeline) consumes and leaves a file pointer.
`|>` (end pipeline) only consumes a file pointer. This allows the pipe words to interoperate with any file I/O words in gforth. If you want to "save a command to a variable", you just use a regular Forth word. [bracket] words make things work in compile mode. `: hack [c] echo [p] hack! $ ;` Executing hack will then build and execute the command. This also works with arbitrary pipeline fragments. I did my best with syntax, but existing shells have already aggressively minimized typing for short commands. The most I could do was have people type `l ` instead of `--` for long options and `s ` instead of `-` for short options. However, I find quoting much improved over existing shells. You specify the quote character when you type the command, so there is no escaping. You just pick a character that doesn't exist in the string. You are ok as long as your string does not included every printable ASCII character. |