[erlang-questions] idea: ml9 (sort of) in the erlang shell

Ulf Wiger ulf@REDACTED
Wed Nov 14 10:59:59 CET 2007

2007/11/14, Vlad Dumitrescu <vladdu55@REDACTED>:
> BTW, you said that this notation would help for multi-line shell
> expressions. It would be even cooler if the shell could have true
> multi-line input, meaning that the history would be able to handle
> that kind of input and even edit it. But I suppose that wouldn't work
> through telnet to a remote system anyway...

I agree. I've decided to defer that problem, as it is separate from what
I'm currently messing with (as in: the code that handles the line editing
is in an entirely different module.)

So far, I think it helps by just providing a clean, prompt-free area that
you can copy/paste to and from e.g. the emacs *scratch* buffer.

Here's a progress report - what currently works:

Eshell V5.5.4  (abort with ^G)
1> X = x.

   The sections delimited by @ have local scope, so we can
   freely redefine variables. The semantics is like file:script(F),
   by default. We can control the parsing and semantics through

2> @.
X = foo.
3> X.

   We can import variables, and also declare/redefine variables on
   the '@' line:

4> Y=x,Z=z.
5> @ import(X,Y), Z=zzz.

   By default, the shell_exp module is called to handle the block.
   This module does pre-processing, so we can define and use macros:

6> @.
-define(X, 17).

   We can also declare some variables to export out of the local

7> @ export(Res).
Res = result.
8> Res.

The callback is shell_exp:parse(Text, Bindings, Env),
where Env is an opaque variable, which can be queried through
some accessor functions in the shell module:

env_get_define(Name, Env)
env_get_record(Name, Env)

The last two haven't been tested, but I kindof imagined a way to
have the shell memorize a macro, much like it can memorize
record definitions.

The callback function should return

{erl_eval, ExprSeq} | {error, Reason}
where ExprSeq = [Exprs]
           Exprs = [Expr]

Other return types can be added, for example if parsed forms are
returned, which should be compiled into a module. I searched a few
minutes for a core erlang evaluator (as I heard rumours of a Haskell-
to-core-erlang compiler), but couldn't find one.

The handling of options at the @ line is a bit weird. I can document it,
but basically, things like P(A1 .. An) would get expanded to the property
{P, [A1 .. An]}, P(A) into {P,A}. This is just shorthand for specifying options.
History expansion (i.e. e(N) and v(N)) works. You can also write

@  mode = exprs.

which would mean the same thing as

@ {mode, exprs}.

(This is just experimental, and easy to change. Yell if it offends you.)

If anyone wants to play with some other callback (e.g. parsing some other
grammar), let me know, and I'll put up my hack in a subversion repository.

Ulf W

More information about the erlang-questions mailing list