home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / DEMOS / UB_68020.LZH / mini_manual < prev    next >
Text File  |  1996-06-26  |  46KB  |  1,104 lines

  1.                             UniBasic
  2.  
  3.                               DEMO
  4.  
  5.  
  6.                              Preface
  7.  
  8. This archive or disk contains the demo version of UniBasic plus
  9. many examples or its use.
  10.  
  11. This archive or disk may be freely distributed as long as ALL of
  12. the files are kept intact and not modified or edited in any way.
  13. If you add additional files to this archive or disk you must make
  14. that very clear. We do not want to be blamed for any mistakes
  15. other than our own.
  16.  
  17. The file 'ubdemo' is of particular concern to us. It is the
  18. result of years of work and much money invested. It is provided
  19. in a 'limited' form. We made a modification to limit the size of
  20. the program it will compile. It will compile all of the example
  21. programs included with the demo or a program of your own of about
  22. a page or two. We did this by reducing the size of the symbol
  23. table. Otherwise it is the same program as the one we hope you
  24. will buy after you have tried out this demo. (The demo will
  25. always be at version 1.0 while the one you buy will be the
  26. current version.)
  27.  
  28. We are concerned because we know there are people out there that
  29. will take this limitation as a challenge and try to defeat it. In
  30. so doing they will have done the very same thing as if they broke
  31. into our office and stole a copy of the program. Or gotten a copy
  32. from a legitimate buyer. In all cases having a copy of UniBasic
  33. without paying for it is stealing. There is no justification for
  34. this. If you think we are charging too much for UniBasic then
  35. don't buy it. Please don't use the price or any other excuse to
  36. steal it.
  37.  
  38. Thank you
  39. Computer Design Lab
  40.  
  41. Purchase UniBasic, at the address, phone number, or Compuserve address
  42. listed below.
  43.  
  44. Several versions are available are present with more on the way. Those
  45. currently available are:
  46.  
  47. MSDOS Version................................$99.00 US
  48. Linux Version (personal use)................$149.00 US
  49. Linux Version (commercial/multi-user).......$299.00 US
  50. OS9/68000 Version (personal use)............$149.00 US
  51. OS9/68000 Version (commercial/multi-user)...$299.00 US
  52. OS9/68020 Version (personal use)............$149.00 US
  53. OS9/68020 Version (commercial/multi-user)...$299.00 US
  54.  
  55. Make check or money order payable to Computer Design Lab in US funds.
  56. Add $5.00 shipping/handling for US ground transportation.
  57.  
  58. UniBasic is shipped within 24 hours of order and can be shipped
  59. overnight if required.
  60.  
  61. All versions come with a complete printed manual, reference card
  62. and technical support from CDL.
  63.  
  64. To purchase your copy of UniBasic contact:
  65.  
  66. Computer Design Lab
  67. RR1 Box 36
  68. Rhineland, MO 65069
  69. Tel: (314) 236-4373
  70. CompuServe: 72762,3375
  71.  
  72.  
  73. Limited warranty and limitation of remedies
  74. ------- -------- --- ---------- -- --------
  75.  
  76. Computer Design Labs is not responsible for any damage to the
  77. user's computer system or data and in no event will Computer
  78. Design Labs, its officers, directors, employees or agents be
  79. responsible to the purchaser for any consequential, incidental,
  80. or indirect damages (including damages for loss of business
  81. profits, business interruption, loss of business information and
  82. the like) arising out of the use or inability to use the Computer
  83. Design Labs product, even if Computer Design Labs has been
  84. advised of the possibility of such damages.
  85.  
  86. Unless explicitly stated in writing, Computer Design Labs does
  87. not grant permission to distribute the software for profit in any
  88. form, Non-profit distribution of the software is acceptable
  89. without prior written notice, providing that the software is not
  90. modified in any way, and the complete works of the software are
  91. included in the distribution package.
  92.  
  93.  
  94.  
  95.  
  96.                          UniBasic DEMO
  97.  
  98.                            VERSION 1.0
  99.  
  100.                            MiniManual
  101.  
  102.  
  103.  
  104.  
  105.  
  106.                     GENERAL FUNCTION and SYNTAX
  107.  
  108. UniBasic is a C code macro BASIC compiler for use on various operating
  109. systems. This means that the user program written in BASIC (with or
  110. without the UniBasic enhancements) is translated and compiled into C.
  111. UniBasic incorporates many of the features of the newer structured
  112. BASICs,allows the intermixing of C code, and supports a host of
  113. language enhancements and compiler functions never before found in
  114. any BASIC implementation.
  115.  
  116. The compiler features include macro capability, C function compatibility,
  117. conditional compilation, compiler variables, object module linkage, and
  118. a full set of compiler directives to manage these features. These
  119. directives include #MACRO, #ENDM, #SET, #IF, #ENDIF as well as others.
  120.  
  121. The language enhancements include a full range of data types, structured
  122. constructs (such as IF/ENDIF, WHILE/ENDWHILE), C language intermixing,
  123. named labels (instead of line numbers), full access to operating system
  124. calls, and full support of pointer variables, vector variables (based
  125. variables), and memory buffers.
  126.  
  127. Since the output is C, the performance will be greater than interpreter or
  128. "I-code" compiler implementations. The less experienced programmer can
  129. immediately take advantage of the performance of UniBasic even before
  130. learning the advanced features and enhancements.
  131.  
  132. The structure of UniBasic is slightly different than standard BASIC in that
  133. labels, functions, and directives always begin in column #1 while statements
  134. must be indented at least one space (or tab). This is quite similar to
  135. the convention for some assemblers. Also as previously mentioned,
  136. UniBasic uses labels rather than line numbers. If UniBasic encounters
  137. a line number it will convert it to a pseudo label automatically which
  138. greatly simplifies conversion of other BASIC programs to UniBasic.
  139. Also since the style of UniBasic is somewhat akin to assembler,
  140. multiple statements per line are not allowed. Instead the style is
  141. to have the statement (or assembler instruction) followed by a
  142. comment on each line for maximum readability. Unlike interpreters
  143. and "I-code" compilers, comments and remarks have no effect on program
  144. size or speed so their use is strongly encouraged. There are no default
  145. data types which means that each variable must be dimensioned (declared)
  146. before it can be used in a statement (or assembler instruction). Keywords
  147. may be entered in any mix of upper and lower case while symbols are case
  148. sensitive. For example, Test and test are two different symbols.
  149.  
  150. Since the macro capability allows both BASIC and C code within the macro,
  151. macro libraries afford the effect of user-defined statements and
  152. instructions.
  153.  
  154. The syntax of the various BASIC statements are more or less standard with any
  155. other BASIC except for the requirement to indent a least one space or tab.
  156. Labels, variables, macros, and any other symbols must begin with a letter
  157. or underscore and may contain letters, numerals, or the underscore
  158. character. Also, the last character may be a '$'. The maximum length is
  159. 28 characters. Since many system and compiler symbols begin with an
  160. underscore, it is best to avoid the naming of symbols which begin with an
  161. underscore. Each statement and compiler directive is explained in detail
  162. in this manual as to syntax, function, and use.
  163.  
  164. UniBasic allows those who would prefer to program in BASIC to have the same
  165. kind of power and utility as those who program in C and straight assembler
  166. while maintaining the simplicity and straightforwardness of BASIC. Also the
  167. linkage capability allows the combining of UniBasic modules with assembly
  168. and "C" relocatable modules.
  169.  
  170.                              DATA TYPES
  171.  
  172. A brief description of data types is given in the DIM, TYPE, and PARAM
  173. sections and a detailed coverage of pointer variables is given in the
  174. POINTER VARIABLES section so much of what is said here may be redundant.
  175. The mechanics of declaring variables and the various attributes assigned
  176. to them is explained in the DIM, TYPE, and PARAM sections.
  177.  
  178. The first classification of a variable is whether it is a simple variable or
  179. an array variable. An array is a linear table of the data type.
  180. Multi-dimensional arrays are not allowed. UniBasic does no bounds checking
  181. of arrays at run time. This may be an advantage or disadvantage depending
  182. on whether the bounds violation is intentional or accidental. If it is
  183. accidental it is possible to "clobber"adjacent data. Intentional violation
  184. of array bounds is certainly not an example of structured programming, but
  185. does allow the programmer to take advantage of knowing how the data is
  186. stored and to, for example, treat a string as a byte array.
  187.  
  188. The second classification of a variable is whether it is local, global, or
  189. external. Local variables are known only to the module in which it occurs.
  190. Global variables are known to all modules in a set which will be linked
  191. together. External variables refer to those which are declared to be
  192. global by another module but are referred to by the current module.
  193.  
  194. The third classification of a variable is whether or not it is a pointer
  195. variable . Pointer variables are variables in their own right and are a
  196. special form of a 32 bit unsigned integer which have a special property
  197. to index their value according to the data type which they are declared to
  198. point to. The data which is accessed by a pointer variable is treated as
  199. if it came from a standard variable of the type pointed to. There are
  200. three functions which are used with pointers. The first is ADDR() and
  201. is used to set the pointer to an address of a variable (presumably but not
  202. necessarily of the same type as the pointer). The second is BUFADR() which
  203. is used to set the pointer to the address of a memory buffer (see BUFFER,
  204. BUF(), BUFSIZ() section). The third is INDEX() which is used to index the
  205. pointer according to the function argument multiplied by the number of
  206. bytes in the data type of the pointer.
  207.  
  208. The fourth classification of a variable is whether or not it is a vector.
  209. Vectors (based variables) are similar to (but not the same as) "references"
  210. in C++. Vectors are closely related to pointers in concept. Once a vector
  211. has been declared with a DIM statement and subsequently assigned an address
  212. with a SETVEC statement, it may be used as an ordinary variable. The vector,
  213. then, has the power of a pointer without the need for pointer notation and
  214. allows array sub scripting in buffers instead of pointer arithmetic.
  215.  
  216. Another type of variable is defined by the PARAM statement which must
  217. immediately follow the occurrence of a function. The names of these
  218. variables must not conflict with regular variable names, but are unique
  219. within in the function in which declared. In other words, two are more
  220. functions may declare the same PARAM names. These parameter variables as
  221. well as labels within the function are removed from the symbol table
  222. when the function body ends. These parameter variables "accept" values
  223. passed to the function when the function is invoked (called). The
  224. number of these PARAM statements must correspond to the number of
  225. arguments of the caller.
  226.  
  227.                          USING the COMPILER
  228.  
  229. Once the program is written using an editor, the program is ready to be
  230. compiled. This is accomplished by invoking the compile command as follows:
  231.  
  232. ub FileName.b {opts} {CompVar=Const...}
  233.  
  234. ub is the compiler's executable name. The compiler's executable object code
  235. is normally stored in the CMDS directory (OS9), the usr/bin directory
  236. (Linux), or as appropriate for the system being used.
  237.  
  238. If no options are given, UniBasic will compile the source (.b) file, creating
  239. a C (.c) file. UniBasic then invokes the C compiler which in turn compiles
  240. the C code to assembler and links the file into an executable object file.
  241. This sequence of events may be modified or enhanced by the use of command
  242. line options..
  243.  
  244. The options (opts) are as follows:
  245.  
  246. -a    Compile to assemblerfile(.a file OS9)(.s file Linux)
  247.     (do not assemble and link)
  248.  
  249. -e    Compile with no output but check for errors. This is useful at
  250.     various stages of program development. It allows the programmer
  251.    to passively check for certain errors.
  252.  
  253. -f    Function mode. This option is used to compile functions or any
  254.     non-mainline procedure    or subroutine. The file is processed to a
  255.     relocatable assembler file (.r OS9) (.o Linux)
  256.  
  257. -g    Generate symbol module for the debugger. Automatically invokes the -g
  258.     option to the    linker for later debugging purposes.
  259.  
  260. -r    Turn off remarks (comments) in -c option
  261.      
  262. -s    Symbol table dump to stdout
  263.  
  264. -v    Verbose mode. Reports detailed progress of compile process
  265.  
  266. -u    Unabridged hexadecimal symbol dump which also includes internal
  267.     compiler symbols
  268.  
  269. -c    Compile to C file (.c) See -r option
  270.  
  271. -? Display options
  272.  
  273.                      WRITING and USING PROGRAMS
  274.  
  275. The default mode of the compiler is PROGRAM mode (also known as mainline).
  276. To enter FUNCTION mode it is necessary to invoke a command line option,
  277. but to enter PROGRAM mode no action is required.
  278.  
  279. The general form of a program is as follows:
  280.  
  281. * declare variables
  282.  DIM A:LONG
  283.  DIM B:LONG
  284.  
  285. * declare function
  286. #FCN Square() INT
  287.  
  288. * program code body
  289.  B=4
  290.  A=Square(B)
  291.  PRINT A+B
  292. * END statement (optional)
  293.  END
  294.  
  295. * (internal) function body
  296. Square()
  297.  PARAM X:LONG
  298.  RETURN X*X
  299.  
  300. The program is written using your favorite editor. Remember that compiler
  301. directives and labels always start in column one and that statements are
  302. always indented at least one space or tab. When you write the program
  303. remember to include a ".b" suffix to the program name.
  304.  
  305. To compile the program, enter the command to run the compiler.
  306. (In this example the program name is "test")
  307.  
  308. ub test.b
  309.  
  310. If there are no errors reported, you may run the program by typing:
  311.  
  312. test (CR)
  313.  
  314. If the program does not perform as expected, it is sometimes useful to insert
  315. PRINT statements as various points in the program to check its progress.
  316. If the user is familiar with the Debug program, it is useful to compile the
  317. program with the -g option which sets up a symbol module for the debugger.
  318. If there are errors in your program that violate some rule or syntax of
  319. the compiler, an English language indication of that error is reported.
  320. If there are any errors at all, the compiler will not pass the output to the
  321. C compiler (which will in turn invoke an assembler, optimizer and linker).
  322. It is also possible to get an error from the C compiler, assembler, or
  323. linker.Refer to the C compiler, assembler, or linker manual to resolve
  324. these. The UniBasic compiler should "catch" most errors so that you will
  325. not see C compiler, assembler, or linker errors in most cases. If you do,
  326. you should report the error to CDL for possible resolution.
  327.  
  328.                    USING and DECLARING FUNCTIONS
  329.  
  330. UniBasic contains a large number of pre defined functions and the user may
  331. write additional functions. Either compiler functions or user functions are
  332. called and used in the same manner except that USER FUNCTIONS which do not
  333. expect a return value (void functions) may be invoked by entering the
  334. function name just as you would a statement name.
  335.  
  336. The pre defined compiler functions need not be declared. To declare a user
  337. function we use the #FCN compiler directive. We must also "tell" the
  338. compiler where to locate the function we just declared if the function is
  339. external to our program. The optional ReturnType tells the compiler what
  340. type of data to expect to be returned by the function. The three valid
  341. return types are INT, FLOAT, and VOID. The default is INT. VOID means
  342. return nothing. The function should either be in the RELS or LIB directory.
  343. The number in parens tells the compiler how many arguments will be passed
  344. (must be 1 thru 9). If a "c" (or nothing) is used for the number of
  345. arguments, it indicates a variable number of arguments may be passed. If
  346. "c" (or nothing) is used, then no checking is done as to number of
  347. arguments. For example:
  348.  
  349. an internal fuction
  350.  
  351. #FCN DoIt() <ReturnType>
  352.  
  353. or an external function:
  354.  
  355. #FCN DoIt()<ReturnType>
  356. #LIB LibName
  357.  
  358. The method used to set up functions and pass arguments is compatible with the
  359. C compiler so it is possible to use C functions or to write functions for C.
  360.  
  361. If you forget to declare a function before using it, an error will be
  362. reported by the compiler. If you forget the #LIB directive the linker will
  363. return an error in the case of an external function.
  364.  
  365. It is common practice to build "header" files which declare functions and
  366. tell the compiler where to find them. These files are then invoked with the
  367. #USE directive.
  368.  
  369. The compiler will check the number of arguments declared against the number
  370. of those given and will verify the data type (unless the number given is "c"
  371. or nothing).
  372.  
  373. Since these user functions are modular in nature, their use can result in a
  374. well structured program with good readability and if the functions are
  375. general in nature they may be used by many programs (and programmers).
  376.  
  377. Functions which are included in the program (local functions) must be
  378. declared just as external functions are with a #FCN directive. These need
  379. no or #LIB directive. Symbol names used in these local functions are not
  380. unique as in external functions, but are global within the program itself
  381. (except for PARAM variables which are local to a function).
  382.  
  383. Local functions are written the same way as external functions. The function
  384. name is not declared as a global label as in an external function, and as
  385. mentioned above, variables are global with the rest of the program.
  386.  
  387. In the case of external functions, the function must be declared in both the
  388. calling program and in the function itself.
  389.  
  390. WRITING and USING EXTERNAL FUNCTIONS
  391.  
  392. External functions are modules of previously compiled relocatable object
  393. modules (ROF's).They may also be merged with other functions into a
  394. library file.
  395.  
  396. Writing an external function with UniBasic is the same as writing any program
  397. in UniBasic except the function is compiled with the -f option. Execution
  398. begins in the function with the occurrence of the function name in column
  399. 1 followed by "()". The next line(s) are the PARAM statements which must
  400. correspond to the number of arguments being passed to the function.
  401.  
  402. The variables and labels in an external function are independent of the
  403. labels and variables in other functions and the calling programs unless
  404. they are declared as EXTERNAL or GLOBAL.
  405.  
  406. Normally, a function is called with a list of arguments or parameters.
  407. In UniBasic these are passed by value. To pass arguments by reference, the
  408. arguments are passed as pointers. The pointer itself is passed by value but
  409. the data it points to is said to be passed by reference. To pass arguments
  410. to a function the calling program invokes the function in an expression
  411. with the arguments specified in order within parentheses following the
  412. function name. The compiler will put these arguments on the stack as
  413. required automatically. The function extracts these arguments from
  414. the stack when the function declaration is made as described above. The
  415. general order of a function is as follows:
  416.  
  417. * declare local function variables (not used in this example)
  418.  DIM x:BYTE
  419.  DIM y:SHORT
  420.  DIM z;LONG
  421.  
  422. FcnName()
  423.  PARAM p:LONG
  424.  PARAM q:LONG
  425.  
  426. * the body of the function goes here
  427. * finish up with a RETURN
  428.  RETURN p*q
  429.  
  430. To compile this function:
  431.  
  432. cb FcnName.b -f
  433.  
  434. The -f on the command line instructs the compiler to compile to a relocatable
  435. file to be linked in later.
  436.  
  437. Functions can also share labels and variables with the calling program by
  438. using GLOBAL labels and symbols. The calling program declares GLOBAL while
  439. the function declares EXTERNAL or vice-versa.
  440.  
  441.                              C CODE
  442.  
  443. It is possible to intermingle C code in your Basic program. This may be done
  444. on a single line basis by writing a ";" in column 1 followed by C code or on
  445. a block basis by using the #C and #ENDC compiler directives with C code
  446. between.
  447.  
  448. The C code may refer to Basic variables which have been declared but it is
  449. important to know the details of how UniBasic handles the declaration in its
  450. C output. For example, any complex data structure in Basic results in an
  451. array of type char in the C output. Also, any pointer declaration in Basic
  452. results in a long in C. Strings in Basic are null terminated (as in C) only
  453. if the string is not "full". Members of structures are padded to an even
  454. byte boundary when the next member isa short, long or float type or if it
  455. is the last member in the structure. String declarations result in a char[],
  456. but no "extra" byte is required as in C strings. Simple integer types and
  457. float (real) do map as expected to comparable C types as do arrays of
  458. these types.
  459.  
  460. While the compiler thoroughly checks the syntax and compiles BASIC statements
  461. into C code, it does not process C statements to that degree. Since this is
  462. the case, all errors involving C syntax and symbol problems (missing,
  463. duplicate, etc.) will not show up until the C compiler processes the file.
  464. The #SET compiler directive also outputs a C version of its result (#define)
  465. so that the C compiler may apply this result to C code (if used).
  466.  
  467. An example of the use of C code in a BASIC program follows:
  468.  
  469.  REM Program to clear an entire string
  470.  REM
  471.  DIM A$:STRING[32]
  472.  DIM I:LONG
  473.  FOR I=1 TO 32
  474. ;A_Str[I-1]=0;
  475.  NEXT I
  476.  
  477. Notice that since C does not allow a "$" in a symbol name, that UniBasic
  478. changes the "$" to "_Str". Also notice that the string in Basic is an array
  479. of type char in C with the first element addressed as0.
  480.  
  481. Due to the power and efficiency of UniBasic there should not be much (if any)
  482. need to intermix C code, but the ability to do so is there if you need
  483. (or want) it.
  484.  
  485. If you wish to use the C string functions on Basic strings, make sure the
  486. basic string is at least one byte short of being "full" or DIM a byte
  487. immediately following the DIM of the string and then initialize the
  488. "tacked-on" byte to 0 (null).
  489.  
  490. There are several ways to include comments or remarks in a program. The first
  491. and most obvious is the use of the REM statement which is standard BASIC.
  492. The second is to follow the statement (on the same line) with a backslash
  493. (\) followed by any comment desired. The third way is to start a line
  494. (column #1) with a "*" character followed by any comment desired.
  495.  
  496.                          POINTER VARIABLES
  497.  
  498. The concept of pointer variables is foreign to BASIC (until now). Pointers
  499. are a mainstay of the programming language "C". The challenge of adding
  500. pointers to UniBasic was to provide the power of the concept but to do so
  501. with a syntax that has a BASIC flavor rather than the cryptic style of "C".
  502.  
  503. Pointers are variables in their own right and are a special form of a 32 bit
  504. unsigned integer which have a special property to index their value
  505. according to the data type which they are declared to point to. For example
  506. pointers can be assigned values and used in expressions just like the data
  507. type long (integer). This allows the pointer to be set to any value from 0
  508. to $ffffffff and this fact alone gives the pointer concept extreme power as
  509. well as the power to cause a catastrophe if used carelessly. A more
  510. "civilized" setting of a pointer would be to set it to the address of
  511. another variable or to the address of a memory buffer (see BUFFER, BUFADR(),
  512. BUFSIZ() section). When setting a pointer to another variable it is the data
  513. type of the pointer which prevails when accessing data with the pointer (not
  514. the data type of the variable being pointed to). Most "C" compilers give a
  515. warning if a pointer is set to point to a variable with a different data
  516. type than its own. UniBasic gives no such warning.
  517.  
  518. The functions ADDR() and INDEX() are intended solely for use with pointers
  519. although the ADDR() function could be used to find the address of a variable
  520. for any reason. Also the BUFADR() function is intended to set pointers to
  521. the base address of memory buffers. The ADDR() function returns the memory
  522. address of a variable given as the argument to the function. It is used
  523. primarily to set a pointer to the absolute address of a variable. In the
  524. case of an array, the address returned is the base address (address of the
  525. first element of the array). The ADDR() function could also be used in
  526. address calculations to determine the storage relationship of two or more
  527. variables. To reference data pointed to by a pointer the pointer variable is
  528. enclosed in square brackets i.e. [Ptr]. Data referenced by pointers must be
  529. of a compatible type with the variable or constant used with it just as if
  530. the data were to/from a standard variable (I.E. not pointed to by a
  531. pointer). The INDEX function is used to point to different elements of the
  532. object data (assuming the object is an array or is being treated as an
  533. array). In "C" arithmetic operations on pointers take into account the data
  534. type of the pointer. In UniBasic arithmetic operations on pointers do not
  535. take the data type into account. The INDEX() function does take the
  536. pointer's data type into account however. The arguments to the INDEX()
  537. function are the pointer name and the index value. To index backward a
  538. negative index value is specified. In the following example the INDEX()
  539. function will be used on a pointer whose data type is INTEGER (32 bits or
  540. 4 bytes long). When we index the pointer by three it will point 12 bytes
  541. past its previous setting (4 bytes times 3=12). The INC and DEC statements
  542. also take into account the data size pointed to by a pointer. If Ptr is a
  543. an INTEGER pointer then, INC Ptr will add 4 to the value of Ptr since an
  544. INTEGER is 4 bytes in size.
  545.  
  546.  DIM Pointer:INTEGER ADDRESS
  547.  DIM IntVar(30):INTEGER
  548.  DIM Temp1:INTEGER
  549.  DIM Temp2:INTEGER
  550. Start
  551.  Pointer=ADDR(IntVar) \ assigns base address of IntVar to Pointer
  552.  Temp1=[Pointer] \ assigns the value of the first element to Temp1
  553.  Pointer=INDEX(Pointer,3) \ Pointer now points to the fourth element
  554.  Temp2=[Pointer] = assigns the value of the fourth element to Temp2
  555.  DEC Pointer \ Pointer now points to the third element
  556.  
  557.                         COMPILER DIRECTIVES
  558.  
  559.                             #SET, #FIX
  560.  
  561.  The #SET compiler directive is used to define compiler variables and to set
  562.  them to a numeric (long integer) value. The most common use of the compiler
  563.  variable is to assign values to symbolic constants. Typically, since BASICs
  564.  do not contain this feature, all constants must be literals (200, $0f,
  565.  etc). Just as named variables such as Radius, Total, SubTotal, etc. are
  566.  helpful and named labels such as GetInput, PrintList, etc. are more useful
  567.  than line numbers, symbolic constants add much more meaning to the program
  568.  than do abstract literal numbers. Any place that literal numeric constants
  569.  are used (such as in expressions and DATA statements) symbolic constants
  570.  may be used. The #Set directive may be used to set the same variable as
  571.  many times as desired throughout the program. Thus when a compile variable
  572.  is referenced the value last assigned by a #SET directive is the value
  573.  referenced. Compiler variables are also used to control the flow of
  574.  conditional compilation by being tested with the #IF compiler directive.
  575.  The #FIX directive is a permanent #SET. The general form of the #SET
  576.  compiler directive is as follows:
  577.  
  578. #SET CompVar=OPERAND1{OPERATOR|OPERAND2}
  579.  
  580. CompVar is the desired symbol name (the naming rules are the same as for
  581. BASIC variable, labels, etc.). The name must be unique from any other
  582. compiler variable, label, BASIC variable, macro, etc. or a symbol already
  583. defined error will occur. The "=" is mandatory as is OPERAND1. OPERAND1 (and
  584. OPERAND2 if used) must be either a compiler variable (previously created and
  585. defined with a #SET directive) or a numeric literal (either a decimal
  586. integer or Hexadecimal). Hexadecimal is indicated by a leading "$". The
  587. OPERATOR must be a "+", "-", "*", "/","&", "|", "<<" or ">>" indicating
  588. addition, subtraction, multiplication, division, AND, OR, left shift, or
  589. right shift respectively. If the OPERATOR is used it must be immediately
  590. followed by OPERAND2. Examples of the use of #SET directive follow: 
  591.  
  592. #SET xyz=1 \ creates the compiler variable xyz and sets it to 1
  593.  A=A+xyz \ implied LET statement equivalent to A=A+1
  594. #SET xyz=$ff \ changes xyz to equal Hexadecimal $ff (255)
  595. Label DATA "test",xyz \ equivalent to Label DATA "test",255
  596. #SET Side=4 \ creates the compiler variable Side and sets it to 4
  597.  Area=Side*Side \ implied LET statement equivalent to Area=4*4
  598. #SET xyz=2 \ now equals 2
  599. #SET abc=xyz \ creates the compiler var abc and sets it to the value of xyz
  600. #FIX xyz=xyz+abc \ now equals 4 (permanently)
  601. #IF xyz=5 \ example of testing a compiler variable for conditional compilation
  602.  
  603. The SET directive may also be used in the body of a macro declaration such as:
  604.  
  605. #MACRO MacroName \ declares a macro named MacroName
  606. #SET CompVar=~0
  607.  DATA CompVar
  608. #ENDM \ defines end of macro declaration
  609.  
  610. MacroName
  611. MacroName
  612.  
  613. Results in the following source code generation:
  614.  
  615.  DATA 1
  616.  DATA 2
  617.  
  618.                           #IF, #ELSE, #ENDIF
  619.  
  620. These compiler directives are used to provide conditional compilation which
  621. is a feature commonly found in assemblers and "C" compilers, but rarely in
  622. Basic. Conditional compilation is useful when it is necessary to maintain
  623. more than one version of a program which has many common sections but some
  624. different sections. Conditional sections may be nested up to 20 deep.
  625.  
  626. The argument to the #IF directive is a simple condition of equality. The
  627. general syntax is as follows:
  628.  
  629.  #IF CompVar=Const
  630.  
  631. CompVar is a compiler variable which my be declared by a #SET or #FIX
  632. directive or on the compiler command line. Const is a constant which my be a
  633. decimal or hexadecimal integer value or another compiler variable.
  634.  
  635. The most common way to use this feature is to assign a compiler variable at
  636. the command line. For example:
  637.  
  638. cb testprog c=1
  639.  
  640. The #ELSE directive is optional and follows the body of code after the #IF
  641. directive.
  642.  
  643. The #ENDIF directive ends the conditional section.
  644.  
  645. An example follows which would go with the command line example above:
  646.  
  647. #IF c=1
  648. print "c=1"
  649. #ELSE
  650. print "c<>1"
  651. #ENDIF
  652.  
  653. The above example is of no practical use, but shows the effect of conditional
  654. compilation.
  655.  
  656. Also note that macros may be declared inside conditional sections which
  657. effectively offers conditional macros. This is especially useful in writing
  658. I/O drivers.
  659.  
  660.                               #C, #ENDC
  661.  
  662. These directives allow the use of C code blocks within a program or function.
  663. After the #C directive, all input is simply passed through to the output
  664. file until a #ENDC directive is encountered. C code may also be used on a
  665. single line basis by writing a ";" in column 1. See section on C Code.
  666.  
  667.                              #MACRO, #ENDM
  668.  
  669. The #MACRO and #ENDM compiler directives are used to declare MACROS. The
  670. purpose of macros is to allow the programmer to create complex blocks of
  671. code and then use them as if they were a single instruction with a
  672. descriptive name. At first glance the use of a macro might appear as a
  673. subroutine. This is not the case, however, because a subroutine appears only
  674. once in a program but may be called many times, while a macro is replicated
  675. in the code each time it is used. Also the macro invocation allows
  676. the specification of up to 9 arguments which are assigned to corresponding
  677. variables in the macro. The general form of the macro declaration and
  678. invocation are as follows:
  679.  
  680. Declaration:
  681.  
  682. #MACRO MacroName
  683.  {body of macro}
  684. #ENDM
  685.  
  686. Invocation:
  687.  
  688.  MacroName Arg#1,Arg#2,Arg#3,Arg#4,Arg#5,Arg#6,Arg#7,Arg#8,Arg#9
  689.  
  690. The macro declaration begins with the #MACRO compiler directive. All compiler
  691. directives must have a "#" in character position #1 (no indentation
  692. allowed). The body of the macro may contain no tilde characters (~) except
  693. where an argument is being specified. The body of the macro willwhen
  694. invoked be expanded to enter the source input stream, so the syntax within
  695. the body must conform to compiler syntax rules. Any occurrence of the tilde
  696. character without a single digit 0-9 immediately following will result in an
  697. invalid macro argument error. Any occurrence of the tilde character
  698. immediately followed by a single digit (0-9) will be replaced when the
  699. macro is invoked with the corresponding invocation argument or in the case
  700. of ~0 with the macro invocation number. Macros may NOT be nested. This means
  701. that a macro declaration (#MACRO) may not appear in the body of a macro.
  702. This will result in a nested macro error. The macro declarations are stored
  703. in a fixed size macro buffer (20,000 bytes as of this writing) and if this
  704. limit is exceeded a macro buffer full error will occur. The macro
  705. declaration is terminated by an #ENDM compiler directive. An #ENDM directive
  706. without a prior #MACRO directive will result in an #ENDM without #MACRO
  707. error. If a macro is declared which already exists the result will be a
  708. macro already defined error.
  709.  
  710. The macro invocation begins with the MacroName followed by a space followed
  711. by up to 9 macro arguments. If the macro definition has no arguments then
  712. none should be supplied in the invocation (the macro is invoked with the
  713. MacroName only). The MacroName must NOT begin in character position #1 as it
  714. will be taken for a Label. If there are less arguments in the macro
  715. invocation than are used in the macro declaration a macro argument error
  716. will occur. Macro invocation arguments are separated by a comma. NULL
  717. arguments are specified by adjacent commas (I.E. no argument). Alpha-Numeric
  718. strings (including "_","@", and "$") are valid arguments as are single
  719. special characters such as "!", "#","%", etc. The SPACE and BACKSLASH
  720. characters are NOT permitted. Quoted strings are passed as arguments with
  721. the quotes themselves included in the argument.
  722.  
  723. Macros must be declared before they are invoked or the invocation will result
  724. in an undefined symbol error.
  725.  
  726. Macro names must not conflict with other symbol names such as variables,
  727. labels, compiler variables, etc. or a symbol already defined error will
  728. occur.
  729. #MACRO, #ENDM (cont)
  730.  
  731. The following example illustrates a simple macro declaration and invocation:
  732.  
  733. #MACRO GetName \ declares a macro named "GetName"
  734. PRINT "Enter Name"
  735.  INPUT ~1
  736.  PRINT ~2
  737. #ENDM \ defines end of macro declaration
  738.  
  739.  GetName UserName,"Thank You"
  740.  
  741. The invocation of the macro (GetName UserName) causes the generation of the
  742. following lines in the source code stream:
  743.  
  744.  PRINT "Enter Name"
  745.  INPUT UserName
  746.  PRINT "Thank You"
  747.  
  748. The tilde character in the declaration followed by the numeral 1 indicates a
  749. macro argument which is assigned a value during invocation. In this example
  750. it is assigned "UserName" because it is argument #1 and UserName is the
  751. first invocation argument. Accordingly the second argument (~2) is assigned
  752. the quoted string "Thank You". Each macro may have up to 9 such arguments
  753. which may appear any number of times in the macro declaration.
  754.  
  755. A special argument (~0) is also available in the declaration which is
  756. replaced by the invocation number. For example, the first time a macro is
  757. invoked the ~0 will be replaced with a "1", the second time with a "2" and
  758. so on. This function is particularly useful in generating labels within a
  759. macro. For Example:
  760.  
  761. #MACRO Demo \ declares a macro named "Demo"
  762. Label~0 A=A+1
  763.  IF A<200 THEN Label~0
  764. #ENDM \ defines end of macro declaration
  765.  
  766. The first invocation of the Demo macro causes the generation of the following
  767. lines in the source code stream:
  768.  
  769. Label1 A=A+1
  770.  IF A<200 then Label1
  771.  
  772. The seventh invocation of the Demo macro causes the generation of the
  773. following lines in thes ource code stream:
  774.  
  775. Label7 A=A+1
  776.  IF A<200 THEN Label7
  777.  
  778. For the advanced user, the macro declaration body may contain a series of C
  779. statements (or BASICstatements or both) with the effect of implementing
  780. new statements not included in the language. This practice will eliminate
  781. much of the "trickery" and "cheat coding" often found in BASIC programs and
  782. result in much cleaner and readable code with faster execution speed. The
  783. user may accumulate a MACRO library through freeware, shareware, and
  784. purchased software.
  785.  
  786.              #USE, #SBRTN, #LIB, #FCN #STRUCT, #ENDSTRUCT
  787.  
  788. The #USE compiler directive is used to incorporate other files into the
  789. source data stream. It is equivalent to the "include" directive in "C" and
  790. is especially useful in declaring macros and functions. The USE directive
  791. may be nested up to 20 deep. This is to say that a file called by #USE may
  792. have a #USE directive itself. The general syntax of the #USE directive is as
  793. follows:
  794.  
  795. #USE PathList
  796.  
  797. PathList is any legal path list to a file to be included in the source data
  798. stream.
  799.  
  800. The #SBRTN compiler directive may be used to declare a subroutine. If the
  801. subroutine is referenced by a GOSUB before it appears, no declaration is
  802. required. even when not required, an ordered list of subroutines at the
  803. beginning of a program is useful.
  804.  
  805. #SBRTN PathList
  806.  
  807. The #LIB compiler directive is used to declare any library files which may
  808. contain relocatable files required by the program. Library files are merely
  809. a collection of relocatable modules. The #LIB directive may also be used to
  810. invoke C compiler options. The general syntax is as follows:
  811.  
  812. #LIB PathList
  813.  
  814. The #FCN compiler directive is used to declare functions. The name of the
  815. function is declared as well as the number of arguments.The general syntax
  816. is as follows:
  817.  
  818. #FCN FcnName(NumArgs)
  819.  
  820. NumArgs is a simple integer such as 1,2,3..etc. (or none)
  821.  
  822. The #STRUCT and #ENDSTRUCT are used to declare data structures just as the
  823. TYPE statement does. The only difference is#STRUCT directive allows
  824. declarations that are not limited by line length and the structure is more
  825. clear to look at. For example:
  826.  
  827. #STRUCT UsrType
  828.  Name:STRING[20}
  829.  Address:STRING[30]
  830.  ZipCode:BYTE
  831. #ENDSTRUCT
  832.  
  833. The above example is equivalent to:
  834.  
  835.  TYPE UsrType=Name:STRING[20];Address:STRING[30];ZipCode:BYTE
  836.  
  837.  
  838.  
  839. ******************** Important! READ THIS: *******************
  840.  
  841. Subroutines in UniBasic are actually void C functions. Unless the subroutine
  842. is referenced by a GOSUB before it appears, the compiler will "think" it is
  843. a label rather than a subroutine. Therefore a subroutine must be referenced
  844. before it appears or, alternatively it may be declared with a #SBRTN
  845. directive. Also the last statement of a subroutine must be a RETURN. Any
  846. RETURN statement before the end of a subroutine must be inside a control
  847. structure such as a FOR loop or WHILE/ENDWHILE block. Violations of these
  848. rules will result in a "nesting" error.
  849.  
  850. The RETURN statement transfers control back to the caller and is also used to
  851. return integer or floating point data to the caller in the case of integer
  852. or floating point functions. For example:
  853.  
  854.  RETURN x+y
  855.  
  856.                            DIRECTIVES
  857.  
  858. #SET            #SET CompVar=Const
  859.                 #SET CompVar=Const+Const
  860.                 #SET CompVar=Const-Const
  861.                 #SET CompVar=Const*Const
  862.                 #SET CompVar=Const/Const
  863.  
  864. #FIX            #FIX CompVar=Const\ same as #SET but is permanent
  865.  
  866. #USE            #USE PathName
  867.  
  868. #IF                #IF CompVar=Const\ conditional compile
  869. #ELSE            #ELSE\ conditional compile
  870. #ENDIF            #ENDIF\ conditional compile
  871.  
  872. #MACRO            #MACRO MacroName
  873.                 Macro Body
  874. #ENDM           #ENDM
  875.  
  876. #FCN            #FCN (NumArgs) <return data type> <modifier(s)>
  877.                 (NumArgs is number of arguments)
  878.                 (if NumArgs="c", NumArgs is variable)
  879.                 (return data type may be INT (default), FLOAT, or VOID)
  880.                 (modifiers may be POINTER, GLOBAL, and EXTERNAL)
  881.  
  882. #ROF            #ROF PathList\ relocatable file for linker
  883.  
  884. #LIB            #LIB PathList\ library file(s) for linker
  885.  
  886. #STRUCT         #STRUCT StructName\ same function as TYPE statement
  887.  
  888. #ENDSTRUCT      #ENDSTRUCT\ terminates structure declaration
  889.  
  890. #C              #C\ marks the beginning of a C code block
  891.  
  892. #ENDC           #ENDC\ marks the end of a C code block
  893.  
  894. #SBRTN          #SBRTN\ declares a subroutine
  895.  
  896.                         STATEMENTS
  897.  
  898. IF             IF CondExp THEN LABEL
  899.             or
  900.             IF CondExp THEN
  901.                 code body
  902.             ENDIF
  903.             or
  904.             IF CondExp THEN
  905.                 code body
  906.             ELSE
  907.                 code body
  908.             ENDIF
  909.  
  910. WHILE         WHILE CondExp DO
  911.                 code body
  912.             ENDWHILE
  913.  
  914. REPEAT         REPEAT
  915.                 code body
  916.             UNTIL CondExp
  917.  
  918. LOOP         LOOP
  919.                 code body
  920.             ENDLOOP
  921.  
  922. LOOP         LOOP COUNT=IntExp
  923.                 code body
  924.             ENDLOOP
  925.  
  926. FOR         FOR Int=IntExp TO IntExp {STEP IntExp}
  927.                 code body
  928.             Next Int
  929.  
  930. EXITIF         EXITIF CondExp <THEN>
  931.             Falls thru to end of any of above structures
  932.  
  933. GOTO         GOTO Label
  934.             GOTO [IntVar]
  935.  
  936. GOSUB         GOSUB Label
  937.             GOSUB [IntVar]
  938.  
  939. RETURN         RETURN
  940.             Return from subroutine or function
  941.  
  942. ON             ON Int GOTO
  943.             ON Int GOSUB
  944.             ON ERROR GOTO
  945.             ON ERROR
  946.  
  947. STATUS:     STATUS \ optional prefix to any input/output statement
  948.             which turns off error trapping
  949.  
  950. STATUS      STATUS\ contains status of last input/output operation
  951.             -1 indicates error
  952.  
  953. READ         READ VAR,VAR...,VAR\ reads data statements
  954.             READ #PathNum,StringVar
  955.  
  956. WRITE         WRITE #PathNum,StringVar
  957.  
  958. GET         GET #PathNum,Var\ can be simple var or whole array
  959.  
  960. PUT         PUT #PathNum,Var\ can be simple var or whole array
  961.  
  962. BUFREAD     BUFREAD #PathNum,Addr,Bytes
  963.  
  964. BUFWRITE     BUFWRITE #PathNum,Addr,Bytes
  965.  
  966. PRINT         PRINT Expr
  967.             PRINT #PathNum,Expr
  968.             PRINT USING(FormatString,Var,Var,...,Var)
  969.             PRINT #PathNum USING(FormatString,Var,Var,...,Var)
  970.             <<<<<<< left justified format field of 7 positions
  971.             >>>>>> right justified format field of 6 positions
  972.             ^^^^^ center justified format field of 5 positions
  973.  
  974. INPUT         INPUT Var
  975.             INPUT "prompt",Var
  976.             INPUT #PathNum,Var
  977.  
  978. FPRINT         Same as PRINT but sends no Line Feed
  979.  
  980. FINPUT         Same as input but sends no prompt
  981.  
  982. CREATE         CREATE #ByteVar,PathName     AccMode
  983.  
  984. OPEN         OPEN #ByteVar,PathName     AccMode
  985.  
  986. CLOSE         CLOSE #PathNum
  987.  
  988. SEEK         SEEK #PathNum,IntVal
  989.  
  990. DELETE         DELETE StringVal
  991.  
  992. LET         {LET} Var=Expr
  993.  
  994. POKE         POKE Addr,ByteVal
  995.  
  996. END         END
  997.  
  998. REM         REM\ Remark
  999.  
  1000. SHELL         SHELL String
  1001.  
  1002. RESTORE     RESTORE Label
  1003.  
  1004. DATA         DATA Const,Const...,Const
  1005.  
  1006. BUFFER         BUFFER BufName=MemBytes\ opens buffer to size=MemBytes
  1007.             BUFFER BufName=0\ closes buffer
  1008.             (MemBytes=-1 opens largest buffer available)
  1009.  
  1010. DIM         DIM VarName[(ArraySize)}     DataType {modifier modifier}
  1011.             DataTypes      BOOLEAN, BYTE, SHORT, LONG, FLOAT, STRING,POINTER
  1012.             Modifiers      GLOBAL, EXTERNAL, ALIAS=, ADDRESS(POINTER),
  1013.             REMOTE, REGISTER, VECTOR
  1014.             DIM StringVarName{(ArraySize)}     STRING[StringSize] {modifier}
  1015.  
  1016. PARAM       Similar to DIM, immediately follows a function occurence
  1017.             with one PARAM to receive each argument to the function
  1018.  
  1019. TYPE         TYPE UserType=VarName{(ArraySize)}     DataType;VarName...etc.
  1020.  
  1021. INC         INC IntVar\ IntVar=IntVar+1
  1022.             INC PtrVar\ PtrVar=PtrVar+DataSize
  1023.  
  1024. DEC         DEC IntVar\ IntVar=IntVar-1
  1025.             DEC PtrVar\ PtrVar=PtrVar-DataSize
  1026.  
  1027. DIGITS         DIGITS NumConst\ # of digits for FLOAT (1-15) default 15
  1028.  
  1029. DECIMALS     NumConst\ # of decimal places for FLOAT (default 2)
  1030.  
  1031. BASE         BASE 0, BASE 1\ base of arrays (default  1)
  1032.  
  1033. ENDEXIT     ENDEXIT\ Terminates EXITIF CondExp THEN
  1034.  
  1035. SETVEC         SETVEC VectorVar=Addr\ Sets vector to address
  1036.  
  1037. EXCHANGE     EXCHANGE Var,Var\ vars must be same type and size
  1038.  
  1039.                 FUNCTIONS and SPECIAL VARIABLES
  1040.  
  1041. EOF()            EOF(#PathNum)\ BOOLEAN result
  1042. LEN()            LEN(String)\ INT result
  1043. STR$()            STR$(NumVal)\ String result
  1044. ZSTR$()            ZSTR$(NumVal)\ String result zero padded
  1045. VAL()            VAL(StringVal)\ INT or FLOAT result
  1046. IVAL()          IVAL(StringVal)\ INT RESULT
  1047. FVAL()          FVAL(StringVal)\ FLOAT result
  1048. LAND()            LAND(IntVAl)\ INT result
  1049. LOR()            LOR(IntVal)\ INT result
  1050. LXOR()            LXOR(IntVal)\ INT result
  1051. LNOT()            LNOT(IntVal)\ INT result
  1052. MID$()            MID$(StringVal,Org,Bytes)\ String result
  1053. LEFT$()            LEFT$(StringVal,Bytes)\ String result
  1054. RIGHT$()        RIGHT$(StringVal,Bytes)\ String result
  1055. MOD()            MOD(IntVal,IntVal)\ INT result
  1056. CHR$()            CHR$(IntVal)\ String result
  1057. ASC()            ASC(StringVal)\ INT result
  1058. NOT()            NOT(BoolVal)\ Boolean result
  1059. BUFADR()        BUFADR(BufName)\ INT result (address of BufName)
  1060. BUFSIZ()        BUFSIZ(BufName)\ Int result (size of BufName)
  1061. PEEK()            PEEK(Addr)\ Byte result
  1062. ERR                ERR\ INT result
  1063. FILSIZ()        FILSIZ(#PathNum)\ INT result
  1064. POS                POS\ Int result
  1065. FILPOS()        FILPOS(#PathNum)\ INT result
  1066. INDEX()            INDEX(PtrVar,IndexVal)\ INT result
  1067. SIZE()            SIZE(VarName)\ INT result
  1068. TAB()            TAB(IntVal)\ INT result
  1069. ADDR()            ADDR(VarName)\ INT result
  1070. NextArg            StringVar=NextArg\    must be used in LET statement
  1071.                 (Do once to get each arg)
  1072.                 (When LEN(StringVar)=0 then all command line
  1073.                 arguments are exhausted)
  1074. XferBytes        Total bytes transfered after I/O operation
  1075. THOUR()         THOUR(0)\ Hour BYTE result
  1076. TMIN()          TMIN(0)\ Minutes BYTE result
  1077. TSEC()          TSEC(0)\ Seconds BYTE result
  1078. TYEAR()         TYEAR(0) \ Year BYTE result
  1079. TMON()          TMON(0)\ Month BYTE result
  1080. TDAT()          TDAT(0)\ Date BYTE result
  1081. TDAY()          TDAY(0)\ DAY BYTE result 0=Sunday, 1=Monday, etc.
  1082. SQR()           SQR(FloatVal)\ Square Root FLOAT result
  1083. ABS()           ABS(NumExpr)\ Absolute Value INT or FLOAT result
  1084. INT()           INT(FloatVal)\ Integer Value of Float
  1085. SIN()           SIN(NumVal)\ FLOAT result
  1086. COS()           COS(NumVal)\ FLOAT result
  1087. TAN()           TAN(NumVal)\ FLOAT result
  1088. ASN()           ASN(NumVal)\ FLOAT result
  1089. ACS()           ACS(NumVal)\ FLOAT result
  1090. ATN()           ATN(NumVal)\ FLOAT result
  1091. LOG()           LOG(NumVal)\ FLOAT result
  1092. LOG10()         LOG10(NumVal)\ FLOAT result
  1093. HEX$()            HEX$(NumVal)\ String result
  1094. ZHEX$()            ZHEX$(NumVal)\ String result zero padded
  1095. BITTST()        BITTST(IntVal,IntConst)\ BOOLEAN result
  1096. BITCLR()        BITCLR(IntVal,IntConst)\ INT result
  1097. BITSET()        BITSET(IntVal,IntConst)\ INT result
  1098. BITCHG()        BITCHG(IntVal,IntConst)\ INT result
  1099. SHL()            SHL(IntVal,IntConst)\ INT result
  1100. SHR()            SHR(IntVal,IntConst)\ INT result
  1101. ROL()            ROL(IntVal,IntConst)\ INT result
  1102. ROR()            ROR(IntVal,IntConst)\ INT result
  1103. SUBSTR()        SUBSTR(Str1,Str2)\ Int result position of Str1 in Str2
  1104.