16.8 Sling Functions


 
Building Parsers with Java
By Steven  John  Metsker

Table of Contents
Chapter  16.   Parsing an Imperative Language

    Content

In the source code for the function classes in the SlingFunction hierarchy, the design principles show through. They are as follows :

  • Represent each known function with a class that implements the method f() .

  • Write f() for each function class so that it wraps its function around other function objects. Require that these objects be supplied to the class constructor.

  • Define the signature of f() to be Point f(double t).

  • For any base function that would naturally return a single number y , return new Point(t, y) , where t is the input parameter to f() .

The classes in this hierarchy also provide the ability to create unvariable functions from variable functions by evaluating their sources. The Variable class and the hierarchy superclass SlingFunction are the only classes that actually implement methods that support evaluation.

16.8.1 SlingFunction

This class is at the top of the hierarchy of functions (see Figure 16.26).

Figure 16.26. The SlingFunction class. This class defines, for a large number of subclasses, the methods for evaluating and copying a function.

graphics/16fig26.gif

Class SlingFunction defines f() as an abstract method and defines eval() for evaluating a function into an unvariable form.

16.8.2 Abs, Ceil, Cos, Floor, Sin, and Tan

Each of these Sling functions wraps a routine from class Math in java.lang . Each of these functions normally takes a single number and returns a single number. To follow the Sling environment design principles, each function must find its input number by evaluating its source at a given time and then extracting the y component. The Sling functions pass this number to the appropriate Math method and get back a single number. The Sling functions augment this number, using time as the x component, to create a two-dimensional point. For example, Abs.f(t) contains the statement

 return new Point(t, Math.abs(source[0].f(t).y)); 

The other functions in the title of this section operate in the same way, each using a different function from Math .

16.8.3 Arithmetic

This class wraps an arithmetic function around two source functions. The Arithmetic class's constructor requires a char (to indicate an operator), and two source functions. The operator must be " + ", " - ", " / ", " * ", or " % "; otherwise , f(t) of this object will always be the point (0, 0) .

The value of an arithmetic function at time t is the value of the operator applied to the source functions at time t . For example, evaluating the arithmetic sum

 f1 + f2 

at time t creates the point

 (f1(t).x + f2(t).x, f1(t).y + f2(t).y) 

16.8.4 Cartesian

This class combines the y component of each of two source functions to form a new two-dimensional function. This allows functions that are normally one-dimensional to combine into a two-dimensional function.

For example, both sin and cos are normally one-dimensional functions, returning a single number for any given value. The classes Sin and Cos store their results in the y dimension of a function, augmenting any particular point with t as the x value. Objects of the Cartesian class ignore the x component of each source function. The y component of the first source function becomes the x component of the Cartesian function, and the y component of the second function becomes the y component of the Cartesian function.

Consider the following program, which plots a circle:

 theta = 2*pi*t;  x = cos(theta); y = sin(theta); plot cartesian(x, y); 

The design principles at play in sjm.examples.sling augment the x and y functions so that they are effectively cartesian(t, cos(theta)) and cartesian(t, sin(theta)) . The program recombines the y components of these functions into a new cartesian with an x value of cos(theta) and a y value of sin(theta).

16.8.5 Point

Objects of this class store two numbers that effectively determine a point in two-dimensional space.

16.8.6 Polar

This class represents the location of a sling stone in terms of the length of a sling's strap and the angle (in radians) around the slinger's head. The constructor accepts two source functions. The y component of the first function represents the length of the strap, and the y component of the second function represents the strap's angle.

When you whirl a sling, the stone's path covers 2*pi radians of arc as the stone makes one revolution. The arc varies from 0 to 2*pi, starting in the positive x direction and rotating counterclockwise. You can use the variable r to represent the strap's length, and the variable theta to represent the strap's angle. At any point in time, then, the stone's position is

 polar(r, theta) 

This is equivalent to

 cartesian(r * cos(theta), r * sin(theta)) 

because the cos and sin functions represent the x and y components of a stone's path. Thus, the implementation of Polar.f() is

 public Point f(double t) {      double r = source[0].f(t).y;     double theta = source[1].f(t).y;     return new Point(         r * Math.cos(theta), r * Math.sin(theta)); } 

16.8.7 Random

Objects of this class return a random number between 0 and 1 when asked for their value. Here is the implementation of Random.f ():

 public Point f(double t) {      return new Point(t, Math.random()); } 

16.8.8 Scale

A Scale function varies between two limits. As a plot unfolds, time varies from 0 to 1. When time is 0, the value of a Scale object is the value of its first limit. When time is 1, the value of a Scale object is the value of its second limit. For example, the Sling program

 plot scale(cartesian(-1, -1), cartesian(1, 1)); 

plots a 45-degree line from the lower-left corner to the upper-right corner.

16.8.9 Sling

This class represents the location of a sling stone in terms of the length of a sling's strap and the speed of the stone's rotation around the slinger's head.

The constructor accepts two source functions. The y component of the first function represents the length of the strap, and the y component of the second function represents the stone's angular speed. A speed of 1 represents one full rotation that occurs during the course of a plot. Here is the implementation of Sling.f() :

 public Point f(double t) {      double r = source[0].f(t).y;     double speed = source[1].f(t).y;     double theta = Math.PI * 2 * speed * t;     return new Point(         r * Math.cos(theta), r * Math.sin(theta)); } 

16.8.10 Slider

This class holds a Swing JSlider component, returning the slider's value in its f(t) call. The slider, which this class's constructor requires, should vary from 0 to 100. This class divides that value by 100 so that the slider effectively varies from 0 to 1. The y component of the return value of f(t) ignores time and depends only on the slider value. Like all one-dimensional functions, however, this function uses time as the x component of the value it returns.

16.8.11 T

This class represents time, which the Sling environment defines to vary from 0 to 1 as a plot unfolds. Here is the implementation of T.f ():

 public Point f(double t) {      return new Point(t, t); } 

16.8.12 Variable

A variable is a named place that can store another function. The Variable class is a subclass of SlingFunction , which allows functions to compose themselves from other functions. During the execution phase, term objects evaluate themselves into function objects that do not contain variables . It is an error to ask a variable for f(t) because this function applies only in the drawing phase. Here is the implementation of Variable.f(t) :

 public Point f(double t) {      throw new InternalError(); } 

   
Top


Building Parsers with Java
Building Parsers With Javaв„ў
ISBN: 0201719622
EAN: 2147483647
Year: 2000
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net