SBL Commands and Functions and the SIMPOL Equivalents
The following table contains an alphabetical list of SBL key words and their SIMPOL equivalent together with some explanatory text describing the differences.
SBL | SIMPOL | Comments | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ASC() | .charval() |
The ASC() function in SBL returns the ASCII (OEM) value of the first
character in the string that is passed as the argument. In SIMPOL the
.charval() function returns the Unicode character value of the first
character in the string passed as the argument.
| ||||||||||||||||||||
BLANK | type(db1table).newrecord() |
Creating a new record in a database in SIMPOL is done by calling the Unlike with SBL, the default formulae are not executed at the point in time of creating a new record, so it is the responsibility of the SIMPOL programmer to perform any default calculations and assign the results to the associated fields. | ||||||||||||||||||||
CALL | !execute() |
The CALL command in SBL that is used to execute external programs has its
equivalent in SIMPOL in the form of the !execute() system function. One
current difference between the two is that the SIMPOL version does not create a shell, so if
you are using it in Windows to call things like the COPY or
DEL commands, you need to call the command shell with appropriate command
line switches or call a batch file that contains the commands instead.
| ||||||||||||||||||||
CHAR$() | .char() |
The CHAR$() function in SBL returns the value passed as an ASCII
(OEM) character. In SIMPOL the .char() function returns a Unicode character
that is the equivalent of the value passed as the argument.
| ||||||||||||||||||||
DATE$() | DATESTR() |
The Table 20.3.
| ||||||||||||||||||||
DAYS | string2date() |
The SBL command DAYS takes either a date or a text containing a date and returns an integer representing the number of days since 01 January, 0001. The SIMPOL version only supports converting a date expressed as a string. It requires a format string in order to know how to process the date. It returns a date object represnting that time. The value of a date object is an integer containing the number of days since 01 January, 0001.
| ||||||||||||||||||||
END | no equivalent |
The SBL command END allows the program to stop executing. In SIMPOL programs
will exit only when the reach an error condition or they exit through the end of the
main() function.
| ||||||||||||||||||||
ERR$() , ERRNO, ERROR, ON ERROR, RESUME, etc. | No equivalent | In SIMPOL there is no error handling in the form of interrupts such as is the case in SBL. Instead, most function calls that can cause an error take an error object and in some cases an error text object. In the case of an error, if the error object has been passed, then the error will be returned in the object. If no object has been passed, then the program will halt at that point with an error. Most syntax errors will be found during compilation and post-processing of the IDE. In some cases errors will occur at runtime but should normally be found during testing. | ||||||||||||||||||||
EXISTS() | fileexists() |
In SBL the EXISTS() function has two variants. One variant checks whether
the argument passed exists as a file in the file system. That functionality is provided for in
SIMPOL by the fileexists() function. The other variant takes a value and an index
and returns whether a record exists with that value in the target database table without changing the current
record pointer in the target index. No exact equivalent exists for this since none is really needed. There
is a function called lookup() that is found in the
appframework.sml library and which takes an index object, a value,
and an error variable and which returns a record object if a match is found, otherwise it returns .nul .
| ||||||||||||||||||||
FCASE$() | .tcase() |
In SBL to convert a string such that only the first character is capitalized the programmer calls
the FCASE$() function; the equivalent in SIMPOL is the
.tcase() (titlecase) function.
| ||||||||||||||||||||
FIX() | .fix() |
The FIX() function is commonly used in SBL to ensure that a floating point
value is as close as possible to a desired number of decimal places as desired (floating point numbers
are not precise because base ten fractions are not reliably representable in binary). In SIMPOL the
more important use of the .fix() function is to truncate the exactly precise but
potentially extremely large number of trailing digits from a value. It would not be uncommon to have
a decimal value as the result of a division operation that had tens, hundreds, or even thousands of
digits trailing the decimal point.
| ||||||||||||||||||||
HRS() | HRS() | There is essentially no difference between these two functions, other than that in SIMPOL the parameter passed must be a time object. In both cases the number of hours in the time are returned as an integer. | ||||||||||||||||||||
IF() | .if() |
There is essentially no difference between these two functions, other than that in SIMPOL the
argument must result in a Boolean value of either .true or
.false , whereas in SBL zero is false and non-zero is considered to be true.
| ||||||||||||||||||||
INSTR() | .instr() | In both SBL. and SIMPOL these functions are used to determine whether some substring can be found in the target string. The only real difference between the two is that the SBL version can take an optional leading parameter that tells the function where in the string to begin looking. The equivalent in SIMPOL is to pass only the portion of the string in which to look, and then to adjust the value returned by adding the offset to the beginning of the substring that was passed. | ||||||||||||||||||||
IS() | =@= |
In SBL the IS() fuction is used to compare if two variables refer to the same
object. In SIMPOL this handled using an operator. This question can be negated in SBL by applying
the NOT to the result of the function. In SIMPOL there are two equivalent
operators for this: !@= and <@>.
| ||||||||||||||||||||
LCASE$() | .lcase() |
In SBL to convert a string to lowercase the programmer calls the LCASE$()
function and in SIMPOL the .lcase() function serves the same purpose.
| ||||||||||||||||||||
LEFT$() | .lstr() | These two functions are essentially identical in their function: they return the portion of the string from the first character until the end of the string or until the position passed whichever is less. | ||||||||||||||||||||
LEN() | .len() | Both in SBL and SIMPOL these functions return the length of the argument passed. One difference is that in SIMPOL this is the length of the argument in characters that are Unicode characters, whereas in SBL these are single-byte ASCII (OEM) characters. | ||||||||||||||||||||
LIKE | .like1() | For the most part the two versions of LIKE work the same. There are a few more options in the SIMPOL version, such as optional case-sensitivity, but otherwise they should be compatible (other than the fact that the SBL version is an operator and the other is a function). | ||||||||||||||||||||
LOAD | !loadmodulefile() |
The SBL LOAD command is used to load program files into memory and is most
commonly used with the , NEW option to load a set of routines into memory for
use by the program. It is also used to load queries, updates, text editor files, function key files,
and labels definitions. Almost all of these latter items are better dealt with in SIMPOL as methods
of the associated object. The function !loadmodulefile() is a SIMPOL system
function for loading a compiled SIMPOL library so that its exported types and functions can be
used. Although it is possible to directly include a library module in the resulting program when
the program is compiled, it may be more efficient in some cases to load the module as needed, for
example when the module may not always be needed.
| ||||||||||||||||||||
LOCK() | ppcstype1file.locked, ppcstype1record.locked, sbme1table.locktype, sbme1record.locktype |
In SBL the LOCK() serves to test whether a given record is locked in a
database file. A similar capability exists in SIMPOL except that what is tested is the value of
a property of the file (table) or record object. One difference in this is that this will only tell
if the user has locked the record or table, it will not tell if others have done so (or even if
another object in the same program has done so).
| ||||||||||||||||||||
LOCK ALL |
ppcstype1file.lock() ,
sbme1file.lock()
| These two items are very similar, other than from an architectural perspective: with one being a command and the others being methods of types. In all cases the file is locked. In the case of the sbme1 type, it is also necessary to hold at least a shared lock on the table in order to create records. | ||||||||||||||||||||
MAX | .max() | The SIMPOL version of this function simply takes an unlimited number of arguments and returns the one that is of the highest value. The SBL version can only be used with arrays or on reports under special circumstances. | ||||||||||||||||||||
MID$() | .substr() |
These two functions are virtually identical, except that in SBL to return everything until the end
of the string, the last parameter is left out, whereas in SIMPOL all three parameters are always
required so to return everything the last parameter can be set to .inf .
| ||||||||||||||||||||
MIN | .min() | The SIMPOL version of this function simply takes an unlimited number of arguments and returns the one that is of the lowest value. The SBL version can only be used with arrays or on reports under special circumstances. | ||||||||||||||||||||
MINS() | MINS() | There is essentially no difference between these two functions, other than that in SIMPOL the parameter passed must be a time object. In both cases the number of minutes in the time are returned as an integer. | ||||||||||||||||||||
MOD | mod | These two operators do the same thing, they return the fractional portion of a division operation. | ||||||||||||||||||||
MOD() | no equivalent |
The MOD() function in SBL is intended to indicate whether the current record
in the file passed as the argument has been modified. Since there is no such thing as a current
record (current file, etc.) in SIMPOL this function is meaningless. At some point when data-aware
forms have been added there may be a method to indicate if any record on the form has been modified
since it was read. That would be the appropriate location for such functionality.
| ||||||||||||||||||||
NOT | not |
These two operators are essentially the same, other than that the SBL version operates with
0 and non-0 and the SIMPOL version works with
.false and .true .
| ||||||||||||||||||||
NOTHING | .nul |
The literal value NOTHING in SBL is used exclusively together with the
IS() to test whether an object variable refers to nothing. In SIMPOL this
test can be carried out using the =@= operator and the literal value
.nul . This value is used in many different areas and ways within SIMPOL.
| ||||||||||||||||||||
QUIT | no equivalent |
The SBL command QUIT allows the program to suddenly exit, closing down
the Superbase environment after calling the OnUnload event procedure of the Superbase object
(if it was set). SIMPOL programs are self-sufficient so there is no additional environment to
shut down and they will exit only when the reach an error condition or they exit through the
end of the main() function assuming that all threads have also ended.
| ||||||||||||||||||||
REM, ' | ', ", // | The REM statement and the single quote character can both be used to indicate a comment in an SBL program. The single quote character can also immediately follow a command in SBL. In SIMPOL both the single and double-quote characters can be used to indicate a comment but unlike SBL, in SIMPOL these are only considered to be comment characters if they are on the left side of an equation (at the beginning of a statement). Also, if another matching quote is found inside, then the comment is ended and must be followed by an end-of-line character or end of statement character (: or ;). Using this technique a comment can be embedded in the middle of a line of code. The only line-level comment is the double forward slash (//). This must be placed at the beginning of a statement (either at the beginning of a line or directly following an end of statement character and separated only by white space). | ||||||||||||||||||||
REPLICATE (svar$, nvar%%) | nvar * svar |
The REPLICATE() is part of the standard BASIC repertoire and SBL includes
this function to replicate a string a given number of times. This function is unnecessary in SIMPOL
since it is possible to directly multiply a string by an integer and thereby replicate the string
that many times.
| ||||||||||||||||||||
RIGHT$() | .rstr() | These two functions are essentially identical in their function: they return the portion of the string from the last character until the beginning of the string or until the number of characters backwards from the end of the string, whichever is less. | ||||||||||||||||||||
SECS() | SECS() | There is essentially no difference between these two functions, other than that in SIMPOL the parameter passed must be a time object. In both cases the number of seconds in the time are returned as an integer. | ||||||||||||||||||||
SELECT FIRST INDEX "" | db1tablevar.select(lastrecord=.false, error=e) |
One of the significant differences between SBL and SIMPOL is the fact that in SBL, the entire
Superbase product is always present, and there is always a globally visible current database table
(or file), for each database table (file) there is a current index, and each index has a current
record that may be different for each index. There is also a currently loaded record. When working
with multiple windows open, this gets even messier still, since each
The return value of a record selection in SIMPOL is a record object. If an error occurs, then
the record object may be equal to | ||||||||||||||||||||
SELECT LAST INDEX "" | db1tablevar.select(lastrecord=.true, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. In this particular case, by using the double-quote
"" argument for the INDEX parameter, Superbase is
being told to select the last record in the sequential order of the table. Using the
select() method of the table object, SIMPOL is doing the same thing.
| ||||||||||||||||||||
SELECT FIRST INDEX RecNo.TEST | db1indexvar.select(lastrecord=.false, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. Here, the RecNo index is being used as an argument to select
the first entry in that index. In SIMPOL this can be done using a variable that refers to
the RecNo index, or it may be done using valid object syntax to reach the index object. For
example: db1tablevar!RecNo.index.select(lastrecord=.false) uses the table
variable. From the db1tablevar variable the member operator
(! ) is used to retrieve the field object for the RecNo
field, and then its index property is accessed using the dot
(. ) operator, and again using the dot (. ) operator, the
select() method is called.
| ||||||||||||||||||||
SELECT LAST INDEX RecNo.TEST | db1indexvar.select(lastrecord=.true, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. See the prior entry for
SELECT FIRST INDEX RecNo.TEST for details about how to select records using
an index in SIMPOL. The only difference to the SELECT FIRST version is that
the lastrecord parameter is assigned the value .true
rather than the value .false .
| ||||||||||||||||||||
SELECT KEY 123 INDEX RecNo.TEST | db1indexvar.selectkey(123, error=e, found=f) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. See the prior entry for
SELECT FIRST INDEX RecNo.TEST for details about how to select records using
an index in SIMPOL. In this particular case, the selectkey() method is
being used. The value that is being looked up must match the data type of the field for which
the index was created. The only variation of that is that an integer value can be used to search
within indexes on date, time, and datetime fields. If the
record is successfully found, then the boolean variable (which must be pre-initialized) that was
passed to the found parameter is set to
.true and the variable passed to the error
parameter will be unchanged. If the found parameter is
not passed, and the record is not found, then the return value will be .nul
and an error value will be assigned to the variable that was passed to the error parameter.
| ||||||||||||||||||||
SELECT NEXT | db1recvar.select(previousrecord=.false, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. As stated in that entry, the return value of a selection is a
record object. To select the next record (or the previous one) the select()
method of the record object is called, passing the appropriate value to the previousrecord parameter, in this case the value
.false .
| ||||||||||||||||||||
SELECT PREVIOUS | db1recvar.select(previousrecord=.true, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. As stated in that entry, the return value of a selection is a
record object. To select the next record (or the previous one) the select()
method of the record object is called, passing the appropriate value to the previousrecord parameter, in this case the value
.true .
| ||||||||||||||||||||
SET INDEX Name.TEST | db1recvar.selectcurrent(db1indexvar_Name, error=e) |
This command is supplied by Superbase to allow the programmer to change the controlling index
of an already selected record. In SIMPOL, it is necessary to call the
selectcurrent() method and to pass the desired index object to switch
to a different controlling index. If no index parameter is passed, then the default is to use
the value .nul , which results in the record being switched to having been
selected using the sequential order of the table. It is important to remember this when
reselecting a record with a lock, since otherwise the record may be switched away from the
desired index without realizing it!
| ||||||||||||||||||||
SELECT FIRST LOCK INDEX "" | db1tablevar.select(lastrecord=.false, lock=.true, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. The only significant difference here is that in both cases the
relevant locking parameter LOCK " or
lock is being passed. In SBL if the locking operation
fails, then an error occurs which may result in a call to a global error handler, or if the
error has been disabled, then it will simply set the value of the ERRNO
system value. In SIMPOL this will result in a return value of .nul , and
the variable passed in the error parameter will be
set to the error value that was the cause of the problem.
| ||||||||||||||||||||
SELECT FIRST LOCK INDEX RecNo.TEST | db1indexvar.select(lastrecord=.false, lock=.true, error=e) | See the prior entry for SELECT FIRST INDEX "" for details about how to select records using SIMPOL. See the prior entry for SELECT FIRST LOCK INDEX "" for details about how to select records with a lock using SIMPOL. | ||||||||||||||||||||
SELECT KEY 123 LOCK INDEX RecNo.TEST | db1indexvar.selectkey(123, lock=.true, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. In SBL it is a risky venture to use the
LOCK together with a SELECT KEY
statement, since if the selection fails to find the correct record, it will still find a
record and will lock that one instead. It is better practice to make sure the record has
been found and then use the SELECT CURRENT LOCK command to lock the
record. The same is also true of SIMPOL, though it is possible to do this safely, simply
by not passing a found parameter.
| ||||||||||||||||||||
SELECT NEXT LOCK | db1recvar.select(previousrecord=.false, lock=.true, error=e) | See the prior entry for SELECT FIRST INDEX "" for details about how to select records using SIMPOL. See the prior entry for SELECT FIRST LOCK INDEX "" for details about how to select records with a lock using SIMPOL. | ||||||||||||||||||||
SELECT CURRENT LOCK | db1recvar.selectcurrent(lock=.true, error=e) |
See the prior entry for SELECT FIRST INDEX "" for details about how to
select records using SIMPOL. See the prior entry for SELECT FIRST LOCK
INDEX "" for details about how to select records with a lock using SIMPOL. When
selecting the current record in SIMPOL it is important to make sure that the
index parameter is assigned an appropriate value
since otherwise it will default to .nul and potentially change the
current index (though only of the record that is returned). To retain the same index that
was used in the original selection, it is easiest to just pass the index
property of the record object, such as:
db1recvar.selectcurrent(db1recvar.index, lock=.true, error=e).
| ||||||||||||||||||||
SELECT REMOVE | db1recvar.delete(error=e) | In SBL, once the record is deleted it is simply gone. In SIMPOL, the record object still exists and can be treated like a new record object that is not yet stored. This means that a record could be deleted and the record object could then be used (perhaps modified) to create a new record, and then that record could be saved. | ||||||||||||||||||||
SPACE$ (nvar%%) | nvar * " " | Probably related to its BASIC heritage, SBL includes this function to create a string a given number of space characters in length. This function is unnecessary in SIMPOL since it is possible to multiply a string by an integer and thereby replicate the string that many times. | ||||||||||||||||||||
STR$() | .tostr() or STR() |
The STR$() function in SBL allows a large number of different methods for
formatting the number as a string. The equivalent function in SIMPOL simply formulates the number
as a string and also requires the base to be provided. When used for base ten numbers, it is
roughly equivalent to the command STR$(nvar%%, "."), except that in the case of
a zero value the character 0 will be output whereas in SBL the empty string
is the result. For a version that is directly compatible with the SBL version (except for the
lack of support for scientific notation), look for the STR.sml library. It is
also provided in source code. One difference between these is that the SIMPOL library function
requires the user to provide an object that includes the numeric settings for decimal point,
thousands separator, currency symbol, and whether the currency symbol is a prefix or suffix. This
is necessary since there are no such global settings in SIMPOL.
| ||||||||||||||||||||
THOUSECS() | THOUSECS() | There is essentially no difference between these two functions, other than that in SIMPOL the parameter passed must be a time object. In both cases the number of thousandths of a second in the time are returned as an integer. | ||||||||||||||||||||
TIME$() | TIMESTR() |
The Table 20.4.
Table 20.5.
| ||||||||||||||||||||
TIMEVAL() | string2time() |
In SBL the TIMEVAL() function takes either a time or a string representation of
a time. The SIMPOL string2time() function only accepts a string and a format string
and it returns a time object.
| ||||||||||||||||||||
UCASE$() | .ucase() |
In SBL to convert a string to uppercase the programmer calls the UCASE$()
function and in SIMPOL the .ucase() function serves the same purpose.
| ||||||||||||||||||||
VAL() | .toval() |
The VAL() function in SBL is used to convert a string to a number. It is
somewhat idiosyncratic in the way that it works. All leading whitespace is ignored, as are
currency symbols and thousands separators and the number is returned that is found up until the
first non digit character following the first decimal point or the end of the string is reached.
The SIMPOL version of this in keeping with its support for multiple bases, takes the value, the
characters to ignore, and the base to use for interpreting the string as a number. It might seem
a bit awkward dealing with defining the characters to ignore in SIMPOL since it could be all of
the Unicode character set, but in actuality it is quite easy, since it is also possible to
subtract strings from strings in SIMPOL. To define the set of characters to ignore, simply
subtract each of the characters that are desired from the string being evaluated, like this:
n = .toval(s, s - "0" - "1" - "2" - "3" - "4" - "5" - "6" - "7" - "8" - "9" - ".", 10)
, which will result in all of the desired characters being removed from the string and
all of the remaining characters being ignored. For a more typical SBL version check the library
for the VAL.sml .
| ||||||||||||||||||||
WAIT FOR nvar%% | !wait() | These both wait for a specified amount of time. Only the duration and intervals are different. |