Programming  with  the  interpreter


3.1 Introduction

There are two ways to program with the command interpreter. The first is to write a sequence of commands in a command file in the command directory. For example, if the name of this file is  name_of_file , the command

<name_of_file

will launch the reading of the file and the execution of all the commands in it.

The second way is to write programs (i.e. sequences of commands or calls to programs), load them and execute them as commands.

Both command files and programs accept parameters and can call programs or read command files.

In a prior version of the command interpreter the possibility to load and execute programs was not implemented. Programs are easier to use and run faster than command files. Moreover everything done will command files can also be done with programs. Nevertheless the possibility to use command files has been kept in this version of the command interpreter.
 
 


3.2 Parameters

Command files and programs accept arguments. Inside a command file or a program, the first argument is represented by the expression #1, the second by #2, etc. For numbers with more than one digit, for example 11, one must use parentheses : #(11) ( #11 will be interpreted as #1 followed by 1). The maximal number of arguments that a command file or program can accept is fixed in the initialization file (cf  section 2.1).
 

Example :  Suppose that the command file  x.cmd contains the following lines

Xcom1  #1  #2
Xcom2
Xcom3  #2

Then the command

<x.cmd  A  B

will produce the execution of

Xcom1  A  B
Xcom2
Xcom3  B

(provided that the commands  Xcom1 , Xcom2 , Xcom3  mean something).

