PSC Applet Description

Please go to the applet after glancing at this page to learn how to use it.


The psc applet interface

On start-up the applet should resemble the diagram. The labeled components of the interface are explained one-by-one below, but first we describe how to enter commands for psc to execute and how to view the output.

Entering Commands

There are two ways of entering commands. The first method is to type a line of text into the "Command Line" and then press the return key. When you press the return key, the text that you entered is appended to the History Buffer and then parsed and executed. The Command Line is also cleared to make room for you to enter your next command.

The list of previous commands saved in the History Buffer may be traversed from the Command Line by using the up-arrow or ^U to go up in the history and the down-arrow or ^D to go down. (On some platforms either the arrow keys or the control keys may not function properly.) A command recalled from the History Buffer may be executed by pressing the return key as if it had been typed afresh.

The second method of entering commands is to execute them directly from the History Buffer. You may freely edit the text in the History Buffer. Any tract of text in the History Buffer can be executed by first selecting the text and then clicking the button labeled "Run Selection". This works whether the tract of text consists of text entered directly into the History Buffer or of text automatically appended from the Command Line by the history mechanism, and the tract may contain any number of lines of text.


The psc applet has two output modes: "Text" and "Canvas". A button labeled either "Text" or "Canvas" allows you to switch between modes. The contents of each output mode are preserved when you switch modes and will be restored when you return. The button labeled "Clear Output" will clear the current mode's output, but will not affect the output of the other mode.

The only way to create Text mode output is via the print and println commands or by executing a bare expression whose value is automatically printed. On the other hand there is a great variety of graphics routines that operate on the Canvas mode output. Most of these routines are named after equivalent Java routines.

Each of the modes automatically flushes its output when command execution completes. To flush text output in the middle of a long command use the pre-defined procedure "flush()". To flush graphics output use the pre-defined procedure "repaint()"; this is particularly useful for animation. (There is also a pre-defined procedure "sync()".)

Component Descriptions

History Buffer
A scrolling text area to which commands entered from the command line are appended. You may freely edit its text. Commands may be executed from this component using the "Run Selection" button as described in the Entering Commands section.
Command Line
A text field in which one line of text may be typed and then executed by pressing the return key as described in the Entering Commands section.
Buttons and Controls
"Run Selection" button
Causes the text currently selected in the History Buffer to be parsed and executed.
"Interrupt" button
Interrupts execution of the current command.
"Clear Output" button
Clears the output of the active output mode.
"Clear History" button
Clears the History Buffer.
"Text" or "Canvas" button
Toggles the output mode.
"Load Resource" button
Loads the URL in the Resource Choice box and parses and executes it.
Resource Choice box
Offers a list of resources that may be loaded.
Has two modes: "Text" and "Canvas" as described in the Output section.

The syntax of psc

The syntax of psc is specified by the CUP grammar psc.cup, which those familiar with CUP or yacc may find interesting. The formated man page for the C version of psc may also be helpful. Certain features of the syntax are listed below.

Special Symbols

A number of symbols have special meaning to psc. Most are operators; a list by precedence appears below. All binary operators use infix notation, as in 2 + 3 or 3.2 * 45, not prefix or postfix (RPN) notation. The assignment, ?:, and exponentiation operators are right-associative. All others are left-associative.

Operators listed by precedence

