Back


Adding a new Value

The next thing to add is a new value. Let's have one that returns the square of a number; the test script then looks like this:

!	Test.ls

	variable N

	put 5 into N
	prompt the square of N
	exit

As before, the compiler will object to the prompt line since there's no handler for the square of. So let's add one. The first thing to do is load up the value compiler for the basic package. Unlike keyword handlers, all values are processed in a single class, in this case BLGetValue.java. This is in directory basic. Add the following lines:

   if (tokenIs("index")) return new BVIndex(getProgram());
   else if (tokenIs("square"))
   {
      skip("of");
      return new BVSquare(getValue());
   }
   else if (tokenIs("value"))

The lines shown in green are the new ones, which should help you find where to put them. [Note: Since writing this I've decided to include the square of as a standard part of the basic package, so you may like to experiment with cube instead.]

The compiler code calls for a new value handler called BVSquare(), which takes an LVValue as its sole parameter. An LVValue is a description of a value that can be either an integer value or a string or both; the compiler and runtime will usually sort out which is appropriate in any given context. Because it's a description it can be created at compile time, saved as part of the compiled script and evaluated at runtime.

The code for the new value handler is as follows. Put it in the basic/value subdirectory.

//	BVSquare.java

package basic.value;

import runtime.*;
import linguist.*;
import linguist.condition.*;
import linguist.debug.*;
import linguist.handler.*;
import linguist.keyword.*;
import linguist.value.*;

/******************************************************************************
   Return the square of a value.
*/
public class BVSquare extends LVValue
{
   LVValue value;                     // the value to square

   public BVSquare(LVValue value)
   {
      this.value=value;
   }

   public int getNumericValue() throws LRError
   {
      int v=value.getNumericValue();
      return v*v;
   }

   public String getStringValue() throws LRError
   {
      return String.valueOf(getNumericValue());
   }
}

This is pretty simple too; it's just a subclass of LVValue. The constructor stores the value to be squared, then two methods are available to access it either as a numeric value or a string. In this case the code doesn't tell you much about how the numeric value is stored, since the parameter is itself any LVValue; study some of the other value handlers to see how values are ultimately accessed.

You'll find that if the syntax is chosen carefully you can use compound constructs such as

add the square of the square of N to M

without the compiler being confused.

Adding a new Package


Back