QMBasic - Expressions and operators

QMBasic  -  Expressions and Operators

Top  Previous  Next

 

A QMBasic expression consists of one or more data items (constants or variables) linked by operators.

 

constantUse constant value (string or numeric)
varUse value of named variable
var[s,n]Extract n character substring starting at character s of var
var[n]Extract last n characters of string var
var[d,s,n]Extract n consecutive sections of string var delimited by character d, starting at section s.
var[s,*]Extract from character n onwards of string var
var[d,s,*]Extract all sections of string var delimited by character d, starting at section s.
var<f>Extract field f of dynamic array variable
var<f,v>Extract field f, value v of dynamic array variable
var<f,v,s>Extract field f, value v, subvalue s of dynamic array variable
var{path}Extract the data collection element with the given element path
func(args)Use the returned value from a function which may take arguments

 

In all cases above, var may be a matrix reference, for example

 

var(r,c)[s,n]

 

where r and c are expressions which evaluate to the desired matrix row and column index values.

 

There is also a special conditional item of the form

 

IF conditional.expr THEN expr.1 ELSE expr.2

 

where conditional.expr is evaluated to determine whether the overall value is that of expr.1 or expr.2.

 

The Boolean (True/False) values used by QMBasic are stored internally as a Boolean data type, however, use of a Boolean value in an operation that requires a numeric value converts True to one and False to zero.

 

The Boolean constant values are available as @TRUE and @FALSE for use in programs and dictionary I-type expressions.

 

 

The substring extraction operation x[s,n] extracts n characters starting at character s of the string x. Character positions are numbered from one. Thus

A = "abcdefghijkl"

Z = A[5,3]

sets Z to the string "efg".

 

If the bounds of the substring extend beyond the end of the string from which it is to be extracted, the result is truncated. Trailing spaces are not added to make up the shortfall. A start position of less than one is treated as one.

 

Specifying the number of characters, n, as an asterisk extracts from character s onwards, regardless of the length of the string.

A = "abcdefghijkl"

Z = A[5,*]

sets Z to the string "efghijkl".

 

 

The trailing substring extraction operation x[n] extracts the last n characters of the string x. Thus

A = "abcdefghijkl"

Z = A[3]

sets Z to the string "jkl".

 

If the length of the substring to be extracted is greater than the length of the source string, the entire source string is returned.

 

 

The third form of substring extraction, known as group extraction, is of the form var[d,s,n]. It treats var as being made up of a series of sections delimited by character d and returns n consecutive sections, starting at section s. See the FIELD() function for an alternative syntax.

 

 

The field extraction operator x<f,v,s> extracts field f, value v, subvalue s from the source string x. If s is omitted or zero, field f, value v is extracted. If v is omitted or zero, field f is extracted. Thus

x<2>extracts field 2
x<2,7>extracts field 2, value 7
x<2,7,3>extracts field 2, value 7, subvalue 3

 

 

The operators of QMBasic are set out in the table below. The numbers in the right hand column are the operator precedence, the lower valued operators taking precedence in execution. Operations of equal precedence are processed left to right. Round brackets may be used to alter the order of execution or to improve readability of complex expressions.

 

+

Unary plus

0

-

Unary minus

0

~

Unary bitwise not

0

< >

Dynamic array extraction

1

[ ]

Substring extraction

1

{ }

Collection element reference

1

** or ^

Exponentiation (raising to power)

2

*

Multiplication

3

/

Division

3

//

Integer division

3

+

Addition

4

-

Subtraction

4

 

Implicit format (See FMT() function)

5

:

Concatenation

6

<

Less than

7

>

Greater than

7

=

Equal to

7

==

Case sensitive string equality

7

~=

Case insensitive string equality

7

#

Not equal to

7

<=

Less than or equal to

7

>=

Greater than or equal to

7

MATCHES

Pattern match (see below)

7

AND

Logical AND

8

OR

Logical OR

8

.&

Bitwise logical AND

8

.!

Bitwise logical OR

8

 

 

The following alternative logical and relational operator formats may be used

<

LT

 

 

>

GT

 

 

=

EQ

 

 

#

NE

<>

><

<=

LE

=<

#>

>=

GE

