Futurebasic/Language/data types

Data Types and Data Representation
Revised: May 30, 2000 (Release 3)

Integers
Integers can be represented as literals, as symbolic constants, or as variables.

Integer Literals
 Decimal: a string of decimal digits, optionally preceded by "+" or "-". Examples: 7244     -328442  Hexadecimal: a string of up to 8 hexadecimal digits, preceded by " " or " " or " " (that's a zero-x). Hexadecimal digits include the digits 0 through 9, and the letters  through. Letters can be either in upper or lower case. Examples: &amp;H12a7     0x47BeeF      &amp;42AD9 Octal: a string of up to 10 octal digits, preceded by " " (that's the letter " ", not a zero). Octal digits include the digits 0 through 7. Examples: &amp;o70651     &amp;o32277 Binary: a string of up to 32 binary digits, preceded by " ". Binary digits include the digits 0and1. Examples: &amp;x0100011     &amp;x10110000111011001 Quoted: a string of up to 4 characters, surrounded by double-quotes, with an underscore preceding the initial quote. Each character in the quoted string represents 8 bits in the internal bit pattern of the resulting integer, according to the character's ASCII code.

Examples: _&quot;TEXT&quot;     _&quot;N*&quot;  Note: Hexadecimal, octal, binary and quoted literals reflect the actual bit patterns of the integers as they're stored in memory. These may be interpreted either as positive or negative quantities, depending on which types of variables they're assigned to. If they're not assigned to any variable, they're generally interpreted as positive quantities.

Symbolic Constants
A symbolic constant is an identifier preceded by an underscore character. There are many symbolic constants which have pre-defined values in FB. You can also define your own symbolic constants within your program, either by using a ... block; or a  ...  block; or by using a "constant declaration" statement. A constant declaration statement has this syntax: _constantName = staticExpression where  is a symbolic constant which has not been previously defined, and   is a "static integer expression" (see Appendix D: Numeric Expressions). The value of  must be within the range -2,147,483,648 through +2,147,483,647. Once a symbolic constant has a value assigned to it, that value cannot be changed within your program. Like all constants, a symbolic constant has a global scope.

A constant declaration may also include pascal style strings using one of the following formats _constantName$   = &quot;I am a string constant&quot; _constantTab$    = 9      : REM CHR$(9) = tab character _constantCR$     = 13     : REM CHR$(13) = carriage return _twoByteKanjiChar = 10231 : REM KCHR$(10231)

Integer Variables
There are six different types of integer variables in FB; they differ in the amount of storage space they occupy, and in the range of values they can represent. An integer variable's name may end with a type-identifier suffix which indicates its type; alternatively, you can declare an integer variable's type by using the  clause in a   statement. If a variable has no type-identifier suffix, and wasn't declared with an  clause, then FB checks whether there are any   statements which are applicable to the variable. Finally, if the variable can't be typed by any of the above means, FB assigns the type "signed short integer" to the variable. Arrays of integers, and integer record fields, are typed by similar means.

Real Numbers
"Real numbers" are numbers which may have a fractional part. They can be represented as literals or as variables.

Real Number literals
 Standard notation: a string of decimal digits including a decimal point; optionally preceded by "+" or "-". Examples: 17.3     -62.       0.03 Scientific notation: a string of characters in this format:

is a string of decimal digits with an optional decimal point, optionally preceded by "+" or "-";  is a string of decimal digits, optionally preceded by "+" or "-". Examples:  3e-20     -6.7E4      0.05E+14 The value of a number expressed in scientific notation is: exponent



Real Number variables
There are three types of real number variables in FB; they differ in the amount of storage space they occupy, the range of values they can represent, and their precision (number of significant digits).

Fixed-point Reals
A fixed-point real number variable must be declared in a  statement, using the   clause. It's accurate to about 5 places past the decimal point, and can handle numbers in the range of approximately -32767.99998 through +32767.99998. A fixed-point variable occupies 4 bytes of storage.

