<!-- FIXME: I'd like this file to be generated from the actual strings
     in Hilfe.pmod and all examples autogenerated in a wrapper like
     the one in testhilfe.pike -->

<chapter title="Hilfe">

<p>Hilfe stands for Hubbes Incremental LPC Front End, and is an
incremental Pike evaluator. As the name hints Hilfe has its roots back
when Pike was called LPC, but none of the code from that Hilfe
remains. Hilfe is one of the most useful tools for Pike developers,
since it enables them to try various Pike constructions and see how
they work. Even the most experienced Pike programmer can forget how
the return data structure of a function looks like or if + or | is the
best way to merge to mappings for a specific purpose.
</p>

<section title="Basic operations">

<p>In short hilfe is a command line version of pike, allowing you to
   do real time evaluation of pike code. Simply write a line of pike
   code and press return. If you gave hilfe a complete block of code
   it will be evaluated and the result will be returned. Side effects will
   also be effective, hence changing a variable will indeed change the
   variables value. You are of course not limited to basic variable
   types like integers and strings, or reference data types like
   mappings and arrays. You can just as well define functions and
   classes, enabling you to experiment with inherits, operator
   overloading and other object oriented things. To start hilfe, just
   execute the pike binary without any arguments.</p>

<example>
bash$ pike
Pike v7.3 release 49 running Hilfe v3.5 (Incremental Pike Frontend)
> int a=5;
> a+3.3;
(1) Result: 8.300000
> (string)(enumerate(32)[*]+65);
(2) Result: "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
> string b=(string)(enumerate(32)[*]+65);
> b/(a+3.3);
(3) Result: ({ /* 4 elements */
                "ABCDEFGH",
                "IJKLMNOPQ",
                "RSTUVWXY",
                "Z[\\]^_`"
            })
>
</example>

<p>A history of the 512 last entered lines is kept in Hilfe. You can
browse this list with your arrow keys up/down. When you exit Hilfe
your history will be saved in .hilfe_history in the directory set
in environment variable $HOME or $USERPROFILE. Next time hilfe is
started the history is imported.</p>

<p>A history of the last returned results is kept and can be accessed
from your hilfe expressions with the variable <expr>__</expr>. You can
either "address" your results with absolute addresses, e.g.
<expr>__[2]</expr> to get the second result ever, or with relative
addresses, e.g. <expr>__[-1]</expr> to get the last result. The last
result is also available in the variable <expr>_</expr>, thus
<expr>_==__[-1]</expr> is true. The magic <expr>_</expr> and
<expr>__</expr> variable can be shadowed with local definitions to
disable them, e.g. by typing <expr>int _;</expr>. The result history
is ten entries long by default, but it could easily be altered by
using the <tt>set history</tt> command. Note that some Pike code only
works when there is at most one object created from a class, which
means that the result history must be turned off. Otherwise the
previous object will remain in the history during the next nine
results.</p>

<p>You can put a .hilferc file in the directory set in your
environment variable $HOME or $USERPROFILE. The contents of this file
will be evaluated in hilfe during each startup. It may contain both
commands and Pike expressions.</p>

<p>One must however always remember that code entered in Hilfe does
not always work exactly as if it was written in a stand alone Pike
program. All variables are kept in a mapping so that their values can
be view and altered by subsequent code lines. Every expression is
compiled and evaluated in a wrapper which then returns the return
value to Pike. Use the <tt>dump wrapper</tt> command after a line has
been evaluated to see the actual code compiled.</p>

<example>
> int a=5;
> a+3.3;
(1) Result: 8.300000
> dump wrapper
Last compiled wrapper:
001: #pragma unpragma_strict_types
002: mapping(string:mixed) ___hilfe = ___Hilfe->variables;
003: # 1
004: mixed ___HilfeWrapper() { return (([mapping(string:int)]___hilfe)->a)+3.3; ; }
005:
>
</example>

<p>Note that there are a few symbols that you can not define, since
they are used by Hilfe.</p>

<matrix>
<r><c><expr>___hilfe</expr></c><c>A mapping containing all defined symbols.</c></r>
<r><c><expr>___Hilfe</expr></c><c>The Hilfe object.</c></r>
<r><c><expr>___HilfeWrapper</expr></c><c>A wrapper around the entered expression.</c></r>
</matrix>

</section>

<section title="Commands">

<p>In addition to be able to enter Pike expressions, there are also a
few commands available which controls Hilfe. To avoid having the
commands shadowed by Pike declarations with the same name, it is also
possible to add a dot in front of the command.</p>

<example>
> int help=3;
Hilfe Warning: Command "help" no longer reachable. Use ".help" instead.
> help
>> +2;
(1) Result: 5
>
</example>

