MISCELLANEOUS Statements
Updated: Nov 25, 2007

BYTESWAP MyVar

  BYTESWAP i, where i is a 32-bit, non-floating value (INTEGER, LONG, etc)
  reverses the byte order of variable i.  Among other things, BYTESWAP can
  be used to convert back and forth from little-endian to big-endian
  representations.

  BYTESWAP is also a Numeric Function:  j = BYTESWAP(i).

DEC(MyVar[,amount])
INC(MyVar[,amount])

  Can use real numbers and fractional values for INC/DEC amount.

  The second optional operand in INC/DEC statements (amount) can be a numeric
  expression.  Thus, we can write:

    INC(i, j+k)

  or 

    INC(i, INSTR(s$,t$))

  INC and DEC are optimized to autodetect non-float values.

    INC(i,10): DEC(j,2): INC(k)

  is faster than

    i = i + 10: j = j - 2: k = k + 1

IADD(int1, int2)  int1 = int1 + int2.  Similar to INC().  Examples:

  IADD(i,20)  'i = i + 20
  IADD(i,j)   'i = i + j

IDIV(int1, int2)  int1 = int1 / int2.  Examples:

  IDIV(i,20)  'i = i / 20
  IDIV(i,j)   'i = i / j

IMOD(int1, int2)  int1 = remainder of int1 / int2.  Examples:

  IMOD(i,20)  'i = remainder of i / 20
  IMOD(i,j)   'i = remainder of i / j

IMUL(int1, int2)  int1 = int1 * int2.  Examples:

  IMUL(i,20)  'i = i * 20
  IMUL(i,j)   'i = i * j

ISHL(int1, immediate)  int1 = int1 SHL immediate.  Multiply by a power of 2:

  ISHL(i,4)  'i = i * 16 where 2^4 = 16
  ISHL(i,2)  'i = i * 4  where 2^2 = 4

ISHR(int1, immediate)  int1 = int1 SHR immediate.  Divide by power of 2:

  ISHR(i,4)  'i = i / 16 where 2^4 = 16
  ISHR(i,2)  'i = i / 4  where 2^2 = 4

  Note:  immediate values above are 1 to 31.  Your code, where prudent,
  should check for overflow (incorrect result) with IMUL and ISHL.
  For the "I" integer functions, HotBasic error checks that the int1 argument
  is a dimensioned INTEGER (alias LONG) variable.

ISUB(int1, int2)  int1 = int1 - int2.  Similar to DEC().  Examples:

  ISUB(i,20)  'i = i - 20
  ISUB(i,j)   'i = i - j

DOEVENTS + processes pending messages in $APPTYPE GUI.

  Used primarily in event procedures which generate messages or which require
  multiple time slices to complete.

END terminates program; same as Application.Terminate; not same as end of
  source code.

  If you have GOSUB routines (LABEL ... RETURN), place them after END so your
  main program code will not "fall into" a routine.

ENVIRON string; string is {variable}={value}; ENVIRON "TEMP=C:\temp"

FREECONSOLE "frees console window".  Typically used in GUI applications after
  SHOWCONSOLE, if no more console display or PRINT's are wanted.

GOTO label; jumps to code at label.

  IF {conditional expression} THEN GOTO Finished 

INITARRAY array; clears array data.

  DIM dat(99) As LONG
  'code
  INITARRAY dat

  INITARRAY is *not* needed at program startup for any array.

LPRINT string; sends string expression to lpt1

  LPRINT "hello world"+crlf  'prints one line
  mystring.loadfromfile("myfile.txt")
  LPRINT mystring  'prints entire file
  MyVar = RETFUNC  'optionally retrieve number of bytes sent to lpt1

  If LPRINT is used, HotBasic internal variable hbPrinter = port IO handle.

  Note: LPRINT supported in PentHouse registered version.

OUT addr, integer; write byte value integer to I/O port address.

OUTW addr, integer; write word value integer to I/O port address.

  Note: OUT and OUTW are not used for recent Windows versions.

POPUP integer + displays popup menu where integer is a POPUPMENU handle.

  POPUP MyPopUpMenu.handle  'POPUPMENU is an alias for MAINMENU

  POPUP may show a POPUPMENU under program control or in GUI event procedures,
  as response to user input or other event (hotpopup.bas).

  POPUP menus may be placed under any FORM object (e.g., EDIT, LABEL) except
  FORM itself, in which case, it is rendered as a form menu bar.

