Skip to content

criezy/script_cmd

Repository files navigation

This program interprets C-like mathematical expressions and prints the result.

In Script mode, you can specify a multi-line script that contains variables,
then set the variable values and run the script multiple times (changing the
variable values between each run if you want to.

In simple mode, each line you type is interpreted as a simple equation and the
result is printed when you press return.

The program was written during free time in my universities days (in 2000) and
was cleaned in 2013 when I decided to share it. If you somehow stumble onto
this code and find it useful, or merely interesting, please drop me an email
to let me know (although I doubt it will ever happen, if I receive even only
one email that will make my day :) ). Also fill free to open pull requests
on github.com/criezy/ for any improvement you make.


1) Usage and options
2) Simple Mode
3) Script Mode
4) Compilation and contributions


1) Usage and options
--------------------
Usage: script [options]

When no option is given it starts the program in interactive script mode.

Options can be:\n");
  --help              Print this help.
  --simple-mode       Interactive simple equation mode.
  -e                  Same as --simple-mode
  --script='command'  Start in script mode and set the script to the given one.
  -s 'command'        Same as --script='command'
  --file=path         Start in script mode and load the script from the given file.
  -f path             Same as --file=path

2) Simple Mode
--------------
Each line you type is interpreted as a mathematical expression and the result is
printed on the next line. Type 'help' to get a list of recognised constant names,
functions and operators. Type 'exit' or 'quit' to quit the program.

Example of expression syntax:
$ ./script -e
Starting simple equation mode.
Type 'help' to get some help.
> (3 + 12) / 5
3
> 3 + 12 / 5
5.4
> if (cos(3 + 12 / 5) < 0, ceil(fabs(cos(3 + 12 / 5))), sqrt(3 + 12 / 5))
2.32379000772
> cos(3 + 12 / 5) 
0.634692875943
> sqrt(3 + 12 / 5)
2.32379000772

You can also use variables. Use 'define VAR' to define a variable and 'undefine VAR'
to undefine a previously defined variable. You can also use 'variables' to list the
defined variables.
For example:
$ ./script -e
Starting simple equation mode.
Type 'help' to get some help.
> define a
> define b cos(PI / 3)
0.5
> variables
There are 2 variables defined:
a = 0.000000
b = 0.500000
> a + b
0.5
> undefine a
> variables
There is 1 variable defined:
b = 0.500000

If you enabled the tree debug feature at compile time, you can use the
tree <equation> command to print the parser tree for the given equation.
For example:
$ ./script -e
Starting simple equation mode.
Type 'help' to get some help.
> tree (3 + 12) / 5
DivideOperator
  PlusOperator
    Constant: 3.000000
    Constant: 12.000000
  Constant: 5.000000
3


3) Script Mode
--------------
In script mode, you enter a multi-line script that may contain variables. Then
you can set the variable values and run the script multiple times. To define
the script you can:
  - give it to the program on the command line (--script= option) 
  - give it to the program as a text file (--file= option)
  - type it after starting the program

To type the script in the program, type 'START'. Then everything you type until
you type 'END' will define the script. If you start typing a script it will
throw away any script that might already have been defined (either passed to
the command line or previously typed in the program).

When not typing the script, the following commands are recognised:
  - 'start [name]'  Start defining the script with the given name.
  - 'help [topic]'  Print a help message.
  - 'scripts'       List defined scripts.
  - 'clear [name]'  Undefined the script with the given name.
  - 'run [name]'    Run the script previously defined with the given name.
  - 'run [name] > file' Run the script previously defined with the given name and redirect output
                        to file.
  - 'script [name]' Print the script previously defined with the given name.
  - 'script [name] < file' Initialise the script with the given name to the content of the given file.
  - 'script [name] > file' Save the script previously defined with the given name to the given file.
  - 'variables'     Print the list of variables in the previously defined script.
  - 'quit'          Quit the program ('exit' also works).
  - Everything else will be interpreted as a one line script and run immediately.
    This is usually used to set variable values (e.g. 'foo = 12.5').

For all the commands above that take a script name, the name is optional. Using
names allows to defined several scripts that will coexist.

Consider the following script.
$ ./script
Starting script mode.
Type 'help' to get some help.
> start
  if (z == 0) {
      x = y;
  } else {
      x = y / (2. * z);
  }
  print(x);
  print(y);
  print(z);
  z = z + 1;
  end
> 

You can then set the initial value for the variables y and z:
> y = 48;
> z = 0;

And then run the script several times:
> run
x = 48
y = 48
z = 0
> run
x = 24
y = 48
z = 1


You can also use external text file for scripts and variable values. External
variable files contain the variable name on the first line and values on
following lines. The script is then run once for each line. And you can
specify external files to which print() outputs are written.

> script init < examples/elastic_init.txt
> script compute < examples/elastic_compute.txt
> script stats < examples/elastic_stats.txt
> run init > result.txt
> run compute < examples/elastic_data.txt > result.txt
> run stats
Total number of samples: 12
Number of invalid samples: 1


You can use the 'tree' command to print the parser tree for a script. This is
only available if you enabled the tree debugging feature when compiling.

$ ./script
Starting script mode.
Type 'help' to get some help.
> start
if (z == 0) {
  x = y;
} else {
  x = y / (2. * z);
}
print(x);
z = z + 1;
end
> tree
Script
  If
    Condition
      Is equal
        Variable: z
        Constant: 0.000000
    Then
      Assign
        Variable: x
        Variable: y
    Else
      Assign
        Variable: x
        Divide
          Variable: y
          Multiply
            Constant: 2.000000
            Variable: z
  Print
    Variable: x
  Assign
    Variable: z
    Add
      Variable: z
      Constant: 1.000000

You can also provide a script name for a previously defined script:
> start foo
[...]
end
> tree foo

And you can redirect the output to a file:
> tree foo > foo_tree.txt


4) Compilation and contributions
--------------------------------
Compilation should be straightforward: type 'make' and that's it.

You can compile with support for the GNU deadline library for improved
text inout (including history). To do so you need to edit two lines in the
Makefile.

You can also enable some debugging features by editing the corresponding
line in the Makefile.

The source code was originally written on SunOS, IRIX and HP-UX. I have not
tested compilation on those systems when cleaning the code as I don't have
access to those anymore. I can however confirm it compiles and works on
Debian and Mac OS X. And I don't see why it would not work on any other
Linux and Unix systems.

Part of the code is documented as I was experimenting with doxygen, but
overall there is little comments or documentation (now you have been warned
feel free to look at the code anyway).

And if you do any modifications you deem worthwhile, please open a pull
request on github.com/criezy/ where the code is hosted.

About

A command line C-like script interpreter

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published