<subsection title="Help">

<p>The help command displays a very short introduction to Pike and
lists all the available commands with a brief explaination.</p>

<example>
> help

Pike v7.3 release 49 running Hilfe v3.5 (Incremental Pike Frontend)
Hilfe is a tool to evaluate Pike code interactively and
incrementally. Any Pike function, expression or variable declaration
can be entered at the command line. There are also a few extra
commands:

 dump       - Dump variables and other info.
 exit       - Exit Hilfe.
 help       - Show help text.
 new        - Clears the Hilfe state.
 quit       - Exit Hilfe.
 set        - Change Hilfe settings.
 start      - Start a subsystem.
 stop       - Stop a subsystem.
 .          - Abort current input batch.

Enter "help me more" for further Hilfe help.
>
</example>

<p>In addition to this elementary help there are a few extra arguments
that can be given to help to see other help pages. "<tt>help me
more</tt>" returns a brief summary of everything in this manual
chapter. "<tt>help hilfe todo</tt>" shows the items in the bug section
below. "<tt>help about hilfe</tt>" show version information. In
addition to these three arguments it is also possible to type help
follow with the name of any other command. That will display the
documentation for that command.</p>

</subsection>

<subsection title="Exit and Quit">
<p>It is possible to end a Hilfe session by entering the command
<tt>exit</tt> or <tt>quit</tt>. It is also possible to exit by using
Control+D. Note that no history will be saved if Control+C is used to
terminate Hilfe.</p>
</subsection>

<subsection title=".">
<p>When a single dot is inputed into Hilfe on a new line, any
multiline expression currently in progress to be inputed will be
discarded.</p>
<example>
&gt; foreach(getenv(); string env; string value)
&gt;&gt; if(has_prefix(env, "LC_"))
&gt;&gt; .
&gt;
</example>
</subsection>

<subsection title="dump">
<p>Dump shows certain states within Hilfe or Pike. If only
<tt>dump</tt> is given, Hilfe prints out the currently defined
constants, variables, functions and programs. It also lists all active
inherits and imports.</p>
<example>
&gt; dump

Constants:
pi       : 3.141593

Variables:
int i            : 3
float|string res : "VRkjMs28m0PCU"

Functions:
plot

Inherits:
Parser.XML.Tree

Imports:
GL
</example>

<p><tt>dump history</tt> shows all items in the result history queue.</p>
<example>
&gt; dump history
  1 (-4) : 3102
  2 (-3) : 8.039803
  3 (-2) : "D3Y1jk2fOYl5M"
  4 (-1) : "CsuBAXhfB9HWI"
4 out of 10 possible entries used.
</example>

<p><tt>dump memory</tt> shows the current memory usage.</p>
<example>
> dump memory
             Num   Bytes
array        511   67860 (66.3 kb)
callable     235   16304 (15.9 kb)
callback       3    4128 (4.0 kb)
frame          7   16296 (15.9 kb)
mapping      125  121262 (118.4 kb)
multiset      42   20064 (19.6 kb)
object       710  129024 (126.0 kb)
program      412  2070184 (2.0 Mb)
string      9522  743959 (726.5 kb)
</example>