RANDOMIZE integer; sets RND function seed value; e.g., RANDOMIZE TIMER

  To regenerate the same pseudo-random number sequence repeatedly, use a
  constant argument:  e.g., RANDOMIZE 100

REDIM array(subscripts); redefine subscript usage and/or size of an array.

  Decreasing overall array size will not erase previous data or reduce its ram
  allocation.  Array item size or type cannot be changed.

  DIM dat(99) As LONG
  'code
  REDIM dat(9,19)

  For FORM objects, REDIM will not destroy, recreate or create additional
  objects if overall array size is changed.  If a FORM object array size is
  increased, REDIMEX (Statements > Advanced Techniques) is used after REDIM
  to initialize the new array items.

RUN {command line string}; with executable pathname and optional arguments;
  does not block application.

SHELL {command line string}; with executable pathname and optional arguments;
  blocks application while shelled program runs.

  If pipe symbols are used in string, then "command.com /c" or "cmd.exe /c"
  may have to be added as a prefix to the command line string.  The VERSION
  object may be used to determine which prefix to use.

SHELL1 {command line string}; with executable pathname and optional arguments;
  same as SHELL but starts executable at a higher priority level.

  Use for CPU-instensive child processes, such as a compiler or linker, but
  not for GUI apps, which can cause problems if run at a higher CPU priority.

  Application.ErrorLevel after SHELL/SHELL1 retrieves error level value. 

  SHELL and SHELL1 may also be used as Numeric Functions to retrieve error
  level.  E.g.,

  ErrLvl = SHELL "myprog"  'ErrLvl gets exit code of myprog

SHOWCONSOLE   Please see description in CONSOLE section.

SHOWMESSAGE {single or multi-line message string}

  SHOWMESSAGE "Star on your chart for using this application"

SLEEP number

  number is seconds with millisecond resolution; suspends application.
  Use SLEEP to save CPU time if application is waiting for an input or event.

  SLEEP 0.05 '50 milliseconds for 20/second frame rate.

SWAP MyVar1, MyVar2; exchanges values for 2 or 4 byte variables.

  MyVars should be the same size: WORD, SHORT, SINGLE, DWORD, LONG, INTEGER

THIS +

  THIS facilitates access to UDT/Custom Objects by pointer.  With THIS
  syntax, code blocks may process data from different Objects.  Example:

  $apptype console

  TYPE MyUDT
    item1 as LONG
    item2 as LONG
  END MyUDT

  DECLARE SUB ProcessData (x as LONG, y as LONG)

  SUB ProcessData
  this.item1 = x
  this.item2 = y
  print this.item1 + this.item2
  END SUB

  DIM abc as MyUDT
  DIM xyz as MyUDT

  THIS = abc: ProcessData (10, 20)
  THIS = xyz: ProcessData (30, 40)

  pause
  end

  Notice that the SUB code block using this.SomeProperty syntax appears
  after the UDT to which THIS will refer.  Thus, at compile-time, the 
  proper offsets to .item1 and .item2 will be used.  At run-time, the
  SUB will use the pointer obtained from a THIS = <name of UDT instance>
  statement.

  THIS syntax is based on the BYREF() and BYREF$() keywords and has the
  same limitations, such as 8-byte numbers are not supported.

  HotBasic internal variable hbThis is associated with THIS syntax.  E.g.,
  THIS = abc results in two actions: (1) hbThis = OBJPTR(abc) and (2)
  code using this.SomeProperty will use MyUDT item offsets.

  THIS = NOTHING  'set THIS to undefined state

  If THIS is used for multiple UDT's, it is suggested that procedures
  using THIS to refer to a particular UDT be located after its TYPE ...
  END TYPE block and before the next TYPE ... END TYPE block.
  Alternatively, one can force a code block using this.SomeProperty to
  compile with proper offsets by preceding it with a THIS = 
  <name of any UDT instance> even where such statement is never executed
  at run-time.

  The Commander Keene download shows an example of THIS usage.

WITH {object or type name}

  WITH FPU: .load x: .load y: .mul: END WITH

  WITH may be used with destination values located first in a statement or
  preceding an "=" character.  That is, source values are not referenced using
  WITH syntax.


+ Penthouse (registered) version

Copyright 2003-2007 James J Keene PhD
Original Publication: Oct 8, 2003
