Previous section To contents Next section

4.2.4 program

Normally, when we say program we mean something we can execute from a shell prompt. However, Pike has another meaning for the same word. In Pike a program is the same as a class in C++. A program holds a table of what functions and variables are defined in that program. It also holds the code itself, debug information and references to other programs in the form of inherits. A program does not hold space to store any data however. All the information in a program is gathered when a file or string is run through the Pike compiler. The variable space needed to execute the code in the program is stored in an object which is the next data type we will discuss.

fig 4.4
Writing a program is easy, in fact, every example we have tried so far has been a program. To load such a program into memory, we can use compile_file which takes a file name, compiles the file and returns the compiled program. It could look something like this:
program p = compile_file("hello_world.pike");
You can also use the cast operator like this:
program p = (program) "hello_world";
This will also load the program hello_world.pike, the only difference is that it will cache the result so that next time you do (program)"hello_world" you will receive the _same_ program. If you call compile_file("hello_world.pike") repeatedly you will get a new program each time.

There is also a way to write programs inside programs with the help of the class keyword:

class class_name {
    inherits, variables and functions
The class keyword can be written as a separate entity outside of all functions, but it is also an expression which returns the program written between the brackets. The class_name is optional. If used you can later refer to that program by the name class_name. This is very similar to how classes are written in C++ and can be used in much the same way. It can also be used to create structs (or records if you program Pascal). Let's look at an example:
class record {
    string title;
    string artist;
    array(string) songs;

array(record) records = ({});

void add_empty_record()
    records+=({ record() });

void show_record(record rec)
    write("Record name: "+rec->title+"\n");
    write("Artist: "+rec->artist+"\n");
    foreach(rec->songs, string song)
        write(" "+song+"\n");
This could be a small part of a better record register program. It is not a complete executable program in itself. In this example we create a program called record which has three identifiers. In add_empty_record a new object is created by calling record. This is called cloning and it allocates space to store the variables defined in the class record. Show_record takes one of the records created in add_empty_record and shows the contents of it. As you can see, the arrow operator is used to access the data allocated in add_empty_record. If you do not understand this section I suggest you go on and read the next section about objects and then come back and read this section again.

To create a data area for a program you need to instantiate or clone the program. This is accomplished by using a pointer to the program as if it was a function and call it. That creates a new object and calls the function create in the new object with the arguments. It is also possible to use the functions new() and clone() which do exactly the same thing except you can use a string to specify what program you want to clone.
All programs are generated by compiling a string. The string may of course be read from a file. For this purpose there are three functions:
program compile(string p);
program compile_file(string filename);
program compile_string(string p, string filename);
compile_file simply reads the file given as argument, compiles it and returns the resulting program. compile_string instead compiles whatever is in the string p. The second argument, filename, is only used in debug printouts when an error occurs in the newly made program. Both compile_file and compile_string calls compile to actually compile the string after calling cpp on it.
Another way of compiling files to program is to use the cast operator. Casting a string to the type program calls a function in the master object which will compile the program in question for you. The master also keeps the program in a cache, so if you later need the same program again it will not be re-compiled.
int programp(mixed p)
This function returns 1 if p is a program, 0 otherwise.
As with all data types == and != can be used to see if two programs are the same or not.

The following operators and functions are important:

cloning ( p ( args ) )
Creates an object from a program. Discussed in the next section.
indexing ( p [ string ], or p -> identifier )
Retreives the value of the named constant from a program.
array(string) indices(program p)
Returns an array with the names of all non-static constants in the program.
array(mixed) values(program p)
Returns an array with the values of all non-static constants in the program.

Previous section To contents Next section