Floating-point Reals
FB supports two kinds of floating-point real number variables. A floating-point variable's name may end with a type-identifier suffix which indicates its type; alternatively, you can declare a floating-point variable's type by using the  clause in a   statement. If a variable has no type-identifier suffix, and wasn't declared with an  clause, FB checks whether there are any   or  statements which are applicable to the variable. Floating-point arrays, and floating-point record fields, are typed by similar means.

The methods used by FB when handling one of these variables can be modified by you. A set of constants is maintained in a file in the headers folder. (Path: FB Extensions/Compiler/Headers/UserFloatPrefs). If you want to change these parameters for all of your projects, copy the file named "UserFloatPrefs" into the User Libraries folder. The User Libraries folder is located at the same level as the editor. // // Required Floating Point Constants // // _NumberLeadingSpace = _True //FB II Default = _true _RoundUpFloat2Long = _true // Un-remark to round up Float to Integer Double-precision floating-point variables occupy more storage, represent a greater range of values, and have greater precision than single-precision floating-point variables. (4 bytes) double-precision

(8 bytes

Strings
A string is a list of up to 255 characters, which is usually interpreted as text in MacPascal encoding. Strings can be represented as literals or as variables.

String Literals
A string literal is a group of characters surrounded by a pair of double-quotation marks (note: in certain contexts, such as in  statements, the quotation marks are optional). If the string literal contains a pair of contiguous double-quotes, they are interpreted as a (single) embedded double-quote mark and treated as part of the string, rather than as a delimiter. Example: print &quot;I said, &quot;&quot;Hello.&quot;&quot;&quot; Output: I said, &quot;Hello.&quot;

String Variables
A  statement specifies a string variable and its size in the following ways: dim as Str255 s // s is a 255 character string dim as Str63 s  // s is a 63 character string dim as Str31 s // s is a 31 character string dim as Str15 s // s is a 15 character string

dim s as Str255 // s is a 255 character string dim s$          // s is a 255 character string dim 3 s$        // s is a 3 character string [the custom size value can range from 1 to 255]

dim as Str31 s$ // s is a 255 character string [this anomaly, present in the old FB Compiler, may be removed from FBtoC]

If a variable has no type-identifier suffix, and wasn't declared with an  clause, then FB checks whether there are any   statements applicable to the variable.

String arrays, and string record fields, are typed similarly to string variables.

Internally, strings are stored in Pascal format, beginning with a length byte indicating the number (0 through 255) of characters currently in the string. The length byte is followed immediately by the string's characters, one byte per character. FutureBASIC always allocates an even number of bytes for a string variable in memory; this is enough to include the length byte, plus enough character bytes for the variable's maximum string length, plus an exta "pad" byte (if necessary) to make the total come out even. Use  to determine the number of bytes allocated to a particular string variable.

Containers
Containers are compiler-managed Handles that hold up to 2 GB of ASCII or numeric information. Containers may be identified by a double dollar sign or in a   statement. In FBtoC containers hold only ASCII information, numeric assignements and operations are not allowed.

Containers are always global. An attempt to dimension a container inside of a local function will result in an error message during compilation. When a container is first dimensioned, it is a long integer variable with a value of zero. Once data is placed in the container, a handle is allocated and the data is moved to that handle. To dispose of the allocated handle, set the container to a null string with.

Because a container may hold ASCII or numeric information, there are some trade-offs. The first is speed. Numeric values stored in containers are first converted to ASCII. When math operations are required, the data is reconverted before the calculation is performed. (In FBtoC containers hold only ASCII information, numeric assignements and operations are not allowed.)

Another limitation relates to how containers are filled. Since FB has no idea what data may be in the container, it has to evaluate the information on the other side of the equal sign to see what it should be doing. If this data is a series of Pascal strings, then the container must be limited to 255 characters. myContainer$$ = a$ + b$ + c$ If the information is to be a concatenated string and the right side of the equal sign contains only Pascal style strings, you must approach things from a different direction. myContainer$$ = a$ myContainer$$+= b$ myContainer$$+= c$ In some cases, the compiler will not be able to determine what type of operation you had in mind. For instance... a$$ = b$$ + c$$ The compiler has no clue as to whether it should concatenate strings or add numbers. You can force the correct operation by inserting an additional operator. a$$ = b$$ + c$$ + 0 : REM math a$$ = b$$ + c$$ + &quot;&quot; : REM strings This is not a problem with other math operators like the minus sign or the multiplication (asterisk) symbol as these cannot pertain to strings.

Containers may not be compared in the traditional sense. This is because a comparison by its very nature must return a numeric value. If you execute a statement like  the result will be zero  or -1. We have provided a substitute function that can handle the comparison for you. rslt&amp; = fn FBcompareContainers(a$$,b$$) If  is less than   then the result will be negative and will represent the character position at which the difference was found. If  is -3000 then   and   were identical for the first 2999 characters, at which time the next character in   was found to be less than the one in.

When  is zero, the containers are equal.

When  is positive, it points to the character position at which it was determined that   is greater than.

Containers are stored in the application heap as relocatable blocks. You can extract the handle to these blocks as follows: hndl&amp; = [@myContainer$$] Be aware that the handle may be zero if the container has been cleared or if it was never initialized.

A syntax similar to that used for filling edit fields may be used to pass information to a container. The percent sign indicates that the container is to be filled with the contents of a   resource. An ampersand tells FB to fill the container with information from a Handle. a$$ = %resID // fill container with TEXT res ID resID a$$ = &amp; myHandle; // fill container with contents of myHandle Note: You may not use complex expressions that include containers and/or Pascal strings on the right side of the equal sign. Instead of using: c$$ = c$$ + left$$(a$$,10) d$$ = c$$ + a$ Use: c$$ += left$$(a$$,10) d$$ = c$$ d$$ += a$

Pointers
A pointer variable is always declared in a  statement. It can be declared using the  (or  ) clause, or an   clause, where   is a type which was previously identified as a   type (in a   statement). If the  clause included a   clause, then the variable is identified as "pointing to" a data structure of the indicated type; otherwise it's considered a "generic" pointer.

The value of a pointer is actually a long integer; it's the address of a data structure. In some cases a pointer's value may be  (zero), which indicates that the pointer currently isn't "pointing to" anything.

If you declare a pointer variable as pointing to a particular record type, you can use the pointer variable to refer to specific fields within a record (see Appendix B: Variables, for more information). This is the main advantage of using pointer variables rather than long integer variables to store a data structure's address.

Handles
A handle variable is always declared in a  statement. It can be declared using the  (or  ) clause, or an   clause, where   is a type which was previously identified as a   type (in a   statement). If the  clause included a   clause, then the variable is identified as a handle to a data structure of the indicated type; there are also a couple of pre-defined types (  and  ) which are recognized as handles to particular types of MacOS structures (specifically: to regions and TextEdit records). If the variable is declared simply " " (with no  clause), it's considered a "generic" handle.

The value of a handle is actually a long integer; it's the address of a "master pointer" which points to a relocatable block that contains a data structure. In some cases a handle's value may be  (zero), which indicates that it doesn't currently refer to any data structure. You can use a long integer variable to store the same address as a handle variable, and for many purposes handle variables and long integer variables are interchangeable.

If you declare a handle variable as referring to a particular record type, you can use the handle variable to refer to specific fields within a record (see Appendix B: Variables, for more information). This is the main advantage of using handle variables rather than long integer variables to store a handle value.

Records
A record is a collection of data items that are stored together in memory. You can access an entire record as a unit, or access its data elements individually. Unlike an array, whose elements are all of the same type, the elements of a record (also called its "fields") can be of differing types.

A record variable must be declared in a  statement: dim varName as RecordType dim as RecordType varName where RecordType is previously-defined record type. You can define a record type and its fields by using a  ...   block. In addition, FB recognizes two built-in record types:  and. You use the  syntax to access the fields of a record variable (see Appendix B: Variables).

Compatibility of Types
You can assign values of one type to variables of another type, sometimes with certain restrictions. The following table shows which kinds of values can be assigned to which kinds of variables.