« PreviousContinue »
Since the program can't know when it has ended (although it can know when it hasn't), you must assure that the programs terminate at the right time.
PRINTing And Simple Assignment (LET)
This group of programs examines the ability of the implementation to print strings and numbers correctly. Both constants and variables are tested as print-items. The variables, of course, have to be given a value before they are printed, and this is done with the LET statement.
PRINT is among the most semantically complex statements in BASIC. Furthermore, the PRINT statement is the outstanding case of a feature whose operation cannot be checked internally. The consequence is that this group calls for the most sophisticated user interpretation of any in the test sequence. Please read carefully the specifications in the programs, section 12 of the ANSI standard, and this documentation; the interpretation of test results should then be reasonably clear.
The emphasis in this group is on the correct representation of numeric and string values. There is some testing that TAB, comma, and semi-colon perform their functions, but a challenging exercise of these features is deferred until group 14.6 because of the other features needed to test them.
The PRINTing of strings is fairly straightforward and should be relatively easy
to check, since there are no implementation-defined features which affect the printing. The only possible problem is the margin width. The program assumes a margin of at least 60 characters with at least 4 print zones. your implementation supports only a shorter margin, you must make due allowance for it. The standard does not prescribe a minimum margin.
The string overflow test requires careful interpretation. Your implementation must have a defined maximum string length, and the fatal exception should occur on the assignment corresponding to that documented length. If the implementation supports at least 58 characters in the string, overflow should not occur. Be sure, if there is no overflow exception report, that the processor has indeed not lost data. Do this by checking that the output has not been truncated. A processor that loses string data without reporting overflow definitely fails.
Checking for a TAB exception is simple enough; just follow the conditional pass/fail messages closely. Note that one section of the test should not generate an exception since, even itself is less than one, its value becomes
though the argument one after rounding.
Numeric constants And
In the following discussion, the terms "significand" Mexrad", "explicit point", "implicit point", and "scaled" are used in accordance with the meaning ascribed them
the ANSI standard.
The rules for printing numeric values are fairly elaborate, and, moreover, are heavily implementation-dependent;
accordingly conscientious scrutiny is in order. There are two rules to
keep in mind. First, the expected output format depends on the value of the print-item, not its source format. In particular, integer values should print as integers as long as the significand-width can accommodate them, fractional values should print in explicit point unscaled format where no loss of accuracy results, and the rest should print in explicit point scaled format. For example "PRINT 2.1E2" should produce "210" because the item has an integer value, even though it is written in source code in explicit point scaled format. Second, leading zeros in the exrad and trailing zeros in the significand may be omitted.
for an implementation with a significand-width of 8 and an exrad-width of
the value 1,230,000,000 could print as "1.2300000E+009" at one extreme or "1.23E+9" at the other. The tests generally display the expected output in the latter form, but it should be understood that extra zeros can be tacked on to the actual output, up to the widths specified for the implementation.
The tests in general are oriented toward the minimum requirements of six decimal digits of accuracy, a significand length of six and an exrad-width of two. You must apply the standard requirements in terms of
your own implementation's widths, however.
This group checks that the simple control structures all work when used in a simple way. Some of the same facilities are checked more rigorously in later groups. As with PRINT, END and STOP, these features must come early in the test sequence, since a BASIC program cannot do much of consequence without them. If any of these tests fail, the validity of much of the rest of the test sequence is doubtful, since following tests rely heavily on GOTO, GOSUB, and IF. Note especially that trailing blanks should be significant in comparing strings, e.8. "ABC" <> "ABC Subsequent tests which rely on this property of IF will give false results if the implementation doesn't
process the comparison properly.
The tests for GOTO and GOSUB exercise a variety of transfers to make sure the processor handles control correctly. If everything works, you should get intelligible, self-consistent output. If the output looks scrambled, the test has failed. There are no helpful diagnostics for failures since it
is impossible to anticipate exactly how a
processor might misinterpret transfers of control. Look carefully at the sample output for the GOTO and GOSUB programs in Volume 2, to know what to expect.
The IF... THEN tests use a somewhat complex algorithm, so pay attention to the REM statements if you are trying to understand the logic. On the other hand, these tests are easy to use because they are completely self-checking. You need only look for the pass/fail messages to see if they worked. It is worth noting that the IF... THEN test for numeric values depends on the validity of the IF... THEN test for strings, which comes just before.
The error tests are understandable in light of the rules for interpretation of error programs given earlier.
The first of these programs simply checks that the set of valid names is as guaranteed by the standard. In particular, A, AO, and A $ are all distinct. There are no diagnostics for failure, since we expect failures to be rare and it is simple enough to isolate the misinterpretation by modifying the program, if that proves necessary. A later test in group 8.1 tests that the implementation fulfills the requirements for array names.
Default initialization of variables is one of the most important aspects of semantics left to implementation definition. Implementations may treat this however they want to, but it must be documented, and you should check that the documentation agrees with the behavior of the program. Thus this is not merely an informative test: the processor must have correct documentation for its behavior in order to conform.
Numeric constants, Variables, And Operations
This group of programs introduces the
of numeric expressions, specifically those formed with the arithmetic operations ( +,
^) provided in BASIC.
The most troublesome aspect of these tests is the explicit disavowal in the standard of any criterion of accuracy for the result of the operations. Thus it becomes somewhat difficult to say at what point a processor fails to implement a given operation. We finally decided to require exact results only for integer arithmetic, and, in the case of non-integral operands, to apply an extremely loose criterion of accuracy such that if an implementation failed to meet it, one could reasonably conclude either that the precedence rules had been violated or that the operation had not been implemented at all.
Although the standard does not mandate accuracy for expressions, it does require that individual numbers be accurate to at least six significant decimal digits. This requirement tested by assuring that values which differ by 1 in the 6th digit actually compare in the proper order, using the IF statement. The rationale for the accuracy test is best explained with an example: Suppose we write the constant "333.333" somewhere the program. For
digits of accuracy to be maintained, it must evaluate internally
some value between 333.3325 and 333.3335, since six digits of accuracy implies an error less than 5 in the 7th place. By the same reasoning, "333.334" must evaluate between 333.3335 and 333.3345. Since the allowable ranges do not overlap, the standard requires that 333.333 compare as strictly less than 333.334. Of course this same reasoning would apply to any two numbers which differed by 1 in the sixth digit.
The accuracy test not only assures that these minimal requirements are met, but also attempts to measure how much accuracy the implementation actually provides. It does this both by comparing some numbers in the manner described above for 7, 8, and 9 decimal digits, and also by using an algorithm to compute any reasonable internal accuracy. Since such an algorithm is highly sensitive to the peculiarities of the system's implementation of arithmetic, this last test is informative only.
The standard specifies a variety of exceptions for numeric expressions. All the mandatory non-fatal exceptions occur when machine infinity is exceeded and
they all call for the implementation to supply machine
infinity as the result and continue execution. The tests ensure that machine infinity is at least as great as
the guaranteed minimum of 1E38, but since machine infinity is implementation-defined, you must assure that the value actually supplied is accurately documented.
It is worth repeating here the general guidance that the timing of exception reports is not specified by the standard. The wording is intentionally imprecise to allow implementations to anticipate exceptions, if they desire. Such anticipation may well occur for overflow and underflow of numeric constants; that an implementation
may issue the exception report before execution of
the program begins. Note that the recovery procedure, substitution of machine infinity for overflow, remains in effect.
Underflow, whether for expressions or constants, is only recommended
exception, but, in any case, zero must be supplied when the magnitude of the result is below the minimum representable by the implementation. Note that this is required in the semantics sections (7.4 and 5.4) of the standard, not the exception sections (7.5 and 5.5).
These programs try out the effect of various constructions which represent either
common programming errors (missing parentheses) or common enhancements
as the involution operator) or a blend of the two (adjacent operators). No special interpretation rules apply to these tests beyond those normally associated with error programs.
Although the standard mandates no particular accuracy
for expression evaluation, such accuracy is nonetheless an important measure of the quality of language implementation, and
to a large proportion of language users. Accordingly, these tests apply a criterion of accuracy for the arithmetic operations which is suggested by the standard's requirement that individual numeric values be represented accurate
to six significant decimal digits. Note, however, that these tests are informative, not
strict accuracy requirement, but also because there is no generally valid way for а computer to measure precisely the accuracy of its own operations. Such a measurement involves calculations which must use the very facilities being measured.
The criterion for passing or failing is based on
on the concept that
least as accurate as a reasonable hypothetical implementation which uses the least accurate numeric representation allowed by the standard. It is best explained by first considering accuracy for functions of
a single variable, and then generalizing to operations, which may be thought of as functions of two variables. Given an internal precision of at least d decimal digits, we simply require that the computed value for f(x) (hereinafter denoted by "cf(x)") be some value actually taken on by the function within the domain [x-e,x+e), where
(int (log 10 ( abs (x))) + 1
For example, suppose we want to test the sin (29.1234) and we specify that d=6. Then:
e = 10 (int (10g10 (29.1234)) + 1 - 6)
10 ^ (int (1.464) 5)