DBM Scripting Basics
What is a Script?
A DBM script is made up of more or less human readable text. It can be created with a simple text editor such as notepad.exe and stored in a plain text file.
Scripts consist of instructions which must strictly follow the rules laid out in this manual. Entities which you will encounter in a script are:
instructions
functions and procedures
variables
Case Sensitivity
In the majority of cases, scripts are case sensitive, i.e. upper and lower case character stand for different entities; myFunc
and MyFunc
are two different things. There are a few exceptions to this rule; however, you should make it a habit to be consistent in your casing, and to not create two names which are different in case only.
Variables
A variable is a place to store a value; it has a name by which it can be referred to. Values can be calculated in the script, or they can result from function calls or, in some cases, from external entities.
Variables have a name, a scope (the part of the script in which they are visible), a type, and a value. The name and scope are defined by the place where a variable is used for the first time; type and value can change dynamically.
Name
The name of a variable starts with a prefix which is either a dollar sign ($
) or a per cent sign (%
). The prefix is followed by an alphabetic character (A
-Z
, a
-z
) or underscore (_
), and then a sequence of alphabetic characters, decimal digits (0
-9
), and underscores of virtually unlimited length.
Variables must have unique names within their respective scopes. Upper and lower case characters are treated equal, so that $myVar
and $Myvar
refer to thee same variable.
A dollar prefix creates a variable that has global scope, i.e. it can be referred to from every position in the script.
A per cent prefix creates a local variable. Its scope begins where it is used for the first time, and ends at the curly brace which terminates the block in which it was used for the first time.
Type and Value
When you store a value in a variable, this value can either be a “string”, i.e. a sequence of alphabetic, numeric, typographic and other characters, of virtually unlimited length; or it can be a “number”, i.e. an integer value in the range from -2147483647 to 2147483648. The type is determined by the value. For example, by storing “23” in a variable, its type is set to “number” and its value to twenty-three. When you, later, store “abc” into the same variable, its type changes to “string”.
Scope
A variable’s scope defines from which places in a script the variable is known. A variable’s scope normally starts on the line where the variable for the first time is assigned a value, and ends at the closing curly brace which follows this first assignment, or at the end of the script if no right brace follows.
As a consequence, known variables are “imported” into instruction blocks within their scope.
%var = 1
if (%x == 0)
{
%var = %var + 1
%othervar = 3
}
In the above example, the variable %var
is first assigned in line 1, in the outer-most scope. The instruction block in lines 3 through 6 defines its own scope, but imports %var
, so that the expression %var+1
can be evaluated, and the assignment stores the value in the same %var
. On the other hand, %othervar
is assigned for the first time in line 5, and its scope ends on line 6. At this point, %othervar
is removed, so that this assignment has no effect.
This general rule has two exceptions.
Function Scope
Instructions that make up the body of a function do not import local variables from a surrounding block.
%i = 1
function Get_i()
{
return %i // %i is unknown here; execution of this line produces an error
}
Get_i()
Global Scope
Variables whose name starts with the $
(dollar sign) prefix are globally scoped. That means, once a value is assigned to such variable, it can be retrieved anywhere in a script.
Instructions
An instruction tells the script processor to do something. This “something” can be the calculation of an arithmetic value, the manipulation of a value in a database, display of a message in the screen, and many more things.
Instructions are processed top-to-bottom, i.e. starting with the first line in the script and proceeding line by line until the end of the script is reached. When the last instruction has been executed, script processing stops. Each Instruction usually takes one line in the script, with a few exceptions listed on this page.
A special subgroup of instructions serves to change the top-to-bottom flow of script processing. While some of them skip over a block of instructions if a condition is or isn’t fulfilled, others divert the flow to a different place in the script (“function call”) or return from this diversion to the place where it took place. Another instruction allows repeated execution of a block of instructions (“loop execution”).
More than One Statement per Line
At times you may want to place two or more statements on a single line. You can do that when you separate the statements with semicolons (;
).
Statements that Extend over Several Lines
Some statements are allows to extend over more than one line. Rules are under investigation.
Instruction Blocks
An instruction block is a sequence of instructions, enclosed in a pair of curly braces. Some contexts mandate the use of a function block. Function blocks create a new scope for local variables (see the “Variables” section on this page for more details).
Comments
A comment is text which is not relevant to macro execution; it provides information to the human reader of the macro.
It is introduced with two forward slashes anywhere on a macro line (except within a string literal), and extends to the end of the line.
%myVar = 23 // Storing 23 into my variable
Constants
A constant is something that cannot change. In the context of a DBM script, a constant is a value that is interpreted as-is. For example, a 76
is interpreted as the number seventy-six, no matter what the circumstances may be.
DBM scripting knows two type of constants, numbers and strings. String constants can be written in three different ways.
Number Constants
A number constant (also called “numeric constant” or “integer constant”) consists of an uninterrupted sequence of decimal digits (0
-9
), optionally prefixed with a minus sign (-
). It is interpreted exactly as a human would read it. The constant 2023
, for example, is interpreted as "two thousand and twenty-tree."
It is not possible to specify numeric values with decimal places, like “19.4”.
String Constants
A string constant represents a sequence of alphabetic, numeric, or punctuation characters of arbitrary length. There are three ways of writing a string constant:
Enclose the string in double quotation marks, like so:
"This is a string constant."
Don't use "typographic" quotation marks which are places automatically by popular word processors when you hit the"
key.Since the first method doesn't allow for strings that contain double quotation marks, there is an alternate set of string delimiters:
\{{This string contains "quotation marks."\}}
The opening delimiter is a backslash followed by two left curly braces, and the closing delimiter is a backslash followed by two right curly braces.Finally, any uninterrupted sequence of purely alphanumeric characters (or underscores) whose first character is alphabetic, and which is not the name of a procedure or function, is interpreted as a string constant:
TAKE_5
Embedding Line Breaks in a String Constant
One of the common uses of strings is to create output to the user. To format this output, you may want to break text lines. You can include a line break in a string constant by simply continuing the string constant on the next line.
%text_with_newline = "This text
is displayed on two lines"
Value Assignments
To store a value into a variable, or in other words, to “assign a value to a variable,” you use an assignment instruction. You write the variable name, an equals sign (=), and the value, like this:
$output = "Hello world!"
%value = 42
These examples assign use constant values (a string and a number) to variables. However, the value can be the result of a computation which may involve function calls and references to other variables.
%minValue = max(%currentValue, 1)
Read more about arithmetic and logical operations and about functions in the following sections.
Computing Values
Arithmetic Operations and String Concatenation
The previous section showed how you can assign a simple value to a variable. But there’s more you can do.
You can use the value stored in a variable, perform some calculations with it, and assign the result to another (or to the same) variable. Arithmetic operations are usually quite easy to understand:
%i = 1
%j = %i + 1 // %j is now 2
%k = 2 * %j + 6 // %k is now 10
%n = %k / 2 - 1 // %n is now 1
%i = %j * %k + 1 // %i i now 21
%j = %j * (%k + 1) // %j is now 22
These examples show the basic arithmetic operations (addition, subtraction, multiplication, division) and how they are represented in a script. The also show operator precedence (* and / go before + and -) and how to use round parentheses to override precedence.
A “number” in the context of DBM scripting always means a whole number, also called “integer”, i.e. a number with no decimal point. It can be positive like 1, 2, 3, …, or negative like -1, -2, -3, …, or zero (0). The range is limited from -2147483648 to 2147483647.
An arithmetic addition (e.g. %i + %j
) can only be preformed when both operands contain numbers. However, when both operands contain strings, the expression %i + %j
is interpreted as concatenation, i.e. the content of the right string is joined to the end of the left string. This also works if operands are string constants.
%x = "Hel"
%y = %x + "lo" // %y now contains "Hello"
%z = "world"
%r = %y + " " + %z // %r now contains "Hello world"
This feature is unique to the +
operator. Subtraction, multiplication, and division cannot be executed in strings, and addition/concatenation doesn’t work if one operand is a string and the other operand is a number.
Arithmetic operation | Operator |
---|---|
addition |
|
subtraction |
|
multiplication |
|
division |
|
string concatenation |
|
Comparing Values
Sometimes the script code must make a decision based on whether a variable contains a specific value, or contains a value greater or smaller than something else, etc. The scripting language supplies the following comparison operators (note that several operators consist of two characters):
Comparison | Operator |
---|---|
Equal |
|
Not equal |
|
Greater than |
|
Greater than or equal |
|
Less than |
|
Less than or equal |
|
Case-blind equal (see note below) |
|
Contains (see note below) |
|
The “case-blind equal” comparison operates on two string values. The values are considered equal if the only difference is in upper/lower case.
The “contains” comparison also requires two string values. The condition is fulfilled when the right string is contained in the left string.
The result of a comparison is the number 0 if is not fulfilled, or a positive number if it is fulfilled. It can be used directly to control the flow of execution, or you can save it into a variable for later use.
Combining Logical Values
The logic of your script may require that two or more conditions be fulfilled at the same time, e.g. a number should be greater than 0 and less than 9. To achieve this, you can combine two comparisons in an “and” operation: %i > 0 && %i < 9
. The result of this operation is nonzero only if both comparisons hold at the same time.
On the other hand, your condition may be like “the value must be 3 or 6, but nothing else”. Here, the “or” operator comes into play: %value==3 || %value==6
. The “or” operator consists of two vertical bars, which are sometimes called “pipe symbols”.
Finally, you may want to create a condition which is the exact opposite of a condition which you have calculated earlier and saved into a variable. Use the “not” operator ! %cond
(a single exclamation mark).
Logical Operation | Operator |
---|---|
AND: two conditions must be fulfilled |
|
OR: one of two conditions, or both, must be fulfilled |
|
NOT: negation of a condition |
|
Precedence of Operations
Precedence defines the order in which arithmetic and string operations, comparisons, and logical operations are executed. For example, the expression 1+2*3
yields 7 because the multiplication has higher precedence than the addition. The following table lists all operators and their respective precedence.
Precedence | Operator(s) | Note |
---|---|---|
6 |
| Terms in parentheses are evaluated first |
5 |
| Negation |
4 |
| Multiplication, division |
3 |
| Addition, subtraction |
2 |
| Comparisons |
1 |
| Logical operations |
Operations with equal precedence are executed left to right.
Functions and Procedures
Functions and procedures encapsulate (more or less) complex functionality. A function computes a value which it returns as result of its execution, whereas a procedure doesn’t return a value. A function typically computes a value, or fetches a value from the GUI or from the database, and returns the result. Procedures typically write a value into the GUI or into the database and have no result.
The script processor provides a number of predefined functions and procedures. In addition, the scripting language provides the means to create additional functions in the script.
Function and procedure execution is also called “calling a function or procedure,” and the resulting value of a function call is called its “result.”
Examples:
%i = abs(%a - %b) // abs discards the sign of its argument
%smallest = min(%i1, %i2, %i3, %i4) // min returns the smallest value of its argments
For more about functions and procedures, refer toScript Functions and Procedures. An alphabetical list of built-in functions and procedures can be found at Alphabetical List of Built-in Functions and Procedures. See Defining a Script Function for how to define your own functions.