Akin to the DIM statement, SET gives you a convenient means of declaring and loading array variables in one easy statement. SET supports local and global contexts. If SET is used inside a SUB or FUNCTION then the variable and its data, implicity, are local in scope.
Syntax:SET VArray[] AS data type Comma, delimited, values, list END SET Parameters:
|
👉 The OPTION BASE statement does not work with the arrays generated with the SET statement.
When a partial initalization is being done, braces { } are used to delimit the parts of the SET to be initialized. For example,
TYPE foo A AS INTEGER B AS INTEGER C AS BYTE END TYPE SET MyFoo[] AS foo {12,13}, {19,20} END SET
would initialize as:
MyFoo[0].A = 12 MyFoo[0].B = 13 MyFoo[0].C = 0 👉 not initialized MyFoo[1].A = 19 MyFoo[1].B = 20 MyFoo[1].C = 0 👉 not initialized
Here are some examples using SET.
Instead of coding this:
DIM A[6] AS DOUBLE A[0] = 1.1 A[1] = 5.5 A[2] = 9.9 A[3] = 3.3 A[4] = 10.1 A[5] = 4.41
Do this instead! The size of the array is automatically calculated.
SET A[] AS DOUBLE 1.1, 5.5, 9.9, 3.3, 10.1, 4.4 END SET
Here's another example using strings
SET B$[3] "apples", "oranges", "bananas" END SET
which is the same as
DIM B$[3] B$[0] = "apples" B$[1] = "oranges" B$[2] = "bananas"
The example below demonstrates SET in a subroutine.
TEST() SUB TEST () SET b$[10] AS CHAR PTR "one" , "two", "three", "four", "five", "six", "seven", "eight" END SET PRINT b$[0] PRINT b$[1] PRINT b$[2] PRINT b$[3] PRINT b$[4] PRINT b$[5] PRINT b$[6] PRINT b$[7] END SUB
one two three four five six seven eight
Here is an example of SET with comments.
SET C[16] AS COLORREF 16777215, 'white 16776960, 'cyan 16711935, 'pink 16711680, 'blue 65535, 'yellow 65280, 'green 255, 'red 12632256, 'lightgray 8421504, 'darkgray 8421376, 'darkcyan 8388736, 'darkpink 8388608, 'darkblue 32896, 'brown 32768, 'darkgreen 128, 'darkred 0 'black END SET
Here is an example using pointers.
SET errmsg[] AS CHAR PTR "Overflow", "Division by zero", "etc", "etc" END SET DIM i FOR i = 0 TO 3 ? "Error ";i;" ";errmsg$[i] NEXT PAUSE
Error 0 Overflow Error 1 Division by zero Error 2 etc Error 3 etc
Here is an example using BCX functions and operators.
SET iX[] AS INTEGER ASC("A"), ASC("c"), 23 AND 14, 1 OR 3, 5 XOR 6, BNOT 8 END SET DIM i% FOR i% = 0 TO 5 PRINT iX[i] NEXT i% PAUSE
65 99 6 3 3 -9
Here is how to use SET to read mixed type data which needs to be modified at run-time.
TYPE GameData s$ x1, y1, z1, x2, y2, z2 u v END TYPE SET GD[] AS GameData "outside a house", 1,0,0,1,0,0, 0, 0, "by a window", 0,1,0,0,0,0, 1, 0 END SET PRINT GD[0].s$ PRINT GD[0].x1 GD[0].s$ = "Inside the door" GD[0].x1 = 345 PRINT GD[0].s$ PRINT GD[0].x1 PRINT GD[1].s$ PRINT GD[1].x1 PAUSE
outside a house 1 Inside the door 345 by a window 0
The example below uses SET in functions.
PRINT Month$(2)," has", DaysInMonth(2), " days, 29 on leap years." FUNCTION DaysInMonth (MonthNumber) SET nDays[] AS LONG 31,28,31,30, 31,30,31,31, 30,31,30,31 END SET IF MonthNumber>0 AND MonthNumber<13 THEN FUNCTION = nDays [MonthNumber-1] ELSE FUNCTION = 0 END IF END FUNCTION FUNCTION Month$ (MonthNumber) SET _months[] AS PSTR "January", "February", "March", "April" "May", "June", "July", "August", "September", "October", "November", "December" END SET IF MonthNumber>0 AND MonthNumber<13 THEN FUNCTION = _months$ [MonthNumber-1] ELSE FUNCTION = 0 END IF END FUNCTION
February has 28 days, 29 on leap years.
Although SET data within a SUB, implicitly, is local, the example below shows that it can be accessed from outside the SUB.
CALL TEST_LOCAL_SCOPE SUB TEST_LOCAL_SCOPE LOCAL UpperLimit SET Buff[] AS CHAR PTR "A", "D", "C", "B", "F", "H", "E", "G" END SET UpperLimit = UBOUND(Buff) + 1 QSORT DYNAMIC Buff$, 4 CALL PrintTheBuff(Buff$, UpperLimit) QSORT DYNAMIC Buff$, UpperLimit CALL PrintTheBuff(Buff$, UpperLimit) END SUB SUB PrintTheBuff (A AS STRARRAY, UpLim) DIM Aye WHILE Aye < UpLim IF LEN( A[Aye] ) > 0 THEN PRINT A$[Aye] ' IF A$ [Aye] > "" THEN ... will not work. INCR Aye WEND ? END SUB
A B C D F H E G A B C D E F G H
SHAREDSET can be used instead of SET. When SHAREDSET is used, the C code generated does not have the static storage class qualifier that is generated with SET. This difference comes into play when multiple files are being compiled to object files and then linked together. All the object files can see the SHAREDSET, while SET can only be seen in the object in which it is coded.
Syntax:SHAREDSET VArray[] AS data type Comma, delimited, values, list END SET Parameters:
|
Copy the following three files to a directory and run the batch file to translate and compile.
File 1. Build.bat
call povars32.bat bc Level1 bc SharedSet pocc -W1 -Ot -Gd -Ze -Zx -Tx86-coff Level1.c pocc -W1 -Ot -Gd -Ze -Zx -Tx86-coff SharedSet.c polink -release -machine:ix86 -subsystem:console SharedSet.obj Level1.obj ECHO Finished!
File 2. SharedSet.bas
$PRJUSE Level1.use #INCLUDE "Level1.h" SHAREDSET B$[3] "apples", "oranges", "bananas" END SET CALL LEVEL1
File 3. Level1.bas
$PRJ $NOMAIN SUB LEVEL1 EXTERN B$[] PRINT B$[2] END SUB
bananas
Using SHAREDSET in the preceding example,
generates this C code for the array
CHAR B[3][BCXSTRSIZE]= { "apples", "oranges", "bananas" };
When SET is used instead of SHAREDSET, this C code is generated for the array.
STATIC CHAR B[3][BCXSTRSIZE]= { "apples", "oranges", "bananas" };
and the compiler errors out with this message.
SharedSet.c(206): warning #2135: Static 'B' is not referenced. POLINK: error: Unresolved external symbol '_B' - referenced from 'Level1.obj'. POLINK: fatal error: 1 unresolved external(s).