In a command line, in expressions of type {1, {2, ..., a substitution of # to { is made.
 
 
 


3.3 Numeric evaluation of expressions

The command interpreter contains an expression evaluator, written by Mark Morley. With it it is possible to make directly computations or to parse arguments of commands (see  section 6 for more details). With this expression evaluator it is possible to define variables and to use numerical functions. If the command interpreter receives a command that it not in its list of known commands, this command is sent to the expression evaluator, evaluated as a numerical expression, and the result is printed to screen. The evaluation gives 0 if the expression is incorrect (it is an unknown variable for example).
 

Example :

- interpreter -> a=1
1.000000
- interpreter -> b=-2
-2.000000
- interpreter -> newvar=a+b
-1.000000

(here  - interpreter ->   is the prompt of the interpreter). It is possible also to insert spaces :

- interpreter -> newvar = a + b

This will give the same result, except of course if you have a command called   newvar . So in general it is better to put no spaces inside a numerical expression.

It is possible to substitute the value of a numerical expression to this expression in strings of characters. Suppose for example that you have a command  defobj1 defining some type of objects (cf  section 5), and want to create objects  p_0 , p_1 , p_2 , and so on up to  n (a variable). This is the correct way to write it in a program :

do  i  0  n
defobj1  p_!(i)
enddo

(for the  do  loop, see section 3.6). Here the numerical expression i is converted to an integer, and this integer is substituted to !(i)  in the argument. It is possible to put any kind of numerical expression inside  !()  (for example !(i*j+2) ). It is possible also to substitute floating point values : if you write

defobj1   p_%(i)

you will obtain  p_0.000000 , p_1.000000 , p_2.000000 , and so on up to n .

The library contains some functions that can be used to evaluate the arguments of commands with the expression evaluator (cf. &6). For example if the command Xcom1  needs a floating point parameter, it may be useful to be allowed to write

- interpreter -> Xcom  a*(b+cos(x))

as well as

- interpreter -> Xcom  2.252

In this case the parameter must be parsed inside the C-function corresponding to the command  Xcom , using the appropriate function of the library (cf.  section 6).
 
 
 


3.4 Conditions

It is possible to execute contitionally some instructions, interactively or in command files or programs, using the commands  si ... and  is .... Inside programs it is better to use conditional jumps (cf.  section 3.6.2). For example suppose you type

- interpreter -> si  ccc

where  ccc  is a variable name. In this case the interpreter will evaluate  ccc . If the resulti is 0 or negative, the commands that follow will be ignored, until the interpreter receives the command

- interpreter -> is  ccc

and then the commands will be again accepted. It is also possible to avoid the following instructions if  ccc is positive, by using

- interpreter -> si  non  ccc
 

Example :

interpreter -> c=1
1.000000
interpreter -> d=-1
-1.000000
interpreter -> a=24
24.000000
interpreter -> si  c
interpreter -> a
24.000000
interpreter -> si  d
interpreter -> a
interpreter -> is  d
interpreter -> a
24.000000
interpreter -> si  non  d
interpreter -> a
24.000000
interpreter -> is  d
interpreter -> is  c

The maximal number of current conditions (not closed with is...) is fixed in the initialization file (cf. section 2.1).
 
 
 


3.5 Command files

3.5.1 Definition

A command file is a file containing a succession of commands understood by the command interpreter. It resides usually in the command directory which is fixed in the initialization file (cf.  section 2.4). It is invoked by a command

interpreter -> <name_of_file  arg1  arg2 ...

where  name_of_file  is the name of the command file, and arg1 , arg2 ,... are the arguments (if any, cf.  section 3.2). It the command file is somewhere else than in the command directory, its adress relatively to this directory must be given, instead of its name.

A command file can call other command files or programs too. Comments may be written in command files, in lines beginning with the character  ; .
 

3.5.2 Simulation of loops

This can be done by using the commands  loop ... , loopf...  and repete ... The instruction

interpreter -> loop  com1  com2  n1  n2  n3  par1  par2 ...

will create a command file called  com1 (in the command directory). This file will contains  n1 successive calls to  com2  with the parameters

n2  par1  par2...
n2+n3  par1  par2...
.
.
n2+(n1-1)*n3  par1  par2...

Here  n1 , n2 , n3  are numerical expressions that will be evaluated as integers. There is a similar command  loopf... which is the same except that  n1 , n2 , n3 will be evaluated as floating point numbers.
 

Example : The instruction

interpreter -> loop  com1  com2  4  100  10  A

will produce the command file  com1 wich contains :

<com2  100  A
<com2  110  A
<com2  120  A
<com2  130  A

and

interpreter -> loopf  com1  com2  4  100.5  0.1  A

will produce the command file com1 wich contains :

<com2  100.500000  A
<com2  100.600000  A
<com2  100.700000  A
<com2  100.800000  A

The instruction

interpreter -> repete  com1  com2  xx1  xx2

will create a command file called  com1 (in the command directory). This file will contain successive calls to the command file  com2 , the first with the argument xx1 , the second with the argument xx2 , and so on.
 

Example : The instruction

interpreter -> repete  com1  com2  44.00  22  125 36

will produce the command file  com1  wich contains :

<com2  44.00
<com2  22
<com2  125
<com2  36

It is possible also to create command files with commands containing #1 (or #2, etc.). This can be done by replacing the # in the command line by {.
 

Example : The instruction

interpreter -> loop  com1  com2  4  100  10  {1

will produce the command file  com1 wich contains :

<com2  100  #1
<com2  110  #1
<com2  120  #1
<com2  130  #1
 
 
 


3.6 Programs


3.6.1 Structure of programs

Programs can reside in files (in the command directory, cf. section 2.4) or in the initialization file. A program file can contain several programs. A program begins in the following way

: name
n1
n2 ...
mode1  mode2

where  name  is the name of the program (don't forget the : before), and  n1 , mode1 , mode2 ,..., n2  are integers.

The first integer  n1 , is the number of arguments needed by the program.

The second integer  n2  must be 0 or 1. If it is 0, the program will run silently, i.e. the successive instructions that it contains will not be printed on screen. This is useful if the program produces the execution of many instructions, if it contains loops for example. It is possible to run silently only a part of a program, by using the command silence... (cf. section 8). It is also possible to print something on screen  inside a silent program (or part of program), by using the commands echo , echoi  and echof (cf.  section 8).

The integers  mode1 , mode2 ,... are the running modes where it is allowed to use the program (cf. section 2.2). If the only mode -1 is put here, then the program can be used in all the running modes.

In a program file, a program ends when another one begins or when the file ends. A program can call other programs or command files.

Programs written in the initialization file will be loaded when the interpreter begins to run. Program files can be loaded using the command load . For example the instruction

interpreter -> load  prog.cmd

will load the program file  prog.cmd  which resides in the command directory. The command

interpreter -> proglist

prints the list of all the loaded programs. If  prog1  is one of them, the instruction

interpreter -> proglist  prog1

prints the list of all the instructions of the program  prog1 . The instruction

interpreter -> delprog  prog1

deletes the program  prog1 . Comments may be written in programs, using lines beginning with the character  ; .
 
 

3.6.2 Labels, conditional jumps and loops

A label in a program is a line of the following type

name:

where name is a string of characters (with no '#', '{', '&' or ':') followed by a ':'. It is possible to jump to this line (inside the same program) by using the instruction

goto  name

It is possible also to make conditional jumps by testing the value of numerical expressions. The instruction

if>  expr  name1

will jump to label  name1:  or not, according to the numerical expression  expr . If it is positive the program jumps to  name1: , otherwise it goes to the next line. The label must of course exist somewhere in the program. It is also possible to test if an expression is negative or zero, by using

if<  expr  name1

in the first case, and

if=  expr  name1

in the second case.

The syntax of loops is as follows :

do  var  var1  var2  incr
.
.
.
enddo

where  var  is a variable name, var1 , var2  and incr are numerical expressions. It is not necessary to define var  before using it in this loop. Initially, var  is set to var1  and in each step it if incremented by adding incr . The loop ends when  var  becomes larger than var2 . This will always work if  var2  and incr  are constant during the loop and incr  is positive, and definitely never if  var2  is constant and incr negative or zero. The parameter incr  can be omitted. In this case it is assumed to be 1. It is possible to nest loops.

In fact there is not a real implementation of loops, but rather a translation of the instructions  do ..., enddo  when the program is loaded, using conditional jumps. It is possible to see this by listing a program containing loops.
 

Example : Suppose that the file  prog.cmd in the command directory contains the following lines :

:example1
3
1
-1
x=0
do  i  #1  #2
x=x+i*i
enddo

Given two numbers a and b this program computes the sum of the integers between a and b.

The instruction

interpreter -> proglist  example1

prints the following on the screen

x=0
i=#1-1
0:
i=i+1
if>  i-(#2)  1
x=x+i*i
goto  0
1:
 

3.6.3 Questions and answers inside programs

It is possible that inside a function called by a command some data are asked to the user of the program. A standard way to do this is as follows :

int   i;
float   x;
printf("Enter an integer : ")
scanf("%d", &i);
printf("Enter a number : ")
scanf("%f", &x);

This is not good inside a program of the command interpreter, if you don't want it to stop to wait the answers. Instead of scanf one can use the library functions

void   read_int(int *);
void   read_float(float *);
void   read_char(char *);

(the last to read character strings). The program becomes

int   i;
float   x;
printf("Enter an integer : ")
read_int(&i);
printf("Enter a number : ")
read_float(&x);

In this case, the functions will behave like  scanf if they are used in a command in a interactive way (i.e not in a program). Moreover the entered values will be parsed by the expression evaluator; you can enter for example :

Enter  an  integer :
2*k+5
Enter  a  number :
cos(y)+2*c-4.

If the command corresponding to the function containing this piece of code is used inside a program, the interpreter will read the following lines of the program (2 in this example). So the program of the command interpreter could look like

.
.
command_name  arg1  arg2 ....
2*k+5
cos(y)+2*c-4.
.
.
 
 
 


3.7 Monitor files

It is possible to write in a file all the instructions executed by the command interpreter, and the messages printed on screen by it, using the command  mon.... The syntax is

mon  xxx

where  xxx  is a file name. If this instruction is given, the file is created if it did not exist, otherwise it is erased. All the subsequent instructions and messages of the command interpreter will be written not only on screen but also in this file, until the program ends, or the instruction   end_mon  appears. In the later case, the monitor file is closed. For the messages that come from functions written by the user, the function

void   print(char*, ...);

can be used instead of the usual   printf . This function prints on screen and on the monitor file, if it has been defined. Only the flags   %d , %f and  %s  have been implemented.
 
 
 


Main page
Chapters   1   2   3   4   5   6   7   8    9    10   11