7.2.1 Running an Example Program in CSS

The following example will be used to illustrate the use of the CSS system:

// a function that decodes the number
String Decode_Number(float number) {
  String rval = "The number, " + number + " is: ";
  if(number < 0)
    rval += "negative";
  else if(number < .5)
    rval += "less than .5";
  else if(number < 1)
    rval += "less than 1";
  else
    rval += "greater than 1";
  return rval;
}

// decodes n_numbers randomly generated numbers
void Decode_Random(int n_numbers) {
  int i;
  for(i=0; i<n_numbers; i++) {
    float number = 4.0 * (drand48()-.5);
    String decode = Decode_Number(number);  // call our decoding function
    cout << i << "\t" << decode << "\n";    // c++ style output
  }
}

You can enter this code using a text editor (e.g., emacs or vi), or use the example code in `css_example.css' included with the PDP++ software in the `css/include' directory. Then, run the PDP++ software. At the prompt (which will vary depending on which executable you run -- the example will use css>), type:

css> load "css_example.css"

and the prompt should return. If you made any typos, they might show up as a Syntax Error, and should be corrected in the text file, which can be re-loaded with:

css> reload

Loading the text file translates it into an internal "machine code" that actually implements CSS. This is like compiling the code in traditional C, but it does not write out an executable file. Instead, it keeps the machine code in memory, so that it can be run interactively by the user.

To ensure that CSS has loaded the text, you can list the program:

css> list

Listing of Program: css_example.css
1
2       // a function that decodes the number
3       String Decode_Number(float number) {
4         String rval = "The number, " + number + " is: ";
5         if(number < 0)
6           rval += "negative";
7         else if(number < .5)
8           rval += "less than .5";
9         else if(number < 1)
10          rval += "less than 1";
11        else
12          rval += "greater than 1";
13        return rval;
14      }
15
16      // decodes n_numbers randomly generated numbers
17      void Decode_Random(int n_numbers) {
18        int i;
19        for(i=0; i<n_numbers; i++) {
20          float number = 4.0 * (drand48()-.5);
21          String decode = Decode_Number(number);  // call decoder
css> list

Listing of Program: css_example.css
21          String decode = Decode_Number(number);  // call decoder
22          cout << i << "\t" << decode << "\n";    // c++ style output
23        }
24      }
26      list

Note that you have to type list in twice in order to see the whole program (by default, list only shows 20 lines of code). Also, notice that the list command itself shows up at the end of the program--this is because commands that are entered on the command line are actually compiled, run, and then deleted from the end of the program. Because list, when run, shows the current state of the code (i.e., before it has itself been deleted), it shows up at the bottom of the listing.

Now, let's try running the example:

css> run
css>

Nothing happens! This is because the code as written only defines functions, it does not actually call them. The program would have to have had some statements (i.e., function calls, etc) at the top level (i.e., not within the definition of a function) in order to do something when the run command is issued.

However, we can call the functions directly:

css> Decode_Random(5);
0       The number, -0.414141 is: negative
1       The number, 1.36194 is: greater than 1
2       The number, -0.586656 is: negative
3       The number, -0.213666 is: negative
4       The number, -0.725229 is: negative
css>

(of course, your output will vary depending on the random number generator). This illustrates the interactive nature of CSS -- you can call any function with any argument, and it will execute it for you right then and there. This is especially useful for debugging functions individually. Thus, we can call the Decode_Number function directly with different numbers to make sure it handles the cases appropriately:

css> Decode_Number(.25);
css>

Notice, however, that there was no output. This is because the function simply returns a string, but does not print it out. There are several ways to print out results, but the easiest is probably to use the print command:

css> print Decode_Number(.25);
(String)  = The number, 0.25 is: less than .5

print gives you the type name, the variable name (which is blank in this case), and the value. To illustrate this, you can just declare a variable directly:

css> String foo = "a string";
css> print foo
(String) foo = a string

Compare this with the print function (not command) printf:

css> printf(Decode_Number(.25));
The number, 0.25 is: less than .5css>

which just gives you the value of the string (and does not automatically append a '\n' return at the end of the line). Finally, we can use C++ stream-based printing, which directs the return value from the function to print itself to the default current output cout:

css> cout << Decode_Number(.75) << "\n";
The number, 0.75 is: less than 1
css>

Note also that you can put any expression in the arguments to the function:

css> print Decode_Number(exp(cos(tan(.2) + .5) * PI)/ 20);
(String)  = The number, 0.549689 is: less than 1

In order to actually be able to run a script, we can add the following lines to the code by switching to define mode instead of the default interactive mode:

css> define
css# cout << Decode_Number(.75) << "\n";
css# Decode_Random(5);
css# exit

Note that we use exit to exit the define mode. You could also use the EOF character (ctrl-D on most systems) to exit this mode. To see that we have added to the program, list it from line 20 onwards:

css> list 20

Listing of Program: css_example.css
20          float number = 4.0 * (drand48()-.5);
21          String decode = Decode_Number(number);  // call decoder
22          cout << i << "\t" << decode << "\n";    // c++ style output
23        }
24      }
26      cout << Decode_Number(.75) << "\n";
27      Decode_Random(5);
28      exit
29      list 20

Now, when we run the program, we get:

css> run
The number, 0.75 is: less than 1
0       The number, 1.54571 is: greater than 1
1       The number, -1.93767 is: negative
2       The number, 0.336361 is: less than .5
3       The number, -1.36253 is: negative
4       The number, -0.465137 is: negative
css>

All of the C language rules about declaring or defining functions before they are called apply in CSS as well (in general, CSS obeys most of the same rules as C), so we could not have put those two extra lines of code in the example program before the functions themselves were defined. In general, this leads to a program layout consisting of various different functions, followed at the very end by one or two lines of code at the top-level which call the relevant function to start things off. If you are feeling traditional, you can call this function main, and it will look like a regular C/C++ program, except for the last line which calls the main function.