<p><tt>dump state</tt> shows the current parser state. Only useful for
debugging Hilfe.</p>
<example>
> while(0) {
>> dump state
Current parser state
Parenthesis stack: {
Current pipeline: ({ /* 7 elements */
    "while",
    "(",
    "0",
    ")",
    " ",
    "{",
    "\n\n"
})
Last token: ")"
Current block: ")"
</example>

<p><tt>dump wrapper</tt> show the latest Hilfe wrapper that the last
expression was evaluated in. Useful when debugging Hilfe (i.e.
investigating why valid Pike expressions doesn't compile).</p>
<example>
> int i=5;
> i+=5;
(1) Result: 10
> dump wrapper
Last compiled wrapper:
001: #pragma unpragma_strict_types
002: mapping(string:mixed) ___hilfe = ___Hilfe->variables;
003: # 1
004: mixed ___HilfeWrapper() { return (([mapping(string:int)]___hilfe)->i)+=5; ; }
005:
</example>
</subsection>

<subsection title="new">
<p>When <tt>new</tt> is given without any arguments it clears the
current Hilfe state. This includes the parser state, variables,
constants, functions, programs, inherits, imports and the history. It
does not include the currently installed commands. Note that code in
your .hilferc will not be reevaluated.</p>

<p><tt>new history</tt> removes all entries from the result history.
<tt>new constants</tt>, <tt>new functions</tt>, <tt>new programs</tt>,
and <tt>new variables</tt> clears all locally defined symbols of the
given type. <tt>new imports</tt> and <tt>new inherits</tt> removes all
imports and inherits respectively.</p>
</subsection>

<subsection title="set">
<p>With the <tt>set</tt> commands various settings in Hilfe can be
changed. Set is used as <tt>"set &lt;setting&gt;
&lt;parameter&gt;"</tt>.</p>

<p><b>assembler_debug</b> Changes the level of assembler debug used
when evaluating expressions in Pike. Requires that Pike is compiled
with RTL debug.</p>

<p><b>compiler_trace</b> Changes the level of compiler trace used when
evaluating expressions in Pike. Requires that Pike is compiled with
RTL debug.</p>

<p><b>debug</b> Changes the level of debug used when evaluating
expressions in Pike. Requires that Pike is compiled with RTL debug.</p>

<p><b>format</b> Changes the formatting of the result values from
evaluated Pike expressions. Currently the following set format
parameters are available:</p>
<matrix>
<r><c>default</c><c>The normal result formatting.</c></r>
<r><c>bench</c><c>A result formatting extended with compilation and
evaluation times.</c></r>
<r><c>sprintf</c><c>The result formatting will be decided by the succeeding
Pike string. The sprintf will be given the arguments shown in
the table below.</c></r>
</matrix>

<matrix>
<r><c>0</c><c>The result as a string.</c></r>
<r><c>1</c><c>The result number in the history.</c></r>
<r><c>2</c><c>The result in its native type.</c></r>
<r><c>3</c><c>The compilation time as a string.</c></r>
<r><c>4</c><c>The evaluation time as a string.</c></r>
<r><c>5</c><c>The compilation time in nanoseconds as an int.</c></r>
<r><c>6</c><c>The evaluation time in nanoseconds as an int.</c></r>
</matrix>
<example>
> 1+2/3.0;
(1) Result: 1.666667
> set format bench
> 1+2/3.0;
Result 2: 1.666667
Compilation: 573ns, Execution: 6ns
> set format sprintf "%s (%[2]t)\n"
> 1+2/3.0;
1.666667 (float)
> set format sprintf "%s (%d/%[3]s/%[4]s)\n"
> 1+2/3.0;
1.666667 (4/575ns/6ns)
</example>

<p><b>hedda</b> Initializes some variables for quick access, unless
they are already defined. Hilfe attempts to do the following
declarations: mixed foo, mixed bar, int i, float f=0.0, mapping
m=([]), array a=({}) and string s="".</p>

<p><b>history</b> Change the maximum number of entries that are kept in
the result history. Default is 10. When dealing with objects of which
there can only exist one copy you should set history to 0.</p>

<p><b>trace</b> Changes the level of trace used when evaluating expressions
in Pike. Possible values are:</p>
<matrix>
<r><c>0</c><c>Off</c></r>
<r><c>1</c><c>Calls to Pike functions are printed.</c></r>
<r><c>2</c><c>Calls to buitin functions are printed.</c></r>
<r><c>3</c><c>Every opcode interpreted is printed.</c></r>
<r><c>4</c><c>Arguments to these opcodes are printed as well.</c></r>
</matrix>

<p><b>warnings</b> Change the current level of warnings checking.
Possible values are:</p>
<matrix>
<r><c>off</c><c>No warnings are shown.</c></r>
<r><c>on</c><c>Normal warnings are shown.</c></r>
<r><c>strict</c><c>Try a little harder to show warnings.</c></r>
</matrix>

</subsection>

<subsection title="start and stop">
<p>Start and stop turns various subsystems in Hilfe on and off.
Currently there are two subsystems implemented in Hilfe, backend and
logging.</p>
</subsection>

</section>

<section title="Bugs and possible improvements">

<ul>
<li>Hilfe can not handle sscanf statements like
  <expr>int a = sscanf("12", "%d", int b);</expr></li>
<li>The variable scope is not correctly adjusted for sscanf
  constructions like <expr>sscanf(x, "%2d%2d", int a, int b);</expr></li>
<li><expr>int x=x;</expr> does not generate an error when <expr>x</expr> is undefined.</li>
<li>Hilfe can not handle enums.</li>
<li>Hilfe can not handle typedefs.</li>
<li>Hilfe can not handle implicit lambdas.</li>
<li>Hilfe can not handle unnamed classes.</li>
<li>Hilfe can not handle named lambdas.</li>
<li>Hilfe should possibly handle imports better, e.g. overwrite the
  local variables/constants/functions/programs.</li>
<li>Filter exit/quit from history. Could be done by adding a 'pop'
  method to Readline.History and calling it from StdinHilfe's
  destroy.</li>
<li>Add some better multiline edit support.</li>
<li>Tab completion of variable and module names.</li>
</ul>

</section>

</chapter>

