home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ob140os2.zip / MINI_MAN < prev    next >
Text File  |  1997-10-29  |  48KB  |  1,103 lines

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