Introduction |
Introduction |
BaCon usage and parameters |
|
General syntax |
BaCon is an acronym for BAsic CONverter. The BaCon BASIC converter is a |
Mathematics, variables |
tool to convert programs written in BASIC syntax to C. The resulting C |
Equations |
code can be compiled using generic C compilers like GCC or CC. It can be |
The BETWEEN and BEYOND keywords |
compiled using a C++ compiler as well. |
Indexed arrays |
|
* Declaration of static arrays |
BaCon intends to be a programming aid in creating small tools which can be |
* Declaration of dynamic arrays |
compiled on different Unix-based platforms. It tries to revive the days of |
* Dimensions |
the good old BASIC. |
* Passing arrays to functions or subs |
|
* Returning arrays from functions |
The BaCon converter passes expressions and numeric assignments to the C |
Associative arrays |
compiler without verification or modification. Therefore BaCon can be |
* Declaration |
considered a lazy converter: it relies on the expression parser of the C |
* Relations, lookups, keys |
compiler. |
* Basic logic programming |
|
Records |
BaCon usage and parameters |
* Declaration |
|
* Arrays of records |
To use BaCon, download the converter package and run the installer. The |
* Passing records to functions or subs |
converter can be used as follows: |
* Returning records from functions |
|
Strings by value or by reference |
bash ./bacon.sh myprog.bac |
ASCII, Unicode, UTF8 |
|
Binary trees |
Note that BASH 4.x or higher is required to execute the Shell script |
Creating and linking to libraries created with BaCon |
version of BaCon. |
* Step 1: create a library |
|
* Step 2: compile the library |
By default, the converter will refer to '/bin/bash' by itself. It uses a |
* Step 3: copy library to a system path |
so-called 'shebang' which allows the program to run standalone provided |
* Step 4: update linker cache |
the executable rights are set correctly. This way there is no need to |
* Step 5: demonstration program |
execute BaCon with an explicit use of BASH. So this is valid: |
* Step 6: compile and link |
|
* Remarks |
./bacon.sh myprog.bac |
Creating internationalization files |
|
* Step 1: create program |
Alternatively, also Kornshell93 (releases after 2012) or Zshell (versions |
* Step 2: compile program |
higher than 4.x) can be used: |
* Step 3: create catalog file |
|
* Step 4: add translations |
ksh ./bacon.sh myprog.bac |
* Step 5: create object file |
|
* Step 6: install |
zsh ./bacon.sh myprog.bac |
* Step 7: setup Unix environment |
|
Networking |
All BaCon programs should use the '.bac' extension. But it is not |
* TCP |
necessary to provide this extension for conversion. So BaCon also |
* UDP |
understands the following syntax: |
* BROADCAST |
|
* MULTICAST |
./bacon.sh myprog |
* SCTP |
|
TLS secured network connections |
Another possibility is to point to the URL of a BaCon program hosted by a |
Ramdisks and memory streams |
website. The program will then be downloaded automatically, after which it |
Delimited strings |
is converted: |
Regular expressions |
|
Error trapping, error catching and debugging |
./bacon.sh http://www.basic-converter.org/fetch.bac |
Notes on transcompiling |
|
Using the BaCon spartanic editor (BaSE) |
The BaCon Basic Converter can be started with the following parameters. |
Support for GUI programming |
|
* Enabling GUI functions |
* -c: determine which C compiler should create the binary (defaults to |
* Defining the GUI |
'gcc') |
* Setting properties |
|
* Entering the mainloop |
* -l: pass a library to the C linker |
* Defining helper functions |
|
* Using native functions |
* -o: pass a compiler option to the C compiler |
Overview of BaCon statements and functions |
|
* ABS |
* -i: the compilation will use an additional external C include file |
* ACCEPT |
|
* ACOS |
* -d: determine the directory where BaCon should store the generated C |
* ADDRESS |
files (defaults to the current directory) |
* ALARM |
|
* ALIAS |
* -x: extract gettext strings from generated c sources |
* ALIGN$ |
|
* AMOUNT |
* -z: allow the usage of lowercase statements and functions |
* AND |
|
* APPEND |
* -e: starts the embedded ASCII editor |
* APPEND$ |
|
* ARGUMENT$ |
* -f: create a shared object of the program |
* ASC |
|
* ASIN |
* -n: do not compile the C code automatically after conversion |
* ATN |
|
* ATN2 |
* -y: suppress warning about temporary files if these exist |
* B64DEC$ |
|
* B64ENC$ |
* -j: invoke C preprocessor to interpret C macros which were added to |
* BAPPEND |
BaCon source code |
* BASENAME$ |
|
* BIN$ |
* -p: do not cleanup the generated C files (default behavior is to |
* BIT |
delete all generated C files automatically) |
* BLOAD |
|
* BREAK |
* -q: suppress line counting during conversion and only show summary |
* BSAVE |
after conversion |
* BYTELEN |
|
* CA$ |
* -r: convert and execute the resulting program in one step |
* CALL |
|
* CATCH |
* -s: suppress warnings about semantic errors |
* CEIL |
|
* CERTIFICATE |
* -t: tweak internal BaCon parameters for the string core engine and |
* CHANGE$ |
memory pool: |
* CHANGEDIR |
|
* CHOP$ |
pbc=<x>: set the Pool Block Count to <x> defaults to: 1024 |
* CHR$ |
pbs=<x>: set each individual Pool Block Size to <x> defaults to: 1024 |
* CIPHER$ |
hld=<x>: set the Hash Linear Depth probing to <x> defaults to: 16 |
* CL$ |
hss=<x>: set the Hash String Store size to <x> defaults to: 0x100000 |
* CLASS |
mrb=<x>: set the Maximum Return Buffers to <x> defaults to: 64 |
* CLEAR |
|
* CLOSE |
* -w: store command line settings in the configuration file |
* CMDLINE |
~/.bacon/bacon.cfg. This file will be used in subsequent invocations |
* CN$ |
of BaCon (not applicable for the GUI version) |
* COIL$ |
|
* COLLAPSE$ |
* -v: shows the current version of BaCon |
* COLLECT |
|
* COLOR |
* -h: shows an overview of all possible options on the prompt. Same as |
* COLUMNS |
the '-?' parameter |
* CONCAT$ |
|
* CONST |
The shell script implementation can convert and compile the BaCon version |
* CONTINUE |
of BaCon. This will deliver the binary version of BaCon which has an |
* COPY |
extremely high conversion performance. On newer systems, the average |
* COS |
conversion rate usually lies above 10.000 lines per second. |
* COUNT |
|
* CR$ |
This documentation refers both to the shell script and binary |
* CURDIR$ |
implementation of BaCon. |
* CURSOR |
|
* CUT$ |
Here are a few examples showing the usage of command line parameters: |
* DATA |
|
* DAY |
* Convert and compile program with debug symbols: bacon -o -g |
* DEC |
program.bac |
* DECLARE |
|
* DECR |
* Convert and compile program, optimize and strip: bacon -o -O2 -o -s |
* DEF FN |
program.bac |
* DEG |
|
* DEL$ |
* Convert and compile program and export functions as symbols: bacon -o |
* DELETE |
-export-dynamic yourprogram.bac |
* DELIM$ |
|
* DIRNAME$ |
* Convert and compile program using TCC and export functions as symbols: |
* DLE$ |
bacon -c tcc -o -rdynamic yourprogram.bac |
* DO |
|
* DOTIMES |
* Convert and compile program forcing 32bit and optimize for current |
* EDITBOM$ |
platform: bacon -o -m32 -o -mtune=native yourprogram.bac |
* EL$ |
|
* END |
* Convert and compile program linking to a particular library: bacon -l |
* ENDFILE |
somelib program.bac |
* ENUM |
|
* EPRINT |
* Convert and compile program including an additional C header file: |
* EQ |
bacon -i header.h yourprogram.bac |
* EQUAL |
|
* ERR$ |
* Store compile options permanently: bacon -w -l tcmalloc -o -O2 |
* ERROR |
program.bac (subsequent invocations of BaCon will now always use the |
* ESCAPE$ |
mentioned options) |
* EVAL |
|
* EVEN |
Most of the aforementioned options also can be used programmatically by |
* EXCHANGE$ |
use of the PRAGMA keyword. |
* EXEC$ |
|
* EXIT |
General syntax |
* EXP |
|
* EXPLODE$ |
BaCon consists of statements, functions and expressions. Each line should |
* EXTRACT$ |
begin with a statement. A line may continue onto the next line by using a |
* FALSE |
space and the '' symbol at the end of the line. The LET statement may be |
* FILEEXISTS |
omitted, so a line may contain an assignment only. Expressions are not |
* FILELEN |
converted, but are passed unchanged to the C compiler (lazy conversion). |
* FILETIME |
|
* FILETYPE |
BaCon does not require line numbers. More statements per line are |
* FILL$ |
accepted. These should be separated by the colon symbol ':'. |
* FIND |
|
* FIRST$ |
All keywords must be written in capitals to avoid name clashes with |
* FLATTEN$ |
existing C keywords or functions from libc. Keywords in small letters are |
* FLOOR |
considered to be variables unless the '-z' command line option is |
* FOR |
specified, in which case BaCon tries to parse lowercase keywords as if |
* FORK |
they were written in capitals. Note that this may lead to unexpected |
* FP |
results, for example if the program uses variable names which happen to be |
* FREE |
BaCon keywords. |
* FUNCTION |
|
* GETBYTE |
Statements are always written without using brackets. Functions however |
* GETENVIRON$ |
must use brackets to enclose their arguments. Functions always return a |
* GETFILE |
value or string, contrary to subs. Functions created in the BaCon program |
* GETKEY |
can be invoked standalone, meaning that they do not need to appear in an |
* GETLINE |
assignment. |
* GETPEER$ |
|
* GETX / GETY |
Subroutines may be defined using SUB/ENDSUB and do not return a value. |
* GLOBAL |
With the FUNCTION/ENDFUNCTION statements a function can be defined which |
* GOSUB |
does return a value. The return value must be explicitly stated with the |
* GOTO |
statement RETURN. |
* GOTOXY |
|
* GUIDEFINE |
The three main variable types in BaCon are defined as STRING, NUMBER and |
* GUIEVENT$ |
FLOATING. These are translated to char*, long and double. |
* GUIFN |
|
* GUIGET |
A variable will be declared implicitly when the variable is used in an |
* GUISET |
assignment (e.g. LET) or in a statement which assigns a value to a |
* GUIWIDGET |
variable. By default, implicitly declared variables are of 'long' type. |
* HASBOM |
This default can be changed by using the OPTION VARTYPE statement. Note |
* HASDELIM |
that implicitly declared variables always have a global scope, meaning |
* HASH |
that they are visible to all functions and routines in the whole program. |
* HEAD$ |
Variables which are used and implicitly declared within a SUB or FUNCTION |
* HEX$ |
also by default have a global scope. When declared with the LOCAL |
* HOST$ |
statement variables will have a scope local to the FUNCTION or SUB. |
* HOSTNAME$ |
|
* HOUR |
In case of implicit assignments, BaCon assumes numeric variables to be of |
* IF |
long type, unless specified otherwise with OPTION VARTYPE. Also, it is |
* IIF / IIF$ |
possible to define a variable to any other C-type explicitly using the |
* IMPORT |
DECLARE and LOCAL statements. |
* INBETWEEN$ |
|
* INCLUDE |
Next to this, BaCon accepts type suffixes as well. For example, if a |
* INCR |
variable name ends with the '$' symbol, a string variable is assumed. If a |
* INDEX |
variable name ends with the '#' symbol, a float variable is assumed. If a |
* INDEX$ |
variable name ends with the '%' symbol, it is considered to be an integer |
* INPUT |
variable. The type suffixes also can be used when defining a function |
* INSERT$ |
name. |
* INSTR |
|
* INSTRREV |
Mathematics, variables |
* INTL$ |
|
* INVERT |
The standard C operators for mathematics can be used, like '+' for |
* ISASCII |
addition, '-' for subtraction, '/' for division and '*' for |
* ISFALSE |
multiplication. For the binary 'and', the '&' symbol must be used, and for |
* ISKEY |
the binary 'or' use the pipe symbol '|'. Binary shifts are possible with |
* ISTOKEN |
'>>' and '<<'. |
* ISTRUE |
|
* ISUTF8 |
C operator Meaning C Operator Meaning |
* JOIN |
+ Addition | Inclusive or |
* LABEL |
- Subtraction ^ Exclusive or |
* LAST$ |
* Multiplication >> Binary shift right |
* LCASE$ |
/ Division << Binary shift left |
* LEFT$ |
& Binary and |
* LEN |
|
* LET |
Variable names may be of any length but may not start with a number or an |
* LINENO |
underscore symbol. |
* LOAD$ |
|
* LOCAL |
Equations |
* LOG |
|
* LOOKUP |
Equations are used in statements like IF...THEN, WHILE...WEND, and |
* LOOP |
REPEAT...UNTIL. In BaCon the following symbols for equations can be used: |
* LOOP$ |
|
* MAKEDIR |
Symbol Meaning Type |
* MAP |
0 Equal to String, numeric |
* MATCH |
!=, <> Not equal to String, numeric |
* MAX / MAX$ |
> Greater than String, numeric also allows GT |
* MAXNUM |
< Less than String, numeric also allows LT |
* MAXRANDOM |
>= Greater or equal String, numeric also allows GE |
* ME$ |
<= Less or equal String, numeric also allows LE |
* MEMCHECK |
EQ, IS Equal to Numeric |
* MEMORY |
NE, ISNOT Not equal to Numeric |
* MEMREWIND |
AND, OR Logical and,or String, numeric |
* MEMTELL |
BETWEEN In between String, numeric |
* MERGE$ |
BEYOND Outside String, numeric |
* MID$ |
EQUAL() Equal to String |
* MIN / MIN$ |
|
* MINUTE |
The BETWEEN and BEYOND keywords |
* MOD |
|
* MONTH |
When using equations in WHILE, IF, REPEAT, IIF or IIF$ it often happens |
* MONTH$ |
that a check needs to be performed to see if a certain value lies within a |
* MYPID |
range. For this purpose, BaCon accepts the BETWEEN comparison keyword. For |
* NANOTIMER |
example: |
* NE |
|
* NL$ |
IF 5 BETWEEN 0;10 THEN PRINT "Found" |
* NNTL$ |
|
* NOT |
This comparison will return TRUE in case the value 5 lies within 0 and 10. |
* NOW |
The comparison will include the lower and upper boundary value during |
* NRKEYS |
evaluation. Note that the lower and upper values are being separated by a |
* OBTAIN$ |
semicolon. Alternatively, the keyword AND may be used here as well: |
* ODD |
|
* ON |
IF 5 BETWEEN 0 AND 10 THEN PRINT "Found" |
* OPEN |
|
* OPTION |
Note that this may lead to confusing constructs when adding more logical |
* OR |
requirements to the same equation. |
* OS$ |
|
* OUTBETWEEN$ |
The BETWEEN comparison also accepts strings: |
* PARSE |
|
* PEEK |
IF "C" BETWEEN "Basic" AND "Pascal" THEN PRINT "This is C" |
* PI |
|
* POKE |
The order of the mentioned range does not matter, the following code will |
* POW |
deliver the exact same result: |
* PRAGMA |
|
* PRINT |
IF "C" BETWEEN "Pascal" AND "Basic" THEN PRINT "This is C" |
* PROPER$ |
|
* PROTO |
In case the boundary values should be excluded, BaCon accepts the optional |
* PULL |
EXCL keyword: |
* PUSH |
|
* PUTBYTE |
IF variable BETWEEN 7 AND 3 EXCL THEN PRINT "Found" |
* PUTLINE |
|
* RAD |
The last example will print "Found" in case the variable lies within 3 and |
* RANDOM |
7, values which themselves are excluded. |
* READ |
|
* READLN |
Similarly, to check if a value lies outside a certain range, the keyword |
* REALPATH$ |
BEYOND can be used: |
* REAP |
|
* RECEIVE |
IF 5 BEYOND 1 AND 3 THEN PRINT "Outside" |
* RECORD |
|
* REDIM |
Note that in case of the BEYOND keyword the boundary values themselves are |
* REGEX |
considered to be part of the outside range. The same EXCL keyword can be |
* REGLEN |
used to exclude them. |
* RELATE |
|
* REM |
Indexed arrays |
* RENAME |
|
* REPEAT |
Declaration of static arrays |
* REPLACE$ |
|
* RESIZE |
An array will never be declared implicitly by BaCon, so arrays must be |
* RESTORE |
declared explicitly. This can be done by using the keyword GLOBAL or |
* RESUME |
DECLARE for arrays which should be globally visible, or LOCAL for local |
* RETURN |
array variables. |
* RETVAL |
|
* REV$ |
Arrays must be declared in the C syntax, using square brackets for each |
* REVERSE$ |
dimension. For example, a local string array must be declared like this: |
* REWIND |
'LOCAL array$[5]'. Two-dimensional arrays are written like 'array[5][5]', |
* RIGHT$ |
three-dimensional arrays like 'array[5][5][5]' and so on. |
* RIP$ |
|
* RND |
In BaCon, static numeric arrays can have all dimensions, but static string |
* ROL |
arrays cannot have more than one dimension. |
* ROR |
|
* ROTATE$ |
Declaration of dynamic arrays |
* ROUND |
|
* ROWS |
Also dynamic arrays must be declared explicitly. To declare a dynamic |
* RUN |
array, the statements GLOBAL or LOCAL must be used together with the ARRAY |
* RUN$ |
keyword, which determines the amount of elements. For example, to declare |
* SAVE |
a dynamic array of 5 integer elements: 'LOCAL array TYPE int ARRAY 5'. |
* SCREEN |
|
* SCROLL |
The difference with a static array is that the size of a dynamic array can |
* SEARCH |
declared using variables, and that their size can be redimensioned during |
* SECOND |
runtime. The latter can be achieved with the REDIM statement. This is only |
* SEED |
possible for arrays with one dimension. |
* SEEK |
|
* SELECT |
As with static numeric arrays, also dynamic numeric arrays can have all |
* SEND |
dimensions, and dynamic string arrays cannot have more than one dimension. |
* SETENVIRON |
The syntax to refer to elements in a dynamic array is the same as the |
* SETSERIAL |
syntax for elements in a static array. |
* SGN |
|
* SIGNAL |
Dimensions |
* SIN |
|
* SIZEOF |
Static arrays must be declared with fixed dimensions, meaning that it is |
* SLEEP |
not possible to determine the dimensions of an array using variables or |
* SORT |
functions, so during program runtime. The reason for this is that the C |
* SORT$ |
compiler needs to know the array dimensions during compile time. Therefore |
* SOURCE$ |
the dimensions of an array must be defined with fixed numbers or with |
* SP |
CONST definitions. Also, the size of a static array cannot be changed |
* SPC$ |
afterwards. |
* SPLIT |
|
* SQR |
Dynamic arrays however can be declared with variable dimensions, meaning |
* STOP |
that the size of such an array also can be expressed by a variable. |
* STR$ |
Furthermore, the size of a one dimensional dynamic array can be changed |
* SUB |
afterwards with the REDIM statement. This statement also works for |
* SUM / SUMF |
implicitly created dynamic arrays in the SPLIT and LOOKUP statements. |
* SWAP |
|
* SYSTEM |
By default, if an array is declared with 5 elements, then it means that |
* TAB$ |
the array elements range from 0 to 4. Element 5 is not part of the array. |
* TAIL$ |
This behavior can be changed using the OPTION BASE statement. If OPTION |
* TALLY |
BASE is set to 1, an array declared with 5 elements will have a range from |
* TAN |
1 to 5. |
* TELL |
|
* TEXTDOMAIN |
The UBOUND function returns the dimension of an array. In case of |
* TIMER |
multi-dimensional arrays the total amount of elements will be returned. |
* TIMEVALUE |
The UBOUND function works for static and dynamic arrays, but also for |
* TOASCII$ |
associative arrays. |
* TOKEN$ |
|
* TOTAL |
Passing arrays to functions or subs |
* TRACE |
|
* TRAP |
In BaCon it is possible to pass one-dimensional arrays to a function or |
* TREE |
sub. The caller should simply use the basename of the array (so without |
* TRUE |
mentioning the dimension of the array). |
* TYPE |
|
* TYPEOF$ |
When the function or sub argument mentions the dimension, a local copy of |
* UBOUND |
the array is created. |
* UCASE$ |
|
* UCS |
CONST dim = 2 |
* ULEN |
DECLARE series[dim] TYPE NUMBER |
* UNESCAPE$ |
|
* UNFLATTEN$ |
SUB demo(NUMBER array[dim]) |
* UNIQ$ |
array[0] = 987 |
* USEC |
array[1] = 654 |
* USEH |
END SUB |
* UTF8$ |
|
* VAL |
series[0] = 123 |
* VAR |
series[1] = 456 |
* VERIFY |
demo(series) |
* VERSION$ |
FOR x = 0 TO dim - 1 |
* WAIT |
PRINT series[x] |
* WALK$ |
NEXT |
* WEEK |
|
* WEEKDAY$ |
This will print the values originally assigned. The sub does not change |
* WHERE |
the original assignments. |
* WHILE |
|
* WITH |
When the function or sub argument does not mention the dimension, but only |
* WRITELN |
uses square brackets, the array is passed by reference. |
* YEAR |
|
Appendix A: Runtime error codes |
CONST dim = 2 |
Appendix B: standard POSIX variables |
DECLARE series[dim] TYPE NUMBER |
Appendix C: reserved keywords and functions |
|
Appendix D: details on string optimization in BaCon |
SUB demo(NUMBER array[]) |
* Different binary layout |
array[0] = 987 |
* Hash table |
array[1] = 654 |
* Pointer swap |
END SUB |
* Static character pointers |
|
* Using a pre-buffer |
series[0] = 123 |
* Memory pool |
series[1] = 456 |
|
demo(series) |
|
FOR x = 0 TO dim - 1 |
|
PRINT series[x] |
|
NEXT |
|
|
|
This will modify the original array and prints the values assigned in the |
|
sub. |
|
|
|
Returning arrays from functions |
|
|
|
In BaCon, it is also possible to return a one dimensional array from a |
|
function. This only works for dynamic arrays, as the static arrays always |
|
use the stack memory assigned to a function. This means, that when a |
|
function is finished, also the memory for that function is destroyed, |
|
together with the variables and static arrays in that function. Therefore |
|
only dynamic arrays can be returned. |
|
|
|
The syntax to return a one dimensional dynamic array involves two steps: |
|
the declaration of the array must contain the STATIC keyword, and the |
|
RETURN argument should only contain the basename of the array without |
|
mentioning the dimensions. For example: |
|
|
|
FUNCTION demo |
|
LOCAL array TYPE int ARRAY 10 STATIC |
|
FOR x = 0 TO 9 |
|
array[x] = x |
|
NEXT |
|
RETURN array |
|
END FUNCTION |
|
DECLARE my_array TYPE int ARRAY 10 |
|
my_array = demo() |
|
|
|
This example will create a dynamic array and assign some initial values, |
|
after which it is returned from the function. The target 'my_array' now |
|
will contain the values assigned in the function. |
|
|
|
The statements SPLIT, LOOKUP, COLLECT, PARSE and MAP also accept the |
|
STATIC keyword, which allows the implicitly created dynamic array |
|
containing results to be returned from a function. |
|
|
|
Note that when returning arrays, the assigned array should have the same |
|
dimensions in order to prevent memory errors. |
|
|
|
Associative arrays |
|
|
|
Declaration |
|
|
|
An associative array is an array of which the index is determined by a |
|
string, instead of a number. Associative arrays use round brackets '(...)' |
|
instead of the square brackets '[...]' used by normal arrays. |
|
|
|
An associative array can use any kind of string for the index, and it can |
|
have an unlimited amount of elements. The declaration of associative |
|
arrays therefore never mentions the range. |
|
|
|
To declare an associative array, the following syntax applies: |
|
|
|
DECLARE info ASSOC int |
|
|
|
This declares an array containing integer values. To assign a value, using |
|
a random string "abcd" as example: |
|
|
|
info("abcd") = 1 |
|
|
|
Similarly, an associative array containing other types can be declared, |
|
for example strings: |
|
|
|
DECLARE txt$ ASSOC STRING |
|
|
|
As with other variables, declaring associative arrays within a function |
|
using LOCAL will ensure a local scope of the array. |
|
|
|
An associative array can have any amount of dimension. The indexes in an |
|
associative array should be separated by a comma. For example: |
|
|
|
DECLARE demo$ ASSOC STRING |
|
demo$("one") = "hello" |
|
demo$("one", "two") = "world" |
|
|
|
Alternatively, the indexes also can be specified in a delimited string |
|
format, using a single space as delimiter: |
|
|
|
demo$("one two") = "world" |
|
|
|
Note that the OPTION BASE statement has no impact on associative arrays. |
|
Also note that an associative array cannot be part of a RECORD structure. |
|
|
|
For the index, it is also possible to use the STR$ function to convert |
|
numbers or numerical variables to strings: |
|
|
|
PRINT txt$(STR$(123)) |
|
|
|
Relations, lookups, keys |
|
|
|
In BaCon, it is possible to setup relations between associative arrays of |
|
the same type. This may be convenient when multiple arrays with the same |
|
index need to be set at once. To setup a relation the RELATE keyword can |
|
be used, e.g: |
|
|
|
RELATE assoc TO other |
|
|
|
Now for each index in the array 'assoc', the same index in the array |
|
'other' is set. It also is possible to copy the contents of one |
|
associative array to another. This can simply be done by using the |
|
assignment operator, as follows: |
|
|
|
array$() = other$() |
|
|
|
Next to this, the actual index names in an associative array can be looked |
|
up using the LOOKUP statement. This statement returns a dynamically |
|
created array containing all string indexes. The size of the resulting |
|
array is dynamically declared as it depends on the amount of available |
|
elements. Instead of creating a dynamic array, it is also possible to |
|
return the indexes of an associative array into a delimited string by |
|
using the function OBTAIN$. |
|
|
|
To find out if a key already was defined in the associative array, the |
|
function ISKEY can be used. This function needs the array name and the |
|
string containing the index name, and will return either TRUE or FALSE, |
|
depending on whether the index is defined (TRUE) or not (FALSE). |
|
|
|
The function NRKEYS will return the amount of members in an associative |
|
array. |
|
|
|
Deleting individual associative array members can be done by using the |
|
FREE statement. This will leave the associative array insertion order |
|
intact. The FREE statement also can be used to delete a full associative |
|
array in one step. |
|
|
|
The function INDEX$ allows looking up a specific key based on value. The |
|
function INVERT can swap the keys and values of an associative array. The |
|
SORT statement also can sort associative arrays based on their value, |
|
effectively changing the insertion order in the underlying hash table. |
|
|
|
Basic logic programming |
|
|
|
With the current associative array commands it is possible to perform |
|
basic logic programming. Consider the following Logic program which can be |
|
executed with any Prolog implementation: |
|
|
|
mortal(X) :- human(X). |
|
|
|
human(socrates). |
|
human(sappho). |
|
human(august). |
|
|
|
mortals_are: |
|
write('Mortals are:'), |
|
mortal(X), |
|
write(X), |
|
fail. |
|
|
|
The following BaCon program does the same thing: |
|
|
|
DECLARE human, mortal ASSOC int |
|
RELATE human TO mortal |
|
|
|
human("socrates") = TRUE |
|
human("sappho") = TRUE |
|
human("august") = TRUE |
|
|
|
PRINT "Mortals are:" |
|
LOOKUP mortal TO member$ SIZE amount |
|
FOR x = 0 TO amount - 1 |
|
PRINT member$[x] |
|
NEXT |
|
|
|
Records |
|
|
|
Declaration |
|
|
|
Records are collections of variables which belong together. A RECORD has a |
|
name by itself and members of the record can be accessed by using the |
|
<name>.<member> notation. The members should be declared using the LOCAL |
|
statement. For example: |
|
|
|
RECORD rec |
|
LOCAL value |
|
LOCAL nr[5] |
|
END RECORD |
|
rec.value = 99 |
|
|
|
As soon a record is created, it also exists as a type. The name of the |
|
type always consists of the record name followed by the '_type' suffix. |
|
From then on, it is possible to declare other variables as being of the |
|
same type. To continue with the same example: |
|
|
|
DECLARE var TYPE rec_type |
|
var.value = 123 |
|
|
|
Arrays of records |
|
|
|
Record definitions also can be created as static arrays or as dynamic |
|
arrays. The size of the static array is determined during compile time and |
|
the data will be stored in the stack frame of a SUB or FUNCTION. This |
|
means that the array data is lost when the SUB or FUNCTION is ended. |
|
Example of a static array definition: |
|
|
|
RECORD data[10] |
|
LOCAL info$ |
|
END RECORD |
|
|
|
To declare a dynamic array of records, the keyword ARRAY must be used. The |
|
size of a dynamic record array is determined during runtime, and |
|
therefore, can be set with variables and functions. The data is stored in |
|
the heap. The BaCon memory management will clean up the data when leaving |
|
a FUNCTION or SUB. Example: |
|
|
|
RECORD data ARRAY 10 |
|
LOCAL name$[5] |
|
LOCAL age[5] |
|
END RECORD |
|
|
|
Note that dynamic arrays of records do not allow members which are dynamic |
|
arrays themselves. |
|
|
|
Passing records to functions or subs |
|
|
|
To pass a record, simply declare the variable name with the appropriate |
|
record type in the header of the function or sub. Example code: |
|
|
|
RECORD rec |
|
LOCAL nr |
|
LOCAL area$ |
|
END RECORD |
|
|
|
SUB subroutine(rec_type var) |
|
PRINT var.nr |
|
PRINT var.area$ |
|
ENDSUB |
|
rec.nr = 123 |
|
rec.area$ = "europe" |
|
CALL subroutine(rec) |
|
|
|
Similarly, it is possible to pass an array of records as well. Note the |
|
square brackets in the function header: |
|
|
|
RECORD rec ARRAY 10 |
|
LOCAL nr |
|
LOCAL area$ |
|
END RECORD |
|
|
|
SUB subroutine(rec_type var[]) |
|
PRINT var[0].nr |
|
PRINT var[0].area$ |
|
ENDSUB |
|
rec[0].nr = 123 |
|
rec[0].area$ = "europe" |
|
CALL subroutine(rec) |
|
|
|
Returning records from functions |
|
|
|
In order to return a record from a function, the record type must be |
|
visible to the caller. The below example declares the record in the main |
|
program. The function declares a variable of the same type and initializes |
|
the record to 0. This initialization is obligatory for string members to |
|
work properly. Then some values are assigned. Lastly, the complete record |
|
is returned to the caller: |
|
|
|
RECORD rec |
|
LOCAL id |
|
LOCAL zip$[2] |
|
END RECORD |
|
|
|
FUNCTION func TYPE rec_type |
|
LOCAL var = { 0 } TYPE rec_type |
|
var.id = 1 |
|
var.zip$[0] = "XJ342" |
|
var.zip$[1] = "YP198" |
|
RETURN var |
|
ENDFUNCTION |
|
rec = func() |
|
PRINT rec.id |
|
PRINT rec.zip$[0] |
|
PRINT rec.zip$[1] |
|
|
|
Strings by value or by reference |
|
|
|
Strings can be stored by value or by reference. By value means that a copy |
|
of the original string is stored in a variable. This happens automatically |
|
when when a string variable name ends with the '$' symbol. |
|
|
|
Sometimes it may be necessary to refer to a string by reference. In such a |
|
case, simply declare a variable name as STRING but omit the '$' at the |
|
end. Such a variable will point to the same memory location as the |
|
original string. The following examples should show the difference between |
|
by value and by reference. |
|
|
|
When using string variables by value: |
|
|
|
a$ = "I am here" |
|
b$ = a$ |
|
a$ = "Hello world..." |
|
PRINT a$, b$ |
|
|
|
This will print "Hello world...I am here". The variables point to their |
|
individual memory areas so they contain different strings. Now consider |
|
the following code: |
|
|
|
a$ = "Hello world..." |
|
LOCAL b TYPE STRING |
|
b = a$ |
|
a$ = "Goodbye..." |
|
PRINT a$, b FORMAT "%s%sn" |
|
|
|
This will print "Goodbye...Goodbye..." because the variable 'b' points to |
|
the same memory area as 'a$'. (The optional FORMAT forces the variable 'b' |
|
to be printed as a string, otherwise BaCon assumes that the variable 'b' |
|
contains a value.) |
|
|
|
Note that as soon an existing string variable is referred to by a |
|
reference variable, the string will not profit from the optimized high |
|
performance string engine anymore. |
|
|
|
ASCII, Unicode, UTF8 |
|
|
|
BaCon is a byte oriented converter. This means it always will assume that |
|
a string consists of a sequence of ASCII bytes. Though this works fine for |
|
plain ASCII strings, it will cause unexpected results in case of non-Latin |
|
languages, like Chinese or Cyrillic. However, BaCon supports UTF8 encoded |
|
strings also. |
|
|
|
The original text already may contain the UTF8 byte order mark 0xEF 0xBB |
|
0xBF. The function HASBOM can be used to detect if such byte order mark is |
|
present. To add or delete a byte order mark, use EDITBOM$. |
|
|
|
In order to work with UTF8 strings, OPTION UTF8 needs to be enabled. This |
|
option will put all string related functions in UTF8 mode at the cost of |
|
some performance loss in string processing. |
|
|
|
Next to this option, BaCon also provides a few functions which relate to |
|
UTF8 encoding. The following functions work independently from OPTION |
|
UTF8: |
|
|
|
* ULEN will correctly calculate the actual characters based on the |
|
binary UTF8 sequence. |
|
|
|
* BYTELEN will show the actual amount of bytes used by a UTF8 string. |
|
|
|
* ISASCII can be used to verify if a string only consists of ASCII data. |
|
|
|
* UTF8$ needs the Unicode value as argument and returns the |
|
corresponding character depending on environment settings and the |
|
current font type. |
|
|
|
* UCS needs a UTF8 character as an argument and returns the |
|
corresponding Unicode value. |
|
|
|
* ESCAPE$ will convert a UTF8 string to an ASCII sequence with escape |
|
characters. |
|
|
|
* UNESCAPE$ will convert an ASCII sequence with escaped characters back |
|
to valid UTF8. |
|
|
|
* HASBOM will detect if the UTF8 byte order mark is present in the text |
|
|
|
* EDITBOM$ can be used to add or delete a UTF8 byte order mark |
|
|
|
Binary trees |
|
|
|
BaCon has a built-in API for binary trees. Compared to arrays, a binary |
|
tree is a data structure which can access its elements in a faster and |
|
more efficient manner. Regular arrays store an element in a linear way, |
|
which, in worst case, can end up in long sequential lookup times. A binary |
|
tree however uses an internal decision tree to lookup an element, of which |
|
the lookup time, depending on the tree position, is logarithmic. |
|
|
|
A typical application using a binary tree is a database, which needs to |
|
lookup information from a large amount of data. A search in a binary tree |
|
will be a lot faster compared to a plain linear search in a regular array. |
|
|
|
To declare a binary tree, BaCon uses the DECLARE or LOCAL keyword together |
|
with TREE. For example, to declare a binary tree containing strings: |
|
|
|
DECLARE mytree TREE STRING |
|
|
|
Subsequently, it is possible to declare other types as well, for example |
|
integers or floats: |
|
|
|
DECLARE myinttree TREE int |
|
DECLARE myfloattree TREE float |
|
|
|
After the declaration, new values (nodes) can be added to the tree. Adding |
|
a string is very straightforward. It can be added to a binary tree using |
|
the TREE statement: |
|
|
|
TREE mytree ADD "hello" |
|
text$ = "world" |
|
TREE mytree ADD text$ |
|
|
|
Similarly, to add an integer or float to the binary tree: |
|
|
|
TREE myinttree ADD 567 |
|
TREE myfloattree ADD 4.127 |
|
|
|
When adding a duplicate string or value nothing happens. Such attempt will |
|
silently be ignored. As a result, all entries in a binary tree are unique. |
|
|
|
The FIND function can lookup the presence of an element. If found, the |
|
FIND function will return TRUE (1), otherwise it will return FALSE (0). |
|
The following example looks up a string in a binary tree: |
|
|
|
IF FIND(mytree, "abc") THEN PRINT "Found!" |
|
|
|
Similarly it is possible to lookup an integer or float value: |
|
|
|
result = FIND(myfloattree, 2.2) |
|
var = 123 |
|
result = FIND(myinttree, var) |
|
|
|
It is also possible to remove an element from the tree using the DELETE |
|
statement. If an element is not found then nothing happens: |
|
|
|
DELETE result$ FROM mytree |
|
DELETE 1.2 FROM myfloattree |
|
|
|
The COLLECT statement can collect all the strings or values of all nodes |
|
in the binary tree and put them into a regular array: |
|
|
|
COLLECT mytree TO allnodes$ |
|
COLLECT myinttree TO intnodes |
|
|
|
Lastly, the function TOTAL can be used to find out the total amount of |
|
elements in a binary tree: |
|
|
|
PRINT "Amount of nodes:", TOTAL(mytree) |
|
|
|
Creating and linking to libraries created with BaCon |
|
|
|
With Bacon, it is possible to create libraries. In the world of Unix these |
|
are known as shared objects. The following steps should explain how to |
|
create and link to BaCon libraries. |
|
|
|
Step 1: create a library |
|
|
|
The below program only contains a function, which accepts one argument and |
|
returns a value. |
|
|
|
FUNCTION bla (NUMBER n) |
|
LOCAL i |
|
i = 5 * n |
|
RETURN i |
|
END FUNCTION |
|
|
|
In this example, the program will be saved as 'libdemo.bac'. Note that the |
|
name must begin with the prefix 'lib'. This is a Unix convention. The |
|
linker will search for library names starting with these three letters. |
|
|
|
Step 2: compile the library |
|
|
|
The program must be compiled using the '-f' flag: bacon -f libdemo.bac |
|
|
|
This will create a file called 'libdemo.so'. |
|
|
|
Step 3: copy library to a system path |
|
|
|
To use the library, it must be located in a place which is known to the |
|
linker. There are several ways to achieve this. For sake of simplicity, in |
|
this example the library will be copied to a system location. It is common |
|
usage to copy additional libraries to '/usr/local/lib': sudo cp libdemo.so |
|
/usr/local/lib |
|
|
|
Step 4: update linker cache |
|
|
|
The linker now must become aware that there is a new library. Update the |
|
linker cache with the following command: sudo ldconfig |
|
|
|
Step 5: demonstration program |
|
|
|
The following program uses the function from the new library: |
|
|
|
PROTO bla |
|
x = 5 |
|
result = bla(x) |
|
PRINT result |
|
|
|
This program first declares the function 'bla' as prototype, so the BaCon |
|
parser will not choke on this external function. Then the external |
|
function is invoked and the result is printed on the screen. |
|
|
|
Step 6: compile and link |
|
|
|
Now the program must be compiled with reference to the library created |
|
before. This can be done as follows: ./bacon -l demo program.bac |
|
|
|
With the Unix command 'ldd' it will be visible that the resulting binary |
|
indeed has a dependency with the new library. |
|
|
|
When executed, the result of this program should show 25. |
|
|
|
Remarks |
|
|
|
In case global dynamic string arrays are used by the BaCon shared object, |
|
then these need to be initialized prior to using the arrays. This can be |
|
done by calling a special function available in each shared object created |
|
in BaCon: the 'BaCon_init()' function. In case the shared object is |
|
compiled by a GNU C compatible compiler, then this function is executed |
|
automatically. |
|
|
|
Creating internationalization files |
|
|
|
It is possible to create internationalized strings for a BaCon program. In |
|
order to do so, OPTION INTERNATIONAL should be enabled in the beginning of |
|
the program. After this, make sure that each translatable string is |
|
surrounded by the INTL$ or NNTL$ function. |
|
|
|
Now start BaCon and use the '-x' option. This will generate a template for |
|
the catalog file, provided that the 'xgettext' utility is available on |
|
your platform. The generated template by default has the same name as your |
|
BaCon program, but with a '.pot' extension. |
|
|
|
Then proceed with the template file and fill in the needed translations, |
|
create the PO file as usual and copy the binary formatted catalog to the |
|
base directory of the catalog files (default: "/usr/share/locale"). |
|
|
|
The default textdomain and base directory can be changed with the |
|
TEXTDOMAIN statement. |
|
|
|
Below a complete sequence of steps creating internationalization files. |
|
Make sure the GNU gettext utilities are installed. |
|
|
|
Step 1: create program |
|
|
|
The following simple program should be translated: |
|
|
|
OPTION INTERNATIONAL TRUE |
|
PRINT INTL$("Hello cruel world!") |
|
x = 2 |
|
PRINT x FORMAT NNTL$("There is %ld green bottle", "There are %ld green |
|
bottles", x) |
|
|
|
This program is saved as 'hello.bac'. |
|
|
|
Step 2: compile program |
|
|
|
Now compile the program using the '-x' option. |
|
|
|
# bacon -x hello.bac |
|
|
|
Next to the resulting binary, a template catalog file is created called |
|
'hello.pot'. |
|
|
|
Step 3: create catalog file |
|
|
|
At the command line prompt, run the 'msginit' utility on the generated |
|
template file. |
|
|
|
# msginit -l nl_NL -o hello.po -i hello.pot |
|
|
|
In this example, the nl_NL locale is used, which is Dutch. This will |
|
create a genuine catalog file called 'hello.po' from the template |
|
'hello.pot'. |
|
|
|
Step 4: add translations |
|
|
|
Edit the catalog file 'hello.po' manually, by adding the necessary |
|
translations. |
|
|
|
Step 5: create object file |
|
|
|
Again at the command line prompt, run the 'msgfmt' utility to convert the |
|
catalog file to a binary machine object file. The result will have the |
|
same name but with an '.mo' extension: |
|
|
|
# msgfmt -c -v -o hello.mo hello.po |
|
|
|
Step 6: install |
|
|
|
Copy the resulting binary formatted catalog file 'hello.mo' into the |
|
correct locale directory. In this example, the locale used was 'nl_NL'. |
|
Therefore, it needs to be copied to the default textdomain directory |
|
'/usr/share/locale' appended with the locale name, thus: |
|
/usr/share/locale/nl_NL. In there, the subdirectory LC_MESSAGES should |
|
contain the binary catalog file. |
|
|
|
# cp hello.mo /usr/share/locale/nl_NL/LC_MESSAGES/ |
|
|
|
The TEXTDOMAIN statement can be used to change the default directory for |
|
the catalog files. |
|
|
|
Step 7: setup Unix environment |
|
|
|
Finally, the Unix environment needs to understand that the correct locale |
|
must be used. To do so, simply set the LANG environment variable to the |
|
desired locale. |
|
|
|
# export LANG=nl_NL |
|
|
|
After this, the BaCon program will show the translated strings. |
|
|
|
Networking |
|
|
|
TCP |
|
|
|
Using BaCon, it is possible to create programs which have access to TCP |
|
networking. The following small demonstration shows a client program which |
|
fetches a website over HTTP: |
|
|
|
OPEN "www.basic-converter.org:80" FOR NETWORK AS mynet |
|
SEND "GET / HTTP/1.1rnHost: www.basic-converter.orgrnrn" TO mynet |
|
REPEAT |
|
RECEIVE dat$ FROM mynet |
|
total$ = total$ & dat$ |
|
UNTIL ISFALSE(WAIT(mynet, 5000)) |
|
CLOSE NETWORK mynet |
|
PRINT total$ |
|
|
|
The following program verifies if a remote site can be reached by a |
|
specific port, trying to access it via a specific interface on the |
|
localhost: |
|
|
|
CATCH GOTO Error |
|
OPEN "www.basic-converter.org:443" FOR NETWORK FROM "192.168.1.107" AS net |
|
PRINT "The host 'basic-converter.org' listens at port 443." |
|
CLOSE NETWORK net |
|
END |
|
LABEL Error |
|
PRINT "The host 'basic-converter.org' either is not reachable, |
|
filtered or has port 443 not open." |
|
|
|
The next program shows how to setup a simple TCP server. The main program |
|
uses OPEN FOR SERVER after which the ACCEPT function handles the incoming |
|
connection: |
|
|
|
PRINT "Connect from other terminals with 'telnet localhost 51000' and |
|
enter text - 'quit' ends." |
|
OPEN "localhost:51000" FOR SERVER AS mynet |
|
WHILE TRUE |
|
fd = ACCEPT(mynet) |
|
REPEAT |
|
RECEIVE dat$ FROM fd |
|
PRINT "Found: ", dat$; |
|
UNTIL LEFT$(dat$, 4) = "quit" |
|
CLOSE SERVER fd |
|
WEND |
|
|
|
UDP |
|
|
|
The UDP mode can be set with the OPTION NETWORK statement. After this, a |
|
network program for UDP looks the same as a network program for TCP. This |
|
is an example client program: |
|
|
|
OPTION NETWORK UDP |
|
OPEN "localhost:1234" FOR NETWORK AS mynet |
|
SEND "Hello" TO mynet |
|
CLOSE NETWORK mynet |
|
|
|
Example server program: |
|
|
|
OPTION NETWORK UDP |
|
OPEN "localhost:1234" FOR SERVER AS mynet |
|
RECEIVE dat$ FROM mynet |
|
CLOSE SERVER mynet |
|
PRINT dat$ |
|
|
|
BROADCAST |
|
|
|
BaCon also knows how to send data in UDP broadcast mode. For example: |
|
|
|
OPTION NETWORK BROADCAST |
|
OPEN "192.168.1.255:12345" FOR NETWORK AS mynet |
|
SEND "Using UDP broadcast" TO mynet |
|
CLOSE NETWORK mynet |
|
|
|
Example server program using UDP broadcast, listening to all interfaces: |
|
|
|
OPTION NETWORK BROADCAST |
|
OPEN "*:12345" FOR SERVER AS mynet |
|
RECEIVE dat$ FROM mynet |
|
CLOSE SERVER mynet |
|
PRINT dat$ |
|
|
|
MULTICAST |
|
|
|
If UDP multicast is required then simply specify MULTICAST. Optionally, |
|
the TTL can be determined also. Here are the same examples, but using a |
|
multicast address with a TTL of 5: |
|
|
|
OPTION NETWORK MULTICAST 5 |
|
OPEN "225.2.2.3:1234" FOR NETWORK AS mynet |
|
SEND "This is UDP multicast" TO mynet |
|
CLOSE NETWORK mynet |
|
|
|
Example server program using multicast: |
|
|
|
OPTION NETWORK MULTICAST |
|
OPEN "225.2.2.3:1234" FOR SERVER AS mynet |
|
RECEIVE dat$ FROM mynet |
|
CLOSE SERVER mynet |
|
PRINT dat$ |
|
|
|
SCTP |
|
|
|
BaCon also supports networking using the SCTP protocol. Optionally, a |
|
value for the amount of streams within one association can be specified. |
|
|
|
OPTION NETWORK SCTP 5 |
|
OPEN "127.0.0.1:12380", "172.17.130.190:12380" FOR NETWORK AS mynet |
|
SEND "Hello world" TO mynet |
|
CLOSE NETWORK mynet |
|
|
|
An example server program: |
|
|
|
OPTION NETWORK SCTP 5 |
|
OPEN "127.0.0.1:12380", "172.17.130.190:12380" FOR SERVER AS mynet |
|
RECEIVE txt$ FROM mynet |
|
CLOSE SERVER mynet |
|
PRINT txt$ |
|
|
|
TLS secured network connections |
|
|
|
The previous chapter demonstrated network connections where the data is |
|
transferred over the wire in plain text. However, with the increasing |
|
vulnerabilities in current network traffic, it usually is a good idea to |
|
apply Transport Layer Security (TLS). |
|
|
|
BaCon does not implement a propriety TLS standard by its own. However, it |
|
can make use of existing libraries like OpenSSL. Alternatively, BaCon also |
|
allows other TLS implementations, in case these provide an OpenSSL |
|
compatible API. Examples are the GnuTLS and WolfSSL libraries but also |
|
projects forking from OpenSSL, like BoringSSL and LibreSSL. |
|
|
|
To enable TLS, simply add OPTION TLS to the program. From then on, new |
|
network connections are considered to be TLS encapsulated: |
|
|
|
OPTION TLS TRUE |
|
|
|
This option enables the usage of OpenSSL by default. The presence of the |
|
OpenSSL libraries and header files on the system is required. BaCon will |
|
try to convert the source program and assumes the default locations of the |
|
OpenSSL development files. However, if these reside at a different |
|
location, it is possible to specify their location as follows: |
|
|
|
PRAGMA TLS openssl INCLUDE <openssl/ssl.h> LDFLAGS -lssl -lcrypto |
|
|
|
The OPTION TLS statement is always required, but instead of OpenSSL, it is |
|
possible to specify a different library: |
|
|
|
PRAGMA TLS gnutls |
|
|
|
This will provide an indication that BaCon should make use of the |
|
development files from the GnuTLS implementation. If these files should be |
|
taken from a special location: |
|
|
|
PRAGMA TLS gnutls INCLUDE <gnutls/openssl.h> LDFLAGS -lgnutls |
|
-lgnutls-openssl |
|
|
|
Lastly, BaCon supports WolfSSL as well: |
|
|
|
PRAGMA TLS wolfssl |
|
|
|
Also for the WolfSSL library it is possible to specify the location of the |
|
development files: |
|
|
|
PRAGMA TLS wolfssl INCLUDE <wolfssl/options.h> <wolfssl/openssl/ssl.h> |
|
LDFLAGS -lwolfssl |
|
|
|
BaCon can use the function CA$ to discover the certificate authority of |
|
the connection, and CN$ to discover the common name. The CIPHER$ function |
|
can be used to obtain details on the encryption and the VERIFY function to |
|
verify the validity of the certificate. |
|
|
|
The following small program queries a Mac address API over TLS using |
|
default OpenSSL: |
|
|
|
OPTION TLS TRUE |
|
website$ = "api.macvendors.com" |
|
mac$ = "b0:52:16:d0:3c:fb" |
|
OPEN website$ & ":443" FOR NETWORK AS mynet |
|
SEND "GET /" & mac$ & " HTTP/1.1rnHost: " & website$ & "rnrn" TO |
|
mynet |
|
RECEIVE info$ FROM mynet |
|
CLOSE NETWORK mynet |
|
PRINT TOKEN$(info$, 2, "rnrn") |
|
|
|
The next program shows how to setup a simple webserver using TLS: |
|
|
|
OPTION TLS TRUE |
|
CERTIFICATE "key.pem", "certificate.pem" |
|
CATCH GOTO resume_on_error |
|
CONST Msg$ = "<html><head>Hello from BaCon!</head></html>" |
|
PRINT "Connect with your browser to 'https://localhost:51000'." |
|
OPEN "localhost:51000" FOR SERVER AS mynet |
|
WHILE TRUE |
|
client = ACCEPT(mynet) |
|
IF client < 0 THEN CONTINUE |
|
RECEIVE dat$ FROM client |
|
PRINT dat$ |
|
SEND "HTTP/1.1 200 OkrnContent-Length: " & STR$(LEN(Msg$)) & |
|
"rnrn" & Msg$ TO client |
|
CLOSE SERVER client |
|
WEND |
|
LABEL resume_on_error |
|
RESUME |
|
|
|
The program below demonstrates a plain HTTPS connection using GnuTLS: |
|
|
|
OPTION TLS TRUE |
|
PRAGMA TLS gnutls INCLUDE <gnutls/openssl.h> LDFLAGS -lgnutls |
|
-lgnutls-openssl |
|
website$ = "www.google.com" |
|
OPEN website$ & ":443" FOR NETWORK AS mynet |
|
SEND "GET / HTTP/1.1rnHost: " & website$ & "rnrn" TO mynet |
|
WHILE WAIT(mynet, 2000) |
|
RECEIVE data$ FROM mynet |
|
total$ = total$ & data$ |
|
IF REGEX(data$, "</html>") THEN BREAK |
|
WEND |
|
PRINT REPLACE$(total$, "rn[0-9a-fA-F]+rn", "rn", TRUE) |
|
PRINT "--------------------------" |
|
PRINT CIPHER$(mynet) |
|
PRINT CA$(mynet) |
|
PRINT CN$(mynet) |
|
PRINT VERIFY(mynet, pem_file_with_rootca$) |
|
PRINT "--------------------------" |
|
CLOSE NETWORK mynet |
|
|
|
Ramdisks and memory streams |
|
|
|
When creating programs which need heavy I/O towards the hard drive, it may |
|
come handy to create a ramdisk for performance reasons. Basically, a |
|
ramdisk is a storage in memory. While on Unix level administrator rights |
|
are required to create such a disk, BaCon can create an elementary ramdisk |
|
during runtime which is accessible within the program. |
|
|
|
First, some amount of memory needs to be claimed which has to be opened in |
|
streaming mode. This returns a memory pointer which indicates the current |
|
position in memory, similar to a file pointer for files. |
|
|
|
Then, the statements GETLINE and PUTLINE can be used to read and write |
|
lines of data towards the memory storage. For example: |
|
|
|
memory_chunk = MEMORY(1000) |
|
OPEN memory_chunk FOR MEMORY AS ramdisk |
|
PUTLINE "Hello world" TO ramdisk |
|
|
|
If the ramdisk needs to be read from the beginning, use MEMREWIND to |
|
reposition the memory pointer. In the next example, a GETLINE retrieves |
|
the line which was stored there: |
|
|
|
MEMREWIND ramdisk |
|
GETLINE text$ FROM ramdisk |
|
|
|
If the option MEMSTREAM was set to TRUE, BaCon can treat the created |
|
ramdisk also as a string variable, which allows manipulations by using the |
|
standard string functions. The variable used for the memory pointer must |
|
be a string variable: |
|
|
|
OPTION MEMSTREAM TRUE |
|
memory_chunk = MEMORY(1000) |
|
OPEN memory_chunk FOR MEMORY AS ramdisk$ |
|
PUTLINE "Hello world" TO ramdisk$ |
|
MEMREWIND ramdisk$ |
|
IF INSTR(ramdisk$, "world") THEN PRINT "found! |
|
PRINT REPLACE$(ramdisk$, "Hello", "Goodbye") |
|
|
|
Always make sure that there is enough memory to perform string changes to |
|
the ramdisk. The RESIZE statement safely can be used to enlarge the |
|
claimed memory during runtime, as this will preserve the data. |
|
|
|
The contents of the ramdisk can be written to disk using PUTBYTE. However, |
|
it must be clear how many bytes need to be written, as the total amount of |
|
memory reserved to the ramdisk may be bigger than the actual amount of |
|
data. The function MEMTELL can be used in case the memory pointer is |
|
positioned at the end of the ramdisk: |
|
|
|
memory_chunk = MEMORY(1000) |
|
OPEN memory_chunk FOR MEMORY AS ramdisk |
|
PUTLINE "Hello world" TO ramdisk |
|
OPEN "ramdisk.txt" FOR WRITING AS txtfile |
|
PUTBYTE memory_chunk TO txtfile CHUNK |
|
MEMTELL(ramdisk)-memory_chunk |
|
CLOSE FILE txtfile |
|
CLOSE MEMORY ramdisk |
|
FREE memory_chunk |
|
|
|
Alternatively, if the ramdisk was opened with OPTION MEMSTREAM set to |
|
TRUE, the string function LEN also will return the length of the data. |
|
|
|
Delimited strings |
|
|
|
A delimited string is a string which can be cut into parts, based on a |
|
character or on a set of characters. An example of such a string is a |
|
plain space delimited line in a textbook, where the words are separated by |
|
a whitespace. Another example is an ASCII file, in which the lines are |
|
separated by a newline. A very famous example of a delimited string is the |
|
Comma Separated Value (CSV) string. From another point of view, a |
|
delimited string also can be looked at as a list of items, which is the |
|
basis of LISP like languages. |
|
|
|
The SPLIT statement can be used to split a string into elements of an |
|
array, based on a delimiter. As with all statements and functions handling |
|
delimited strings, the SPLIT statement will ignore a delimiter when it |
|
occurs between double quotes. Such delimiter is considered to be part of |
|
the string. For example: |
|
|
|
csv$ = "This,is,a,CSV,string,"with,an",escaped,delimiter" |
|
SPLIT csv$ BY "," TO member$ SIZE x |
|
|
|
One of the resulting members of the array will contain "with,an" because |
|
the comma is enclosed within double quotes. BaCon will consider this a |
|
piece of text where the characters should be kept together. The behavior |
|
of skipping delimiters within double quotes can be changed by setting or |
|
unsetting OPTION QUOTED. The JOIN statement can be used to merge array |
|
elements back into one (delimited) string. |
|
|
|
Instead of SPLIT, it is possible to use FOR..IN as well. This statement |
|
will subsequently return the parts of the delimited text into a variable. |
|
Example: |
|
|
|
FOR i$ IN "aa bb cc" |
|
|
|
In this example, the variable 'i$' will subsequently have the value 'aa', |
|
'bb' and 'cc' assigned. Also the FOR statement will skip a delimiter |
|
occurring within double quotes. Note that the OPTION COLLAPSE will prevent |
|
empty results, both for SPLIT and FOR. |
|
|
|
It is also possible to return a single member in a delimited string. This |
|
can be achieved with the TOKEN$ function. Note that all element counting |
|
is 1-based. The following returns the 5^th member of a space delimited |
|
string, being "e f". It does not use an optional third parameter, because |
|
for all delimited string processing, BaCon defines the default delimiter |
|
as a single space: |
|
|
|
PRINT TOKEN$("a b c d "e f" g h i j", 5) |
|
|
|
But this function also works in case some other delimiter is used. The |
|
delimiter must then be specified in the third optional argument. |
|
|
|
PRINT TOKEN$("1,2,3,4,5", 3, ",") |
|
|
|
All the functions handling delimited strings accept such an optional |
|
argument. Alternatively, OPTION DELIM can define the delimiter string |
|
which should be used in subsequent functions. As mentioned, the default |
|
value is a single space. |
|
|
|
The function EXPLODE$ will return a delimited string based on a specified |
|
amount of characters: |
|
|
|
PRINT EXPLODE$("aabbcc", 1) |
|
|
|
Alternatively, the inline loop function COIL$ can create a delimited |
|
string also, using an optional variable, for example the alphabet: |
|
|
|
PRINT COIL$(i, 26, CHR$(64+i)) |
|
|
|
The MERGE$ function will do the opposite: merging the elements of a |
|
delimited string to one regular string, again optionally specifying a |
|
delimiter, for example: |
|
|
|
PRINT MERGE$("aa,bb,cc", ",") |
|
|
|
The ISTOKEN function can verify if a text occurs as a token in a delimited |
|
string. If so, this function returns the actual position of the token: |
|
|
|
t$ = "Kiev Amsterdam Lima Moscow Warschau Vienna Paris Madrid Bonn Bern |
|
Rome" |
|
PRINT "Is this a token: ", ISTOKEN(t$, "Rome") |
|
|
|
To obtain the first members from a delimited string, the function HEAD$ |
|
can be used: |
|
|
|
PRINT "The first 2 elements: ", HEAD$(t$, 2) |
|
|
|
Similarly, it is possible to get the last elements by using TAIL$: |
|
|
|
PRINT "The last element: ", TAIL$(t$, 1) |
|
|
|
The TAIL$ and HEAD$ functions have their complementary functions in LAST$ |
|
and FIRST$. The following example will show all members of a delimited |
|
string except the first 2 members: |
|
|
|
PRINT "All except the first 2 elements: ", LAST$(t$, 2) |
|
|
|
The next code shows all members except the last: |
|
|
|
PRINT "All except the last element: ", FIRST$(t$, 1) |
|
|
|
It also is possible to obtain an excerpt using CUT$. The following piece |
|
of code will get the members from delimited string 't$' starting at |
|
position 2 and ending at position 4 inclusive: |
|
|
|
PRINT "Some middle members: ", CUT$(t$, 2, 4) |
|
|
|
Instead of fetching a member, BaCon also can change a member in a |
|
delimited string directly by using the CHANGE$ function: |
|
|
|
result$ = CHANGE$("a,b,c,d,e,f,g,h,i,j", 5, "Ok", ",") |
|
|
|
It is even possible to swap two members in a delimited string with the |
|
EXCHANGE$ function: |
|
|
|
result$ = EXCHANGE$("a b c d e f g h i j", 5, 4) |
|
|
|
The UNIQ$ function will return a delimited string where all members occur |
|
only once: |
|
|
|
city$ = "Kiev Lima Moscow "New York" Warschau "New York" Rome" |
|
PRINT "Unique member cities: ", UNIQ$(city$) |
|
|
|
To add more members to a delimited string, use APPEND$: |
|
|
|
t$ = APPEND$(t$, 2, "Santiago") |
|
|
|
And to delete a member from a delimited string, use DEL$: |
|
|
|
t$ = DEL$(t$, 3) |
|
|
|
There are also functions to sort the members in a delimited string (SORT$) |
|
and to put them in reversed order (REV$). With PROPER$ it is possible to |
|
capitalize the first letter of each individual element in a delimited |
|
string. The ROTATE$ function rotates the items in a delimited string. The |
|
COLLAPSE$ function will remove empty items in a delimited string. The |
|
MATCH function can compare elements between two delimited strings and |
|
PARSE can return parts of a delimited string based on wildcards. The WHERE |
|
function returns the actual character position of the indicated token. |
|
|
|
To determine if a string contains a delimiter at all, the HASDELIM |
|
function can be used, while the DELIM$ function can change the actual |
|
delimiter in a string to some other definition. |
|
|
|
If a member still contains double quotes and escaped double quotes, then |
|
this can be flattened out by using the FLATTEN$ function. This function |
|
will remove double quotes and put escaping one level lower: |
|
|
|
PRINT FLATTEN$(""Hello \" world"") |
|
|
|
Lastly, the function AMOUNT will count the number of members in a |
|
delimited string: |
|
|
|
nr = AMOUNT("a b c d e f g h i j") |
|
PRINT AMOUNT("a,b,c,d,e,f,g,h,i,j", ",") |
|
|
|
BaCon also has string functions available to handle delimited strings |
|
which use unbalanced delimiters. These are delimiters which consist of |
|
different characters, or different sets of characters. Examples of such |
|
strings are HTML or XML strings. They can be handled by functions like |
|
INBETWEEN$ and OUTBETWEEN$ very easily. For example, to obtain the title |
|
of a website from an HTML definition: |
|
|
|
PRINT INBETWEEN$("<html><head><title>Website</title></head>", "<title>", |
|
"</title>") |
|
|
|
By default, INBETWEEN$ will perform a non-greedy match, but the fourth |
|
optional argument can be set to specify a greedy match. |
|
|
|
Similarly, the OUTBETWEEN$ function will return everything but the matched |
|
substring, effectively cutting out a substring based on unbalanced |
|
delimiters. |
|
|
|
Note that OPTION COLLAPSE does not impact both INBETWEEN$ and OUTBETWEEN$. |
|
|
|
Regular expressions |
|
|
|
BaCon can digest POSIX compliant regular expressions when using the REGEX |
|
function or the string functions EXTRACT$, REPLACE$ and WALK$. For this, |
|
BaCon relies on the standard libc implementation. However, it is possible |
|
to define a different regular expression engine with the PRAGMA statement. |
|
|
|
For example, to specify the very fast NFA based regular expression library |
|
TRE, the following line must be added at the top of the program: |
|
|
|
PRAGMA RE tre |
|
|
|
This will include the header file from the TRE library and will link |
|
against its shared object. Of course, the system needs to have the |
|
required development files from the TRE library installed. |
|
|
|
BaCon will add the default locations of all necessary files to the compile |
|
flags. In case these files are kept at a different location, it is |
|
possible to define this explicitly as well: |
|
|
|
PRAGMA RE tre INCLUDE <tre/regex.h> LDFLAGS -ltre |
|
|
|
Next to the TRE library, also the Oniguruma library can be specified: |
|
|
|
PRAGMA RE onig |
|
|
|
When specifying the required development files: |
|
|
|
PRAGMA RE onig INCLUDE <onigposix.h> LDFLAGS -lonig |
|
|
|
Also the famous PCRE library is supported: |
|
|
|
PRAGMA RE pcre |
|
|
|
The full definition looks like: |
|
|
|
PRAGMA RE pcre INCLUDE <pcreposix.h> LDFLAGS -lpcreposix |
|
|
|
Basically, any regular expression library with a functional POSIX |
|
interface can be specified. This allows a lot of flexibility when certain |
|
features for regular expression parsing are required. The libraries TRE, |
|
Oniguruma and PCRE do not need a further INCLUDE or LDFLAGS specification |
|
if their development files have their default names and reside at their |
|
default location. |
|
|
|
Error trapping, error catching and debugging |
|
|
|
BaCon can distinguish between 4 types of errors. |
|
|
|
1. System errors. These relate to the environment in which BaCon runs. |
|
|
|
2. Syntax errors. These are detected during the conversion process. |
|
|
|
3. Compiler errors. These are generated by the C compiler and passed on |
|
to BaCon. |
|
|
|
4. Runtime errors. These can occur during execution of the program. |
|
|
|
When an error occurs, the default behavior of a BaCon program is to stop. |
|
Only in case of runtime errors, it is possible to let the program handle |
|
the error. |
|
|
|
* In case of statements, the CATCH GOTO command can jump to a |
|
self-defined error handling function. This is especially convenient |
|
when creating GUI applications, as runtime errors by default appear on |
|
the Unix command prompt. |
|
|
|
* In case of functions, the OPTION ERROR must be set to FALSE to prevent |
|
the program from stopping. The program then needs to check the |
|
reserved ERROR variable to handle any unexpected situation. |
|
|
|
Alternatively, it is possible to set a callback function for both |
|
statements and functions. This callback function can be defined by the |
|
CATCH ERROR statement. It should point to a function with three arguments: |
|
the first argument capturing the statement or function causing the error, |
|
the second the name of the file and the last the line number. |
|
|
|
To prevent BaCon from detecting runtime errors altogether, use TRAP |
|
SYSTEM. |
|
|
|
The reserved ERROR variable contains the number of the last error |
|
occurred. A full list of error numbers can be found in appendix A. With |
|
the ERR$ function a human readable text for the error number can be |
|
retrieved programmatically. |
|
|
|
Next to these options, the statement TRACE ON can set the program in such |
|
a way that it is executed at each keystroke, step-by-step. This way it is |
|
possible to spot the location where the problem occurs. The ESC-key will |
|
then exit the program. To switch of trace mode within a program, use TRACE |
|
OFF. |
|
|
|
Also the STOP statement can be useful in debugging. This will interrupt |
|
the execution of the program and return to the Unix command prompt, |
|
allowing intermediate checks. By using the Unix 'fg' command, or by |
|
sending the CONT signal to the PID of the program, execution can be |
|
resumed. |
|
|
|
Notes on transcompiling |
|
|
|
The process of translating a programming language into another language, |
|
and then compiling it, is also known as transcompiling. BaCon is a Basic |
|
to C translator, or a transcompiler, or transpiler. |
|
|
|
When using BaCon, three stages can be distinguished: |
|
|
|
1. conversion time |
|
|
|
2. compilation time |
|
|
|
3. runtime |
|
|
|
It is important to realize that BaCon commands can function in all these |
|
stages. Examples of statements which have impact the on conversion stage |
|
are INCLUDE, RELATE, USEC, USEH, WITH and some of the OPTION arguments. |
|
These statements instruct BaCon about the way the Basic code should be |
|
converted. |
|
|
|
A statement impacting the compilation stage is PRAGMA. With this statement |
|
it is possible to influence the behavior of the compiler. |
|
|
|
Most other BaCon statements are effective during runtime. These form the |
|
actual program being executed. |
|
|
|
It should be clear that the aforementioned stages cannot be mixed. For |
|
example, it does not make sense to define the argument for the INCLUDE |
|
statement in a string variable, as the INCLUDE statement is effective |
|
during conversion time, while variables are used during runtime. |
|
|
|
Note that except for system errors, the logic of the error messages |
|
basically follows the same structure: there are syntax errors (conversion |
|
time), compiler errors and runtime errors. The system errors relate to the |
|
possibility of using BaCon itself. |
|
|
|
Using the BaCon spartanic editor (BaSE) |
|
|
|
BaCon comes with a limited built-in ASCII editor which can display BaCon |
|
code using syntax highlighting. The editor requires an ANSI compliant |
|
terminal. To start the editor, simply use the '-e' argument and a |
|
filename: |
|
|
|
# bacon -e prog.bac |
|
|
|
If the file does not exist, then an empty screen occurs. Pressing the |
|
<ESC> button will pop up a menu down below the screen. The options are: |
|
|
|
- (H)elp: display the Help screen |
|
- (Q)uit: quit the editor |
|
|
|
The usual functionality for editing text applies. Most actions can be |
|
performed using the <CTRL> key and a regular key. The <CTRL>+<h> key |
|
combination will pop up the Help screen. |
|
|
|
The Help screen will show the following information: |
|
|
|
- <CTRL>+<n>: new file |
|
- <CTRL>+<l>: load file |
|
- <CTRL>+<s>: save file |
|
- <CTRL>+<x>: cut line of text |
|
- <CTRL>+<c>: copy line of text |
|
- <CTRL>+<v>: paste line of text |
|
- <CTRL>+<w> or <CTRL>+<del>: delete line |
|
- <HOME>: put cursor at start of line |
|
- <END>: put cursor at end of line |
|
- <PgUp>: move one page upwards |
|
- <PgDn>: move page downwards |
|
- <cursor keys>: navigate through text |
|
- <CTRL>+<f>: find term in code |
|
- <CTRL>+<g>: goto line number |
|
- <CTRL>+<e>: compile and execute program |
|
- <CTRL>+<a>: apply indentation |
|
- <CTRL>+<r>: toggle line numbers |
|
- <CTRL>+<b>: toggle text boldness |
|
- <CTRL>+<d>: show context info |
|
- <CTRL>+<h>: show this help |
|
- <CTRL>+<q>: quit BaCon spartanic editor |
|
|
|
The context info works by first moving the cursor to the statement or |
|
function for which more information is desired. Then, the <CTRL>+<d> key |
|
combination will try to lookup the keyword in the manpage. |
|
|
|
It is also possible to adjust the colors of the syntax highlighting. |
|
Create the BaCon configuration file ~/.bacon/bacon.cfg if it does not |
|
exist yet. The following keywords can set the coloring scheme, following |
|
the numbering of the COLOR statement: |
|
|
|
- statement_color (default: 2) |
|
- function_color (default: 6) |
|
- variable_color (default: 3) |
|
- type_color (default: 3) |
|
- number_color (default: 1) |
|
- comment_color (default: 4) |
|
- quote_color (default: 5) |
|
- default_color (default: 7) |
|
|
|
For example, to set the color for quoted text strings to green, the |
|
following definition can be added to the BaCon configuration file: |
|
|
|
quote_color 2 |
|
|
|
Support for GUI programming |
|
|
|
BaCon has a few functions available which enable basic GUI programming. |
|
These functions follow the "object/property" model and implement simple |
|
event handling. |
|
|
|
Enabling GUI functions |
|
|
|
To enable these functions, add the following line to your code: |
|
|
|
OPTION GUI TRUE |
|
|
|
By default, BaCon assumes Xaw as a backend. Though this is not the most |
|
attractive widget set in the world, it is always available on any Unix |
|
platform which has X installed. Alternatively, a different backend can be |
|
set using PRAGMA GUI. Currently, Xaw3d, Motif, TK, GTK2, GTK3, GTK4 and |
|
the console based CDK widgets (experimental) sets are supported. The |
|
following code will select Motif as a backend: |
|
|
|
PRAGMA GUI motif |
|
|
|
Instead of "motif", the PRAGMA GUI statement also accepts "xaw3d", "uil", |
|
"gtk2", "gtk3", "gtk4", "tk" and "cdk". |
|
|
|
BaCon generates the source code for the GUI so the required header files |
|
for the toolkits should be available on the compiling platform. |
|
|
|
Defining the GUI |
|
|
|
To define the GUI, the function GUIDEFINE can be used. This function may |
|
occur in the program only once. Its string argument should contain a list |
|
of declarative widget definitions, each set of definitions grouped between |
|
curly brackets. The GUIDEFINE function returns the GUI id number. This is |
|
an example for the Xaw widget toolkit: |
|
|
|
gui = GUIDEFINE( " |
|
{ type=window name=window callback=window XtNwidth=300 |
|
XtNtitle="Information" } |
|
{ type=dialogWidgetClass name=dialog parent=window XtNlabel="Enter |
|
term:" XtNvalue="<term>" } |
|
{ type=commandWidgetClass name=submit parent=dialog callback=XtNcallback |
|
XtNlabel="Submit" } ") |
|
|
|
As can be observed, each widget refers to properties which are specific to |
|
the Xaw toolkit. A widget must have a type and a name. Optionally, a |
|
widget can be attached to a parent, and it can submit a callback signal, |
|
in which case the signal name must be specified. |
|
|
|
The callback keyword can also define a particular string to be returned in |
|
the event loop, defined after the signal name. The following will return |
|
"click" when the button is pressed: |
|
|
|
{ type=commandWidgetClass name=submit parent=dialog |
|
callback=XtNcallback,click XtNlabel="Submit" } |
|
|
|
Setting properties |
|
|
|
The function GUISET can be used to specify more properties at a later |
|
stage in the program: |
|
|
|
CALL GUISET(gui, "label", XtNjustify, XtJustifyLeft) |
|
|
|
The function GUIGET is used to retrieve a value from a widget. The value |
|
is stored in a pointer variable: |
|
|
|
CALL GUIGET(gui, "text", XtNstring, &txt) |
|
|
|
For the TK backend, these functions can get and set variables from and to |
|
the several TK functions. |
|
|
|
Entering the mainloop |
|
|
|
Once the GUI is defined, the program can enter the event loop using |
|
GUIEVENT$. It requires the GUI id as an argument: |
|
|
|
WHILE TRUE |
|
event$ = GUIEVENT$(gui) |
|
SELECT event$ |
|
CASE "submit" |
|
BREAK |
|
ENDSELECT |
|
WEND |
|
|
|
When an event has happened, either the name of the widget causing the |
|
event is returned, or the defined string in the callback keyword. The |
|
BaCon program can decide what to do next. |
|
|
|
In some cases it may be necessary to obtain a value which is passed to the |
|
callback by the widget library. In such situation, the GUIEVENT$ function |
|
accepts an optional second boolean parameter. This will add the incoming |
|
callback value as a pointer attached as a string to the return value. |
|
|
|
For example, to obtain the selected item in a XawList widget, the Xaw |
|
library returns a struct containing information about the XawList. This |
|
can be fetched as follows: |
|
|
|
WHILE TRUE |
|
event$ = GUIEVENT$(gui, TRUE) |
|
SELECT TOKEN$(event$, 1) |
|
CASE "submit" |
|
BREAK |
|
CASE "list" |
|
info = (XawListReturnStruct*)DEC(TOKEN$(event$, 2)) |
|
PRINT TOKEN$(info->string, 1) |
|
ENDSELECT |
|
WEND |
|
|
|
Defining helper functions |
|
|
|
It is also possible to define supplementary helper functions. A widget |
|
library can implement additional functions to perform actions on widgets. |
|
These helper functions can be configured in the BaCon program by setting |
|
up a function pointer and then use GUIFN. |
|
|
|
For example, to define a helper function showing a Xaw widget: |
|
|
|
LOCAL (*show)() = XtPopup TYPE void |
|
CALL GUIFN(id, "window", show, XtGrabNonexclusive) |
|
|
|
Such definition may seem unnecessary, however, using GUIFN has several |
|
advantages: it is compliant with the overall API design, the source code |
|
becomes smaller in size, and most importantly, we do not need to worry |
|
about argument types of the helper function. |
|
|
|
For the TK backend, the GUIFN statement can define additional TCL code in |
|
the current TK context. |
|
|
|
Using native functions |
|
|
|
The function GUIWIDGET will return the memory address of a widget based on |
|
the defined name for that widget. This can come handy in cases where a GUI |
|
helper function is used natively. |
|
|
|
Overview of BaCon statements and functions |
|
|
|
ABS |
|
|
|
ABS(x) |
|
|
|
Type: function |
|
|
|
Returns the absolute value of x. This is the value of x without sign. |
|
Example without and with ABS, where the latter always will produce a |
|
positive output: |
|
|
|
PRINT x-y |
|
PRINT ABS(x-y) |
|
|
|
ACCEPT |
|
|
|
ACCEPT(fd) |
|
|
|
Type: function |
|
|
|
In a network program, this function waits for an incoming connection and |
|
returns a new descriptor to be used for SEND and RECEIVE. If the ACCEPT |
|
functions fails, then the returned value is a negative number. Example: |
|
|
|
OPEN "localhost:51000" FOR SERVER AS mynet |
|
WHILE TRUE |
|
fd = ACCEPT(mynet) |
|
REPEAT |
|
RECEIVE dat$ FROM fd |
|
PRINT "Found: ", dat$; |
|
UNTIL LEFT$(dat$, 4) = "quit" |
|
CLOSE SERVER fd |
|
WEND |
|
|
|
ACOS |
|
|
|
ACOS(x) |
|
|
|
Type: function |
|
|
|
Returns the calculated arc cosine of x, where x is a value in radians. |
|
|
|
ADDRESS |
|
|
|
ADDRESS(x) |
|
|
|
Type: function |
|
|
|
Returns the memory address of a variable or function. The ADDRESS function |
|
can be used when passing pointers to imported C functions (see IMPORT). |
|
|
|
ALARM |
|
|
|
ALARM <sub>, <time> |
|
|
|
Type: statement |
|
|
|
Sets a SUB to be executed in <time> milliseconds. The value '0' will |
|
cancel an alarm. The alarm will interrupt any action the BaCon program |
|
currently is performing; an alarm always has priority. |
|
|
|
After the sub is executed, the program will continue the operation it was |
|
doing when the alarm occurred. Example: |
|
|
|
SUB dinner |
|
PRINT "Dinner time!" |
|
END SUB |
|
ALARM dinner, 5000 |
|
|
|
ALIAS |
|
|
|
ALIAS <function> TO <alias> |
|
|
|
Type: statement |
|
|
|
Defines an alias to an existing function or an imported function. Aliases |
|
cannot be created for statements or operators. Example: |
|
|
|
ALIAS "printf" TO DISPLAY |
|
DISPLAY("Hello worldn") |
|
|
|
ALIGN$ |
|
|
|
ALIGN$(string$, width, type [,indent]) |
|
|
|
Type: function |
|
|
|
Aligns a multi line <string$> over a maximum of <width> characters. The |
|
<type> indicates the kind of alignment to apply: 0 = left alignment, 1 = |
|
right alignment, 2 = center alignment, and 3 means fill or justify. |
|
|
|
The alignment takes place in three stages. First, if the text starts with |
|
the UTF-8 byte order mark bytes 0xEF 0xBB 0xBF, then these are removed and |
|
the ALIGN$ function will automatically enable UTF8 mode for the text. |
|
Then, if the original text contains newline characters (0x0A), these are |
|
replaced with a single space. However, empty lines (double new lines |
|
indicating a paragraph) are preserved, as well as all other special |
|
characters, like a space (0x20), tab (0x09), carriage return (0x0D), non |
|
breaking space (0xA0) or a form feed (0x0C). Therefore, in some cases, it |
|
may be necessary to remove such special characters before using ALIGN$. |
|
|
|
The second stage will try to find the best spot where to replace the space |
|
character (0x20) for a newline character (0x0A). This is done within the |
|
provided <width>. If there are redundant adjacent spaces then these are |
|
removed. |
|
|
|
Note that the ALIGN$ function will not hyphenate words. Lines are being |
|
cut at a white space where possible. If a word does not fit in the |
|
provided width by itself, then it will be wrapped around. |
|
|
|
The third stage will apply the chosen type of alignment. In case type is |
|
0, 1 or 2, the lines in the final result are being padded with a single |
|
space character. In case type is 3, additional spaces are being added |
|
equally in between the words to align the text on both sides, except for |
|
the last line in a paragraph (where paragraphs are considered to be |
|
separated from each other by an empty line). |
|
|
|
If the original text contained the UTF8 order mark 0xEF 0xBB 0xBF, then |
|
the ALIGN$ function will put back the byte order mark in the first bytes |
|
of the result. For more information on the UTF8 byte order mark, see also |
|
the HASBOM and EDITBOM$ functions. |
|
|
|
The optional argument <indent> will prepend additional space characters to |
|
each line. Example: |
|
|
|
data$ = LOAD$("ascii_data.txt") |
|
PRINT ALIGN$(data$, 40, 0) |
|
|
|
The ALIGN$ can handle UTF8 strings correctly as well. If the original text |
|
does not contain the UTF8 byte order mark then UTF8 mode should be enabled |
|
manually. The following example aligns a UTF8 text without byte order mark |
|
at two sides, each line not containing more than 50 characters, starting |
|
10 positions from the left, while the text is being stripped from carriage |
|
return symbols: |
|
|
|
OPTION UTF8 TRUE |
|
text$ = LOAD$("Jane_Austen.txt") |
|
PRINT ALIGN$(EXTRACT$(text$, CR$), 50, 3, 10) |
|
|
|
AMOUNT |
|
|
|
AMOUNT(string$ [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Returns the amount of tokens in a string split by delimiter$. The |
|
delimiter$ is optional. If it is omitted, then the definition from OPTION |
|
DELIM is assumed. When specified, it may consist of multiple characters. |
|
If delimiter$ occurs between double quotes in string$ then it is ignored. |
|
Example: |
|
|
|
PRINT AMOUNT("a b c d "e f" g h i j") |
|
PRINT AMOUNT("Dog Cat@@@Mouse Bird@@@123@@@456@@@789", "@@@") |
|
|
|
AND |
|
|
|
<expr> AND <expr> |
|
|
|
Type: operator |
|
|
|
Performs a logical 'and' between two expressions. For the binary 'and', |
|
use the '&' symbol. Example: |
|
|
|
IF x = 0 AND y = 1 THEN PRINT "Hello" |
|
|
|
APPEND |
|
|
|
APPEND string$ TO filename$ |
|
|
|
APPEND string$, other$ |
|
|
|
Type: statement |
|
|
|
This statement can be used two ways. The first is to save a string to disk |
|
in one step. If the file already exists, the data will be appended. See |
|
BAPPEND for appending binary files in one step, and |
|
OPEN/WRITELN/READLN/CLOSE to read and write to a file using a filehandle |
|
in append mode. |
|
|
|
In the second way, this statement simply will append one string to |
|
another, thereby modifying the original string. |
|
|
|
Examples: |
|
|
|
APPEND result$ TO "/tmp/more_data.txt" |
|
APPEND str$, "world" |
|
|
|
APPEND$ |
|
|
|
APPEND$(string$, pos, token$ [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Inserts <token$> into a delimited string$ split by delimiter$, at position |
|
<pos>. The delimiter$ is optional. If it is omitted, then the definition |
|
from OPTION DELIM is assumed. When specified, it may consist of multiple |
|
characters. |
|
|
|
If the <pos> parameter is 0, or is bigger than the amount of members in |
|
<string$>, then <token$> is appended. If OPTION COLLAPSE is FALSE |
|
(default) then APPEND$ always will add a delimiter to an empty <string$>, |
|
after which <token$> will be added. In case of TRUE however, appending |
|
<token$> will simply copy the contents of <token$> to an empty <string$>. |
|
|
|
If the <pos> parameter is negative, then <string$> will be returned |
|
unmodified. If delimiter$ occurs between double quotes in string$, then it |
|
is ignored. This behavior can be changed by setting OPTION QUOTED to |
|
FALSE. See DEL$ to delete members, and the chapter on delimited string |
|
functions for more information about delimited strings. Example: |
|
|
|
PRINT APPEND$("Rome Amsterdam Kiev Bern Paris London", 2, "Vienna") |
|
|
|
ARGUMENT$ |
|
|
|
ARGUMENT$ |
|
|
|
Type: variable |
|
|
|
Reserved variable containing name of the program and the arguments to the |
|
program. These are all separated by spaces. |
|
|
|
If the CMDLINE function is used then this variable will contain optional |
|
arguments to command line functions. |
|
|
|
ASC |
|
|
|
ASC(char) |
|
|
|
Type: function |
|
|
|
Calculates the ASCII value of char (opposite of CHR$). See also UCS for |
|
UTF8 characters. Example: |
|
|
|
PRINT ASC("x") |
|
|
|
ASIN |
|
|
|
ASIN(x) |
|
|
|
Type: function |
|
|
|
Returns the calculated arcsine of x, where x is a value in radians. |
|
|
|
ATN |
|
|
|
ATN(x) |
|
|
|
Type: function |
|
|
|
Returns the calculated arctangent of x, where x is a value in radians. |
|
|
|
PRINT ATN(RAD(90)) |
|
|
|
ATN2 |
|
|
|
ATN2(y, x) |
|
|
|
Type: function |
|
|
|
Returns the calculated arctangent of y/x. The sign of the arguments is |
|
used to determine the quadrant. |
|
|
|
PRINT ATN2(30, -35) |
|
|
|
B64DEC$ |
|
|
|
B64DEC$(x$) |
|
|
|
Type: function |
|
|
|
Returns the decoded string or data from a BASE64 string. In case of binary |
|
data, the LEN function will correctly provide the amount of bytes |
|
available in the string. Example: |
|
|
|
PRINT B64DEC$("QmFDb24gaXMgZnVu") |
|
|
|
Example where binary PNG data is recovered into a string variable and |
|
saved: |
|
|
|
png$ = B64DEC$(some_encoded_png$) |
|
BSAVE png$ TO "picture.png" SIZE LEN(png$) |
|
|
|
B64ENC$ |
|
|
|
B64ENC$(x$[, length]) |
|
|
|
Type: function |
|
|
|
Returns the encoded string from a regular string or memory area. In case |
|
of a string, the length of the string is the default. In case of a memory |
|
area, the additional <length> argument must specify the amount of bytes to |
|
encode. Examples: |
|
|
|
PRINT B64ENC$("Encode me") |
|
PRINT B64ENC$(mem, 1024) |
|
|
|
BAPPEND |
|
|
|
BAPPEND data TO filename$ SIZE amount |
|
|
|
Type: statement |
|
|
|
Saves a memory area with binary data to disk in one step. If the file |
|
already exists, the data will be appended. See APPEND for appending text |
|
files in one step, and OPEN/PUTBYTE/GETBYTE/CLOSE to read and write to a |
|
file using a filehandle. Example: |
|
|
|
BAPPEND mem TO "/home/me/data" SIZE 10 |
|
|
|
BASENAME$ |
|
|
|
BASENAME$(filename$ [, flag]) |
|
|
|
Type: function |
|
|
|
Returns the filename part of a given full filename. The optional [flag] |
|
indicates the part of the filename to be returned. The values are: 0 = |
|
full filename (default), 1 = filename without extension and 2 = extension |
|
without filename. See also DIRNAME$. |
|
|
|
BIN$ |
|
|
|
BIN$(x) |
|
|
|
Type: function |
|
|
|
Calculates the binary value of x and returns a string with the result. The |
|
type size depends on the setting of OPTION MEMTYPE. If MEMTYPE is set to |
|
char (default), then 8 bits are returned, if it is set to short then 16 |
|
bits are returned, etc. See also DEC to convert back to decimal. |
|
|
|
BIT |
|
|
|
BIT(x) |
|
|
|
Type: function |
|
|
|
This function returns the value for a bit on position <x>. If x = 0 then |
|
it returns 1, if x = 1 then it returns 2, if x = 2 then it returns 4 and |
|
so on. |
|
|
|
PRINT BIT(x) |
|
|
|
BLOAD |
|
|
|
BLOAD(filename$) |
|
|
|
Type: function |
|
|
|
Performs a load into a memory address of a binary file. The memory address |
|
is returned when the loading was successful. When done with the data, the |
|
memory should be freed with the FREE statement. See LOAD$ for loading text |
|
files in one step, and OPEN/PUTBYTE/GETBYTE/CLOSE to read and write to a |
|
file using a file handle. Example: |
|
|
|
binary = BLOAD("/home/me/myprog") |
|
PRINT "First two bytes are: ", PEEK(binary), " ", PEEK(binary+1) |
|
FREE binary |
|
|
|
BREAK |
|
|
|
BREAK [x] |
|
|
|
Type: statement |
|
|
|
Breaks out loop constructs like FOR/NEXT, WHILE/WEND, REPEAT/UNTIL or |
|
DOTIMES/DONE. |
|
|
|
The optional parameter can define to which level the break should take |
|
place in case of nested loops. This parameter should be an integer value |
|
higher than 0. See also CONTINUE to resume a loop. |
|
|
|
BSAVE |
|
|
|
BSAVE data TO filename$ SIZE amount |
|
|
|
Type: statement |
|
|
|
Saves a memory area with binary data to disk in one step. If the file |
|
already exists it is overwritten. The amount must be specified in bytes. |
|
See SAVE for saving text files in one step, and OPEN/PUTBYTE/GETBYTE/CLOSE |
|
to read and write to a file using a filehandle. Example: |
|
|
|
BSAVE mem TO "/home/me/picture.png" SIZE 12123 |
|
|
|
BYTELEN |
|
|
|
BYTELEN(x$, y [, z]) |
|
|
|
Type: function |
|
|
|
Returns the actual byte length of UTF8 string x$ in case of y characters. |
|
This is a wrapper function which can be used in combination with regular |
|
string functions, allowing correct processing of UTF8 string sequences. If |
|
the optional argument z is set then start counting the byte length from |
|
the right size of string x$. Example: |
|
|
|
str$ = "A © and a ® symbol" |
|
PRINT LEFT$(str$, BYTELEN(str$, 3)) |
|
PRINT RIGHT$(str$, BYTELEN(str$, 8, TRUE)) |
|
|
|
CA$ |
|
|
|
CA$(connection) |
|
|
|
Type: function |
|
|
|
Returns the Certificate Authority from the certificate used in the current |
|
network connection. Assumes that TLS has been enabled. See the chapter on |
|
secure network connections for more details. See also CN$. |
|
|
|
CALL |
|
|
|
CALL <sub name> [TO <var>] |
|
|
|
Type: statement |
|
|
|
Calls a subroutine if the sub is defined at the end of the program. With |
|
the optional TO also a function can be invoked which stores the result |
|
value in <var>. |
|
|
|
Example: |
|
|
|
CALL fh2celsius(72) TO celsius |
|
PRINT celsius |
|
|
|
CATCH |
|
|
|
CATCH GOTO <label> | RESET | ERROR <function> |
|
|
|
Type: statement |
|
|
|
The GOTO keyword sets the error function where the program should jump to |
|
if runtime error checking is enabled with TRAP. This only is applicable |
|
for statements. For an example, see the RESUME statement. |
|
|
|
The RESET keyword restores the BaCon default error messages for |
|
statements. |
|
|
|
The ERROR keyword allows setting a callback function where the program |
|
will jump to in case an error occurs. This works both for statements and |
|
functions provided that OPTION ERROR is set to FALSE. This is to prevent |
|
that erroneous functions will stop the program. The callback function |
|
should have three arguments which will hold the name of the statement or |
|
function, the name of the file and the line number where the error |
|
occurred. Example: |
|
|
|
OPTION ERROR FALSE |
|
CATCH ERROR help |
|
SUB help(c$, f$, no) |
|
PRINT "Error is: ", ERR$(ERROR), " in function ", c$, " in file '", |
|
f$, "' at line ", no |
|
PRINT "Callback ended" |
|
END SUB |
|
|
|
CEIL |
|
|
|
CEIL(x) |
|
|
|
Type: function |
|
|
|
Rounds x up to the nearest integral (integer) number. This function always |
|
returns a float value. See also FLOOR and ROUND. |
|
|
|
CERTIFICATE |
|
|
|
CERTIFICATE <key.pem>, <certificate.pem> |
|
|
|
Type: statement |
|
|
|
Defines the private key and certificate file in PEM format. This function |
|
is used to setup TLS server networking. For an example, see the chapter on |
|
TLS. |
|
|
|
CHANGE$ |
|
|
|
CHANGE$(string$, position, new$ [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Changes the token in string$, which is split by delimiter$, at position |
|
with new$. The delimiter$ is optional. If it is omitted, then the |
|
definition from OPTION DELIM is assumed. When specified, it may consist of |
|
multiple characters. If delimiter$ occurs between double quotes in string$ |
|
then it is ignored. This behavior can be changed by setting OPTION QUOTED |
|
to FALSE. |
|
|
|
If the indicated position is outside a valid range, the original string is |
|
returned. Use the FLATTEN$ function to flatten out the returned token. See |
|
also EXCHANGE$, TOKEN$ and SPLIT. |
|
|
|
Examples: |
|
|
|
PRINT CHANGE$("a b c d "e f" g h i j", 5, "OK") |
|
PRINT CHANGE$("a,b,c,d,e,f,g,h,i,j", 4, "123", ",") |
|
|
|
CHANGEDIR |
|
|
|
CHANGEDIR <directory> |
|
|
|
Type: statement |
|
|
|
Changes the current working directory. Example: |
|
|
|
CHANGEDIR "/tmp/mydir" |
|
|
|
CHOP$ |
|
|
|
CHOP$(x$[, y$[, z]]) |
|
|
|
Type: function |
|
|
|
Returns a string defined in x$ where on both sides <CR>, <NL>, <TAB> and |
|
<SPACE> have been removed. If other characters need to be chopped then |
|
these can be specified in the optional y$. The optional parameter z |
|
defines where the chopping must take place: 0 means on both sides, 1 means |
|
chop at the left and 2 means chop at the right. Examples: |
|
|
|
PRINT CHOP$("bacon", "bn") |
|
PRINT CHOP$(" hello world ", " ", 2) |
|
|
|
PRINT CHOP$("print "end"", "nrt " & CHR$(34)) |
|
|
|
CHR$ |
|
|
|
CHR$(x) |
|
|
|
Type: function |
|
|
|
Returns the character belonging to ASCII number x. This function does the |
|
opposite of ASC. The value for x must lie between 0 and 255. See UTF8$ for |
|
Unicode values. Example: |
|
|
|
LET a$ = CHR$(0x23) |
|
PRINT a$ |
|
|
|
CIPHER$ |
|
|
|
CIPHER$(connection) |
|
|
|
Type: function |
|
|
|
Returns the description of the encryption methods in use by the current |
|
network connection. Assumes that TLS has been enabled. See the chapter on |
|
secure network connections for more details. See also CA$ and CN$. |
|
|
|
CL$ |
|
|
|
CL$ |
|
|
|
Type: variable |
|
|
|
The Clear Line variable clears the line indicated by the current cursor |
|
position. See also EL$. |
|
|
|
CLASS |
|
|
|
CLASS |
|
<body> |
|
ENDCLASS | END CLASS |
|
|
|
Type: statement |
|
|
|
Defines a class in original C++ code. This code is put unmodified into the |
|
generated global header source file. It is particularly useful when |
|
embedding C++ code into BaCon. See also USEC and USEH. Example: |
|
|
|
CLASS TVision : public Tapplication |
|
public: |
|
TVision() : TProgInit(&TVision::TV_initStatusLine, |
|
&TVision::TV_initMenuBar, &Tvision::initDeskTop) |
|
{ |
|
} |
|
static TMenuBar *TV_initMenuBar(TRect); |
|
static TStatusLine *TV_initStatusLine(TRect); |
|
ENDCLASS |
|
|
|
CLEAR |
|
|
|
CLEAR |
|
|
|
Type: statement |
|
|
|
Clears the terminal screen. To be used with ANSI compliant terminals. |
|
|
|
CLOSE |
|
|
|
CLOSE FILE|DIRECTORY|NETWORK|SERVER|MEMORY|LIBRARY|DEVICE x[, y, z, ...] |
|
|
|
Type: statement |
|
|
|
Close file, directory, network, memory or library identified by handle. |
|
Multiple handles of the same type maybe used in a comma separated list. |
|
Examples: |
|
|
|
CLOSE FILE myfile |
|
CLOSE MEMORY mem1, mem2, block |
|
CLOSE LIBRARY "libgtk.so" |
|
|
|
CMDLINE |
|
|
|
CMDLINE(options$) |
|
|
|
Type: function |
|
|
|
Defines the possible command line options to the current program. The |
|
CMDLINE function returns the ASCII value of each option until all provided |
|
options are parsed, in which case a '-1' is returned. In case an unknown |
|
option is encountered, question mark is returned. |
|
|
|
If <options$> contains a colon, then an extra argument to the option is |
|
required. Such argument will appear in the reserved variable ARGUMENT$. |
|
Example where a program recognizes the options '-n' and '-f <arg>': |
|
|
|
REPEAT |
|
option = CMDLINE("nf:") |
|
PRINT option |
|
PRINT ARGUMENT$ |
|
UNTIL option = -1 |
|
|
|
CN$ |
|
|
|
CN$(connection) |
|
|
|
Type: function |
|
|
|
Returns the Common Name from the certificate used in the current network |
|
connection. Assumes that TLS has been enabled. See the chapter on secure |
|
network connections for more details. See also CA$. |
|
|
|
COIL$ |
|
|
|
COIL$([variable,] nr, expression$[, delimiter$]) |
|
|
|
Type: function |
|
|
|
This is an inline loop which returns the results of the repeatedly |
|
evaluated <expression$> appended to a delimited string. The optional |
|
<variable> must be a numeric variable and <nr> defines how many times the |
|
<expression$> is carried out. If <variable> is not present then the |
|
anonymous variable "_" will be used. |
|
|
|
It is possible to specify the concatenation delimiter explicitly. Note |
|
that this only works when COIL$ also defines a variable name, so COIL$ |
|
counts 4 parameters in total. |
|
|
|
It is not allowed to use nested COIL$ constructs, or to use COIL$ |
|
multitple times in the same statement. Such code will generate a syntax |
|
error during conversion time. See also EXPLODE$ for another method to |
|
create delimited strings, the inline LOOP$ to create regular strings, or |
|
the inline if IIF$. More info on delimited strings can be found in the |
|
chapter on delimited string functions. |
|
|
|
Example to get the first 10 letters in the Latin alphabet as a delimited |
|
string, using the anonymous variable: |
|
|
|
PRINT COIL$(10, CHR$(64+_)) |
|
|
|
The following code prints only the even numbers between 0 and 100: |
|
|
|
PRINT COIL$(100, IIF$(EVEN(), STR$())) |
|
|
|
This example prints the elements in a string array, each on a separate |
|
line: |
|
|
|
PRINT COIL$(i, 5, array$[i-1], NL$) |
|
|
|
COLLAPSE$ |
|
|
|
COLLAPSE$(string$ [,delim$]) |
|
|
|
Type: function |
|
|
|
Collapses a delimited string so no empty items are present. The resulting |
|
string will only contain items separated by exactly one delimiter. |
|
|
|
If the delimiter occurs between double quotes in string$, then it is |
|
ignored. This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
See also the chapter on delimited string functions for more information |
|
about delimited strings. Example: |
|
|
|
PRINT COLLAPSE$("a,,,b,,,,,,c,d,,,e", ",") |
|
|
|
COLLECT |
|
|
|
COLLECT <tree> TO <array> [SIZE <variable>][STATIC] |
|
|
|
Type: statement |
|
|
|
Retrieves all values of the nodes which are present in a binary tree. The |
|
results are stored in <array>. As it sometimes is unknown how many |
|
elements this resulting array will contain, the array should not be |
|
declared explicitly. Instead, COLLECT will declare the result array |
|
dynamically. |
|
|
|
If COLLECT is being used in a function or sub, then <array> will have a |
|
local scope. Else <array> will be visible globally, and can be accessed |
|
within all functions and subs. |
|
|
|
The total amount of elements created in this array is stored in the |
|
optional <variable>. This variable can be declared explicitly using LOCAL |
|
or GLOBAL. |
|
|
|
For more information and examples, see the chapter on binary trees. See |
|
also FIND to verify the presence of a node in a binary tree. Example: |
|
|
|
COLLECT mytree TO allnodes |
|
FOR x = 0 TO UBOUND(allnodes)-1 |
|
PRINT allnodes[x] |
|
NEXT |
|
|
|
The optional STATIC keyword allows the created <array> to be returned from |
|
a function. |
|
|
|
COLOR |
|
|
|
COLOR <BG|FG> TO <BLACK|RED|GREEN|YELLOW|BLUE|MAGENTA|CYAN|WHITE> |
|
COLOR <NORMAL|INTENSE|INVERSE|RESET> |
|
|
|
Type: statement |
|
|
|
Sets coloring for the output of characters in a terminal screen. For FG, |
|
the foreground color is set. With BG, the background color is set. The |
|
INTENSE and NORMAL keywords can be used combined with a color. This |
|
statement only works well with ANSI compliant terminals. Refer to the TYPE |
|
statement to set the terminal font type. Example: |
|
|
|
COLOR FG TO GREEN |
|
PRINT "This is green!" |
|
COLOR FG TO INTENSE RED |
|
PRINT "This is red!" |
|
COLOR RESET |
|
|
|
Instead of color names, it is also possible to use a numeric reference. |
|
The FG and BG indicators have an enumeration as well: |
|
|
|
Item Number |
|
Black 0 |
|
Red 1 |
|
Green 2 |
|
Yellow 3 |
|
Blue 4 |
|
Magenta 5 |
|
Cyan 6 |
|
White 7 |
|
BackGround 0 |
|
ForeGround 1 |
|
|
|
Example using numeric color references: |
|
|
|
COLOR 1 TO 3 |
|
PRINT "This is yellow!" |
|
COLOR RESET |
|
|
|
COLUMNS |
|
|
|
COLUMNS |
|
|
|
Type: function |
|
|
|
Returns the amount of columns in the current ANSI compliant terminal. See |
|
also ROWS. Example: |
|
|
|
PRINT "X,Y: ", COLUMNS, ",", ROWS |
|
|
|
CONCAT$ |
|
|
|
CONCAT$(x$, y$, ...) |
|
|
|
Type: function |
|
|
|
Returns the concatenation of x$, y$, ... The CONCAT$ function can accept |
|
an unlimited amount of arguments. Example: |
|
|
|
txt$ = CONCAT$("Help this is ", name$, " carrying a strange ", thing$) |
|
|
|
The CONCAT$ function is deprecated but it still is available for |
|
compatibility reasons. It can be used for high performance string |
|
concatenation but care should be taken when using non-BaCon functions as |
|
arguments. |
|
|
|
Instead, BaCon uses either the '&' symbol or the â+â symbol as infix |
|
string concatenation operator. These operators are more versatile and |
|
allow any kind of concatenation. The following is the same example using |
|
'&': |
|
|
|
txt$ = "Help this is " & name$ & " carrying a strange " & thing$ |
|
|
|
This will work as well: |
|
|
|
txt$ = "Help this is " + name$ + " carrying a strange " + thing$ |
|
|
|
CONST |
|
|
|
CONST <var> = <value> | <expr> |
|
|
|
Type: statement |
|
|
|
Assigns a value a to a label which cannot be changed during execution of |
|
the program. Consts are globally visible from the point where they are |
|
defined. Example: |
|
|
|
CONST WinSize = 100 |
|
CONST Screen = WinSize * 10 + 5 |
|
|
|
CONTINUE |
|
|
|
CONTINUE [x] |
|
|
|
Type: statement |
|
|
|
Skips the remaining body of loop constructs like FOR/NEXT, WHILE/WEND, |
|
REPEAT/UNTIL or DOTIMES/DONE. |
|
|
|
The optional parameter can define at which level a continue should be |
|
performed in case of nested loops, and should be an integer value higher |
|
than 0. |
|
|
|
COPY |
|
|
|
COPY <from> TO <new> [SIZE length] |
|
|
|
Type: statement |
|
|
|
If <from> and <to> contain string values, then COPY copies a file to a new |
|
file. Example: |
|
|
|
COPY "file.txt" TO "/tmp/new.txt" |
|
|
|
If the SIZE keyword is present, then COPY assumes a memory copy. Example |
|
copying one array to another: |
|
|
|
OPTION MEMTYPE long |
|
DECLARE array[5], copy[5] TYPE long |
|
array[0] = 15 |
|
array[1] = 24 |
|
array[2] = 33 |
|
array[3] = 42 |
|
array[4] = 51 |
|
COPY array TO copy SIZE 5 |
|
|
|
COS |
|
|
|
COS(x) |
|
|
|
Type: function |
|
|
|
Returns the calculated COSINE of x, where x is a value in radians. |
|
Example: |
|
|
|
PRINT COS(RAD(45)) |
|
|
|
COUNT |
|
|
|
COUNT(string, y) |
|
|
|
Type: function |
|
|
|
Returns the amount of times the ASCII or UCS value <y> occurs in <string>. |
|
Example: |
|
|
|
PRINT COUNT("Hello world", ASC("l")) |
|
OPTION UTF8 TRUE |
|
PRINT COUNT(FILL$(5, 0x1F600), 0x1F600) |
|
|
|
See also FILL$. |
|
|
|
CR$ |
|
|
|
CR$ |
|
|
|
Type: variable |
|
|
|
Represents the Carriage Return as a string. |
|
|
|
CURDIR$ |
|
|
|
CURDIR$ |
|
|
|
Type: function |
|
|
|
Returns the full path of the current working directory. See also ME$ or |
|
REALPATH$. |
|
|
|
CURSOR |
|
|
|
CURSOR <ON|OFF> | <FORWARD|BACK|UP|DOWN> [x] |
|
|
|
Type: statement |
|
|
|
Shows ("on") or hides ("off") the cursor in the current ANSI compliant |
|
terminal. Also, the cursor can be moved one position in one of the four |
|
directions. Optionally, the amount of steps to move can be specified. |
|
Example: |
|
|
|
PRINT "I am here" |
|
CURSOR DOWN 2 |
|
PRINT "...now I am here" |
|
|
|
CUT$ |
|
|
|
CUT$(string$, start, end [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Retrieves elements from a delimited string$ split by delimiter$, starting |
|
at <start> until <end> inclusive. The delimiter$ is optional. If it is |
|
omitted, then the definition from OPTION DELIM is assumed. When specified, |
|
it may consist of multiple characters. |
|
|
|
If the <start> parameter is higher than <end>, the result will be the same |
|
as when the parameters were reversed. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
HEAD$ and TAIL$, and the chapter on delimited string functions for more |
|
information about delimited strings. Example: |
|
|
|
PRINT "Excerpt: ", CUT$("Rome Amsterdam Kiev Bern Paris London", 2, 4) |
|
|
|
DATA |
|
|
|
DATA <x, y, z, ...> |
|
|
|
Type: statement |
|
|
|
Defines data. The DATA statement always contains data which is globally |
|
visible. The data can be read with the READ statement. If more data is |
|
read than available, then in case of numeric data a '0' will be retrieved, |
|
and in case of string data an empty string. To start reading from the |
|
beginning again use RESTORE. Example: |
|
|
|
DATA 1, 2, 3, 4, 5, 6 |
|
DATA 0.5, 0.7, 11, 0.15 |
|
DATA 1, "one", 2, "two", 3, "three", 4, "four" |
|
|
|
DAY |
|
|
|
DAY(x) |
|
|
|
Type: function |
|
|
|
Returns the day of the month (1-31) where x is amount of seconds since |
|
January 1, 1970. Example: |
|
|
|
PRINT DAY(NOW) |
|
|
|
DEC |
|
|
|
DEC(x [,flag]) |
|
|
|
Type: function |
|
|
|
Calculates the decimal value of x, where x should be passed as a string. |
|
The optional [flag] parameter determines the base to convert from. If flag |
|
= 0 (default) then base is hexadecimal. If flag lies between 2 and 36 then |
|
the corresponding base is assumed. Note that DEC always returns a positive |
|
number. See also HEX$ and BIN$ for hexadecimal and binary conversions. |
|
Example: |
|
|
|
PRINT DEC("AB1E") |
|
PRINT DEC("00010101", 2) |
|
|
|
DECLARE |
|
|
|
DECLARE <var>[,var2,var3,...] TYPE | ASSOC | TREE <c-type> | [ARRAY |
|
<size>] |
|
|
|
Type: statement |
|
|
|
This statement is similar to the GLOBAL statement and is available for |
|
compatibility reasons. |
|
|
|
DECR |
|
|
|
DECR <x>[, y] |
|
|
|
Type: statement |
|
|
|
Decreases variable <x> with 1. Optionally, the variable <x> can be |
|
decreased with <y>. Example: |
|
|
|
x = 10 |
|
DECR x |
|
PRINT x |
|
DECR x, 3 |
|
PRINT x |
|
|
|
DEF FN |
|
|
|
DEF FN <label> [(args)] = <value> | <expr> |
|
|
|
Type: statement |
|
|
|
Assigns a value or expression to a label. Examples: |
|
|
|
DEF FN func(x) = 3 * x |
|
PRINT func(12) |
|
|
|
DEF FN First$(x$) = LEFT$(x$, INSTR(x$, " ")-1) |
|
PRINT First$("One Two Three") |
|
|
|
DEG |
|
|
|
DEG(x) |
|
|
|
Type: function |
|
|
|
Returns the degree value of x radians. Example: |
|
|
|
PRINT DEG(PI) |
|
|
|
DEL$ |
|
|
|
DEL$(string$, pos [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Deletes a member at position <pos> from a delimited string$ split by |
|
delimiter$. The delimiter$ is optional. If it is omitted, then the |
|
definition from OPTION DELIM is assumed. When specified, it may consist of |
|
multiple characters. |
|
|
|
If the <pos> parameter is smaller than 1 or bigger than the amount of |
|
members in <string$>, then the original string$ is returned. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See |
|
APPEND$ for adding members, and the chapter on delimited string functions |
|
for more information about delimited strings. Example: |
|
|
|
PRINT DEL$("Rome Amsterdam Kiev Bern Paris London", 2) |
|
|
|
DELETE |
|
|
|
DELETE <FILE|DIRECTORY|RECURSIVE> <x$> [FROM] <binary tree> |
|
|
|
Type: statement |
|
|
|
Deletes a file with the FILE argument, or an empty directory when using |
|
the DIRECTORY argument. The RECURSIVE argument can delete a directory |
|
containing files. It can also delete a complete directory tree. The FROM |
|
keyword is used when deleting a node from a binary tree. If an error |
|
occurs then this can be captured by using the CATCH statement. Example: |
|
|
|
DELETE FILE "/tmp/data.txt" |
|
DELETE RECURSIVE "/usr/data/stuff" |
|
DELETE value FROM tree |
|
|
|
DELIM$ |
|
|
|
DELIM$(string$, old$, new$) |
|
|
|
Type: function |
|
|
|
Changes the delimiter in string$ from old$ to new$. The new delimiter can |
|
be of different size compared to the old delimiter. |
|
|
|
If the old delimiter occurs between double quotes in string$, then it is |
|
ignored. This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
See also the chapter on delimited string functions for more information |
|
about delimited strings. Example: |
|
|
|
PRINT "Changed delimiter: ", DELIM$("f,q,a,c,i,b,r,t,e,d,z,", ",", "@@@") |
|
|
|
DIRNAME$ |
|
|
|
DIRNAME$(filename$) |
|
|
|
Type: function |
|
|
|
Returns the pathname part of a given filename. See also REALPATH$ and |
|
BASENAME$. |
|
|
|
DLE$ |
|
|
|
DLE$ |
|
|
|
Type: variable |
|
|
|
The DOS Line Ending variable returns a carriage return and a newline |
|
character. See also NL$ and CR$. |
|
|
|
DO |
|
|
|
DO |
|
<body> |
|
DONE |
|
|
|
Type: statement |
|
|
|
With DO/DONE a body of statements can be grouped together. This is useful |
|
in case of special compiler constructs like pragmas. Example: |
|
|
|
PRAGMA omp parallel sections |
|
DO |
|
<...code...> |
|
DONE |
|
|
|
DOTIMES |
|
|
|
DOTIMES x |
|
<body> |
|
[BREAK]|[CONTINUE] |
|
DONE |
|
|
|
Type: statement |
|
|
|
With DOTIMES/DONE a body of statements can be repeated for a fixed amount |
|
of times without the need for a variable. This is known as an anonymous |
|
loop. As with other loops, it can be prematurely exited by using BREAK. |
|
Also, part of the body can be skipped by the use of the CONTINUE |
|
statement. See FOR/NEXT, WHILE/WEND and REPEAT/UNTIL for setting up other |
|
types of loops. To refer to the current loop, the anonymous variable "_" |
|
can be used. Example: |
|
|
|
DOTIMES 10 |
|
PRINT "This is loop number ", _, " in DOTIMES." |
|
DONE |
|
|
|
EDITBOM$ |
|
|
|
EDITBOM$(string$, action) |
|
|
|
Type: function |
|
|
|
Adds or deletes the UTF8 byte order mark from <string$>. If <action> is |
|
â0â then the byte order mark will be removed from <string$>, if found in |
|
the string. If <action> is â1â then the UTF8 byte order will be added to |
|
the string if it is not there already. See also HASBOM to determine if a |
|
string has a UTF8 byte order mark. |
|
|
|
EL$ |
|
|
|
EL$ |
|
|
|
Type: variable |
|
|
|
The Erase Line variable clears the line from the current cursor position |
|
towards the end of the line. See also CL$. |
|
|
|
END |
|
|
|
END [value] |
|
|
|
Type: statement |
|
|
|
Exits a program. Optionally, a value can be provided which the program can |
|
return to the shell. |
|
|
|
ENDFILE |
|
|
|
ENDFILE(filehandle) |
|
|
|
Type: function |
|
|
|
Function to check if EOF on a file opened with <handle> is reached. If the |
|
end of a file is reached, the value '1' is returned, else this function |
|
returns '0'. For an example, see the OPEN statement. |
|
|
|
ENUM |
|
|
|
ENUM |
|
item1, item2, item3 |
|
ENDENUM | END ENUM |
|
|
|
Type: statement |
|
|
|
Enumerates variables automatically. If no value is provided, the |
|
enumeration starts at 0 and will increase with integer numbers. Example: |
|
|
|
ENUM |
|
cat, dog, fish |
|
END ENUM |
|
|
|
It is also possible to explicitly define a value: |
|
|
|
ENUM |
|
Monday=1, Tuesday=2, Wednesday=3 |
|
END ENUM |
|
|
|
EPRINT |
|
|
|
EPRINT [value] | [text] | [variable] | [expression] [FORMAT <format>[TO |
|
<variable>[SIZE <size>]] | [,] | [;] |
|
|
|
Type: statement |
|
|
|
Same as PRINT but uses 'stderror' as output. |
|
|
|
EQ |
|
|
|
x EQ y |
|
|
|
Type: operator |
|
|
|
Verifies if x is equal to y. To improve readability it is also possible to |
|
use IS instead. Both the EQ and IS operators only can be used in case of |
|
numerical comparisons. Examples: |
|
|
|
IF q EQ 5 THEN |
|
PRINT "q equals 5" |
|
END IF |
|
|
|
BaCon also accepts a single '=' symbol for comparison. Next to the single |
|
'=' also the double '==' can be used. These work both for numerical |
|
comparisons and for string comparisons. See also NE. |
|
|
|
IF b$ = "Hello" THEN |
|
PRINT "world" |
|
END IF |
|
|
|
EQUAL |
|
|
|
EQUAL(x$, y$) |
|
|
|
Type: function |
|
|
|
Compares two strings, and returns 1 if x$ and y$ are equal, or 0 if x$ and |
|
y$ are not equal. Use OPTION COMPARE to establish case insensitive |
|
comparison. Example: |
|
|
|
IF EQUAL(a$, "Hello") THEN |
|
PRINT "world" |
|
END IF |
|
|
|
The EQUAL function is in place for compatibility reasons. The following |
|
code also works: |
|
|
|
IF a$ = "Hello" THEN |
|
PRINT "world" |
|
END IF |
|
|
|
ERR$ |
|
|
|
ERR$(x) |
|
|
|
Type: function |
|
|
|
Returns the runtime error as a human readable string, identified by x. |
|
Example: |
|
|
|
PRINT ERR$(ERROR) |
|
|
|
ERROR |
|
|
|
ERROR |
|
|
|
Type: variable |
|
|
|
This is a reserved variable, which contains the last error number. This |
|
variable may be reset during runtime. |
|
|
|
ESCAPE$ |
|
|
|
ESCAPE$(string$) |
|
|
|
Type: function |
|
|
|
Parses the text in <string$> and converts special characters (like newline |
|
or Unicode) into their escaped version. This functionality mainly is used |
|
by C files or JSON files. The special characters are converted into |
|
default C escape sequences like 'n', 'r', 't' etc, and into 'u' and |
|
'U' for Unicode characters. Non-printable binary data in the string is |
|
not converted. See also UNESCAPE$ to do the opposite. Example: |
|
|
|
PRINT ESCAPE$("Hello world ð") |
|
|
|
EVAL |
|
|
|
EVAL(x$) |
|
|
|
Type: function |
|
|
|
Returns the evaluated result of a mathematical function described in a |
|
string. This function relies on the presence of the 'libmatheval' library |
|
and development header files on the compiling platform. The EVAL function |
|
first needs to be enabled using OPTION EVAL. |
|
|
|
The syntax for the mathematical function follows the regular C syntax. |
|
This means that the operators + (add), - (subtract), * (multiply), / |
|
(divide) and ^ (exponent) work as usual. More over, the following |
|
functions are supported as well: exp, log, sqrt, sin, cos, tan, cot, sec, |
|
csc, asin, acos, atan, acot, asec, acsc, sinh, cosh, tanh, coth, sech, |
|
csch, asin), acosh, atanh, acoth, asech, acsch, log2e, e, log10e, ln2, |
|
ln10, pi, pi_2, pi_4, 1_pi, 2_pi, 2_sqrtpi, sqrt, sqrt1_2 and abs. |
|
|
|
The string may contain real variable names from the BaCon program. These |
|
will be evaluated automatically. The variables must be declared as |
|
floating type (double) before. Example: |
|
|
|
OPTION EVAL TRUE |
|
DECLARE x, y TYPE FLOATING |
|
x = 3 |
|
y = 4 |
|
nr = 5 |
|
PRINT EVAL("x*x + y +" & STR$(nr) & " + 6") |
|
|
|
EVEN |
|
|
|
EVEN(x) |
|
|
|
Type: function |
|
|
|
Returns 1 if x is even, else returns 0. |
|
|
|
EXCHANGE$ |
|
|
|
EXCHANGE$(haystack$, pos1, pos2 [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Exchanges the token at pos1 with the token at pos2 in haystack$ split by |
|
delimiter$. The delimiter$ is optional. If it is omitted, then the |
|
definition from OPTION DELIM is assumed. When specified, it may consist of |
|
multiple characters. If delimiter$ occurs between double quotes in |
|
haystack$ then it is ignored. This behavior can be changed by setting |
|
OPTION QUOTED to FALSE. |
|
|
|
If one of the indicated positions is outside a valid range, the original |
|
string is returned. Use the FLATTEN$ function to flatten out the returned |
|
token. See also CHANGE$, TOKEN$ and SPLIT. Examples: |
|
|
|
PRINT EXCHANGE$("a b c d "e f" g h i j", 8, 5) |
|
PRINT EXCHANGE$("a,b,c,d,e,f,g,h,i,j", 4, 7, ",") |
|
|
|
The next example code snippet sorts a delimited string. It uses the Bubble |
|
Sort algorithm: |
|
|
|
t$ = "Kiev Amsterdam Lima Moscow Warschau Vienna Paris Madrid Bonn Bern |
|
Rome" |
|
total = AMOUNT(t$) |
|
WHILE total > 1 |
|
FOR x = 1 TO total-1 |
|
IF TOKEN$(t$, x) > TOKEN$(t$, x+1) THEN t$ = EXCHANGE$(t$, x, x+1) |
|
NEXT |
|
DECR total |
|
WEND |
|
|
|
Note that this is just an example to demonstrate the EXCHANGE$ function. |
|
Delimited strings can be sorted using the native SORT$ function. |
|
|
|
EXEC$ |
|
|
|
EXEC$(command$ [, stdin$[, out]]) |
|
|
|
Type: function |
|
|
|
Executes an operating system command and returns the result to the BaCon |
|
program. The exit status of the executed command itself is stored in the |
|
reserved variable RETVAL. Optionally, a second argument may be used to |
|
feed to STDIN. Also optionally, a third argument can be specified to |
|
determine whether all output needs to be captured (0 = default), only |
|
stdout (1) or only stderr (2). See SYSTEM to plainly execute a system |
|
command. Example: |
|
|
|
result$ = EXEC$("ls -l") |
|
result$ = EXEC$("bc", "123*456" & NL$ & "quit") |
|
PRINT EXEC$("ls xyz123", NULL, 2) |
|
|
|
EXIT |
|
|
|
EXIT |
|
|
|
Type: statement |
|
|
|
Exits a SUB or FUNCTION prematurely. Note that functions which are |
|
supposed to return a value will return a 0. String functions will return |
|
an empty string. |
|
|
|
Also note that it is allowed to write EXIT SUB or EXIT FUNCTION to improve |
|
code readability. |
|
|
|
EXP |
|
|
|
EXP(x) |
|
|
|
Type: function |
|
|
|
Returns e (base of natural logarithms) raised to the power of x. |
|
|
|
EXPLODE$ |
|
|
|
EXPLODE$(string$, [length [, delimiter$]]) |
|
|
|
Type: function |
|
|
|
Splits a string based on <length> characters and returns the result in a |
|
delimited string using the default delimiter. The <length> parameter is |
|
optional. If not specified then the default value is 1. |
|
|
|
Also the delimiter$ is optional. If it is omitted, then the definition |
|
from OPTION DELIM is assumed. When specified, it may consist of multiple |
|
characters. |
|
|
|
See also SPLIT to create an array based on a delimiter, MERGE$ to join the |
|
components of a delimited string back to a regular string, and the chapter |
|
on delimited string functions for more information about delimited |
|
strings. Example: |
|
|
|
PRINT EXPLODE$("Amsterdam", 2) |
|
|
|
EXTRACT$ |
|
|
|
EXTRACT$(x$, y$[, flag]) |
|
|
|
Type: function |
|
|
|
Returns the string defined in <x$> from which the string mentioned in <y$> |
|
has been removed. The optional flag determines if the <y$> should be taken |
|
as a regular expression where OPTION COMPARE establishes case insensitive |
|
expression matching. See also REPLACE$. |
|
|
|
Examples: |
|
|
|
PRINT EXTRACT$("bacon program", "ra") |
|
PRINT EXTRACT$(name$, "e") |
|
PRINT EXTRACT$("a b c", " .* ", TRUE) |
|
|
|
FALSE |
|
|
|
FALSE |
|
|
|
Type: variable |
|
|
|
Represents and returns the value of '0'. |
|
|
|
FILEEXISTS |
|
|
|
FILEEXISTS(filename$) |
|
|
|
Type: function |
|
|
|
Verifies if <filename$> exists. If the file exists, this function returns |
|
1. Else it returns 0. This function also can be used to verify if a |
|
directory exists. If <filename$> is a symbolic link, it is dereferenced. |
|
|
|
FILELEN |
|
|
|
FILELEN(filename$) |
|
|
|
Type: function |
|
|
|
Returns the size of a file identified by <filename$>. If an error occurs |
|
this function returns '-1'. The ERR$ statement can be used to find out the |
|
error if TRAP is set to LOCAL. Example: |
|
|
|
length = FILELEN("/etc/passwd") |
|
|
|
FILETIME |
|
|
|
FILETIME(filename$, type) |
|
|
|
Type: function |
|
|
|
Returns the timestamp of a file identified by <filename$>, depending on |
|
the type of timestamp indicated in <type>. The type can be one of the |
|
following: 0 = access time, 1 = modification time and 2 = status change |
|
time. Example: |
|
|
|
stamp = FILETIME("/etc/hosts", 0) |
|
PRINT "Last access: ", MONTH$(stamp), " ", DAY(stamp), ", ", YEAR(stamp) |
|
|
|
FILETYPE |
|
|
|
FILETYPE(filename$) |
|
|
|
Type: function |
|
|
|
Returns the type of a file identified by <filename$>. If an error occurs |
|
this function returns '0'. The ERR$ statement can be used find out which |
|
error if TRAP is set to LOCAL. The following values may be returned: |
|
|
|
Value Meaning |
|
0 Error or undetermined |
|
1 Regular file |
|
2 Directory |
|
3 Character device |
|
4 Block device |
|
5 Named pipe (FIFO) |
|
6 Symbolic link |
|
7 Socket |
|
|
|
FILL$ |
|
|
|
FILL$(x, y) |
|
|
|
Type: function |
|
|
|
Returns an <x> amount of character <y>. The value for y must lie between 0 |
|
and 127 in ASCII mode, or between 0 and 1114111 (0x10FFFF) in case OPTION |
|
UTF8 is enabled. Example printing 10 times the character '@': |
|
|
|
PRINT FILL$(10, ASC("@")) |
|
|
|
Example printing 5 times a smiley character using unicode: |
|
|
|
OPTION UTF8 TRUE |
|
PRINT FILL$(5, 0x1F600) |
|
|
|
See also COUNT to count the amount of times a character occurs in a |
|
string. |
|
|
|
FIND |
|
|
|
FIND(binary tree, value) |
|
|
|
Type: function |
|
|
|
Verifies the presence of a value in a binary tree. For more information |
|
and examples, see the chapter on binary trees. |
|
|
|
FIRST$ |
|
|
|
FIRST$(string$, amount [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Retrieves the remaining elements except the last <amount> from a delimited |
|
<string$> split by delimiter$. The delimiter$ is optional. If it is |
|
omitted, then the definition from OPTION DELIM is assumed. When specified, |
|
it may consist of multiple characters. |
|
|
|
If no delimiter is present in the string, this function will return the |
|
full <string$>. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
|
|
See also TAIL$ to obtain elements counting from the end from the delimited |
|
string, and HEAD$ to obtain elements counting from the start. Refer to the |
|
chapter on delimited string functions for more information about delimited |
|
strings. Example: |
|
|
|
PRINT "Remaining first members: ", FIRST$("Rome Amsterdam Kiev Bern Paris |
|
London", 2) |
|
|
|
FLATTEN$ |
|
|
|
FLATTEN$(txt$ [, groupingchar$]) |
|
|
|
Type: function |
|
|
|
Flattens out a string where the double quote symbol is used to group parts |
|
of the string together. Instead of the double quote symbol a different |
|
character can be specified (optional). See also UNFLATTEN$ for the reverse |
|
operation. Examples: |
|
|
|
PRINT FLATTEN$(""Hello \"cruel\" world"") |
|
PRINT FLATTEN$(TOKEN$("Madrid,Kiev,"New York",Paris", 3, ",")) |
|
PRINT FLATTEN$("'Hello world'", "'") |
|
|
|
FLOOR |
|
|
|
FLOOR(x) |
|
|
|
Type: function |
|
|
|
Returns the rounded down value of x. Note that this function returns a |
|
float value. Refer to CEIL for rounding up. |
|
|
|
FOR |
|
|
|
FOR var = x TO|DOWNTO y [STEP z] |
|
<body> |
|
[BREAK]|[CONTINUE] |
|
NEXT [var] |
|
|
|
FOR var$ IN source$ [STEP delimiter$] |
|
<body> |
|
[BREAK]|[CONTINUE] |
|
NEXT [var] |
|
|
|
Type: statement |
|
|
|
With FOR/NEXT a body of statements can be repeated a fixed amount of |
|
times. |
|
|
|
In the first usage the variable x will be increased (to) or decreased |
|
(downto) until y with 1, unless a STEP is specified. Example: |
|
|
|
FOR x = 1 TO 10 STEP 0.5 |
|
PRINT x |
|
NEXT |
|
|
|
In the second usage of FOR, the variable <var$> will be assigned the space |
|
delimited strings mentioned in source$. Instead of a space delimiter, some |
|
other delimiter can be specified after the STEP keyword. The delimiter can |
|
consist of multiple characters. If the <delimiter$> occurs in between |
|
double quotes, then it is skipped until FOR finds the next one. This |
|
behavior can be changed by setting OPTION QUOTED to FALSE. |
|
|
|
To prevent empty results, OPTION COLLAPSE can be set to TRUE (or 1). See |
|
also SPLIT to create an array of delimited strings. |
|
|
|
Example: |
|
|
|
OPTION COLLAPSE TRUE |
|
FOR x$ IN "Hello cruel world" |
|
PRINT x$ |
|
NEXT |
|
|
|
FOR y$ IN "1,2,"3,4",5" STEP "," |
|
PRINT y$ |
|
NEXT |
|
|
|
FORK |
|
|
|
FORK |
|
<child> |
|
[ENDFORK [x]] | [END FORK [x]] |
|
|
|
Type: function |
|
|
|
Duplicate the current running program in memory. If the return value is 0, |
|
then we're in the child process. If the child process needs an explicit |
|
exit then ENDFORK can be used. |
|
|
|
If the return value > 0, then we are in the parent process; the actual |
|
value is the process ID of the spawned child. |
|
|
|
If the return value < 0, then an error has occurred. See also REAP to |
|
detect and cleanup child processes which have ended, or SIGNAL to prevent |
|
occurring zombie processes altogether. Example: |
|
|
|
pid = FORK |
|
IF pid = 0 THEN |
|
PRINT "I am the child, my PID is:", MYPID |
|
ENDFORK |
|
ELIF pid > 0 THEN |
|
PRINT "I am the parent, pid of child:", pid |
|
REPEAT |
|
PRINT "Waiting for child to exit" |
|
SLEEP 50 |
|
UNTIL REAP(pid) |
|
ELSE |
|
PRINT "Error in fork" |
|
ENDIF |
|
|
|
FP |
|
|
|
FP (x) |
|
|
|
Type: function |
|
|
|
Returns the memory address of a function with name 'x'. Example: |
|
|
|
SUB Hello |
|
PRINT "Hello world" |
|
END SUB |
|
|
|
DECLARE (*func)() TYPE void |
|
func = FP(Hello) |
|
CALL (*func)() |
|
|
|
FREE |
|
|
|
FREE x[, y, z, ...] |
|
|
|
Type: statement |
|
|
|
Releases claimed memory (see also MEMORY). Multiple memory pointers can be |
|
provided. Example: |
|
|
|
mem1 = MEMORY(500) |
|
mem2 = MEMORY(100) |
|
FREE mem1, mem2 |
|
|
|
This statement also can be used to delete individual members from |
|
associative arrays: |
|
|
|
FREE array$("abc") |
|
|
|
Lastly, it can delete all members of an associative array in one step: |
|
|
|
FREE array$ |
|
|
|
FUNCTION |
|
|
|
FUNCTION <name> ()|(STRING s, NUMBER i, FLOATING f, VAR v SIZE t) [TYPE |
|
<c-type>] |
|
<body> |
|
RETURN <x> |
|
ENDFUNC | ENDFUNCTION | END FUNCTION |
|
|
|
Type: statement |
|
|
|
Defines a function. The variables within a function are visible globally, |
|
unless declared with the LOCAL statement. Instead of the Bacon types |
|
STRING, NUMBER and FLOATING for the incoming arguments, also regular |
|
C-types can be used. If no type is specified, then BaCon will recognize |
|
the argument type from the variable suffix. In case no suffix is |
|
available, plain NUMBER type is assumed. With VAR a variable amount of |
|
arguments can be defined. |
|
|
|
A FUNCTION always returns a value or a string, this should explicitly be |
|
specified with the RETURN statement. If the FUNCTION returns a string, |
|
then the function name should end with a '$' to indicate a string by |
|
value. Function names also may end with the '#' or '%' type suffix, to |
|
force a float or integer return type. |
|
|
|
Furthermore, it is also possible to explicitly define the type of the |
|
return value using the TYPE keyword. |
|
|
|
Examples: |
|
|
|
FUNCTION fh2celsius(FLOATING fahrenheit) TYPE float |
|
PRINT "Calculating Celsius..." |
|
RETURN (fahrenheit-32)*5/9 |
|
ENDFUNCTION |
|
|
|
FUNCTION Hello$(STRING name$) |
|
RETURN "Hello " & name$ & " !" |
|
ENDFUNCTION |
|
|
|
GETBYTE |
|
|
|
GETBYTE <memory> FROM <handle> [CHUNK x] [SIZE y] |
|
|
|
Type: statement |
|
|
|
Retrieves binary data into a memory area from a either a file or a device |
|
identified by handle, with optional amount of <x> bytes depending on |
|
OPTION MEMTYPE (default amount of bytes = 1). Also optionally, the actual |
|
amount retrieved can be stored in variable <y>. Use PUTBYTE to write |
|
binary data. |
|
|
|
Example program: |
|
|
|
OPEN prog$ FOR READING AS myfile |
|
bin = MEMORY(100) |
|
GETBYTE bin FROM myfile SIZE 100 |
|
CLOSE FILE myfile |
|
|
|
GETENVIRON$ |
|
|
|
GETENVIRON$(var$) |
|
|
|
Type: function |
|
|
|
Returns the value of the environment variable 'var$'. If the environment |
|
variable does not exist, this function returns an empty string. See |
|
SETENVIRON to set an environment variable. |
|
|
|
GETFILE |
|
|
|
GETFILE <var> FROM <dirhandle> [FTYPE <var>] |
|
|
|
Type: statement |
|
|
|
Reads a file from an opened directory. Subsequent reads return the files |
|
in the directory. If there are no more files then an empty string is |
|
returned. Optionally, the FTYPE keyword can store the actual file type of |
|
the file. The resulting file type numbering follows the same schedule as |
|
the FILETYPE function. Note that this optional feature is only supported |
|
on a few file systems, like btrfs, ext2, ext3, ext4, recent xfs, etc. |
|
Example: |
|
|
|
OPEN "/tmp" FOR DIRECTORY AS mydir |
|
REPEAT |
|
GETFILE myfile$ FROM mydir FTYPE thetype |
|
PRINT "File found: '", myfile$, "' - type: ", thetype |
|
UNTIL ISFALSE(LEN(myfile$)) |
|
CLOSE DIRECTORY mydir |
|
|
|
GETKEY |
|
|
|
GETKEY |
|
|
|
Type: function |
|
|
|
Returns a key from the keyboard without waiting for <RETURN>-key. See also |
|
INPUT and WAIT. Example: |
|
|
|
PRINT "Press <escape> to exit now..." |
|
key = GETKEY |
|
IF key = 27 THEN |
|
END |
|
END IF |
|
|
|
GETLINE |
|
|
|
GETLINE <variable$> FROM <handle> |
|
|
|
Type: statement |
|
|
|
Reads a line of data from a memory area identified by <handle> into a |
|
string variable. The memory area can be opened in streaming mode using the |
|
the OPEN statement (see also the chapter on ramdisks and memory streams). |
|
A line of text is read until the next newline character. Example: |
|
|
|
GETLINE text$ FROM mymemory |
|
|
|
See also PUTLINE to store lines of text into memory areas. |
|
|
|
GETPEER$ |
|
|
|
GETPEER$(x) |
|
|
|
Type: function |
|
|
|
Gets the IP address and port of the (remote) host connected to a handle |
|
returned by OPEN FOR NETWORK or OPEN FOR SERVER. Example in case of a |
|
client connection: |
|
|
|
website$ = "www.basic-converter.org" |
|
OPEN website$ & ":443" FOR NETWORK AS mynet |
|
PRINT "Remote IP is: ", GETPEER$(mynet) |
|
|
|
Example when setting up a TCP server: |
|
|
|
OPEN "localhost:51000" FOR SERVER AS mynet |
|
PRINT "Peer is: ", GETPEER$(mynet) |
|
CLOSE SERVER mynet |
|
|
|
GETX / GETY |
|
|
|
GETX |
|
GETY |
|
|
|
Type: function |
|
|
|
Returns the current x and y position of the cursor. An ANSI compliant |
|
terminal is required. See GOTOXY to set the cursor position. |
|
|
|
GLOBAL |
|
|
|
GLOBAL <var>[,var2,var3,...] [TYPE]|ASSOC|TREE <c-type> | [ARRAY <size>] |
|
|
|
Type: statement |
|
|
|
Explicitly declares a variable to a C-type. The ASSOC keyword is used to |
|
declare associative arrays. The TREE keyword is used to declare binary |
|
trees. This is always a global declaration, meaning that variables |
|
declared with the GLOBAL keyword are visible in each part of the program. |
|
Use LOCAL for local declarations. |
|
|
|
The ARRAY keyword is used to define a dynamic array, which can be resized |
|
with REDIM at a later stage in the program. |
|
|
|
Optionally, within a SUB or FUNCTION it is possible to use GLOBAL in |
|
combination with RECORD to define a record variable which is visible |
|
globally. |
|
|
|
GLOBAL x TYPE float |
|
GLOBAL q$ |
|
GLOBAL new_array TYPE float ARRAY 100 |
|
GLOBAL name$ ARRAY 25 |
|
|
|
Multiple variables of the same type can be declared at once, using a comma |
|
separated list. In case of pointer variables the asterisk should be |
|
attached to the variable name: |
|
|
|
GLOBAL x, y, z TYPE int |
|
GLOBAL *s, *t TYPE long |
|
|
|
GOSUB |
|
|
|
GOSUB <label> |
|
|
|
Type: statement |
|
|
|
Jumps to a label defined elsewhere in the program (see also the LABEL |
|
statement). When a RETURN is encountered, the program will return to the |
|
last invoked GOSUB and continue from there. Note that a SUB or FUNCTION |
|
also limits the scope of the GOSUB; it cannot jump outside. Example: |
|
|
|
PRINT "Where are you?" |
|
GOSUB there |
|
PRINT "Finished." |
|
END |
|
LABEL there |
|
PRINT "In a submarine!" |
|
RETURN |
|
|
|
GOTO |
|
|
|
GOTO <label> |
|
|
|
Type: statement |
|
|
|
Jumps to a label defined elsewhere in the program. Note that a SUB or |
|
FUNCTION limits the scope of the GOTO; it cannot jump outside. See also |
|
the LABEL statement. |
|
|
|
GOTOXY |
|
|
|
GOTOXY x, y |
|
|
|
Type: statement |
|
|
|
Puts cursor to position x,y where 1,1 is the upper left of the terminal |
|
screen. An ANSI compliant terminal is required. Example: |
|
|
|
CLEAR |
|
FOR x = 5 TO 10 |
|
GOTOXY x, x |
|
PRINT "Hello world" |
|
NEXT |
|
GOTOXY 1, 12 |
|
|
|
GUIDEFINE |
|
|
|
GUIDEFINE(string$) |
|
|
|
Type: function |
|
|
|
Defines a graphical user interface according to an object/property model. |
|
Each object (e.g. widget) should occur between curly brackets and should |
|
contain properties known to the used toolkit. By default, BaCon will |
|
assume the Xaw toolkit, but this can be overridden by the PRAGMA GUI |
|
statement. The GUIDEFINE function can only occur once in a BaCon program. |
|
The return value is a unique handle which should be used in subsequent GUI |
|
functions. For each object, the 'type and 'name' fields are obligatory. |
|
See also the chapter on GUI programming for more information. For example: |
|
|
|
id = GUIDEFINE("{ type=window name=window |
|
resources="*font:lucidasans-18" XtNtitle="Hello world application" }" |
|
|
|
GUIEVENT$ |
|
|
|
GUIEVENT$(handle [,TRUE]) |
|
|
|
Type: function |
|
|
|
Executes the mainloop of the GUI and returns the name of the widget or |
|
string from the callback definition. For example: |
|
|
|
WHILE TRUE |
|
SELECT GUIEVENT$(gui) |
|
CASE "window" |
|
BREAK |
|
CASE "button" |
|
INCR clicked |
|
ENDSELECT |
|
WEND |
|
|
|
The optional second argument allows returning a pointer to data which was |
|
passed to the internal callback function. |
|
|
|
GUIFN |
|
|
|
GUIFN(id, name$, function [, argn]) |
|
|
|
Type: function |
|
|
|
Calls a GUI helper function based on a previously defined function |
|
pointer. It allows to omit specific type casting and does not perform |
|
argument type checks allowing more code flexibility. For example: |
|
|
|
LOCAL (*show)() = XtPopup TYPE void |
|
CALL GUIFN(id, "window", show, XtGrabNonexclusive) |
|
|
|
GUIGET |
|
|
|
GUIGET(id, name$, property$, &variable) |
|
|
|
Type: function |
|
|
|
Fetches a value set by <property$> from a widget with <name$> in a GUI |
|
identified by <id>. The <variable> should be a pointer variable, also in |
|
case of strings. For example: |
|
|
|
CALL GUIGET(dialog, "dialog", XtNvalue, &data) |
|
|
|
GUISET |
|
|
|
GUISET(id, name$, property$, variable) |
|
|
|
Type: function |
|
|
|
Sets a value for <property$> regarding widget with <name$> in a GUI |
|
identified by <id>. For example: |
|
|
|
CALL GUISET(dialog, "label", XtNjustify, XtJustifyLeft) |
|
|
|
GUIWIDGET |
|
|
|
GUIWIDGET(name$) |
|
|
|
Type: function |
|
|
|
Returns the memory address of a widget based on <name$>. This can come |
|
handy when using foreign GUI functions natively. |
|
|
|
HASBOM |
|
|
|
HASBOM(string$) |
|
|
|
Type: function |
|
|
|
Determines whether the string contains a UTF8 byte order mark. Some UTF8 |
|
text files are shipped with a first three bytes of 0xEF 0xBB 0xBF. The |
|
byte order mark is an optional byte sequence to indicate that the text |
|
contains UTF8 encoding. If <string$> contains such byte order mark HASBOM |
|
will return TRUE (1). Otherwise it will return FALSE (0). See also |
|
EDITBOM$ and the chapter on UTF8 encoding. |
|
|
|
HASDELIM |
|
|
|
HASDELIM(string$ [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Determines whether the string contains a delimiter or not. If the |
|
delimiter is not present, FALSE (0) is returned. Otherwise this function |
|
returns the position of the first delimiter in the string. |
|
|
|
The delimiter$ is optional. If it is omitted, then the definition from |
|
OPTION DELIM is assumed. When specified, it may consist of multiple |
|
characters. If delimiter$ occurs between double quotes in string$ then it |
|
is ignored. Refer to the chapter on delimited string functions for more |
|
information about delimited strings. |
|
|
|
For regular strings, see INSTR. |
|
|
|
HASH |
|
|
|
HASH(data [, length]) |
|
|
|
Type: function |
|
|
|
Returns a hash from string data or memory data. The optional <length> |
|
specifies the amount of bytes to be hashed. If no length is specified, the |
|
HASH function will use each byte until a 0 is encountered (like in C |
|
strings). On 64bit systems the returned value is 64bit, on 32bit systems |
|
the returned value is 32bit. |
|
|
|
The hash algorithm used is based on the Fowler-Noll-Vo algorithm (FNV1a). |
|
Example to create a hash from a string: |
|
|
|
PRINT HASH("Hello world") FORMAT "%lun" |
|
|
|
Example to create a hash from data in memory: |
|
|
|
mem = MEMORY(16) |
|
FOR x = 0 TO 15 |
|
POKE mem+x, RANDOM(256) |
|
NEXT |
|
PRINT HASH(mem, 16) FORMAT "%lun" |
|
|
|
HEAD$ |
|
|
|
HEAD$(string$, amount [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Retrieves the first <amount> elements from a delimited string$ split by |
|
delimiter$. The delimiter$ is optional. If it is omitted, then the |
|
definition from OPTION DELIM is assumed. When specified, it may consist of |
|
multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
|
|
See also LAST$ to obtain the remaining elements, and TAIL$ to obtain |
|
elements counting from the end of the delimited string. Refer to the |
|
chapter on delimited string functions for more information about delimited |
|
strings. Example: |
|
|
|
PRINT "First 2 members: ", HEAD$("Rome Amsterdam Kiev Bern Paris London", |
|
2) |
|
|
|
HEX$ |
|
|
|
HEX$(x) |
|
|
|
Type: function |
|
|
|
Calculates the hexadecimal value of x. Returns a string with the result. |
|
See also DEC to convert back to decimal. |
|
|
|
HOST$ |
|
|
|
HOST$(name$) |
|
|
|
Type: function |
|
|
|
When name$ contains a hostname this function returns the corresponding IP |
|
address. If name$ contains an IP address the corresponding hostname is |
|
returned. If the name or IP address cannot be resolved an error is |
|
generated. Examples: |
|
|
|
PRINT HOST$("www.google.com") |
|
PRINT HOST$("127.0.0.1") |
|
|
|
HOSTNAME$ |
|
|
|
HOSTNAME$() |
|
|
|
Type: function |
|
|
|
Retrieves the actual hostname of the current system where the program is |
|
running. Example: |
|
|
|
PRINT "My hostname is: ", HOSTNAME$ |
|
|
|
HOUR |
|
|
|
HOUR(x) |
|
|
|
Type: function |
|
|
|
Returns the hour (0-23) where x is the amount of seconds since January 1, |
|
1970. |
|
|
|
IF |
|
|
|
IF <expression> THEN |
|
<body> |
|
[ELIF] |
|
<body> |
|
[ELSE] |
|
[body] |
|
ENDIF | END IF | FI |
|
|
|
Type: statement |
|
|
|
Execute <body> if <expression> is true. If <expression> is not true then |
|
run the optional ELSE body. Multiple IF's can be written with ELIF. The IF |
|
construction should end with ENDIF or END IF or FI. Example: |
|
|
|
a = 0 |
|
IF a > 10 THEN |
|
PRINT "This is strange:" |
|
PRINT "a is bigger than 10" |
|
ELSE |
|
PRINT "a is smaller than 10" |
|
END IF |
|
|
|
The IF statement also allows comparing strings. The textual order is |
|
determined by the standard ASCII table. As a result, capital letters, |
|
which occur in the ASCII table before the small letters, are considered to |
|
be 'smaller' than regular letters. |
|
|
|
name$ = "BaCon" |
|
IF name$ > "basic" THEN |
|
PRINT "Not printed" |
|
ELSE |
|
PRINT "This is correct!" |
|
END IF |
|
|
|
Equations allow the BETWEEN operator both for numbers and strings: |
|
|
|
IF "c" BETWEEN "basic"; "pascal" THEN PRINT "This is C" |
|
|
|
If only one function or statement has to be executed, then the |
|
if-statement also can be used without a body. For example: |
|
|
|
IF age > 18 THEN PRINT "You are an adult" |
|
ELSE INPUT "Your age: ", age |
|
|
|
It is not allowed to mix an IF without a body and an ELSE which contains a |
|
body, or v.v. For example, the following is not allowed: |
|
|
|
IF year > 1969 THEN PRINT "You are younger" |
|
ELSE |
|
PRINT "You are older" |
|
ENDIF |
|
|
|
IIF / IIF$ |
|
|
|
IIF(expression, true[, false]) |
|
IIF$(expression, true[, false]) |
|
|
|
Type: function |
|
|
|
The inline IF behaves similar to a regular IF, except that it is used as a |
|
function. The first argument contains the expression to be evaluated, the |
|
second argument will be returned when the expression is true, and the |
|
optional last argument will be returned when the expression is false. |
|
|
|
The inline IF function also allows comparing strings. The textual order is |
|
determined by the standard ASCII table. As a result, capital letters, |
|
which occur in the ASCII table before the small letters, are considered to |
|
be 'smaller' than regular letters. |
|
|
|
If the returned values are numeric, a plain IIF must be used. If strings |
|
are returned, then IIF$ should be used. See also LOOP$ for inline loops. |
|
Examples: |
|
|
|
nr = IIF(1 <> 2, 10, 20) |
|
answer$ = IIF$(2 + 2 = 5, "Correct", "Wrong") |
|
PRINT IIF$(a$ = "B", "Yes it is") |
|
PRINT IIF(x BETWEEN y;z, 1, -1) |
|
|
|
IMPORT |
|
|
|
IMPORT <function[(type arg1, type arg2, ...)]> FROM <library> TYPE <type> |
|
[ALIAS word] |
|
|
|
Type: statement |
|
|
|
Imports a function from a C library defining the type of return value. |
|
Optionally, the type of arguments can be specified. Also optionally it is |
|
possible to define an alias under which the imported function will be |
|
known to BaCon. |
|
|
|
When the library name is 'NULL', a function will be imported from the |
|
program itself. In such situation, the ALIAS keyword is obligatory. Note |
|
that the program must be compiled with a linker flag like |
|
'-export-dynamic' (GCC) or '-rdynamic' (TCC) to make the target function |
|
visible for IMPORT. |
|
|
|
An imported library can also be closed afterwards by using CLOSE LIBRARY. |
|
This will unload any symbols from the current program and release the |
|
library. It is mandatory to close a library when symbols need to be |
|
reloaded starting from the first IMPORT statement. |
|
|
|
Examples: |
|
|
|
IMPORT "ioctl" FROM "libc.so" TYPE int |
|
IMPORT "gdk_draw_line(long, long, int, int, int, int)" FROM |
|
"libgdk-x11-2.0.so" TYPE void |
|
IMPORT "fork" FROM "libc.so" TYPE int ALIAS "FORK" |
|
IMPORT "atan(double)" FROM "libm.so" TYPE double ALIAS "arctangens" |
|
IMPORT "MyFunc(void)" FROM NULL TYPE int ALIAS "Othername" |
|
CLOSE LIBRARY "libm.so" |
|
|
|
INBETWEEN$ |
|
|
|
INBETWEEN$(haystack$, lm$, rm$ [,flag]) |
|
|
|
Type: function |
|
|
|
This function returns a substring from <haystack$>, delimited by <lm$> on |
|
the left and <rm$> on the right. The delimiters may contain multiple |
|
characters. They are not part of the returned result. The <flag> is |
|
optional (default value is 0) and specifies if <rm$> should either |
|
indicate the most right match (greedy indication, flag=1), or should |
|
return a balanced match (flag=2). See also OUTBETWEEN$. Note that OPTION |
|
COLLAPSE has no impact on this function. Example usage: |
|
|
|
PRINT INBETWEEN$("Lorem ipsum dolor sit amet", "ipsum", "sit") |
|
PRINT INBETWEEN$("<p>Chapter one.</p>", "<p>", "</p>") |
|
a$ = INBETWEEN$("yes no 123 yes 456 yes", "no", "yes", TRUE) |
|
|
|
INCLUDE |
|
|
|
INCLUDE <filename>[, func1, func2, ...] |
|
|
|
Type: statement |
|
|
|
Adds a external BaCon file to current program. Includes may be nested. The |
|
file name extension may be omitted. Optionally, it is possible to specify |
|
which particular functions in the included file need to be added. |
|
Examples: |
|
|
|
INCLUDE "beep.bac" |
|
INCLUDE "canvas" |
|
INCLUDE "hug", INIT, WINDOW, DISPLAY |
|
|
|
INCR |
|
|
|
INCR <x>[, y] |
|
|
|
Type: statement |
|
|
|
Increases variable <x> with 1. Optionally, the variable <x> can be |
|
increased with <y>. |
|
|
|
INDEX |
|
|
|
INDEX(<array>, <value> [, flag]) |
|
|
|
Type: function |
|
|
|
This function looks up a <value> in <array> and returns the position in |
|
the array where the value was found. If the value was not found, then this |
|
function returns 0. |
|
|
|
By default, BaCon will perform a plain linear lookup. If the optional |
|
[flag] is set to TRUE, then BaCon assumes the array is ordered and the |
|
lookup will use the binary search algorithm, resulting in a better |
|
performance. This function only works for static and dynamic arrays. For |
|
associative arrays, refer to INDEX$. Examples: |
|
|
|
DECLARE data[] = { 0, 1, 3, 5, 7, 8, 12, 30, 44, 55, 61 } |
|
PRINT INDEX(data, 61, TRUE) |
|
|
|
DECLARE floats#[] = { 3.2, 5.3, 7.5, 8.6, 12.2, 30.3, 55.5, 61.6} |
|
PRINT INDEX(floats#, 30.3) |
|
|
|
DECLARE string$[] = { "a", "b", "c", "d", "e" } |
|
PRINT INDEX(string$, "c") |
|
|
|
DECLARE nr TYPE int ARRAY 5 |
|
nr[0] = 1 |
|
nr[1] = 2 |
|
nr[2] = 6 |
|
nr[3] = 8 |
|
nr[4] = 10 |
|
PRINT INDEX(nr, 10) |
|
|
|
INDEX$ |
|
|
|
INDEX$(<associative_array>, <value>) |
|
|
|
Type: function |
|
|
|
This function looks up a <value> in <associative_array> and returns the |
|
index in the array where the value was found. If the value was not found, |
|
then this function returns an empty string. If INDEX$ refers to a value |
|
which occurs multiple times, the returned index is the first inserted into |
|
the associative array. Example: |
|
|
|
DECLARE data$ ASSOC STRING |
|
data$("name") = "BaCon" |
|
data$("place") = "Internet" |
|
data$("language") = "BASIC" |
|
PRINT INDEX$(data$, "Internet") |
|
|
|
INPUT |
|
|
|
INPUT [text[, ... ,]<variable[$]> |
|
|
|
Type: statement |
|
|
|
Interactive input from the user. If the variable ends with a '$' then the |
|
input is considered to be a string. Otherwise it will be treated as |
|
numeric. Example: |
|
|
|
INPUT a$ |
|
PRINT "You entered the following: ", a$ |
|
|
|
The input-statement also can print text. The input variable always must be |
|
present at the end of the line. Example: |
|
|
|
INPUT "What is your age? ", age |
|
PRINT "You probably were born in ", YEAR(NOW) - age |
|
|
|
The INPUT statement by nature is a blocking statement. Note that INPUT |
|
always will chop off a trailing newline from text captured into a string |
|
variable, if there is any. |
|
|
|
The OPTION INPUT parameter can be used to define where INPUT should cut |
|
off the incoming stream from STDIN. This is especially useful in CGI |
|
programs, for example: |
|
|
|
OPTION INPUT CHR$(4) |
|
INPUT data$ |
|
|
|
INSERT$ |
|
|
|
INSERT$(source$, x, string$) |
|
|
|
Type: function |
|
|
|
Inserts the string$ into source$ at position <x>. The letters in source$ |
|
starting from position <x> are pushed forward. If x <= 1 then string$ is |
|
prepended to source$. If position > length of source$ then string$ is |
|
appended to source$. Example: |
|
|
|
PRINT INSERT$("Hello world", 7, "cruel ") |
|
|
|
INSTR |
|
|
|
INSTR(haystack$, needle$ [,z]) |
|
|
|
Type: function |
|
|
|
Returns the position where needle$ begins in haystack$, optionally |
|
starting at position z. If not found then this function returns the value |
|
'0'. See also TALLY to count the occurrences of needle$. |
|
|
|
position = INSTR("Hello world", "wo") |
|
PRINT INSTR("Don't take my wallet", "all", 10) |
|
|
|
INSTRREV |
|
|
|
INSTRREV(haystack$, needle$ [,z]) |
|
|
|
Type: function |
|
|
|
Returns the position where needle$ begins in haystack$, but start |
|
searching from the end of haystack$, optionally at position z also |
|
counting from the end. The result is counted from the beginning of |
|
haystack$. If not found then this function returns the value '0'. |
|
|
|
See also OPTION STARTPOINT to return the result counted from the end of |
|
haystack$. |
|
|
|
INTL$ |
|
|
|
INTL$(x$) |
|
|
|
Type: function |
|
|
|
Specifies that <x$> should be taken into account for internationalization. |
|
All strings which are surrounded by INTL$ will be candidate for the |
|
template catalog file. This file is created when BaCon is executed with |
|
the '-x' switch. See also the chapter about internationalization and the |
|
TEXTDOMAIN statement. |
|
|
|
INVERT |
|
|
|
INVERT(<assoc_array>) |
|
|
|
Type: function |
|
|
|
Swaps the keys and values in an associative array. In case multiple keys |
|
hold the same value, a collision occurs. In such case, the last occurrence |
|
of a value is inverted and the INVERT function returns the amount of |
|
collisions. If all values are unique, then this function returns 0. |
|
|
|
Note that values of numerical associative arrays will silently be |
|
converted to strings and that the key names will be converted back to the |
|
numerical type of the array. So if the keys contain regular strings then |
|
these will be converted to 0 in case of numerical arrays. Example: |
|
|
|
DECLARE example ASSOC int |
|
example("10") = 33 |
|
example("20") = 12 |
|
example("30") = 44 |
|
example("40") = 44 |
|
PRINT INVERT(example) |
|
PRINT OBTAIN$(example) |
|
|
|
ISASCII |
|
|
|
ISASCII(string$) |
|
|
|
Type: function |
|
|
|
Returns TRUE (1) if <string$> only contains ASCII data. If not, FALSE (0) |
|
is returned. See also TOASCII$. Example: |
|
|
|
PRINT ISASCII("hello world") |
|
|
|
ISFALSE |
|
|
|
ISFALSE(x) |
|
|
|
Type: function |
|
|
|
Verifies if x is equal to 0. |
|
|
|
ISKEY |
|
|
|
ISKEY(array, string$) |
|
|
|
Type: function |
|
|
|
Returns TRUE (1) if <string$> is defined as a key in the associative |
|
<array>. If not, FALSE (0) is returned. For static and dynamic arrays, |
|
refer to INDEX. See also NRKEYS to find the amount of keys in an |
|
associative array. Example: |
|
|
|
DECLARE array ASSOC int |
|
array("hello") = 25 |
|
array("world") = 30 |
|
array("compound", "key") = 40 |
|
PRINT ISKEY(array, "goodbye") |
|
PRINT ISKEY(array, "world") |
|
PRINT ISKEY(array, "compound", "key") |
|
|
|
ISTOKEN |
|
|
|
ISTOKEN(string$, token$ [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Verifies if the <token$> occurs in a delimited <string$>. The delimiter$ |
|
is optional. If it is omitted, then the definition from OPTION DELIM is |
|
assumed. When specified, it may consist of multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
|
|
If token$ was found in string$, then this function returns the actual |
|
position of the token in the delimited string, counting from the left. |
|
Otherwise it returns '0'. See also TOKEN$. Example: |
|
|
|
string$ = "Kiev Amsterdam Lima Moscow Warschau Vienna Paris Madrid Bonn |
|
Bern Rome" |
|
PRINT ISTOKEN(string$, "Paris") |
|
|
|
ISTRUE |
|
|
|
ISTRUE(x) |
|
|
|
Type: function |
|
|
|
Verifies if x is not equal to 0. |
|
|
|
ISUTF8 |
|
|
|
ISUTF8(string$) |
|
|
|
Type: function |
|
|
|
Returns TRUE (1) if <string$> is compliant with UTF8 encoding. If not, |
|
FALSE (0) is returned. Note that also random binary data can accidentally |
|
be compliant to UTF8 and that ASCII data always is compliant to UTF8. See |
|
also ISASCII. Example: |
|
|
|
PRINT ISUTF8("Después mañana voy para mi casa") |
|
|
|
JOIN |
|
|
|
JOIN <array> [BY <sub>] TO <string> [SIZE <value>] |
|
|
|
Type: statement |
|
|
|
This statement can join elements of a one dimensional string array into a |
|
single string. The optional argument in BY defines the delimiter string in |
|
between the array elements. If BY is omitted, then no delimiter is put in |
|
between the concatenated array elements. The result is stored in the |
|
<string> argument mentioned by the TO keyword. Optionally, the total |
|
amount of array elements to be joined can be defined in SIZE. If SIZE is |
|
omitted then all elements in the array will be joined together. See also |
|
SPLIT to do the opposite. Example: |
|
|
|
DECLARE name$[3] |
|
name$[0] = "Hello" |
|
name$[1] = "cruel" |
|
name$[2] = "world" |
|
JOIN name$ BY " " TO result$ SIZE 3 |
|
|
|
LABEL |
|
|
|
LABEL <label> |
|
|
|
Type: statement |
|
|
|
Defines a label which can be jumped to by using a GOTO, GOSUB or CATCH |
|
GOTO statement. A label may not contain spaces. |
|
|
|
A label can appear amid existing DATA statements. In such case, RESTORE |
|
may refer to a label so READ will start reading data from that point. The |
|
label must be unique throughout the whole program because DATA statements |
|
are visible globally. |
|
|
|
LAST$ |
|
|
|
LAST$(string$, amount [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Retrieves the remaining elements except the first <amount> from a |
|
delimited string$ split by delimiter$. The delimiter$ is optional. If it |
|
is omitted, then the definition from OPTION DELIM is assumed. When |
|
specified, it may consist of multiple characters. |
|
|
|
If no delimiter is present in the string, this function will return the |
|
full <string$>. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
HEAD$ to get the first element(s), and the chapter on delimited string |
|
functions for more information about delimited strings. Example: |
|
|
|
PRINT "Remaining members: ", LAST$("Rome Amsterdam Kiev Bern Paris |
|
London", 1) |
|
|
|
LCASE$ |
|
|
|
LCASE$(x$) |
|
|
|
Type: function |
|
|
|
Converts x$ to lowercase characters and returns the result. Example: |
|
|
|
PRINT LCASE$("ThIs Is All LoWeRcAsE") |
|
|
|
LEFT$ |
|
|
|
LEFT$(string$[, amount]) |
|
|
|
Type: function |
|
|
|
Returns <amount> characters from the left of <string$>. The <amount> |
|
argument is optional. If omitted, then LEFT$ by default will return 1 |
|
character. See also RIGHT$ and MID$. |
|
|
|
LEN |
|
|
|
LEN(x$) |
|
|
|
Type: function |
|
|
|
Returns the length of ASCII string x$. If OPTION UTF8 is enabled, then the |
|
LEN function will return the length of UTF8 formatted strings correctly as |
|
well. See also ULEN. |
|
|
|
LET |
|
|
|
LET <var> = <value> | <expr> |
|
|
|
Type: statement |
|
|
|
Assigns a value or result from an expression to a variable. The LET |
|
statement may be omitted. Example: |
|
|
|
LET a = 10 |
|
|
|
LINENO |
|
|
|
LINENO |
|
|
|
Type: variable |
|
|
|
Contains the current line number of the program. This variable mainly is |
|
used for debugging purposes. |
|
|
|
LOAD$ |
|
|
|
LOAD$(filename$) |
|
|
|
Type: function |
|
|
|
Returns a string with the content of the specified text file in one step. |
|
See BLOAD for loading binary files in one step, and |
|
OPEN/WRITELN/READLN/CLOSE to read and write to a file using a filehandle. |
|
Example: |
|
|
|
content$ = LOAD$("bacon.bac") |
|
PRINT "Content of 'bacon.bac': ", content$ |
|
|
|
LOCAL |
|
|
|
LOCAL <var>[,var2,var3,...] [TYPE]|ASSOC|TREE <c-type> | [ARRAY <size>] |
|
[STATIC] |
|
|
|
Type: statement |
|
|
|
This statement only has sense within functions, subroutines or records. It |
|
defines a local variable <var> with C type <type> which will not be |
|
visible to other functions, subroutines or records, nor to the main |
|
program. |
|
|
|
If the TYPE keyword is omitted then variables are assumed to be of 'long' |
|
type. If TYPE is omitted and the variable name ends with a '$' then the |
|
variable will be a string. |
|
|
|
The ARRAY keyword is used to define a dynamic array, which can be resized |
|
with REDIM at a later stage in the program. The optional STATIC keyword |
|
allows the array to be returned from a function. |
|
|
|
Examples: |
|
|
|
LOCAL tt TYPE int |
|
LOCAL q$ |
|
LOCAL new_array TYPE float ARRAY 100 |
|
LOCAL name$ ARRAY 25 |
|
|
|
LOCAL key$ ASSOC STRING |
|
|
|
Multiple variables of the same type can be declared at once, using a comma |
|
separated list. In case of pointer variables the asterisk should be |
|
attached to the variable name: |
|
|
|
LOCAL x, y, z TYPE int |
|
LOCAL *s, *t TYPE long |
|
|
|
LOG |
|
|
|
LOG(x) |
|
|
|
Type: function |
|
|
|
Returns the natural logarithm of x. |
|
|
|
LOOKUP |
|
|
|
LOOKUP <assoc> TO <array$> [SIZE <variable>][STATIC]|[SORT[DOWN]] |
|
|
|
Type: statement |
|
|
|
Retrieves all index names created in an associative array. The results are |
|
stored in <array$>. As it sometimes is unknown how many elements this |
|
resulting array will contain, the array should not be declared explicitly. |
|
Instead, LOOKUP will declare the result array dynamically. |
|
|
|
If LOOKUP is being used in a function or sub, then <array> will have a |
|
local scope. Else <array> will be visible globally, and can be accessed |
|
within all functions and subs. |
|
|
|
The optional SORT keyword will first sort the elements in the associative |
|
array before returning the corresponding indexes. A sort in descending |
|
order can be accomplished by adding the DOWN keyword. As with the SORT |
|
statement, string and numeric C-types are supported. |
|
|
|
The total amount of elements created in this array is stored in the |
|
optional <variable>. This variable can be declared explicitly using LOCAL |
|
or GLOBAL. See also OBTAIN$ to store index names into a delimited string. |
|
Example: |
|
|
|
LOOKUP mortal TO men$ SIZE amount |
|
FOR x = 0 TO amount - 1 |
|
PRINT men$[x] |
|
NEXT |
|
|
|
The optional STATIC keyword allows the created <array> to be returned from |
|
a function. |
|
|
|
LOOP |
|
|
|
LOOP([variable,] nr, expression) |
|
|
|
Type: function |
|
|
|
This is an inline loop which returns the sum of the repeatedly evaluated |
|
<expression> as a numeric value. The optional <variable> must be a numeric |
|
variable and <nr> defines how many times the <expression> is carried out. |
|
If <variable> is not present then the anonymous variable "_" will be used. |
|
It is not allowed to use nested LOOP constructs or to use LOOP multitple |
|
times in the same statement. Such code will generate a syntax error during |
|
conversion time. See also FILL$, or COIL$ for an inline loop creating |
|
delimited strings, or the inline if IIF$. |
|
|
|
Example to add all numbers mentioned in a string variable: |
|
|
|
a$ = "123456789" |
|
PRINT LOOP(LEN(a$), VAL(MID$(a$, _, 1))) |
|
|
|
LOOP$ |
|
|
|
LOOP$([variable,] nr, expression$) |
|
|
|
Type: function |
|
|
|
This is an inline loop which returns the result of the repeatedly |
|
evaluated <expression$> as a concatenated regular string. The optional |
|
<variable> must be a numeric variable and <nr> defines how many times the |
|
<expression$> is carried out. If <variable> is not present then the |
|
anonymous variable "_" will be used. It is not allowed to use nested LOOP$ |
|
constructs or to use LOOP$ multitple times in the same statement. Such |
|
code will generate a syntax error during conversion time. See also FILL$, |
|
or COIL$ for an inline loop creating delimited strings, LOOP for numeric |
|
calculations, or the inline if IIF$. |
|
|
|
Example to get all letters in the Latin alphabet: |
|
|
|
PRINT LOOP$(i, 26, CHR$(96+i)) |
|
|
|
Example to print all elements in a delimited list using the anonymous |
|
variable "_": |
|
|
|
PRINT LOOP$(AMOUNT(list$), TOKEN$(list$, _)) |
|
|
|
MAKEDIR |
|
|
|
MAKEDIR <directory> |
|
|
|
Type: statement |
|
|
|
Creates an empty directory. Parent directories are created implicitly. If |
|
the directory already exists then it is recreated. Errors like write |
|
permissions, disk quota issues and so on can be captured with CATCH. |
|
Example: |
|
|
|
MAKEDIR "/tmp/mydir/is/here" |
|
|
|
MAP |
|
|
|
MAP <array1> [,array2, ...array<n>] BY <function> TO <array> [SIZE |
|
<const|variable>] [STATIC] |
|
|
|
Type: statement |
|
|
|
Performs a mapping of a function towards one or more arrays, storing the |
|
results in another array. All arrays shall have one dimension. The target |
|
array can be declared previously with the DECLARE or LOCAL statement. |
|
Using LOCAL in combination with the optional STATIC keyword, the array is |
|
created so it can be returned from a function. However, if there is no |
|
explicit previous declaration, then the MAP statement will declare the |
|
target array implicitly. The STATIC keyword can be used here as well. |
|
|
|
When the target array is declared implicitly, the following logic applies: |
|
if MAP is being used in a function or sub, then the target <array> will |
|
have a local scope. Else <array> will be visible globally, and can be |
|
accessed within all functions and subs. |
|
|
|
The <function> can either be defined by DEF FN, or it can point to a |
|
regular function. Only the function name should be provided, not the |
|
arguments. Note that the amount of arguments must be the same as the |
|
amount of arrays to which the <function> is mapped. |
|
|
|
The SIZE argument is optional. When SIZE is not provided, MAP will apply |
|
the <function> to all elements in the given arrays. Example: |
|
|
|
DEF FN addition(x, y) = x+y |
|
MAP array1, array2 BY addition TO result SIZE 5 |
|
|
|
In this example, the first 5 elements of array1 and array2 are used for |
|
the 'addition' function. The results are stored in the array 'result'. See |
|
also SUM for adding members within the same array. |
|
|
|
String arrays are supported as well: |
|
|
|
word$ = "Hello world this is a program" |
|
DEF FN func(x$) = LEN(x$) |
|
SPLIT word$ TO letter$ SIZE total |
|
MAP letter$ BY func TO new SIZE total |
|
|
|
Here, each word is put into an array, after which the length of the |
|
individual words is being calculated. The results are then stored in |
|
another array. |
|
|
|
MATCH |
|
|
|
MATCH(string$, pattern$, [amount [,delimiter$]]) |
|
|
|
Type: function |
|
|
|
Compares the delimited elements between <string$> and <pattern$>. By |
|
default, the amount of elements to compare is determined by the amount of |
|
elements in <string$>. Optionally, the <amount> of elements to be compared |
|
can be provided explicitly. The value -1 means the default amount of |
|
elements in <string$>. |
|
|
|
The <pattern$> can use the wildcards '?' and '*'. In case of '?' a single |
|
element will be matched. The '*' wildcard can be used to match multiple |
|
elements. To match an actual '?' or '*' in <string$> the wildcard symbol |
|
has to be escaped in <pattern$> or should be written between double |
|
quotes. The use of multiple wildcards in <pattern$> is allowed. |
|
|
|
Both the <string$> and the <pattern$> should be delimited by the same |
|
delimiter$. The delimiter$ argument is optional. If it is omitted, then |
|
the definition from OPTION DELIM is assumed. When specified, it may |
|
consist of multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
the chapter on delimited string functions for more information about |
|
delimited strings. Examples: |
|
|
|
IF MATCH("a b c d", "a b e f", 2) THEN PRINT "Partially the same" |
|
IF MATCH("a b c d", "a b *") THEN PRINT "Matched" |
|
IF NOT(MATCH("a b c d", "a b ? c")) THEN PRINT "Not matched" |
|
IF MATCH("a b "c d" d", "a b * d") THEN PRINT "Matched" |
|
IF MATCH("a b * d", "a b \* d") THEN PRINT "Matched" |
|
IF MATCH("a,b,c,d", "a,b,c,d", -1, ",") THEN PRINT "Matched" |
|
|
|
MAX / MAX$ |
|
|
|
MAX(x, y) |
|
MAX$(x$, y$) |
|
|
|
Type: function |
|
|
|
Returns the maximum value of two numbers or two strings. In case of |
|
strings, this function will follow the ASCII table to determine the |
|
'maximum' string. This means that small letters, which occur in the ASCII |
|
table after capital letters, will have priority. Example: |
|
|
|
PRINT MAX(3, PI) |
|
PRINT MAX$("hello", "HELLO") |
|
|
|
MAXNUM |
|
|
|
MAXNUM(type) |
|
|
|
Type: function |
|
|
|
This function returns the maximum value possible for a certain type. |
|
Example: |
|
|
|
PRINT MAXNUM(short) |
|
PRINT MAXNUM(long) FORMAT "%ldn" |
|
|
|
MAXRANDOM |
|
|
|
MAXRANDOM |
|
|
|
Type: variable |
|
|
|
Reserved variable which contains the maximum value RND can generate. The |
|
actual value may vary on different operating systems. |
|
|
|
ME$ |
|
|
|
ME$ |
|
|
|
Type: function |
|
|
|
Returns the full path of the current active program. See also CURDIR$ and |
|
REALPATH$. |
|
|
|
MEMCHECK |
|
|
|
MEMCHECK(memory address) |
|
|
|
Type: function |
|
|
|
Verifies if <memory address> is accessible, in which case a '1' is |
|
returned. If not, this function returns a '0'. Example: |
|
|
|
IF MEMCHECK(mem) THEN POKE mem, 1234 |
|
|
|
MEMORY |
|
|
|
MEMORY(x) |
|
|
|
Type: function |
|
|
|
Claims memory of x size, returning a handle to the address where the |
|
memory block resides. Use FREE to release the memory. Note that OPTION |
|
MEMTYPE can influence the type of memory created. The following example |
|
creates a memory area to store integers: |
|
|
|
OPTION MEMTYPE int |
|
area = MEMORY(100) |
|
|
|
Effectively, this will provide a memory area of 100 times the length of an |
|
integer. |
|
|
|
MEMREWIND |
|
|
|
MEMREWIND <handle> |
|
|
|
Type: statement |
|
|
|
Returns to the beginning of a memory area opened with <handle>. |
|
|
|
MEMTELL |
|
|
|
MEMTELL(handle) |
|
|
|
Type: function |
|
|
|
Returns the current position in the memory area opened with <handle>. |
|
|
|
MERGE$ |
|
|
|
MERGE$(string$ [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Merges the components of a delimited string to a regular string. The |
|
delimiter$ is optional. If it is omitted, then the definition from OPTION |
|
DELIM is assumed. When specified, it may consist of multiple characters. |
|
|
|
See also EXPLODE$ to create a delimited string, and the chapter on |
|
delimited string functions for more information about delimited strings. |
|
Example: |
|
|
|
PRINT MERGE$("A m s t e r d a m") |
|
|
|
MID$ |
|
|
|
MID$(x$, y, [z]) |
|
|
|
Type: function |
|
|
|
Returns z characters starting at position y in x$. If y is a negative |
|
number, then start counting the position from the end of x$. The parameter |
|
'z' is optional. When this parameter is 0, negative or omitted, then |
|
everything from position 'y' until the end of the string is returned. See |
|
also RIP$ for the complement of MID$. Example: |
|
|
|
txt$ = "Hello cruel world" |
|
PRINT MID$(txt$, 7, 5) |
|
PRINT MID$(txt$, -11) |
|
PRINT MID$(txt$, 12, -1) |
|
|
|
MIN / MIN$ |
|
|
|
MIN(x, y) |
|
MIN$(x$, y$) |
|
|
|
Type: function |
|
|
|
Returns the minimum value of two numbers or two strings. In case of |
|
strings, this function will follow the ASCII table to determine the |
|
'minimum' string. This means that capital letters, which occur in the |
|
ASCII table before the small letters, will have priority. Example: |
|
|
|
PRINT MIN(3, PI) |
|
PRINT MIN$("hello", "HELLO") |
|
|
|
MINUTE |
|
|
|
MINUTE(x) |
|
|
|
Type: function |
|
|
|
Returns the minute (0-59) where x is amount of seconds since January 1, |
|
1970. |
|
|
|
MOD |
|
|
|
MOD(x, y) |
|
|
|
Type: function |
|
|
|
Returns the modulo of x divided by y. |
|
|
|
MONTH |
|
|
|
MONTH(x) |
|
|
|
Type: function |
|
|
|
Returns the month (1-12) in a year, where x is the amount of seconds since |
|
January 1, 1970. |
|
|
|
MONTH$ |
|
|
|
MONTH$(x) |
|
|
|
Type: function |
|
|
|
Returns the month of the year as string in the system's locale ("January", |
|
"February", etc), where x is the amount of seconds since January 1, 1970. |
|
|
|
MYPID |
|
|
|
MYPID |
|
|
|
Type: function |
|
|
|
Returns the process ID of the current running program. |
|
|
|
NANOTIMER |
|
|
|
NANOTIMER |
|
|
|
Type: function |
|
|
|
Keeps track of the amount of nanoseconds the current program is running. |
|
See also TIMER to measure milliseconds. Example: |
|
|
|
SLEEP 100 |
|
PRINT "Slept ", NANOTIMER, " nanoseconds!" |
|
|
|
NE |
|
|
|
x NE y |
|
|
|
Type: operator |
|
|
|
Checks if x and y are not equal. Instead, ISNOT can be used as well to |
|
improve code readability. The NE and ISNOT operators only work for |
|
numerical comparisons. |
|
|
|
Next to these, BaCon also accepts the '!=' and '<>' constructs for |
|
comparison. These work both for numerical and string comparisons. See also |
|
EQ. |
|
|
|
NL$ |
|
|
|
NL$ |
|
|
|
Type: variable |
|
|
|
Represents the New Line as a string. |
|
|
|
NNTL$ |
|
|
|
NNTL$(x$, y$, value) |
|
|
|
Type: function |
|
|
|
Specifies that <x$> should be taken into account for internationalization. |
|
This is a variation to INTL$. With NNTL$ singularities and multitudes can |
|
be specified, which are candidate for the template catalog file. This file |
|
is created when BaCon is executed with the '-x' switch. See also |
|
TEXTDOMAIN and INTL$ and the chapter on internationalization. Example: |
|
|
|
LET x = 2 |
|
PRINT x FORMAT NNTL$("There is %ld green bottlen", "There are %ld green |
|
bottlesn", x) |
|
|
|
NOT |
|
|
|
NOT(x) |
|
|
|
Type: function |
|
|
|
Returns the negation of x. |
|
|
|
NOW |
|
|
|
NOW |
|
|
|
Type: function |
|
|
|
Returns the amount of seconds since January 1, 1970. |
|
|
|
NRKEYS |
|
|
|
NRKEYS(array) |
|
|
|
Type: function |
|
|
|
Returns the amount of index names (keys) in the associative <array>. See |
|
ISKEY to find out if a key exists in an associative array. Refer to UBOUND |
|
for other types of arrays. Example: |
|
|
|
DECLARE array ASSOC int |
|
array("hello") = 25 |
|
array("world") = 30 |
|
PRINT NRKEYS(array) |
|
|
|
OBTAIN$ |
|
|
|
OBTAIN$(assoc$ [,delimiter$ [, sort]]) |
|
|
|
Type: function |
|
|
|
Retrieves all index names from an associative array and returns a |
|
delimited string split by delimiter$. Multiple indexes in the same element |
|
are returned space separated. The delimiter$ is optional. If it is |
|
omitted, then the definition from OPTION DELIM is assumed. When specified, |
|
it may consist of multiple characters. When NULL, the function will take |
|
the default delimiter as defined by OPTION DELIM. |
|
|
|
The optional <sort> argument will first sort the values of the associative |
|
array before retrieving the index names, where TRUE will sort ascending |
|
and FALSE will sort descending. |
|
|
|
See the chapter on delimited string functions for more information about |
|
delimited strings. See also LOOKUP to store index names from an |
|
associative array into a regular array. Example: |
|
|
|
PRINT OBTAIN$(AssocArray, ",") |
|
PRINT OBTAIN$(mydata, NULL, TRUE) |
|
|
|
ODD |
|
|
|
ODD(x) |
|
|
|
Type: Function |
|
|
|
Returns 1 if x is odd, else returns 0. |
|
|
|
ON |
|
|
|
ON x <GOTO label1 [, label2[, label<x>]]>|<CALL func1 [, func2 [, funcx]]> |
|
|
|
Type: statement |
|
|
|
Jump to a label or function based on the value of x. When x is 1 then the |
|
first item is chosen, when x is 2 the second item and so on. When x has a |
|
higher value than the available labels this statement is ignored. Example: |
|
|
|
ON x GOTO a, b |
|
PRINT "No label found" |
|
END |
|
LABEL a |
|
PRINT "a" |
|
END |
|
LABEL b |
|
PRINT "b" |
|
END |
|
|
|
Other example using functions, adding brackets to the called function name |
|
is optional: |
|
|
|
ON ISTOKEN(list$, item$) CALL setx, sety(), print_str(str$) |
|
|
|
OPEN |
|
|
|
OPEN <file|dir|address> FOR |
|
READING|WRITING|APPENDING|READWRITE|DIRECTORY|NETWORK [FROM |
|
address[:port]]|SERVER|MEMORY|DEVICE AS <handle> |
|
|
|
Type: statement |
|
|
|
When used with READING, WRITING, APPENDING or READWRITE, this statement |
|
opens a file assigning a handle to it. The READING keyword opens a file |
|
for read-only, the WRITING for writing, APPENDING to append data and |
|
READWRITE opens a file both for reading and writing. Example: |
|
|
|
OPEN "data.txt" FOR READING AS myfile |
|
WHILE NOT(ENDFILE(myfile)) DO |
|
READLN txt$ FROM myfile |
|
IF NOT(ENDFILE(myfile)) THEN |
|
PRINT txt$ |
|
ENDIF |
|
WEND |
|
CLOSE FILE myfile |
|
|
|
When used with DIRECTORY a directory is opened as a stream. Subsequent |
|
reads will return the files in the directory. Example: |
|
|
|
OPEN "." FOR DIRECTORY AS mydir |
|
REPEAT |
|
GETFILE myfile$ FROM mydir |
|
PRINT "File found: ", myfile$ |
|
UNTIL ISFALSE(LEN(myfile$)) |
|
CLOSE DIRECTORY mydir |
|
|
|
When used with NETWORK a network address is opened as a stream. |
|
Optionally, the source IP address and port can be specified using FROM. |
|
|
|
OPEN "www.google.com:80" FOR NETWORK AS mynet |
|
SEND "GET / HTTP/1.1rnHost: www.google.comrnrn" TO mynet |
|
REPEAT |
|
RECEIVE dat$ FROM mynet |
|
total$ = total$ & dat$ |
|
UNTIL ISFALSE(WAIT(mynet, 500)) |
|
PRINT total$ |
|
CLOSE NETWORK mynet |
|
|
|
When used with SERVER the program starts as a server to accept incoming |
|
network connections. When invoked multiple times in TCP mode using the |
|
same host and port, OPEN SERVER will not create a new socket, but accept |
|
another incoming connection. Instead of specifying an IP address, also the |
|
Unix wildcard '*' can be used to listen to all interfaces. See also OPTION |
|
NETWORK to set the network protocol. |
|
|
|
OPEN "*:51000" FOR SERVER AS myserver |
|
WHILE NOT(EQUAL(LEFT$(dat$, 4), "quit")) DO |
|
RECEIVE dat$ FROM myserver |
|
PRINT "Found: ", dat$ |
|
WEND |
|
CLOSE SERVER myserver |
|
|
|
When used with MEMORY a memory area can be used in streaming mode. |
|
|
|
data = MEMORY(500) |
|
OPEN data FOR MEMORY AS mem |
|
PUTLINE "Hello cruel world" TO mem |
|
MEMREWIND mem |
|
GETLINE txt$ FROM mem |
|
CLOSE MEMORY mem |
|
PRINT txt$ |
|
|
|
When used with DEVICE, a file or device can be opened in any mode. The |
|
open mode can set by using OPTION DEVICE. Use PUTBYTE or GETBYTE to write |
|
and retrieve data from the opened device. |
|
|
|
OPEN "/dev/ttyUSB0" FOR DEVICE AS myserial |
|
SETSERIAL myserial SPEED B38400 |
|
GETBYTE mem FROM myserial CHUNK 5 SIZE received |
|
CLOSE DEVICE myserial |
|
|
|
OPTION |
|
|
|
OPTION <BASE x> | <COMPARE x> | <SOCKET x> | <NETWORK type [ttl]> | |
|
<MEMSTREAM x> | <MEMTYPE type> | <COLLAPSE x> | <INTERNATIONAL x> | |
|
<STARTPOINT x> | <DEVICE x> | <PARSE x> | <FRAMEWORK x> | <VARTYPE x> | |
|
<QUOTED x> | <DQ x> | <ESC x> | <UTF8 x> | <DELIM x> | <BREAK x> | |
|
<EXPLICIT x> | <INPUT x> | <ERROR x> | <PROPER x> | <TLS x> | <EVAL x> | |
|
<NO_C_ESC x> |
|
|
|
Type: statement |
|
|
|
Sets an option to define the behavior of the compiled BaCon program. It is |
|
recommended to use this statement in the beginning of the program, to |
|
avoid unexpected results. |
|
|
|
* The BASE argument determines the lower bound of arrays. By default the |
|
lower bound is set to 0. Note that this setting also has impact on the |
|
array returned by the SPLIT and LOOKUP statements. It has no impact on |
|
arrays which assign their values statically at the moment of |
|
declaration. |
|
|
|
* The COMPARE argument defines if string comparisons in the IF and |
|
IIF/IIF$ statements and in the BETWEEN operator and also in regular |
|
expressions with REPLACE$, EXTRACT$, REGEX and WALK$ should be case |
|
sensitive (0) or not (1). The default is case sensitive (0). |
|
|
|
* The SOCKET argument defines the timeout for setting up a socket to an |
|
IP address. Default value is 5 seconds. |
|
|
|
* The NETWORK argument defines the type of protocol: TCP, UDP, |
|
BROADCAST, MULTICAST or SCTP. When MULTICAST is selected also an |
|
optional value for TTL can be specified. When SCTP is selected an |
|
optional value for the amount of streams can be specified. Default |
|
setting for this option is: TCP. Default value for TTL is 1. Default |
|
amount of SCTP streams is 1. |
|
|
|
* The MEMSTREAM argument allows the handle created by the OPEN FOR |
|
MEMORY statement to be used as a string variable (1). Default value is |
|
0. |
|
|
|
* The MEMTYPE argument defines the type of memory to be used by POKE, |
|
PEEK, MEMORY, RESIZE, PUTBYTE, GETBYTE, COPY, ROL and ROR. Default |
|
value is 'char' (1 byte). Any valid C type can be used here, for |
|
example 'float', 'unsigned int', 'long' etc. |
|
|
|
* The COLLAPSE argument specifies if the results of the SPLIT and |
|
FOR..IN statements and of the delimited string functions may contain |
|
empty results (0) in case the separator occurs as a sequence in the |
|
target string, or not (1). Default value is 0. |
|
|
|
* The INTERNATIONAL argument enables support for internationalization of |
|
strings. It sets the textdomain for INTL$ and NNTL$ to the current |
|
filename. See also TEXTDOMAIN and the chapter on creating |
|
internationalization files. The default value is 0. |
|
|
|
* The STARTPOINT argument has impact on the way the INSTRREV function |
|
returns its results. When set to 1, the result of the INSTRREV |
|
function is counted from the end of the string. Default value is 0 |
|
(counting from the beginning of the string). |
|
|
|
* The DEVICE argument determines the way a device or file is opened in |
|
the OPEN FOR DEVICE statement. By default BaCon uses the following |
|
open mode: O_RDWR|O_NOCTTY|O_SYNC. Other common Unix open modes are |
|
O_APPEND, O_ASYNC, O_CREAT, O_EXCL, O_NONBLOCK and O_TRUNC. Please |
|
refer to the open manpage for more details on the open modes. |
|
|
|
* The PARSE argument defines if BaCon should allow non-BaCon code. It |
|
can be used to embed foreign functions from external C libraries. Use |
|
with care, as this option accepts any random piece of text. Errors |
|
only will popup during compile time, which may be hard to |
|
troubleshoot. The default value is 1. |
|
|
|
* The FRAMEWORK option is used in case of linking to MacOSX frameworks |
|
like Cocoa. This option allows multiple frameworks separated by a |
|
comma. For example: PRAGMA FRAMEWORK COCOA. |
|
|
|
* The VARTYPE option defines the default variable type in case of |
|
implicit declarations. The default value for this option is: long. |
|
|
|
* The QUOTED argument defines whether text delimiters appearing between |
|
double quotes should be skipped (1) or not (0). The default is to skip |
|
delimiters between double quotes (1). |
|
|
|
* The DQ argument defines the symbol for OPTION QUOTED. This is a |
|
numeric ASCII value between 0 and 255. Default value is 34 (double |
|
quotes). |
|
|
|
* The ESC argument defines the escape symbol for OPTION DQ. This is a |
|
numeric ASCII value between 0 and 255. Default value is 92 |
|
(backslash). |
|
|
|
* The UTF8 argument enables all BaCon string functions to process text |
|
in UTF8 format correctly. The default is to process text as ASCII (0). |
|
|
|
* The DELIM argument defines the delimiter string when processing |
|
delimited strings. It always should be provided as a static string |
|
literal. The default value is a single space " ". |
|
|
|
* The BREAK argument prevents and disables the use of BREAK statements |
|
in generated C code. The default is to allow BREAK statement (TRUE). |
|
|
|
* The EXPLICIT argument enforces the declaration of all variables used |
|
in a program. The default value is 0 (FALSE), so no variable |
|
declaration is enforced. |
|
|
|
* The INPUT argument defines where the stream of input characters from |
|
STDIN should be cut off. By default, INPUT returns when a newline is |
|
encountered. The default value is "n". |
|
|
|
* The ERROR argument sets whether or not a program will exit as soon a |
|
runtime error occurs. The default is TRUE (exit upon error). If set to |
|
FALSE, the program must take care of error handling by itself, and |
|
setting an error callback will be possible. See also the chapter on |
|
error catching for more information. |
|
|
|
* The PROPER argument sets whether or not the PROPER$ function should |
|
leave the items in a delimited string intact or not. The default value |
|
is FALSE, causing the PROPER$ function to lowercase the remainder of |
|
each item. |
|
|
|
* The TLS argument enables network connections to be TLS encapsulated. |
|
See the chapter on secure network connections for more details. The |
|
default value is FALSE. |
|
|
|
* The PRIORITY argument defines the TLS priority string for GnuTLS. By |
|
default, the priority string is defined as |
|
"NORMAL:-VERS-TLS1.3:%COMPAT" disabling TLS 1.3. |
|
|
|
* The NO_C_ESC argument can disable the effects of the C escape symbol |
|
"" in string literals. This can come handy when printing ASCII art |
|
for example. Default value is FALSE (do not disable effects of escape |
|
symbol in text). |
|
|
|
* The EVAL argument enables code generation for the EVAL function. It |
|
also adds linking flags for 'libmatheval' to the generated Makefile. |
|
The default value is FALSE. |
|
|
|
OR |
|
|
|
x OR y |
|
|
|
Type: operator |
|
|
|
Performs a logical or between x and y. For the binary or, use the '|' |
|
symbol. |
|
|
|
OS$ |
|
|
|
OS$ |
|
|
|
Type: function |
|
|
|
Function which returns the name and machine of the current Operating |
|
System. |
|
|
|
OUTBETWEEN$ |
|
|
|
OUTBETWEEN$(haystack$, lm$, rm$ [,flag]) |
|
|
|
Type: function |
|
|
|
This function returns <haystack$> where the substring delimited by <lm$> |
|
on the left and <rm$> on the right is cut out. The delimiters may contain |
|
multiple characters. They are not part of the returned result. The <flag> |
|
is optional (default value is 0) and specifies if <rm$> should either |
|
indicate the most right match (greedy indication, flag=1), or should |
|
return a balanced match (flag=2). See also INSERT$ to insert a string and |
|
INBETWEEN$ to return the delimited substring. Note that OPTION COLLAPSE |
|
has no impact on this function. Example usage: |
|
|
|
PRINT OUTBETWEEN$("Lorem ipsum dolor sit amet", "ipsum", "sit") |
|
a$ = OUTBETWEEN$("yes no 123 yes 456 yes", "no", "yes", TRUE) |
|
|
|
PARSE |
|
|
|
PARSE <string$> WITH <pattern$> [BY <delim$>] TO <array$> [SIZE <size>] |
|
[STATIC] |
|
|
|
Type: statement |
|
|
|
This statement can parse a delimited <string$> using a delimited |
|
<pattern$> containing wildcards. The matched results are stored in |
|
<array$> mentioned by the TO keyword. As sometimes it cannot be known in |
|
advance how many elements this resulting array will contain, the array may |
|
not be declared before with LOCAL or GLOBAL. The optional BY argument |
|
determines the delimiter. If the BY keyword is omitted then the default |
|
definition from OPTION DELIM will be used. |
|
|
|
If PARSE is being used in a function or sub, then <array$> will have a |
|
local scope. Else <array$> will be visible globally, and can be accessed |
|
within all functions and subs. |
|
|
|
The total amount of elements created in this array is stored in <size>. |
|
This variable can be declared explicitly using LOCAL or GLOBAL. The SIZE |
|
keyword is optional and may be omitted. |
|
|
|
If <delim$> occurs in between double quotes, then it is skipped. This |
|
behavior can be changed by setting OPTION QUOTED to FALSE. If a double |
|
quote needs to be present in the <string$>, it must be escaped properly. |
|
|
|
The provided <pattern$> must contain a delimited string with wildcards. |
|
The wildcard symbol '?' will match one delimited item, and the wildcard |
|
symbol '*' matches one or more items in the delimited string. Each time a |
|
match is found it will be added to <array$>. Parsing is executed from left |
|
to right and stops as soon matching the pattern fails. |
|
|
|
Example usage: |
|
|
|
OPTION BASE 1 |
|
PARSE "a b c d e f" WITH "a ? c * f" TO array$ |
|
FOR i = 1 TO UBOUND(array$) |
|
PRINT array$[i] |
|
NEXT |
|
|
|
This example will return two array items, one containing a single element |
|
and the other containing two delimited elements. See also MATCH to compare |
|
delimited strings using wildcards and COLLAPSE$ to make sure items in a |
|
string are separated by one delimiter. |
|
|
|
PEEK |
|
|
|
PEEK(x) |
|
|
|
Type: function |
|
|
|
Returns a value stored at memory address x. The type of the returned value |
|
can be determined with OPTION MEMTYPE. |
|
|
|
PI |
|
|
|
PI |
|
|
|
Type: variable |
|
|
|
Reserved variable containing the number for PI: 3.14159265358979323846. |
|
|
|
POKE |
|
|
|
POKE <x>, <y> [SIZE range] |
|
|
|
Type: statement |
|
|
|
Stores a value <y> at memory address <x>. The optional SIZE keyword can be |
|
used to store the value <y> in a complete range of addresses starting from |
|
address <x>. Use PEEK to retrieve a value from a memory address. Use |
|
OPTION MEMTYPE to determine the actual size of the type to store. |
|
Examples: |
|
|
|
OPTION MEMTYPE float |
|
mem = MEMORY(SIZEOF(float)) |
|
POKE mem, 32.123 |
|
area = MEMORY(1024) |
|
POKE area, 0 SIZE 1024 |
|
|
|
POW |
|
|
|
POW(x, y) |
|
|
|
Type: function |
|
|
|
Raise x to the power of y. |
|
|
|
PRAGMA |
|
|
|
PRAGMA <OPTIONS x> | <LDFLAGS x> [TRUE] | <COMPILER x> | <INCLUDE x> | <RE |
|
x [INCLUDE y] [LDFLAGS z]> | <GUI x> |
|
|
|
Type: statement |
|
|
|
Instead of passing command line arguments to influence the behavior of the |
|
compiler, it is also possible to define these arguments programmatically. |
|
Mostly these arguments are used when embedding variables or library |
|
dependent structures into BaCon code. When no valid option to PRAGMA is |
|
provided, BaCon will translate to the plain compiler directive '#pragma'. |
|
Example when SDL code is included in the BaCon program: |
|
|
|
PRAGMA LDFLAGS SDL |
|
PRAGMA INCLUDE SDL/SDL.h |
|
|
|
Example when GTK2 code is included in the BaCon program: |
|
|
|
PRAGMA LDFLAGS pkg-config --libs gtk+-2.0 |
|
PRAGMA INCLUDE gtk-2.0/gtk/gtk.h |
|
PRAGMA COMPILER gcc |
|
|
|
Example on passing optimization parameters to the compiler: |
|
|
|
PRAGMA OPTIONS -O2 -s |
|
|
|
Multiple arguments can be passed too: |
|
|
|
PRAGMA LDFLAGS iup cd iupcd im |
|
PRAGMA INCLUDE iup.h cd.h cdiup.h im.h im_image.h |
|
|
|
The LDFLAGS argument can specify whether the flags should occur before |
|
other flags using TRUE: |
|
|
|
PRAGMA LDFLAGS -Wl,--no-as-needed TRUE |
|
|
|
Example specifying a regular expression engine like PCRE (see the chapter |
|
on Regular Expressions for more details): |
|
|
|
PRAGMA RE pcre INCLUDE <pcreposix.h> LDFLAGS -lpcreposix |
|
|
|
Example using an OpenMP pragma definition: |
|
|
|
PRAGMA omp parallel for private(x) |
|
|
|
Example specifying a GTK backend for the GUI functions: |
|
|
|
PRAGMA GUI gtk3 |
|
|
|
PRINT |
|
|
|
PRINT [value] | [text] | [variable] | [expression] [FORMAT <format>[TO |
|
<variable> [SIZE <size>]]] | [,] | [;] |
|
|
|
Type: statement |
|
|
|
Prints a numeric value, text, variable or result from expression to |
|
standard output. As with most BASICs, the PRINT statement may be |
|
abbreviated using the '?' symbol. A semicolon at the end of the line |
|
prevents printing a newline. For printing to stderr, see EPRINT. Examples: |
|
|
|
PRINT "This line does "; |
|
PRINT "end here: "; |
|
PRINT linenr + 2 |
|
|
|
Multiple arguments maybe used but they must be separated with a comma. |
|
Examples: |
|
|
|
PRINT "This is operating system: ", OS$ |
|
PRINT "Sum of 1 and 2 is: ", 1 + 2 |
|
|
|
The FORMAT argument is optional and can be used to specify different types |
|
in the PRINT argument. The syntax of FORMAT is similar to the printf |
|
argument in C. Example: |
|
|
|
PRINT "My age is ", 42, " years which is ", 12 + 30 FORMAT "%s%d%s%dn" |
|
|
|
The result also can be printed to a string variable. This has to be done |
|
in combination with FORMAT. To achieve this, use the keyword TO. |
|
Optionally, the total amount of resulting characters can be provided with |
|
the SIZE keyword. If no size is given, BaCon will use its default internal |
|
buffer size (512 characters). |
|
|
|
PRINT "Hello cruel world" FORMAT "%s" TO hello$ |
|
PRINT mytime FORMAT "Time is now: %d" TO result$ SIZE 32 |
|
|
|
t = NOW + 300 |
|
PRINT HOUR(t), MINUTE(t), SECOND(t) FORMAT "%.2ld%.2ld%.2ld" TO time$ |
|
PRINT MONTH$(t) FORMAT "%s" TO current$ SIZE 15 |
|
|
|
PROPER$ |
|
|
|
PROPER$(string$ [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Capitalizes the first letter of all elements in a delimited string split |
|
by delimiter$. By default, other letters are put to lowercase. This |
|
behavior can be altered by setting OPTION PROPER. |
|
|
|
The delimiter$ is optional. If it is omitted, then the definition from |
|
OPTION DELIM is assumed. When specified, it may consist of multiple |
|
characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See the |
|
chapter on delimited string functions for more information about delimited |
|
strings. Example: |
|
|
|
PRINT PROPER$("hEllO crUEl wOrLd") |
|
|
|
PROTO |
|
|
|
PROTO <function name>[,function name [, ...]] [ALIAS word] [TYPE c-type] |
|
|
|
Type: statement |
|
|
|
Defines a foreign function so it is accepted by the BaCon parser. Multiple |
|
function names may be mentioned, but these should be separated by a comma. |
|
Optionally, PROTO accepts an alias which can be used instead of the |
|
original function name. Also, PROTO can define a c-type to define the type |
|
of return value for a foreign function. |
|
|
|
During compilation the BaCon program must explicitly be linked with an |
|
external library to resolve the function name. See also OPTION PARSE to |
|
allow foreign functions unconditionally. Examples: |
|
|
|
PROTO glClear, glClearColor, glEnable |
|
PROTO "glutSolidTeapot" ALIAS "TeaPot" |
|
PROTO "gtk_check_version(int,int,int)" TYPE char* |
|
|
|
PULL |
|
|
|
PULL <x> |
|
|
|
Type: statement |
|
|
|
Puts a value from the internal stack into variable <x>. The argument must |
|
be a variable. The stack will decrease to the next available value. |
|
|
|
If the internal stack has reached its last value, subsequent PULL's will |
|
retrieve this last value. If no value has been pushed before, a PULL will |
|
deliver 0 for numeric values and an empty string for string values. See |
|
PUSH to push values to the stack. |
|
|
|
PUSH |
|
|
|
PUSH <x>|<expression> |
|
|
|
Type: statement |
|
|
|
Pushes a value <x> or expression to the internal stack. There is no limit |
|
to the amount of values which can be put onto the stack other than the |
|
available memory. The principle of the stack is Last In, First Out. The |
|
reserved variable SP provides the total amount of elements currently on |
|
the stack. |
|
|
|
See also PULL to get a value from the stack. |
|
|
|
' Initially create a new 0 value for stack |
|
' This will only be 0 when stack wasn't declared before |
|
PULL stack |
|
PUSH stack |
|
' Increase and push the stack 2x |
|
' Stack has now 3 values |
|
INCR stack |
|
PUSH stack |
|
PUSH "End" |
|
PULL var$ |
|
' Print and pull current stack value - will return "end" 1 0 |
|
PRINT var$ |
|
PULL stack |
|
PRINT stack |
|
PULL stack |
|
PRINT stack |
|
|
|
PUTBYTE |
|
|
|
PUTBYTE <memory> TO <handle> [CHUNK x] [SIZE y] |
|
|
|
Type: statement |
|
|
|
Store binary data from a memory area to either a file or a device |
|
identified by handle, with an optional amount of <x> bytes, depending on |
|
OPTION MEMTYPE (default amount of bytes = 1). Also optionally, the actual |
|
amount stored can be captured in variable <y>. |
|
|
|
This statement is the inverse of GETBYTE, refer to this command for an |
|
example. |
|
|
|
PUTLINE |
|
|
|
PUTLINE "text"|<variable$> TO <handle> |
|
|
|
Type: statement |
|
|
|
Write a line of string data to a memory area identified by handle. The |
|
line will be terminated by a newline character. The memory area must be |
|
set in streaming mode first using OPEN (see also the chapter on ramdisks |
|
and memory streams). Example: |
|
|
|
PUTLINE "hello world" TO mymemory |
|
|
|
See also GETLINE to retrieve a line of text from a memory area. |
|
|
|
RAD |
|
|
|
RAD(x) |
|
|
|
Type: function |
|
|
|
Returns the radian value of x degrees. Example: |
|
|
|
PRINT RAD(45) |
|
|
|
RANDOM |
|
|
|
RANDOM (x) |
|
|
|
Type: function |
|
|
|
This is a convenience function to generate a random integer number between |
|
0 and x - 1. See also RND for more flexibility in creating random numbers. |
|
Example creating a random number between 1 and 100: |
|
|
|
number = RANDOM(100) + 1 |
|
|
|
READ |
|
|
|
READ <x1[, x2, x3, ...]> |
|
|
|
Type: statement |
|
|
|
Reads a value from a DATA block into variable <x>. Example: |
|
|
|
LOCAL dat[8] |
|
FOR i = 0 TO 7 |
|
READ dat[i] |
|
NEXT |
|
DATA 10, 20, 30, 40, 50, 60, 70, 80 |
|
|
|
Also, multiple variables may be provided: |
|
|
|
READ a, b, c, d$ |
|
DATA 10, 20, 30, "BaCon" |
|
|
|
See RESTORE to define where to start reading the data. |
|
|
|
READLN |
|
|
|
READLN <var> FROM <handle> |
|
|
|
Type: statement |
|
|
|
Reads a line of ASCII data from a file identified by <handle> into |
|
variable <var>. See the GETBYTE statement to read binary data. Example: |
|
|
|
READLN txt$ FROM myfile |
|
|
|
REALPATH$ |
|
|
|
REALPATH$(filename$) |
|
|
|
Type: function |
|
|
|
Returns the absolute full path and name of a given filename. Symbolic |
|
links are resolved as well as relative references like '../'. See also |
|
CURDIR$. |
|
|
|
REAP |
|
|
|
REAP(pid) |
|
|
|
Type: function |
|
|
|
After a forked process has ended, it can turn into a so-called 'zombie' |
|
process. This function can remove such process from the process list, |
|
using the process ID as an argument. When the value -1 is used as |
|
argument, REAP will remove any zombie child process. |
|
|
|
The return value of REAP indicates the process ID of the process which was |
|
removed from the process list successfully. If the return value is 0, then |
|
no child process has finished yet, and no process ID has been removed. |
|
When the return value is -1, an error has occurred (a common mistake is |
|
providing a wrong process ID value). |
|
|
|
This function does not pause and returns immediately. For an example, |
|
refer to FORK. |
|
|
|
RECEIVE |
|
|
|
RECEIVE <var> FROM <handle> [CHUNK <chunksize>] [SIZE <amount>] |
|
|
|
Type: statement |
|
|
|
Reads data from a network location identified by handle into a string |
|
variable or memory area. Subsequent reads return more data until the |
|
network buffer is empty. The chunk size can be determined with the |
|
optional CHUNK keyword. In case of TLS connections, it is recommended to |
|
use a multitude of 16k for the chunk size. |
|
|
|
The amount of bytes actually received can be retrieved by using the |
|
optional SIZE keyword. If the amount of bytes received is 0, then the |
|
other side has closed the connection in an orderly fashion. In such a |
|
situation the network connection needs to be reopened. Example: |
|
|
|
OPEN "www.google.com:80" FOR NETWORK AS mynet |
|
SEND "GET / HTTP/1.1rnHost: www.google.comrnrn" TO mynet |
|
REPEAT |
|
RECEIVE dat$ FROM mynet |
|
total$ = total$ & dat$ |
|
UNTIL ISFALSE(WAIT(mynet, 500)) |
|
CLOSE NETWORK mynet |
|
|
|
RECORD |
|
|
|
RECORD <var>[ARRAY <x>] |
|
LOCAL <member1> TYPE <type> |
|
LOCAL <member2> TYPE <type> |
|
.... |
|
END RECORD |
|
|
|
Type: statement |
|
|
|
Defines a record <var> with members. If the record is defined in the main |
|
program, it automatically will be visible globally. If the record is |
|
defined within a function, the record will have a local scope, meaning |
|
that it is only visible within that function. To declare a global record |
|
in a function, use the DECLARE or GLOBAL keyword. |
|
|
|
The members of a record should be defined using the LOCAL statement and |
|
can be accessed with the 'var.member' notation. See the chapter on records |
|
for more details on the usage of records. Also refer to WITH for assigning |
|
values to multiple members at the same time. Example: |
|
|
|
RECORD var |
|
LOCAL x |
|
LOCAL y |
|
END RECORD |
|
var.x = 10 |
|
var.y = 20 |
|
PRINT var.x + var.y |
|
|
|
REDIM |
|
|
|
REDIM <var> TO <size> |
|
|
|
Type: statement |
|
|
|
Redimensions a one dimensional dynamic array to a new size. The contents |
|
of the array will be preserved. If the array becomes smaller then the |
|
elements at the end of the array will be cleared. The dynamic array has to |
|
be declared previously using DECLARE or LOCAL. Example: |
|
|
|
REDIM a$ TO 20 |
|
|
|
REGEX |
|
|
|
REGEX (txt$, expr$) |
|
|
|
Type: function |
|
|
|
Applies a POSIX Extended Regular Expression expr$ to the string txt$. If |
|
the expression matches, the position of the first match is returned. If |
|
not, this function returns '0'. The length of the last match is returned |
|
in the reserved variable REGLEN. |
|
|
|
Use OPTION COMPARE to set case sensitive matching. Note that this function |
|
does not support non-greedy matching. See the chapter on regular |
|
expressions to specify different regular expression engines for more |
|
flexibility. Examples: |
|
|
|
' Does the string match alfanum character |
|
PRINT REGEX("Hello world", "[[:alnum:]]") |
|
|
|
' Does the string not match a number |
|
PRINT REGEX("Hello world", "[^0-9]") |
|
|
|
' Does the string contain an a, l or z |
|
PRINT REGEX("Hello world", "a|l|z") |
|
|
|
REGLEN |
|
|
|
REGLEN |
|
|
|
Type: variable |
|
|
|
Reserved variable containing the length of the last REGEX match. |
|
|
|
RELATE |
|
|
|
RELATE <assocA> TO <assocB>[, assocC, ...] |
|
|
|
Type: statement |
|
|
|
This statement creates a relation between associative arrays. Effectively |
|
this will result into duplication of settings; an index in array <assocA> |
|
also will be set in array <assocB>. A previous declaration of the |
|
associative arrays involved is required. Example: |
|
|
|
DECLARE human, mortal ASSOC int |
|
RELATE human TO mortal |
|
human("socrates") = TRUE |
|
PRINT mortal("socrates") |
|
|
|
REM |
|
|
|
REM [remark] |
|
|
|
Type: statement |
|
|
|
Adds a comment to your code. Any type of string may follow the REM |
|
statement. Instead of REM also the single quote symbol ' maybe used to |
|
insert comments in the code. |
|
|
|
BaCon also accepts C-style block comments: this can be done by surrounding |
|
multiple lines using /* and */. |
|
|
|
RENAME |
|
|
|
RENAME <filename> TO <new filename> |
|
|
|
Type: statement |
|
|
|
Renames a file. If different paths are included the file is moved from one |
|
path to the other. Note that an error occurs when the target directory is |
|
on a different partition. Example: |
|
|
|
RENAME "tmp.txt" TO "real.txt" |
|
|
|
REPEAT |
|
|
|
REPEAT |
|
<body> |
|
[BREAK]|[CONTINUE] |
|
UNTIL <equation> |
|
|
|
Type: statement |
|
|
|
The REPEAT/UNTIL construction repeats a body of statements. The difference |
|
with WHILE/WEND is that the body will be executed at least once. The |
|
optional BREAK statement can be used to break out the loop. With CONTINUE |
|
part of the body can be skipped. The BETWEEN operator is allowed in the |
|
equation. Example: |
|
|
|
REPEAT |
|
C = GETKEY |
|
UNTIL C = 27 |
|
|
|
REPLACE$ |
|
|
|
REPLACE$(haystack$, needle$, replacement$ [, flag]) |
|
|
|
Type: function |
|
|
|
Substitutes a substring <needle$> in <haystack$> with <replacement$> and |
|
returns the result. The replacement does not necessarily need to be of the |
|
same size as the substring. With the optional flag set to 1 the <needle$> |
|
should be taken as a regular expression, and OPTION COMPARE impacts case |
|
insensitive matching. With the optional flag set to 2, REPLACE$ will |
|
behave as a translate, meaning that the characters in <needle$> will be |
|
replaced by the successive characters in <replacement$>. See also |
|
EXTRACT$. |
|
|
|
Examples: |
|
|
|
PRINT REPLACE$("Hello world", "l", "p") |
|
PRINT REPLACE$("Some text", "me", "123") |
|
PRINT REPLACE$("Goodbye <all>", "<.*>", "123", TRUE) |
|
PRINT REPLACE$("abc123def", "[[:digit:]]", "x", 1) |
|
PRINT REPLACE$("Hello world", "old", "pme", 2) |
|
|
|
RESIZE |
|
|
|
RESIZE <x> TO <y> |
|
|
|
Type: statement |
|
|
|
Resizes memory area starting at address <x> to an amount of <y> of the |
|
type determined by OPTION MEMTYPE. If the area is enlarged, the original |
|
contents of the area remain intact. |
|
|
|
RESTORE |
|
|
|
RESTORE [label] |
|
|
|
Type: statement |
|
|
|
Restores the internal DATA pointer(s) to the beginning of the first DATA |
|
statement. |
|
|
|
Optionally, the restore statement allows a LABEL from where the internal |
|
DATA pointer needs to be restored. See also READ. Example: |
|
|
|
DATA 1, 2, 3, 4, 5 |
|
LABEL txt |
|
DATA "Hello", "world", "this", "is", "BaCon" |
|
RESTORE txt |
|
READ dat$ |
|
|
|
RESUME |
|
|
|
RESUME |
|
|
|
Type: function |
|
|
|
When an error is caught, this statement tries to continue after the |
|
statement where an error occurred. Example: |
|
|
|
TRAP LOCAL |
|
CATCH GOTO print_err |
|
DELETE FILE "somefile.txt" |
|
PRINT "Resumed..." |
|
END |
|
LABEL print_err |
|
PRINT ERR$(ERROR) |
|
RESUME |
|
|
|
RETURN |
|
|
|
RETURN [value] |
|
|
|
Type: statement |
|
|
|
If RETURN has no argument it will return to the last invoked GOSUB. If no |
|
GOSUB was invoked previously then RETURN has no effect. |
|
|
|
Only in case of functions the RETURN statement must contain a value. This |
|
is the value which is returned when the FUNCTION is finished. |
|
|
|
RETVAL |
|
|
|
RETVAL |
|
|
|
Type: variable |
|
|
|
Reserved variable containing the return status of the operating system |
|
commands executed by SYSTEM or EXEC$. |
|
|
|
REV$ |
|
|
|
REV$(string$ [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Puts all elements in a delimited string split by delimiter$ in reverse |
|
order. The delimiter$ is optional. If it is omitted, then the definition |
|
from OPTION DELIM is assumed. When specified, it may consist of multiple |
|
characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
the chapter on delimited string functions for more information about |
|
delimited strings. Example: |
|
|
|
PRINT "Reverted members: ", REV$("Rome Amsterdam Kiev Bern Paris London") |
|
|
|
REVERSE$ |
|
|
|
REVERSE$(x$) |
|
|
|
Type: function |
|
|
|
Returns the reverse of x$. |
|
|
|
REWIND |
|
|
|
REWIND <handle> |
|
|
|
Type: statement |
|
|
|
Returns to the beginning of a file opened with <handle>. |
|
|
|
RIGHT$ |
|
|
|
RIGHT$(string$[, amount]) |
|
|
|
Type: function |
|
|
|
Returns <amount> characters from the right of <string$>. The <amount> |
|
argument is optional. If omitted, then RIGHT$ by default will return 1 |
|
character. See also LEFT$ and MID$. |
|
|
|
RIP$ |
|
|
|
RIP$(x$, y, [z]) |
|
|
|
Type: function |
|
|
|
This function is the complement of MID$. It returns the characters which |
|
are left after position <y> in <x$> with optional length <z> is omitted. |
|
If y is a negative number, then start counting the position from the end |
|
of x$. The parameter 'z' is optional. When this parameter is 0, negative |
|
or left out, then everything from position 'y' until the end of the string |
|
is omitted. Example: |
|
|
|
txt$ = "Hello cruel world" |
|
PRINT RIP$(txt$, 7, 5) |
|
PRINT RIP$(txt$, -11) |
|
PRINT RIP$(txt$, 12, -1) |
|
|
|
RND |
|
|
|
RND |
|
|
|
Type: function |
|
|
|
Returns a random number between 0 and the reserved variable MAXRANDOM. The |
|
generation of random numbers can be seeded with the statement SEED. See |
|
also the function RANDOM for a more convenient way of generating random |
|
numbers. Example: |
|
|
|
SEED NOW |
|
x = RND |
|
|
|
ROL |
|
|
|
ROL(nr) |
|
|
|
Type: function |
|
|
|
This function performs a binary shift to the left. The highest bit will be |
|
recycled into bit 0. The total amount of bits in a value is determined by |
|
the MEMTYPE option. |
|
|
|
OPTION MEMTYPE short |
|
PRINT ROL(32768) |
|
|
|
ROR |
|
|
|
ROR(nr) |
|
|
|
Type: function |
|
|
|
This function performs a binary shift to the right. The lowest bit will be |
|
recycled into the highest, depending on the setting of the MEMTYPE option. |
|
|
|
OPTION MEMTYPE int |
|
PRINT ROR(1) |
|
|
|
ROTATE$ |
|
|
|
ROTATE$(string$, step [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Rotates all elements in a delimited string split by delimiter$ <step> |
|
positions forward. In case the <step> parameter is a negative number, the |
|
rotation will be backwards. The delimiter$ is optional. If it is omitted, |
|
then the definition from OPTION DELIM is assumed. When specified, it may |
|
consist of multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
the chapter on delimited string functions for more information about |
|
delimited strings. Example: |
|
|
|
PRINT ROTATE$("Rome Amsterdam Kiev Bern Paris London", 2) |
|
|
|
ROUND |
|
|
|
ROUND(x) |
|
|
|
Type: function |
|
|
|
Rounds x to the nearest integer number. For compatibility reasons, the |
|
keyword INT may be used instead. Note that this function always returns an |
|
integer value. |
|
|
|
See also FLOOR to round down to the nearest the integer and MOD to get the |
|
fraction from a fractional number. |
|
|
|
ROWS |
|
|
|
ROWS |
|
|
|
Type: function |
|
|
|
Returns the amount of rows in the current ANSI compliant terminal. Use |
|
COLUMNS to get the amount of columns. |
|
|
|
RUN |
|
|
|
RUN <command$> |
|
|
|
Type: statement |
|
|
|
Executes an operating system command thereby transferring control. This |
|
effectively means that the current program is left permanently, the |
|
process ID is preserved and that this statement does not return to the |
|
BaCon program. Typically, the RUN statement is used at the end of a BaCon |
|
program. It can only execute one system command at a time. |
|
|
|
The behavior of RUN differs from the SYSTEM statement, which can execute a |
|
set of compound commands in a shell and can query the exit status. See |
|
also EXEC$ and RUN$. |
|
|
|
Example: |
|
|
|
RUN "ls -l" |
|
|
|
RUN$ |
|
|
|
RUN$(command$ [, stdin$[, out]]) |
|
|
|
Type: function |
|
|
|
Executes an operating system command in a coprocess and returns the |
|
resulting output to the BaCon program. Because the coprocess PID is not a |
|
shell, but the PID of the executed command itself, this function cannot |
|
return a system command exit status, and can only execute one system |
|
command at a time. Optionally, a second argument may be used to feed to |
|
STDIN. Also optionally, a third argument can be specified to determine |
|
whether all output needs to be captured (0 = default), only stdout (1) or |
|
only stderr (2). See RUN and SYSTEM to plainly execute a system command. |
|
Example: |
|
|
|
result$ = RUN$("ps x") |
|
PRINT RUN$("rev", "This is a string", 1) |
|
PRINT RUN$("ls -z", NULL, 2) |
|
|
|
SAVE |
|
|
|
SAVE string$ TO filename$ |
|
|
|
Type: statement |
|
|
|
Saves a string to disk in one step. If the file already exists it is |
|
overwritten. See BSAVE for saving binary files in one step, and |
|
OPEN/WRITELN/READLN/CLOSE to read and write to a file using a filehandle. |
|
Example: |
|
|
|
SAVE result$ TO "/tmp/data.txt" |
|
SAVE "Hello", "world" TO file$ |
|
|
|
SCREEN |
|
|
|
SCREEN <SAVE> | <RESTORE> |
|
|
|
Type: statement |
|
|
|
This statement can save the state of the current ASCII screen into memory |
|
so it can be restored at a later moment in time. It only works with ANSI |
|
compliant terminals. Example: |
|
|
|
SCREEN SAVE |
|
PRINT "Hello world" |
|
SCREEN RESTORE |
|
|
|
SCROLL |
|
|
|
SCROLL <UP [x]|DOWN [x]> |
|
|
|
Type: statement |
|
|
|
Scrolls the current ANSI compliant terminal up or down one line. |
|
Optionally, the amount of lines to scroll can be provided. |
|
|
|
SEARCH |
|
|
|
SEARCH(handle, string [,flag]) |
|
|
|
Type: function |
|
|
|
Searches for <string> in file opened with <handle>. The search returns the |
|
byte offset in the file where the first occurrence of <string> is located. |
|
Use SEEK to effectively put the filepointer at this position. If the |
|
string data is not found, then the value '-1' is returned. |
|
|
|
Optionally, a third argument can be used to determine where to start the |
|
search and in which direction the search should take place. The following |
|
values are accepted: |
|
|
|
0: start at the beginning of the file, search forward (default) |
|
1: start at the current position of the filepointer, search forward |
|
2: start at the current position of the filepointer, search backward |
|
3: start at the end of the file, search backward. |
|
|
|
Note that when searching backwards, the actual search begins at the start |
|
position minus the length of the searched string. |
|
|
|
SECOND |
|
|
|
SECOND(x) |
|
|
|
Type: function |
|
|
|
Returns the second (0-59) where x is the amount of seconds since January |
|
1, 1970. |
|
|
|
SEED |
|
|
|
SEED x |
|
|
|
Type: statement |
|
|
|
Seeds the random number generator with some value. After that, subsequent |
|
usages of RND and RANDOM will return numbers in a random order. Note that |
|
seeding the random number generator with the same number also will result |
|
in the same sequence of random numbers. |
|
|
|
By default, a BaCon program will automatically seed the random number |
|
generator as soon as it is executed, so it may not be needed to use this |
|
function explicitly. Example: |
|
|
|
SEED NOW |
|
|
|
SEEK |
|
|
|
SEEK <handle> OFFSET <offset> [WHENCE START|CURRENT|END] |
|
|
|
Type: statement |
|
|
|
Puts the filepointer to new position at <offset>, optionally starting from |
|
<whence>. |
|
|
|
SELECT |
|
|
|
SELECT <variable> CASE <body>[;] [DEFAULT <body>] END SELECT |
|
|
|
Type: statement |
|
|
|
With this statement a variable can be examined on multiple values. |
|
Optionally, if none of the values match the SELECT statement may fall back |
|
to the DEFAULT clause. Example: |
|
|
|
SELECT myvar |
|
CASE 1 |
|
PRINT "Value is 1" |
|
CASE 5 |
|
PRINT "Value is 5" |
|
CASE 2*3 |
|
PRINT "Value is ", 2*3 |
|
DEFAULT |
|
PRINT "Value not found" |
|
END SELECT |
|
|
|
Contrary to most implementations, in BaCon the CASE keyword also may refer |
|
to expressions and variables. Note that in such situation, each CASE |
|
keyword will re-evaluate the expression at each occurrence. |
|
|
|
Also, BaCon knows how to 'fall through' by either using a semicolon or a |
|
comma separated list, in case multiple values lead to the same result: |
|
|
|
SELECT human$ |
|
CASE "Man" |
|
PRINT "It's male" |
|
CASE "Woman", "Girl" |
|
PRINT "It's female" |
|
CASE "Child"; |
|
CASE "Animal" |
|
PRINT "It's an it" |
|
DEFAULT |
|
PRINT "Alien detected" |
|
END SELECT |
|
|
|
SEND |
|
|
|
SEND <var> TO <handle> [CHUNK <chunk>] [SIZE <size>] |
|
|
|
Type: statement |
|
|
|
Sends data in <var> to a network location identified by <handle>. |
|
Optionally, the amount of bytes to send can be specified with the CHUNK |
|
keyword. As by default SEND will consider the <var> to be a string, the |
|
default amount of data is the string length of <var>. However, instead of |
|
a string, also binary data can be sent by using a memory area created by |
|
the MEMORY function. In such a situation it is obligatory to also specify |
|
the chunk size. |
|
|
|
The amount of bytes actually sent can be retrieved by using the optional |
|
SIZE keyword. For an example of SEND, see the RECEIVE statement. |
|
|
|
SETENVIRON |
|
|
|
SETENVIRON var$, value$ |
|
|
|
Type: statement |
|
|
|
Sets the environment variable 'var$' to 'value$'. If the environment |
|
variable already exists, this statement will overwrite a previous value. |
|
See GETENVIRON$ to retrieve the value of an environment variable. Example: |
|
|
|
SETENVIRON "LANG", "C" |
|
|
|
SETSERIAL |
|
|
|
SETSERIAL <device> IMODE|OMODE|CMODE|LMODE|SPEED|OTHER <value> |
|
|
|
Type: statement |
|
|
|
This statement can set the properties of a serial device. The Input Mode |
|
(IMODE), Output Mode (OMODE), Control Mode (CMODE) and Local Mode (LMODE) |
|
can be set, as well as the speed and the special properties on the serial |
|
device. A discussion on the details of all these options is outside the |
|
scope of this manual. Please refer to the TermIOS documentation of your C |
|
compiler instead. |
|
|
|
Example usage opening a serial port in 8N1, ignoring 0-byte as a break, |
|
canonical, and non-blocking with a timeout of 0.5 seconds: |
|
|
|
OPEN "/dev/ttyUSB0" FOR DEVICE AS myserial |
|
SETSERIAL myserial SPEED B9600 |
|
SETSERIAL myserial IMODE ~IGNBRK |
|
SETSERIAL myserial CMODE ~CSIZE |
|
SETSERIAL myserial CMODE CS8 |
|
SETSERIAL myserial CMODE ~PARENB |
|
SETSERIAL myserial CMODE ~CSTOPB |
|
SETSERIAL myserial LMODE ICANON |
|
SETSERIAL myserial OTHER VMIN = 0 |
|
SETSERIAL myserial OTHER VTIME = 5 |
|
|
|
Example setting the terminal to raw input mode (no echo and no line based |
|
input): |
|
|
|
SETSERIAL STDIN_FILENO LMODE ~ECHO |
|
SETSERIAL STDIN_FILENO LMODE ~ICANON |
|
|
|
SGN |
|
|
|
SGN(x) |
|
|
|
Type: function |
|
|
|
Returns the sign of x. If x is a negative value, this function returns -1. |
|
If x is a positive value, this function returns 1. If x is 0 then a 0 is |
|
returned. |
|
|
|
SIGNAL |
|
|
|
SIGNAL <sub>, <signal> |
|
|
|
Type: statement |
|
|
|
This statement connects a Unix signal to a callback function. Plain POSIX |
|
signal names can be used, for example SIGINT, SIGTERM, SIGCHLD and so on. |
|
Next to that, this statement accepts the SIG_DFL (default action) and |
|
SIG_IGN (ignore signal) symbols for a callback also. |
|
|
|
Example to ignore the SIGCHLD signal, preventing zombie processes to |
|
occur: |
|
|
|
SIGNAL SIG_IGN, SIGCHLD |
|
|
|
Example connecting the <CTRL>+<C> signal to a SUB: |
|
|
|
SUB Cleanup : ' Signal callback function |
|
SIGNAL SIG_DFL, SIGINT : ' Restore CTRL+C |
|
PRINT "Cleaning up" : ' Do your cleanup here |
|
STOP SIGINT : ' Send the SIGINT to myself |
|
ENDSUB |
|
SIGNAL Cleanup, SIGINT : ' Catch CTRL+C |
|
PRINT "Waiting..." |
|
key = GETKEY |
|
|
|
SIN |
|
|
|
SIN(x) |
|
|
|
Type: function |
|
|
|
Returns the calculated SINUS of x, where x is a value in radians. |
|
|
|
SIZEOF |
|
|
|
SIZEOF(type) |
|
|
|
Type: function |
|
|
|
Returns the bytesize of a C type. |
|
|
|
SLEEP |
|
|
|
SLEEP <x> |
|
|
|
Type: statement |
|
|
|
Sleeps <x> milliseconds (sleep 1000 is 1 second). |
|
|
|
SORT |
|
|
|
SORT <x> [SIZE <x>] [DOWN] |
|
|
|
Type: statement |
|
|
|
Sorts the one-dimensional array <x> in ascending order. Only the basename |
|
of the array should be mentioned, not the dimension. The array may be |
|
indexed or associative. |
|
|
|
For indexed arrays, the amount of elements to sort can be specified with |
|
the optional keyword SIZE. Also optionally, the keyword DOWN can be used |
|
to sort in descending order. |
|
|
|
For associative arrays, sorting means changing the insertion order of the |
|
key/value pairs in the hash table. The ordered keys can be retrieved by |
|
LOOKUP or OBTAIN$. The SIZE keyword has no impact. |
|
|
|
Examples: |
|
|
|
GLOBAL a$[5] TYPE STRING |
|
a$[0] = "Hello" |
|
a$[1] = "my" |
|
a$[2] = "good" |
|
a$[4] = "friend" |
|
SORT a$ |
|
|
|
Sorting an associative array: |
|
|
|
DECLARE aa ASSOC short |
|
aa("one") = 33 |
|
aa("two") = 12 |
|
aa("three") = 44 |
|
aa("four") = 15 |
|
aa("five") = 8 |
|
SORT aa DOWN |
|
|
|
SORT$ |
|
|
|
SORT$(string$ [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Sorts all elements in a delimited string split by delimiter$. The |
|
delimiter$ is optional. If it is omitted, then the definition from OPTION |
|
DELIM is assumed. When specified, it may consist of multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
the chapter on delimited string functions for more information about |
|
delimited strings. Example: |
|
|
|
PRINT "Sorted members: ", SORT$("f,q,a,c,i,b,r,t,e,d,z,", ",") |
|
|
|
SOURCE$ |
|
|
|
SOURCE$ |
|
|
|
Type: variable |
|
|
|
Reserved variable which contains the BaCon source code of the current |
|
running program. Note that for commercial programs this variable should |
|
not be used, because it stores the source code as plain text in the |
|
resulting binary. |
|
|
|
SP |
|
|
|
SP |
|
|
|
Type: variable |
|
|
|
Reserved variable containing the amount of elements currently in the |
|
stack. See also PUSH and PULL. |
|
|
|
SPC$ |
|
|
|
SPC$(x) |
|
|
|
Type: function |
|
|
|
Returns an x amount of spaces. |
|
|
|
SPLIT |
|
|
|
SPLIT <string$> [BY <substr$>|<nr>] TO <array$> [SIZE <variable>] [STATIC] |
|
|
|
Type: statement |
|
|
|
This statement can split a string into smaller pieces. The optional BY |
|
argument determines where the string is being split. If the BY keyword is |
|
omitted then the definition from OPTION DELIM is used to split string$. |
|
The results are stored in the argument <array$> mentioned by the TO |
|
keyword. As sometimes it cannot be known in advance how many elements this |
|
resulting array will contain, the array may not be declared before with |
|
LOCAL or GLOBAL. |
|
|
|
If <substr$> occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See the |
|
chapter on delimited string functions for more information about delimited |
|
strings. |
|
|
|
If SPLIT is being used in a function or sub, then <array$> will have a |
|
local scope. Else <array$> will be visible globally, and can be accessed |
|
within all functions and subs. |
|
|
|
The total amount of elements created in this array is stored in |
|
<variable>. This variable can be declared explicitly using LOCAL or |
|
GLOBAL. The SIZE keyword is optional and may be omitted. |
|
|
|
If the <substr$> delimiter occurs in between double quotes, then it is |
|
skipped. This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
If a double quote needs to be present in the <string$>, it must be escaped |
|
properly. |
|
|
|
If the value for BY is numeric, then string$ will be cut in pieces each |
|
containing <nr> characters. If <nr> is 0 then there are no results. If |
|
<nr> is equal to or bigger than the length of the string, then the |
|
original string will be returned as an array with one element. |
|
|
|
Example usage: |
|
|
|
OPTION BASE 1 |
|
LOCAL dimension |
|
SPLIT "one,two,,three" BY "," TO array$ SIZE dimension |
|
FOR i = 1 TO dimension |
|
PRINT array$[i] |
|
NEXT |
|
|
|
The above example will return four elements, of which the third element is |
|
empty. If OPTION COLLAPSE is put to 1, the above example will return three |
|
elements, ignoring empty entries. |
|
|
|
SPLIT "one,two,"three,four",five" BY "," TO array$ SIZE dim |
|
|
|
This will return 4 elements, because one separator (the comma) lies in |
|
between double quotes. |
|
|
|
The optional STATIC keyword allows the created <array> to be returned from |
|
a function. See also EXPLODE$ to split text returning a delimited string, |
|
TOKEN$ to retrieve one single element from a delimited string, and JOIN to |
|
join array elements into a string. |
|
|
|
SQR |
|
|
|
SQR(x) |
|
|
|
Type: function |
|
|
|
Calculates the square root from a number. |
|
|
|
STOP |
|
|
|
STOP [signal] |
|
|
|
Type: statement |
|
|
|
Halts the current program and returns to the Unix prompt. The program can |
|
be resumed by performing the Unix command 'fg', or by sending the CONT |
|
signal to its pid: kill -CONT <pid>. |
|
|
|
The STOP statement actually sends the 'STOP' signal to the current |
|
program. Optionally, a different signal can be defined. The signal can be |
|
a number or a predefined name from libc, like SIGQUIT, SIGKILL, SIGTERM |
|
and so on. Example sending the <CTRL>+<C> signal: |
|
|
|
STOP SIGINT |
|
|
|
STR$ |
|
|
|
STR$(x) |
|
|
|
Type: function |
|
|
|
Convert numeric value x to a string (opposite of VAL). Example: |
|
|
|
PRINT STR$(123) |
|
|
|
SUB |
|
|
|
SUB <name>[(STRING s, NUMBER i, FLOATING f, VAR v SIZE t)] |
|
<body> |
|
ENDSUB | END SUB |
|
|
|
Type: statement |
|
|
|
Defines a subprocedure. A subprocedure never returns a value (use FUNCTION |
|
instead). |
|
|
|
Variables used in a sub are visible globally, unless declared with LOCAL. |
|
The incoming arguments are always local. Instead of the BaCon types |
|
STRING, NUMBER and FLOATING for the incoming arguments, also regular |
|
C-types also can be used. If no type is specified, then BaCon will |
|
recognize the argument type from the variable suffix. In case no suffix is |
|
available, plain NUMBER type is assumed. With VAR a variable amount of |
|
arguments can be defined. Example: |
|
|
|
SUB add(NUMBER x, NUMBER y) |
|
LOCAL result |
|
PRINT "The sum of x and y is: "; |
|
result = x + y |
|
PRINT result |
|
END SUB |
|
|
|
SUM / SUMF |
|
|
|
SUM(array, amount [,minimum]) |
|
SUMF(array, amount [,minimum]) |
|
|
|
Type: function |
|
|
|
Returns the sum of <amount> elements in <array>. Optionally, a check can |
|
be added which specifies the minimum value for each element to be added. |
|
If an array element falls below the specified value then it is excluded |
|
from the sum calculation. |
|
|
|
The SUM and SUMF functions perform the same task, but SUM requires an |
|
array with integers and SUMF an array with floating values. See also MAP. |
|
Example: |
|
|
|
PRINT SUM(ages, 10) |
|
PRINT SUMF(temperatures, 100, 25.5) |
|
|
|
SWAP |
|
|
|
SWAP x, y |
|
|
|
Type: statement |
|
|
|
Swaps the contents of the variables x and y. The types of the variables |
|
can be mixed. Note that when swapping an integer with a float precision |
|
may be lost. |
|
|
|
Numeric variables can be swapped with string variables, thereby |
|
effectively converting types. Example: |
|
|
|
SWAP x%, y# |
|
SWAP number, string$ |
|
|
|
SYSTEM |
|
|
|
SYSTEM <command$> |
|
|
|
Type: statement |
|
|
|
Executes an operating system command. It causes the BaCon program to hold |
|
until the command has been completed. The exit status of the executed |
|
command itself is stored in the reserved variable RETVAL. Use EXEC$ to |
|
catch the result of an operating system command. Example: |
|
|
|
SYSTEM "ls -l" |
|
|
|
TAB$ |
|
|
|
TAB$(x) |
|
|
|
Type: function |
|
|
|
Returns an x amount of tabs. |
|
|
|
TAIL$ |
|
|
|
TAIL$(string$, amount [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Retrieves the last <amount> elements from a delimited string$ split by |
|
delimiter$. The delimiter$ is optional. If it is omitted, then the |
|
definition from OPTION DELIM is assumed. When specified, it may consist of |
|
multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
|
|
See also FIRST$ to obtain the remaining elements from the delimited |
|
string, and HEAD$ to obtain elements counting from the start. Refer to the |
|
chapter on delimited string functions for more information about delimited |
|
strings. Example: |
|
|
|
PRINT "Last 2 members: ", TAIL$("Rome Amsterdam Kiev Bern Paris London", |
|
2) |
|
|
|
TALLY |
|
|
|
TALLY(haystack$, needle$ [,z]) |
|
|
|
Type: function |
|
|
|
Returns the amount of times needle$ occurs in haystack$, optionally |
|
starting at position z. If the needle$ is not found, then this function |
|
returns the value '0'. See INSTR to find the position of a string. |
|
Example: |
|
|
|
amount = TALLY("Hello world are we all happy?", "ll") |
|
PRINT TALLY("Don't take my ticket", "t", 10) |
|
|
|
TAN |
|
|
|
TAN(x) |
|
|
|
Type: function |
|
|
|
Returns the calculated tangent of x, where x is a value in radians. |
|
|
|
TELL |
|
|
|
TELL(handle) |
|
|
|
Type: function |
|
|
|
Returns current position in file opened with <handle>. |
|
|
|
TEXTDOMAIN |
|
|
|
TEXTDOMAIN <domain$>, <directory$> |
|
|
|
Type: statement |
|
|
|
When OPTION INTERNATIONAL is enabled, BaCon by default configures a |
|
textdomain with the current filename and a base directory |
|
"/usr/share/locale" for the message catalogs. With this statement it is |
|
possible to explicitly specify a different textdomain and base directory. |
|
|
|
TIMER |
|
|
|
TIMER |
|
|
|
Type: function |
|
|
|
Keeps track of the amount of milliseconds the current program is running. |
|
See NANOTIMER to measure nanoseconds. Example: |
|
|
|
iter = 1 |
|
WHILE iter > 0 DO |
|
IF TIMER = 1 THEN BREAK |
|
INCR iter |
|
WEND |
|
PRINT "Got ", iter-1, " iterations in 1 millisecond!" |
|
|
|
TIMEVALUE |
|
|
|
TIMEVALUE(a,b,c,d,e,f) |
|
|
|
Type: function |
|
|
|
Returns the amount of seconds since January 1 1970, from year (a), month |
|
(b), day (c), hour (d), minute (e), and seconds (f). Example: |
|
|
|
PRINT TIMEVALUE(2009, 11, 29, 12, 0, 0) |
|
|
|
TOASCII$ |
|
|
|
TOASCII$(string$) |
|
|
|
Type: function |
|
|
|
Returns the same string of which each byte has bit 7 set to 0. Note that |
|
this can lead to unpredictable results. See also ISASCII or ISUTF8. |
|
Example: |
|
|
|
PRINT TOASCII$("Hello world") |
|
|
|
TOKEN$ |
|
|
|
TOKEN$(haystack$, n [, delimiter$]) |
|
|
|
Type: function |
|
|
|
Returns the n^th token in haystack$ split by delimiter$. The delimiter$ is |
|
optional. If it is omitted, then the definition from OPTION DELIM is |
|
assumed. When specified, it may consist of multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in haystack$, then it is |
|
ignored. This behavior can be changed by setting OPTION QUOTED to FALSE. |
|
|
|
If the indicated position is outside a valid range, the result will be an |
|
empty string. Use the FLATTEN$ function to flatten out the returned token. |
|
See also ISTOKEN, AMOUNT and SPLIT. |
|
|
|
Examples: |
|
|
|
PRINT TOKEN$("a b c d "e f" g h i j", 6) |
|
PRINT TOKEN$("Dog Cat @@@ Mouse Bird@@@ 123@@@", 3, "@@@") |
|
PRINT TOKEN$("1,2,3,4,5", 3, ",") |
|
PRINT TOKEN$("1,2," & CHR$(34) & "3,4" & CHR$(34) & ",5,", 6, ",") |
|
|
|
TOTAL |
|
|
|
TOTAL(binary_tree) |
|
|
|
Type: function |
|
|
|
Returns the amount of nodes in <binary_tree>. See the chapter on binary |
|
trees for more information. Example: |
|
|
|
PRINT "Amount of elements: ", TOTAL(mytree) |
|
|
|
TRACE |
|
|
|
TRACE <ON|MONITOR <var1, var2, ...>|OFF> |
|
|
|
Type: statement |
|
|
|
The ON keyword starts trace mode. The program will wait for a key to |
|
continue. After each key press, the next line of source code is displayed |
|
on the screen, and then executed. A double quote symbol will be replaced |
|
for a single quote, a back slash symbol will be replaced by a forward |
|
slash and a percentage symbol will be replaced by a hash symbol to avoid |
|
clashes with the C printf function. Pressing the ESCAPE key will exit the |
|
program. |
|
|
|
The MONITOR keyword also starts trace mode, but allows monitoring values |
|
of variables. After each line of source code the content of the specified |
|
variables is displayed. |
|
|
|
If TRACE is used within a function, make sure to also add TRACE OFF at the |
|
end of the function. |
|
|
|
Example: |
|
|
|
LOCAL var |
|
TRACE MONITOR var |
|
FOR var = 1 TO 10 |
|
INCR var |
|
NEXT |
|
|
|
TRAP |
|
|
|
TRAP <LOCAL|SYSTEM> |
|
|
|
Type: statement |
|
|
|
Sets the runtime error trapping. By default, BaCon performs error trapping |
|
(LOCAL). BaCon tries to examine statements and functions where possible, |
|
and will display an error message based on the operating system internals, |
|
indicating which statement or function causes a problem. Optionally, when |
|
a CATCH is set, BaCon can jump to a LABEL instead, where a self-defined |
|
error function can be executed, and from where a RESUME is possible. |
|
|
|
When set to SYSTEM, error trapping is performed by the operating system. |
|
This means that if an error occurs, a signal will be caught by the program |
|
and a generic error message is displayed on the prompt. The program will |
|
then exit gracefully |
|
|
|
The setting LOCAL decreases the performance of the program, because |
|
additional runtime checks are carried out when the program is executed. |
|
|
|
TREE |
|
|
|
TREE <binary tree> ADD <value> [TYPE <type>] |
|
|
|
Type: statement |
|
|
|
The TREE statement adds a value to a binary tree. Adding a duplicate value |
|
to the tree will not have any effect, and will silently be ignored. For |
|
more information and examples, see the chapter on binary trees. See also |
|
FIND to verify the presence of a node in a binary tree or TOTAL to |
|
determine the total amount of nodes in a tree. Example: |
|
|
|
DECLARE mytree TREE STRING |
|
IF NOT(FIND(mytree, "hello world")) THEN TREE mytree ADD "hello world" |
|
|
|
TRUE |
|
|
|
TRUE |
|
|
|
Type: variable |
|
|
|
Represents and returns the value of '1'. This is the opposite of the FALSE |
|
variable. |
|
|
|
TYPE |
|
|
|
TYPE [SET|UNSET|RESET] [BOLD|ITALIC|UNDERLINE|INVERSE|BLINK|STRIKE] |
|
|
|
Type: statement |
|
|
|
The TYPE statement sets the font type in an ANSI compliant console. It is |
|
allowed to specify multiple types on the same line. Changes can be undone |
|
per type using the UNSET keyword. The RESET keyword will restore the |
|
default font settings. Note that not all Linux shells implement every |
|
console font type. See also the COLOR statement to set the color. |
|
Examples: |
|
|
|
TYPE SET ITALIC BLINK |
|
PRINT "This is blinking italic!" |
|
TYPE UNSET BLINK |
|
PRINT "Italic left!" |
|
TYPE RESET |
|
|
|
TYPEOF$ |
|
|
|
TYPEOF$(x) |
|
|
|
Type: function |
|
|
|
Returns the type of a variable. |
|
|
|
UBOUND |
|
|
|
UBOUND(array) |
|
|
|
Type: function |
|
|
|
Returns the total elements available in a static, dynamic or associative |
|
array. In case of multi-dimensional static arrays, the total amount of |
|
elements in the array is returned. Example: |
|
|
|
LOCAL array[] = { 2, 4, 6, 8, 10 } |
|
PRINT UBOUND(array) |
|
|
|
UCASE$ |
|
|
|
UCASE$(x$) |
|
|
|
Type: function |
|
|
|
Converts x$ to uppercase characters and returns the result. See LCASE$ to |
|
do the opposite. |
|
|
|
UCS |
|
|
|
UCS(char) |
|
|
|
Type: function |
|
|
|
Calculates the Unicode value of the given UTF8 character (opposite of |
|
UTF8$). See also ASC for plain ASCII characters. Example: |
|
|
|
PRINT UCS("©") |
|
|
|
ULEN |
|
|
|
ULEN(x$ [, y]) |
|
|
|
Type: function |
|
|
|
Returns the length of the UTF8 string x$. Optionally, the position at y |
|
can be specified. See LEN for plain ASCII strings. |
|
|
|
UNESCAPE$ |
|
|
|
UNESCAPE$(string$) |
|
|
|
Type: function |
|
|
|
Parses the text in <string$> and converts escape sequences into actual |
|
special characters (like newline or Unicode). This functionality comes |
|
handy when reading C text or JSON text containing escape sequences. Escape |
|
sequences for actual binary data (like 'x') are not converted. See also |
|
ESCAPE$ to do the opposite. Example: |
|
|
|
OPTION UTF8 TRUE |
|
PRINT UNESCAPE$("Hello\nworld\t\U0001F600") |
|
|
|
UNFLATTEN$ |
|
|
|
UNFLATTEN$(txt$ [, groupingchar$]) |
|
|
|
Type: function |
|
|
|
Unflattens a string where the double quote symbol is used to group parts |
|
of the string together. The string will be surrounded with double quotes |
|
and any existing escapes will be escaped. Instead of the double quote |
|
symbol a different character can be specified (optional). See also |
|
FLATTEN$ for the reverse operation. Examples: |
|
|
|
PRINT UNFLATTEN$(""Hello \"cruel\" world"") |
|
PRINT UNFLATTEN$("'Hello world'", "'") |
|
|
|
UNIQ$ |
|
|
|
UNIQ$(string$ [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Unifies all elements in a delimited string split by delimiter$. The |
|
delimiter$ is optional. If it is omitted, then the definition from OPTION |
|
DELIM is assumed. When specified, it may consist of multiple characters. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
the chapter on delimited string functions for more information about |
|
delimited strings. Example: |
|
|
|
PRINT "A sequence with unique members: ", UNIQ$("a a b c c d e f a c f") |
|
|
|
USEC |
|
|
|
USEC |
|
<body> |
|
ENDUSEC | END USEC |
|
|
|
Type: statement |
|
|
|
Defines a body with C code. This code is put unmodified into the generated |
|
C source file. Example: |
|
|
|
USEC |
|
char *str; |
|
str = strdup("Hello"); |
|
printf("%sn", str); |
|
END USEC |
|
|
|
USEH |
|
|
|
USEH |
|
<body> |
|
ENDUSEH | END USEH |
|
|
|
Type: statement |
|
|
|
Defines a body with C declarations and/or definitions. This code is put |
|
unmodified into the generated global header source file. This can |
|
particularly be useful in case of using variables from external libraries. |
|
See also USEC to pass C source code. Example: |
|
|
|
USEH |
|
char *str; |
|
extern int pbl_errno; |
|
END USEH |
|
|
|
UTF8$ |
|
|
|
UTF8$(x) |
|
|
|
Type: function |
|
|
|
Returns the character belonging to Unicode number x. This function does |
|
the opposite of UCS. The value for x can lie between 0 and 0x10FFFF. Note |
|
that the result only will be visible in a valid UTF8 environment, and also |
|
that the installed character set should support the character. See also |
|
CHR$ for plain ASCII characters. The following should print a smiley |
|
emoticon: |
|
|
|
LET a$ = UTF8$(0x1F600) |
|
PRINT a$ |
|
|
|
VAL |
|
|
|
VAL(x$) |
|
|
|
Type: function |
|
|
|
Returns the actual value of x$. This is the opposite of STR$. Example: |
|
|
|
nr$ = "456" |
|
q = VAL(nr$) |
|
|
|
VAR |
|
|
|
VAR <array$>|<array#>|<array%>|<array> [TYPE c-type] SIZE <total> |
|
|
|
Type: statement |
|
|
|
Declares a variable argument list in a FUNCTION or SUB. There may be no |
|
other variable declarations in the function header. The arguments to the |
|
function are put into an <array> which is visible within the FUNCTION or |
|
SUB. The type can be defined either by the optional TYPE keyword or by a |
|
variable suffix. If no type is specified then VAR will assume NUMBER. The |
|
SIZE keyword defines where the resulting amount of elements will be |
|
stored. Example: |
|
|
|
OPTION BASE 1 |
|
SUB demo (VAR arg$ SIZE amount) |
|
LOCAL x |
|
PRINT "Amount of incoming arguments: ", amount |
|
FOR x = 1 TO amount |
|
PRINT arg$[x] |
|
NEXT |
|
END SUB |
|
|
|
' No argument |
|
demo(0) |
|
' One argument |
|
demo("abc") |
|
' Three arguments |
|
demo("123", "456", "789") |
|
|
|
VERIFY |
|
|
|
VERIFY(connection, file$) |
|
|
|
Type: function |
|
|
|
Verifies the certificates of the current TLS connection against file$. The |
|
file$ should be in PEM format and should contain all root CA certificates. |
|
Usually this information can be extracted from a web browser. See also the |
|
chapter on secure network connections. |
|
|
|
In case of an invalid certificate, OpenSSL and GnuTLS will not drop the |
|
active TLS connection, and the VERIFY function will return the TLS error |
|
code. |
|
|
|
For WolfSSL, the connection will be dropped immediately, and the reserved |
|
ERROR variable will contain the actual TLS error code. Use CATCH GOTO to |
|
prevent the program from stopping and workaround the TLS problem. |
|
|
|
VERSION$ |
|
|
|
VERSION$ |
|
|
|
Type: variable |
|
|
|
Reserved variable which contains the BaCon version text. |
|
|
|
WAIT |
|
|
|
WAIT(handle, milliseconds) |
|
|
|
Type: function |
|
|
|
Suspends the program for a maximum of <milliseconds> until data becomes |
|
available on <handle>. |
|
|
|
This is especially useful in network programs where a RECEIVE will block |
|
if there is no data available. The WAIT function checks the handle and if |
|
there is data in the queue, it returns with value '1'. If there is no data |
|
then it waits for at most <milliseconds> before it returns. If there is no |
|
data available, WAIT returns '0'. Refer to the RECEIVE statement for an |
|
example. |
|
|
|
This statement also can be used to find out if a key is pressed without |
|
actually waiting for a key, so without interrupting the current program. |
|
In this case, use the STDIN file descriptor (0) as the handle. Example: |
|
|
|
REPEAT |
|
PRINT "Press Escape... waiting..." |
|
key = WAIT(STDIN_FILENO, 50) |
|
UNTIL key = 27 |
|
|
|
As can be observed in this code, instead of '0' the reserved POSIX |
|
variable STDIN_FILENO can be used also. See also appendix B for more |
|
standard POSIX variables. |
|
|
|
WALK$ |
|
|
|
WALK$(directory$, filetype, regex, recursive [,delimiter$]) |
|
|
|
Type: function |
|
|
|
This function returns a delimited string with all the file names located |
|
in <directory$>. The <filetype> argument can contain a number and |
|
determines the kind of file to look for. These values can be combined in a |
|
binary OR: |
|
|
|
Value Meaning |
|
1 Regular file |
|
2 Directory |
|
4 Character device |
|
8 Block device |
|
16 Named pipe (FIFO) |
|
32 Symbolic link |
|
64 Socket |
|
|
|
The <regex> argument defines a regular expression and acts as an |
|
additional filter to narrow down the resulting list further. The |
|
<recursive> argument can either be TRUE or FALSE to define whether or not |
|
underlying directories should be searched as well. |
|
|
|
The delimiter$ argument is optional. If it is omitted, then the definition |
|
from OPTION DELIM is assumed. When specified, it may consist of multiple |
|
characters. Note that the default delimiter used by BaCon is a single |
|
whitespace, while file names can contain whitespaces as well. It is |
|
therefore recommended to specify a delimiter like NL$ which usually does |
|
not occur in file names. |
|
|
|
If delimiter$ occurs between double quotes in string$, then it is ignored. |
|
This behavior can be changed by setting OPTION QUOTED to FALSE. See also |
|
the chapter on delimited string functions for more information about |
|
delimited strings. |
|
|
|
Example to list files and directories in the current directory using a |
|
binary OR: |
|
|
|
PRINT WALK$(".", 1|2, ".+", FALSE, NL$) |
|
|
|
Example to list all directories in /tmp containing an underscore symbol: |
|
|
|
PRINT WALK$("/tmp", 2, "[_]+", FALSE, NL$) |
|
|
|
Example to recursively list all files ending in ".jpg" and also start with |
|
a number: |
|
|
|
PRINT WALK$(".", 1, "^[[:digit:]]+.*.jpg$", TRUE, NL$) |
|
|
|
WEEK |
|
|
|
WEEK(x) |
|
|
|
Type: function |
|
|
|
Returns the week number (1-53) in a year, where x is the amount of seconds |
|
since January 1, 1970. Example: |
|
|
|
PRINT WEEK(NOW) |
|
|
|
WEEKDAY$ |
|
|
|
WEEKDAY$(x) |
|
|
|
Type: function |
|
|
|
Returns the day of the week as a string in the system's locale ("Monday", |
|
"Tuesday", etc), where x is the amount of seconds since January 1, 1970. |
|
|
|
WHERE |
|
|
|
WHERE(string$, position [,delimiter$]) |
|
|
|
Type: function |
|
|
|
Returns the actual numerical character position in a delimited string |
|
split by delimiter$. The delimiter$ is optional. If it is omitted, then |
|
the definition from OPTION DELIM is assumed. When specified, it may |
|
consist of multiple characters. If delimiter$ occurs between double quotes |
|
in string$ then it is ignored. Example: |
|
|
|
PRINT WHERE("a b c d "e f" g h i j", 6) |
|
|
|
WHILE |
|
|
|
WHILE <equation> [DO] |
|
<body> |
|
[BREAK]|[CONTINUE] |
|
WEND |
|
|
|
Type: statement |
|
|
|
The WHILE/WEND is used to repeat a body of statements and functions. The |
|
DO keyword is optional. The optional BREAK statement can be used to break |
|
out the loop. With the optional CONTINUE part of the body can be skipped. |
|
Example: |
|
|
|
LET a = 5 |
|
WHILE a > 0 DO |
|
PRINT a |
|
a = a - 1 |
|
WEND |
|
|
|
As the WHILE statement uses an equation to evaluate, it also allows the |
|
BETWEEN operator: |
|
|
|
a = 2 |
|
WHILE a BETWEEN 1;10 |
|
PRINT a |
|
INCR a |
|
WEND |
|
|
|
WITH |
|
|
|
WITH <var> |
|
.<var> = <value> |
|
.<var> = <value> |
|
.... |
|
END WITH |
|
|
|
Type: statement |
|
|
|
Assign values to individual members of a RECORD. For example: |
|
|
|
WITH myrecord |
|
.name$ = "Peter" |
|
.age = 41 |
|
.street = Falkwood Area 1 |
|
.city = The Hague |
|
END WITH |
|
|
|
WRITELN |
|
|
|
WRITELN "text"|<var> TO <handle> |
|
|
|
Type: statement |
|
|
|
Write a line of ASCII data to a file identified by handle. A semicolon at |
|
the end of the line prevents writing a newline. Refer to the PUTBYTE |
|
statement to write binary data. Examples: |
|
|
|
WRITELN "Hello world with a newline" TO myfile |
|
WRITELN "Without newline"; TO myfile |
|
|
|
YEAR |
|
|
|
YEAR(x) |
|
|
|
Type: function |
|
|
|
Returns the year where x is amount of seconds since January 1, 1970. |
|
Example: |
|
|
|
PRINT YEAR(NOW) |
|
|
|
Appendix A: Runtime error codes |
|
|
|
Code Meaning |
|
0 Success |
|
1 Trying to access illegal memory |
|
2 Error opening file |
|
3 Could not open library |
|
4 Symbol not found in library |
|
5 Wrong value |
|
6 Unable to claim memory |
|
7 Unable to delete file |
|
8 Could not open directory |
|
9 Unable to rename file |
|
10 NETWORK argument should contain colon with port number |
|
11 Could not resolve hostname |
|
12 Socket error |
|
13 Unable to open address |
|
14 Error reading from socket |
|
15 Error sending to socket |
|
16 Error checking socket |
|
17 Unable to bind the specified socket address |
|
18 Unable to listen to socket address |
|
19 Cannot accept incoming connection |
|
20 Unable to remove directory |
|
21 Unable to create directory |
|
22 Unable to change to directory |
|
23 GETENVIRON argument does not exist as environment variable |
|
24 Unable to stat file |
|
25 Search contains illegal string |
|
26 Cannot return OS name |
|
27 Illegal regex expression |
|
28 Unable to create bidirectional pipes |
|
29 Unable to fork process |
|
30 Cannot read from pipe |
|
31 Gosub nesting too deep |
|
32 Could not open device |
|
33 Error configuring serial port |
|
34 Error accessing device |
|
35 Error in INPUT |
|
36 Illegal value in SORT dimension |
|
37 Illegal option for SEARCH |
|
38 Invalid UTF8 string |
|
39 Illegal EVAL expression |
|
40 SSL file descriptor error |
|
41 Error loading certificate |
|
42 Widget not found |
|
43 Unsupported array type |
|
|
|
Appendix B: standard POSIX variables |
|
|
|
Variable Value |
|
EXIT_SUCCESS 0 |
|
EXIT_FAILURE 1 |
|
STDIN_FILENO 0 |
|
STDOUT_FILENO 1 |
|
STDERR_FILENO 2 |
|
RAND_MAX System dependent |
|
|
|
Appendix C: reserved keywords and functions |
|
|
|
All keywords belonging to the C language cannot be redefined in a BaCon |
|
program: |
|
|
|
auto, break, case, char, const, continue, default, do, double, else, enum, |
|
extern, float, for, goto, if, int, long, register, return, short, signed, |
|
sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, |
|
while. |
|
|
|
Functions defined in libc, libm or libdl cannot be redefined in a BaCon |
|
program, most notorious being: |
|
|
|
exit, index, y0, y0f, y0l, y1, y1f, y1l, yn, ynf, ynl, dlopen, dlsym, |
|
dlclose. |
|
|
|
Internal symbols and macro definitions cannot be reused. These start with |
|
'_b2c'. |
|
|
|
All symbols mentioned in the paragraph "Reserved Names" of any C manual |
|
cannot be redefined. |
|
|
|
Appendix D: details on string optimization in BaCon |
|
|
|
As BaCon is a plain Basic-to-C converter, the resulting code depends on |
|
the C implementation of strings, which, in fact, comes down to the known |
|
concept of character arrays. A string is nothing more than a series of |
|
values in memory which ends with a '0' value. |
|
|
|
Plain C code is notorious for its bad performance on strings, especially |
|
when it needs to calculate the length of a string. Usually, the bytes in |
|
memory are verified until the terminating '0' value is encountered. For |
|
large strings this will take a considerable amount of time, especially in |
|
repetitive operations. |
|
|
|
In the ongoing attempt to improve the performance of string operations, |
|
several approaches for the BaCon project have been investigated. The below |
|
report is a short summary of techniques which were tried. |
|
|
|
Different binary layout |
|
|
|
A common implementation stores the actual string length in the beginning |
|
of the string. This means that, for example, the first 4 bytes contain the |
|
length of the string, and the next 4 bytes contain the size of the buffer |
|
holding the string. (This would limit the size of the string to 4294967295 |
|
bytes (4Gb), which, for most purposes, should be enough.) After that, the |
|
actual characters of the string itself are stored. |
|
|
|
b1 b2 b3 b4 l1 l2 l3 l4 char1 char2 char<n> |
|
String length Buffer length Actual bytes of the string |
|
|
|
Programming languages like Pascal and Basic usually implement their |
|
strings this way. They change the binary layout of the actual string, |
|
where, as mentioned, the first 8 bytes contain meta information about |
|
length and buffer size. |
|
|
|
For BaCon this seems a promising approach, however, as BaCon is a |
|
Basic-to-C converter, it makes use of the string functions provided by |
|
libc. I am referring to functions like printf, strcat, strcpy and friends. |
|
If strings are being fed to standard C functions like these, then this |
|
would cause unpredictable results. The libc string functions always assume |
|
character arrays in a correct format, otherwise they will not work |
|
properly - encountering binary values would cause printf to print garbage |
|
on the screen, for example. |
|
|
|
Now, it is possible to add a default offset of 8 bytes to the beginning of |
|
the memory address to overcome this problem. However, we do not know in |
|
advance what type of string comes in. For example, the used string very |
|
well may contain a string literal. This is plain text hard coded in the |
|
BaCon program. |
|
|
|
PRINT "Hello" & world$ |
|
|
|
In this example, both a string literal and also a memory address are used. |
|
Clearly, such string literal does not have the 8 bytes offset with meta |
|
information. So how can we check whether a string consists of a string |
|
literal, or whether it contains a memory address with the 8 byte offset? |
|
|
|
I will come back to the concept of using a pre-buffer shortly. |
|
|
|
Hash table |
|
|
|
Another idea is to use hash values paired with the string length. The |
|
approach is to take the actual memory address of a string, which is a |
|
unique value. This unique memory address then can be put into a hash table |
|
which also can store a string length value (key-value store). |
|
|
|
For performance reasons it would be nice if the table would provide values |
|
in a sequence starting from 1 to have indexes available for an array. This |
|
is called a âminimalâ hash. |
|
|
|
Furthermore, as we do not know in advance how many memory addresses the |
|
BaCon program is going to use, the hash table should be able to grow and |
|
shrink dynamically. |
|
|
|
When it comes to performance, it turns out that has tables are too slow. |
|
The implementations of a dynamic hash table often make use of linked |
|
lists, and the unavoidable memory inserts and deletions simply take too |
|
much time. Eventually, it was established that they take more time than a |
|
string length calculation. |
|
|
|
Pointer swap |
|
|
|
In BaCon, all string operating functions make use of a temporary buffer to |
|
store their (intermediate) results. This is to ensure that nested string |
|
functions can pass their results to a higher level. |
|
|
|
text$ = MID$("Goodbye, Hello", 9) & CHR$(32) & RIGHT$("The World", 5) |
|
|
|
The above example concatenates three string operations into one resulting |
|
string. The functions MID$, CHR$ and RIGHT$ first will store their result |
|
into temporary buffers, which then are passed to the '&' operator, which, |
|
in its turn, stores the result of the concatenation into another temporary |
|
buffer. The final result then is assigned to the variable 'text$'. The |
|
assignment is performed by copying the contents from the temporary buffer |
|
to the variable 'text$'. |
|
|
|
So, instead of copying the result into a variable, it also is possible to |
|
swap the memory addresses of the variable and the temporary buffer. The |
|
variable 'text$' will point to the result, and the contents of the |
|
temporary buffer will be changed to the previous character array of the |
|
variable. And because the buffer is temporary, it is going to be |
|
overwritten anyway in a next string operation, so there's no need to care |
|
about that. |
|
|
|
This technique of pointer swapping will save some time, because it avoids |
|
a needless copy of bytes from one memory area to another. Even though it |
|
does not help us with string length calculation, it can help to improve |
|
the performance of string operations. |
|
|
|
Static character pointers |
|
|
|
When using character pointers in functions, it is a good idea to declare |
|
them as static. Such pointers keep their value, e.g. the memory address |
|
they are pointing to, so the next time when the function is called, the |
|
pointer still points to the allocated memory. Therefore, there is no need |
|
to free a pointer at the end of a function, or to allocate new memory when |
|
entering the function. This will save a lot of system calls and kernel |
|
activity. |
|
|
|
Note that it may be needed to set the memory of the string to an empty |
|
string at the beginning of the function. |
|
|
|
Also note that because static pointers always will point to the same |
|
memory, recursive functions may not work properly. So in each level of |
|
recursion, the same memory is overwritten. |
|
|
|
The technique of static pointers is partly implemented in BaCon: static |
|
pointers are used for string variables and string arrays which get their |
|
value assigned at declaration time. This technique is not suitable for |
|
regular string variables, because of the aforementioned problems with |
|
recursion. |
|
|
|
Using a pre-buffer |
|
|
|
The last technique to discuss, which actually has been implemented, is |
|
using a pre-buffer. It is similar to the binary layout discussed earlier. |
|
In this approach, a block of memory is allocated, of which the first bytes |
|
contain meta information about length and buffer size. However, the |
|
returned pointer itself is a pointer to the start of the actual string. |
|
The benefit of this is that the string functions from libc will work |
|
properly, because they see the actual string. |
|
|
|
As mentioned, this concept is used in BaCon. However, there is a severe |
|
problem which needs to be solved: how do we know if an incoming string |
|
already uses a pre-buffer? |
|
|
|
PRINT a$ & b$ & c$ & "Hello" |
|
|
|
In this example, we have three variables and a string literal. If one of |
|
the variables does not have a pre-buffer, and BaCon likes to look into it, |
|
then a crash will occur (segfault). BaCon cannot simply look into memory |
|
which is not allocated. Nor into a non-existing pre-buffer in case of a |
|
string literal. |
|
|
|
To solve this problem, we have to think of a trick. The memory addresses |
|
which point to the strings are in fact numbers, each of which must be |
|
unique. If the addresses were not unique, then the program would overwrite |
|
one string with another. Therefore, the uniqueness of memory addresses is |
|
a property which can be used to identify a string with a pre-buffer: if |
|
the address is taken as a plain number it can be used as an index in a |
|
lookup table. That table contains a list of addresses for which BaCon has |
|
created a pre-buffer. |
|
|
|
Obviously, such table cannot be as large as the amount of possible memory |
|
addresses. But this is not necessary. The biggest BaCon program at the |
|
time of writing is the implementation of BaCon in BaCon itself. It |
|
contains more than 10.000 lines of code, and when compiled with the '-@' |
|
debug parameter it can be observed that there are less than 400 strings |
|
in use, simultaneously, at any moment in time. It is therefore not |
|
realistic to implement a lookup table for all possible memory addresses, |
|
since it is unlikely that actual programs will use that amount of string |
|
data anyway. Currently, the size of the lookup table is 1Mb, which means |
|
that theoretically a program can identify a little over 1 million memory |
|
addresses during runtime. |
|
|
|
The index in the table is determined by taking the modulo from the address |
|
by 1 million and then performing a binary 'AND' with '1 million minus 1'. |
|
This is a very fast algorithm but allows collisions to happen: some memory |
|
addresses will deliver the same index in the lookup table as other address |
|
will. The approach to solve this situation is called linear probing: in |
|
case of a collision, BaCon will take the next slot in the lookup table. If |
|
this slot is occupied with some other address, again it will take the |
|
next. The maximum probe depth currently is set to 16 steps. If the probe |
|
depth is exceeded then the program simply will generate an internal error |
|
and stop. |
|
|
|
String operations now can lookup the address in the lookup table and |
|
quickly fetch information from each pre-buffer, saving time which |
|
otherwise would have been needed for length calculations. |
|
|
|
<n> bytes 1 2 3 4 1 2 3 4 1 2 3 4 <n> bytes |
|
Left buffer String length Size right Size left buffer Right buffer |
|
buffer |
|
<------- area containing metadata -------> Actual string data |
|
---> Returned |
|
pointer |
|
|
|
The above picture represents the new layout. Meta information is stored in |
|
an area which floats freely between two memory buffers. The returned |
|
pointer is the start of the right buffer which contains the actual string |
|
data. The left buffer is used for string concatenations, to insert text |
|
before an existing string, which allows a very fast concatenation of data |
|
(this works by first moving the area with meta data to the left and then |
|
inserting the text). |
|
|
|
The parameters for the lookup table can be altered by the command line |
|
parameter '-t' (see the chapter on Basic Usage and Parameters). |
|
|
|
Memory pool |
|
|
|
As strings are stored in memory, it sometimes can be a good idea to |
|
allocate a block of memory before the actual program starts. A private |
|
function to share and administer can assign parts of that allocated memory |
|
to the program. This could save time, because the real memory allocation |
|
on the heap already took place, and the private memory allocation simply |
|
has to administer small chunks. |
|
|
|
Note that it only saves time in case a lot of subsequent allocations and |
|
frees take place in the program. Previously, BaCon performed almost |
|
500,000 allocations consuming a total of 80 Mb of memory. A memory pool |
|
helps to decrease the allocations requested by BaCon to the kernel and it |
|
also lowers the overall memory usage by reusing existing slots. |
|
|
|
The core string allocation engine now uses a basic memory pool, which, by |
|
default, is defined by 2048 slots each occupying 1024 bytes. This |
|
decreases the amount of memory allocations with more than 85% and |
|
decreases the total memory usage with approximately 45%. |
|
|
|
The parameters for the memory pool dimensions can be altered by the |
|
command line parameter '-t' (see the chapter on Basic Usage and |
|
Parameters). |
|
|