=>

#<

MATCHES

MATCH

 

 

AND

&

 

 

OR

!

 

 

 

The relational operators are defined such that, if the two items to be compared can both be treated as numbers, a simple numeric comparison is performed. If one or both items cannot be treated as numbers, they are compared as left aligned character strings. The COMPARE() function can be used to force a string comparison that returns a value indicating the collating sequence relationship of the two items being compared.

 

If a program is compiled using the $NOCASE.STRINGS directive, string comparisons are case insensitive. The == operator can be used to force a case sensitive comparison. Conversely, in program compiled without this directive, the ~= operator can be used to force a case insensitive comparison.

 

Note:  The language syntax includes an ambiguity with the use of the < and > characters as both relational operators and in dynamic array references. For example, the statement

A = B<C> + 0

could be extracting field C from dynamic array B and adding zero to it (to force it to be stored as a numeric value) or it could be testing whether B is less than C and the result of this comparison is greater than zero. In cases such as this, the compiler looks at the overall structure of the statement and takes the most appropriate view. Use of brackets when mixing relational operators with field references will always avoid possible misinterpretation.

 

 

The MATCHES operator matches a string against a pattern consisting of one or more concatenated items from the following list.

 

...Zero or more characters of any type
0XZero or more characters of any type
nXExactly n characters of any type
n-mXBetween n and m characters of any type
0AZero or more alphabetic characters
nAExactly n alphabetic characters
n-mABetween n and m alphabetic characters
0NZero or more numeric characters
nNExactly n numeric characters
n-mNBetween n and m numeric characters
"string"A literal string which must match exactly. Either single or double quotation marks may be used. Backslashes may not be used as string quotes in this context.

 

The values n and m are integers with any number of digits. m must be greater than or equal to n.

 

The 0A, nA, 0N, nN and "string" patterns may be preceded by a tilde (~) to invert the match condition. For example, ~4N matches four non-numeric characters such as ABCD (not a string which is not four numeric characters such as 12C4).

 

A null string matches patterns ..., 0A, 0X, 0N, their inverses (~0A, etc) and "".

 

The 0X and n-mX patterns match against as few characters as necessary before control passes to the next pattern. For example, the string ABC123DEF matched against the pattern 0X2N0X matches the pattern components as ABC, 12 and 3DEF.

 

The 0N, n-mN, 0A, and n-mA patterns match against as many characters as possible. For example, the string ABC123DEF matched against the pattern 0X2-3N0X matches the pattern components as ABC, 123 and DEF.

 

The pattern string may contain alternative templates separated by value marks. The MATCHES operator tries each template in turn until one is a successful match against the string. If a match is found, the INMAT() function can be used to retrieve the value position within the pattern that matched.

 

As an example of the MATCHES operator, the statement

IF S MATCHES "1N0N'-'1N0N" THEN PRINT "OK"

would print OK when S contains one or more digits followed by a hyphen and one or more digits. Note the use of 1N0N to ensure that at least one digit is present.

 

 
The content of two dimensioned matrices may be compared using

MAT matrix1 = MAT matrix2

as a Boolean element in, for example, an IF statement. The only valid relational operators in this usage are equals and not equals.

 

 

Partial Expression Evaluation

 

The default behaviour of QM, in common with many other multivalue database products, is that a logical expression is always completely evaluated before taking any action conditioned by it. For example,

IF IDX MATCHES '1-2N' AND S<IDX> # 0 THEN ...

will test the value of S<IDX> regardless of whether the value in IDX is numeric or not. This would lead to a run time error if IDX is not numeric.

 

Use of the PARTIAL.EXPRESSIONS setting of the $MODE compiler directive causes logical expression evaluation to terminate as soon as the result can be determined. For a non-numeric value in IDX, the above example would skip the test of S<IDX>.

 

The difference between these two methods of evaluation is also important if the expression includes a reference to a function that has a side effect. For example,

IF X = 1 AND REMOVE(STR, CODE)

In the default mode of operation, the REMOVE() function is executed regardless of the content of X. With the PARTIAL.EXPRESSIONS mode, the REMOVE() function is only executed if X is 1.

 

 

See also:

Data collections, Pattern Matching