The other special symbols not listed above are
( ) { } [ ] @ $ ; \n , \ # " '
A pair of parentheses (()) is used to group expressions and for function or procedure invokation or definition. A pair of braces ({}) groups a list of statements so that they form only one statement, syntactically. The at symbol (@) is a special variable that is always set to the value of the last expression that was automatically printed. The semicolon (;) and newline (\n) are statement separators. The comma (,) separates elements of routine argument lists, of routine local variable declarations, and of print lists. The dollar sign ($) is used within the body of a routine definition to access arguments. The backslash (\) escapes newlines. Everything following a number sign (#) on a line is treated as a comment and ignored. The double-quote (") or single quote (') is used to quote strings in a print list.

All values in psc are double-precision floating point numbers and can be entered in the usual manner using any of the digits zero through nine and the decimal point, or in scientific notation with the character e or E separating the mantissa from the exponent. (For example 4.32e6 is equivalent to four million, three hundred twenty thousand.) psc also supports variables, functions, and procedures. Variable, function, and procedure names, or identifiers, may all contain any upper- or lower-case letter, the underscore character (_), and, except as the first character of the name, any of the digits zero through nine. Identifiers may be arbitrarily long. In identifiers, all characters and case are significant. Function and procedure identifiers must be defined as such before they can be used. Variable identifiers need no declaration. Some identifiers already have special meaning to psc.

Special Identifiers

The identifiers that have special meaning to psc are listed below. They fall into several catagories. The keywords are terms that have special syntactic significance to psc; most should be familiar from other programming languages. The constants are essentially pre-defined variables that cannot be redefined. Some of the constants represent commonly used mathematical constants, while others represent common colors in RGB format for use by graphics routines. The built-in functions are all functions that return a value and take a single argument; most are of a mathematical nature. They cannot be redefined. The pre-defined functions and procedures are new to the Java version of psc. Like built-ins, the pre-defined functions and procedures cannot be redefined, but unlike builtins they can take any number of arguments (though some will complain if they expect more than you give). The basic graphics capabilities of psc are all accessed through this type of procedure or function. Finally, the pre-initialized functions and procedures are quite different from all of the above. This class of routines is redefinable. In fact they are not written into the code for psc, but instead their definitions are written in psc's language and saved in initialization files (an init file and a graphics init file) that are read on start-up.

List of special identifiers

proc, func, return, if, else, while, print, read, for, repeat, until, unless, to, downto, println, step, then, do, exit, quit, div, mod, rem, and, or, not, by, version
Built-in functions
sin, asin, arcsin, sinh, cos, acos, arccos, cosh, tan, atan, arctan, tanh, cot, sec, csc, log, log10, exp, sqrt, int, trunc, abs, ceil, floor, round, rand, erf, erfc,
Pre-defined functions and procedures
sleep, atan2, arctan2, getDate, getDay, getMonth, getYear, getHours, getMinutes, getSeconds, flush, array1, array2, array1_2swap
Pre-defined graphics functions and procedures
drawLine, drawArc, drawOval, drawRect, drawRoundRect, fillArc, fillOval, fillRect, fillRoundRect, clearRect, getColor, setColor, setPaintMode, setXORMode, canvasWidth, canvasHeight, repaint, getBackground, setBackground, getForeground, setForeground, RGBtoHSB, HSBtoRGB, sync, getScreenResolution, getPixelSize, setOrigin, setOriginRelative, getOriginX, getOriginY, clipRect, setClip, copyArea, newPolygonPoint, addPolygonPoint, drawPolygon, fillPolygon, drawPolyline, lastPolygonPointX, lastPolygonPointY, getRed, getGreen, getBlue
Pre-initialized functions and procedures (see the init file)
fac, choose, pascal, base, binary, octal, hex, badfib, fib, gcd2, gcd, lcm, relprime, ack, stirl, digits, sum, av, geoav, var, dev, d6, inv, easter, factor1, factor2, factor, isprime, cf, cv, mand, manset, syra, con, fejer, poisson, gaussian, intfunc, midint, simpint, trapint, integrate, normerf, normerfc
Pre-initialized graphics functions and procedures (see the graphics init file)
drawstar, graphfunc, graph, smileyface, clearsmileyface, animatesmileyface, rgb, rainbow


To learn how to use psc to accomplish what you would like, you can do no better at the moment than to study the init file and graphics init file or other examples. As additional guidance, several peculiarities of the language are pointed out here.

functions and procedures: The difference between a function and a procedure is that a function must return a value and can be invoked in an expression, while a procedure cannot return a value and its invokation is syntactically a statement. (A procedure is like a function returning type void in some programming languages.) Functions and procedures are collectively called routines. Either type of routine is invoked, or called, in a manner similar to that used by many other programming languages: the name of the routine is followed by a pair of parentheses, which may enclose a list of arguments. Routines may call themselves recursively.

The syntax for defining a routine is somewhat idiosyncratic. Consider the definitions:

func foo() return $1^2+2*$2
proc bar() {
  println "procedure bar()"
  println "called with ",$," argument(s)"
First comes the keyword func or proc indicating the type of the routine. Next is the routine name and a pair of parentheses. The body of the routine, consisting of one statement or a group of statements enclosed in braces (which is the same thing) follows. Within the body of the routine, the symbols $1, $2, etc., behave like variables initialized to the value of the first argument, second argument, etc. The arguments to the routine may be assigned to. Within the body, the symbol $ behaves like an expression whose value is the number of arguments the routine was invoked with. Routines may declare local variables in a comma-separated list between the parentheses in the definition. For example
func sum(i,total) { for i = 1 to $ total += $[i]; return total }
defines two local variables named i and total, which are independent of the (global) variables with the same names. Each invokation of the routine gets its own copy of the local variables. Local variables are always initialized to 0. Notice that the $[i] construction is another way to access the arguments to the routine.

for statements: There are two very different forms of the for statement commonly used in programming languages that are both available in psc. Both of the statements

for (i=1; i<=20; i++) println i
for i = 1 to 20 println i
print the numbers 1 to 20 in order. The first version is C (and Java) syntax. The second version has many variations: to may be downto, or "step x" or "by x" may be used to indicate that the for-increment is x.

statement separators: Because psc is designed for interactive use, it does not require that a semicolon (;) end each statement. Instead newlines and semicolons are interchangeable as statement separators. When a newline appears, the code up to that point is parsed and executed (if it is composed of complete, legal statements). This is often very convenient, but leads to some strange behavior with if-else statements in particular. The following is not legal syntax:

if (E < PI) println "E is less than PI"
else println "E is not less than PI"
The second line is illegal because the newline at the end of the first line causes it to be interpreted as a new statement, and of course a statement cannot begin with "else". If you enter the above two lines into psc interactively, then the first line will be executed and will print "E is less than PI" (because it is) before you even get a chance to enter the second line. There are several ways to write what is intended by the above example legally:
if (E<PI) println "E is less than PI" else println "E is not less than PI"

if (E<PI) {
  println "E is less than PI"
} else {
  println "E is not less than PI"

if (E<PI) println "E is less than PI" \
else println "E is not less than PI"
The first alternative avoids breaking the if-else statement into two statements by writing it entirely on one line. (Note that a semicolon must not appear before the else!) The second uses braces to continue the statement to multiple lines. Finally, the third uses a backslash (\) to escape the newline at the end of the first line so that it does not serve as a statement separator.

print statements: The syntax for print statements is convenient but somewhat arcane. A quick summary:

For example the statements
println 15,15^2
println 15,,15^2
println "a",15:4,"b"
println "a",15:-4,"b"
println PI::3,,PI:8:3,"b"
produce the output
15 225
a  15b
a15  b
3.142 3.142   b
Notice that PI was rounded from 3.14159....

automatic printing of expressions: An expression entered on a line by itself is evaluated and automatically printed. Its value is also stored in the special variable @. This variable is assumed as the first operand of the operators +, *, /, %, ^, ** when any of them appears as the first element of an input line.

Example code

The examples show that psc is in fact a very versatile tool. The first group of examples consists of the initialization files. The first two are read and processed by psc on start-up. The third is read and put into the History Buffer on start-up.


A number of resources are available from the applet. These are simply files of psc code that are loaded and processed by psc when you click the "Load Resource" button. Be sure first that the resource that you want to load is selected in the Resource Choice box.

One of the resources is a file defining routines to calculate the particulars of a loan.

It is essentially the concatenation of the two files loan.psc and newton.psc. Once loaded, the routines defined in this resource will be available for you to use, and there is no point in reloading this resource.

The remaining resources are files containing psc code to generate interesting images for the canvas output mode.

The "slow" versions are not much slower--their purpose is to show how the images are built-up incrementally. Sample output and an explanation of the source of the code is below in the Images created with psc section.

Images created with psc

Below are several examples of images generated by psc.

Three of the images were produced by psc code translated semi-automatically from Postscript code. The Postscript code was extracted from issues of the tri-monthly electronic magazine Feng Hua Yuan and was presumably generated by Adobe Photoshop or some such graphics design tool. While psc cannot serve as a general Postscript interpreter, a simple awk script was able to convert the specially formatted Postscript code to psc code for these examples.

Most of the remaining images are images of the Mandelbrot set that were generated by psc procedures defined in the graphics init file.

The last image is a GIF animation of the numerical solution of a certain nonlinear hyperbolic PDE with data from a particle simulation for which the PDE is the hydrodynamical equation superimposed on it.

Leif Jensen / Courant Institute of Mathematical Sciences, NYU /,