home *** CD-ROM | disk | FTP | other *** search
/ Falcon 030 Power 2 / F030_POWER2.iso / ST_STE / MAGS / ICTARI03.ARJ / ictari.03 / GFA / TUTORIAL / GFA3.TXT < prev    next >
Text File  |  1989-07-29  |  38KB  |  761 lines

  1.      Subject: GFA Tutorial, Month One
  2.           By: James Collett (Professor)
  3.  A Member Of: VIRTUAL INFINITY
  4.        Email: s6005146@oxpoly.ac.uk (or s6005146@brookes.ac.uk)
  5.      Address: Room N4, L.S.C.Collage, Wheatley, Oxford, OX9 1HX
  6.  Mono accnt.: bcc
  7.  
  8.  
  9.  Introduction To Syntax And Structure
  10.  ====================================
  11.     In the same way 'human' or natural languages have syntax & structure, 
  12.  computer  languages  do too;  and natural language  syntax  &  structure 
  13.  provide a good analogy for computer languages:
  14.     Syntax is far more than just saying sentences must contain words  and 
  15.  sentences  must  start with capital letters.   It is a complete  set  of 
  16.  rules,  in theory unambiguous,  which can be used to determine whether a 
  17.  sentence  is valid or not.   For example "The built a was tamer  fortune 
  18.  blaze  by lazy." contains words and starts with a capital but would  not 
  19.  be considered a valid sentence!   An example of simple syntax rule would 
  20.  be sentences may consist of 'determiner + adjective + noun':  "The brown 
  21.  fox."
  22.     In a similar way that syntax varies from natural language to  natural 
  23.  language (e.g.  English and French), syntax also varies between computer 
  24.  languages (e.g.  GFA Basic and C++).  If we want a particular program to 
  25.  work, we must ensure the syntax is correct.
  26.  
  27.     In  the natural language called English,  structure is the  way  that 
  28.  sentences  are fitted together into paragraphs,  and  paragraphs  fitted 
  29.  together with a heading at the top/etc to form documents, letters, etc.
  30.     (Both  syntax  and structure will be discussed in  more  detail  this 
  31.  month.)
  32.  
  33.  
  34.  Variables
  35.  =========
  36.     Throughout this tutorial I will try to indicate instructions with  an 
  37.  asterisk (*) to distinguish them from information.
  38.  
  39. *   From low res, load GFA Basic and press <escape> for direct mode:
  40.     A  very  important aspect in programming is being able to  store  and 
  41.  manipulate  numbers and text.   Places where data is stored  are  called 
  42.  variables but can be thought of as 'draws',  where each draw has a label 
  43.  and a contents.  You can think of GFA Basic having an infinite number of 
  44.  draws  (it`s not quite,  but it`s a hell of a lot!) and when  you  first 
  45.  load the language all these draws are unlabelled and empty.
  46.     To label a draw, for example age, and put an age in it type:
  47.  
  48. * age%=19
  49.  
  50.     To label a new draw, for example surname, and put a name in it type:
  51.  
  52. * surname$="Professor"
  53.  
  54.     Note that integer (whole number) variables (or 'numerical draws') are 
  55.  identified with a percentage sign and string variables (or 'text draws') 
  56.  are identified with a 'dollar sign',  which is also called string.  I.e. 
  57.  you  would  pronounce  these two variables 'age  percent'  and  'surname 
  58.  string'.
  59.     Note also that strings must be enclosed in double quotes ("), this is 
  60.  not part of the string but indicates where it starts and finishes.
  61.     Two simple commands used to manipulate variables are PRINT and INPUT, 
  62.  note that commands do not have to be entered into GFA in  capitals,  but 
  63.  throughout this tutorial I will try to put them in capitals to  identify 
  64.  that they are commands.
  65.     PRINT  is used to output to the screen,  to find out the contents  of 
  66.  the variables (or 'draws') type:
  67.  
  68. * PRINT age%
  69. * PRINT surname$
  70.  
  71.     INPUT is used to input, from the keyboard, a value (number) or string 
  72.  into a variable.  Try:
  73.  
  74. * INPUT age%
  75. * INPUT new_value%
  76.  
  77.     GFA should prompt for a number in each case.   After  entering,  type 
  78.  the following, followed by your name at the prompt:
  79.  
  80. * INPUT surname$
  81.  
  82.     Note  that when you put your age into age% the previous contents  are 
  83.  completely destroyed; similarly for surname$.  Check this out by typing:
  84.  
  85. * PRINT age%
  86. * PRINT surname$
  87. * PRINT new_value%
  88.  
  89.     PRINT  can  also be used directly with values and strings  (text)  as 
  90.  well as with variables ('draw' labels).
  91.     Typing  long  commands  every time can be  very  laborious  and  most 
  92.  commands have abbreviations or short hand versions.  The abbreviation of 
  93.  PRINT is simply ?.  Try some of the following, using both PRINT and ?:
  94.  
  95. * ? 7
  96. * ? 7-2
  97. * ? age%+14
  98. * ? "Hi there!!"
  99. * ? "Hi there "+surname$+"!!"
  100. * ? age%+new_value%+2
  101.  
  102.     As well as using plus (+) to return results to screen, it can also be 
  103.  used to store results as variables.  Try this:
  104.  
  105. * new_value%=age%+3
  106. * ? new_value%
  107.  
  108. * age%=age%+1
  109. * PRINT age%
  110.  
  111. * surname$="Hello "+surname$
  112. * ? surname$
  113.  
  114.     Note  that + has a different purpose depending on whether being  used 
  115.  with strings or numbers.   If you try and use it with a mixture of  both 
  116.  then  you will get an error - i.e.  GFA syntax rules have  been  broken!  
  117.  Instead you must use a semicolon (;) as follows:
  118.  
  119. * ? surname$;" is ";age%;" years old"
  120. * ? surname$;" will be ";age%+1;" next year"
  121.  
  122.     You can also use minus (-) to subtract,  asterisk (*) to multiply and 
  123.  slash  (/) to divide numbers,  although obviously not  strings!   So  in 
  124.  summary:
  125.  
  126.         Strings = Use  +  to 'add' strings, to screen or a variable
  127.  
  128.         Integers = Use  + - * /  to manipulate, to screen or a variable
  129.  
  130.         Both = Use  ;  to 'mix' strings and integers, to screen only
  131.  
  132.  
  133.     Before  we write our first program,  note what happens if you try  to 
  134.  put a string in an integer variable (or integer 'draw'), and vise-versa:
  135.  
  136. * surname$=19
  137. * age%="Professor"
  138.  
  139.     Note  also what happens if you try to put a real number (number  with 
  140.  decimal point) into an integer:
  141.  
  142. * new_value%=-6.54321
  143. * PRINT new_value%
  144.  
  145.  
  146.  Our First Program
  147.  =================
  148.     Another note just before we write our first GFA program:  if you have 
  149.  just started programming (maybe today!) I hope you can appreciate,  when 
  150.  you  start  looking  at any sources,  you will come  across  things  you 
  151.  haven`t learned yet and have to take as true or trust the programmer.
  152.     I  think  it  is important to show some demo sources  as  quickly  as 
  153.  possible, thus there maybe one or two lines you`ll just have to trust me 
  154.  on for the minute!
  155.  
  156. *   Press <escape> to return to the editor and Merge VARIAB_1.LST:
  157.     Before  we  Run (execute) the set of instructions  lets  manually  go 
  158.  through  them  (or  'dry-run' them).   First of all a  message  will  be 
  159.  displayed  asking for a name and then INPUT surname$ from the  keyboard. 
  160.  After  getting  age% (presumably in years),  it is multiplied by  12  to 
  161.  convert into months.   The program then greets the person,  and  informs 
  162.  them of their age (now in months!) before ending.   Note that the  first 
  163.  two output lines end with a semicolon but the last output line  doesn`t; 
  164.  if  no  semicolon  is  present  on the end of  a  PRINT  then  GFA  will 
  165.  automatically start a new line (i.e.  LF+CR), if you wish to continue on 
  166.  the same line then you must include a semicolon.
  167.  
  168. *   Run  the program by either pressing the appropriate function  key  or 
  169.  clicking on the appropriate menu button.   Enter a name and age of  your 
  170.  choice.   If you don`t trust the output (why not?!?) then, after ending, 
  171.  goto the direct mode,  check the result by multiplying the input age  by 
  172.  12 and return to the editor.   Note that the 'run screen',  at the point 
  173.  when execution stopped, appears as the 'backdrop' on direct mode.
  174. *   Re-run the program a few times,  try to predict what you would expect 
  175.  to happen if you input a number for the name or string for the age.  Try 
  176.  also inputing negative numbers or real (decimal) numbers as the age.
  177.     This program is very simple,  but not bad for a first effort!   Let`s 
  178.  try improving things:
  179.  
  180. *   From the editor Merge VARIAB_2.LST:
  181.     DO NOT RUN THIS - IT WILL NOT WORK!   Note that Merge [which loads an 
  182.  ASCII  source] doesn`t wipe the previous contents.   The  advantage  (or 
  183.  disadvantage!)  of  Load [which loads a 'tokenised' source] is  it  does 
  184.  wipe the previous contents and starts from scratch.   The reason we have 
  185.  to use Merge,  as already discussed, is to make this tutorial compatible 
  186.  with all versions of GFA.
  187.  
  188. *   From the editor select New to start from scratch, confirm your action 
  189.  and now Merge VARIAB_2.LST:
  190.     I`ve added to this source an initial clear screen,  then scraped  the 
  191.  PRINTs  and  included user-defined prompts with  the  INPUTs.   The  GFA 
  192.  default  prompt is a question mark (?).   Note a comma is  necessary  to 
  193.  separate the optional prompt and variable.   Next is the fastest method, 
  194.  in GFA, to multiply a variable by a value: MUL var,n is about 30% faster 
  195.  than  var=var*n.   There are similar commands to ADD,  SUB and DIV  (all 
  196.  will be dealt with in detail later).
  197.     Moving  to  the  output,  after  the CHR$  you`ll  notice  I`ve  used 
  198.  semicolons instead of plus`s to allow 'mixing' of strings and numbers in 
  199.  a single PRINT statement.   CHR$,  again to be discussed later,  returns 
  200.  (displays) the character of a given ASCII value.  For example to display 
  201.  an "A", which has ASCII 65, type the following in the direct mode:
  202.  
  203. * ? CHR$(65)
  204. * ? CHR$(7)
  205.  
  206.     ASCII  10 is LF and leaves a gap on screen.   ASCII 7 (above) is  BEL 
  207.  and sounds the ST`s bell.
  208.     I personally do not like the standard GFA END command,  which  brings 
  209.  up the horrible alert box, and prefer to "finish off" myself by beeping, 
  210.  waiting  for a key press (INP(2)) and returning directly to the  editor. 
  211.  It`s  a matter of personal preference and you may wish to  beep,  flash, 
  212.  print  "Program Terminated" or a whole host of other things to  indicate 
  213.  your  own programs have reached their normal ends.   As well as END  and 
  214.  EDIT,  there  is  also a STOP command which displays an  alert  box  and 
  215.  returns  to  direct  mode,  STOP does also allow  you  to  continue  (if 
  216.  possible - i.e. stopped in middle) which is occasionally useful.
  217.     Note  in  GFA  3 VOID can be abbreviated to ~.   Thus  I  finish  the 
  218.  majority of my GFA 3 programs with:
  219.  
  220.   PRINT CHR$(7);
  221.   ~INP(2)
  222.   EDIT
  223.  
  224.     VOID  (discussed  later)  is mainly  used  with  numerical  functions 
  225.  (discussed  later) to mean you wish to execute or perform a  calculation 
  226.  but not hold the returned result.   Sounds strange but very useful,  for 
  227.  example wait for key press but not care which key is pressed.
  228.  
  229.  
  230.  Comments And Annotation
  231.  =======================
  232. *   From the editor select New, confirm and Merge COMMENTS.LST:    
  233.     It is often useful, especially with more complex pieces of source, to 
  234.  add  comments  (or remarks) and to annotate  lines.   GFA  provides  the 
  235.  single quota (') for an entire line comment and explanation mark (!) for 
  236.  annotation on,  and after,  a line to be executed.   The text after  the 
  237.  marker will be ignored during execution and can break every syntax  rule 
  238.  in the book!   The convention,  however, is to high-light with asterisks 
  239.  but this depends on your personal preference.
  240.  
  241.  
  242.  Variable Types 
  243.  ==============
  244.     As  well  as being able to store and manipulate  strings  (text)  and 
  245.  integers  (whole numbers),  GFA can also (hopefully  obviously!)  handle 
  246.  real  numbers.   In the same way integers and strings  are  respectfully 
  247.  identified with a percentage sign and string (dollar) sign, real numbers 
  248.  are identified with ... no sign!  In summary:
  249.  
  250.         var$ = string (text) variable, contents marked with quotes (") 
  251.                 when assigned to variable
  252.  
  253.         var% = 32 bit integer variable, range approx -2 billion to +2 
  254.                 billion
  255.         
  256.         var = real number, range VERY BIG and VERY ACCURATE
  257.  
  258.     The advantage of using integer over real, where real is not required, 
  259.  is that of speed - integers are faster that real numbers,  but can  only 
  260.  be  used  if no decimal is needed (e.g.  a counter,  discussed  in  more 
  261.  detail this month).
  262.     GFA  3  also offers 16 bit integer (word) and 8  bit  integer  (byte) 
  263.  variables,  which  are  even  FASTER than a standard  integer  but  with 
  264.  reduced ranges,  as follows.  During this tutorial I shall stick with 32 
  265.  bit integers (long-words) so it is GFA 2 compatible:
  266.  
  267.         var& = 16 bit integer variable, range -32768 to +32767
  268.  
  269.         var| = 8 bit integer variable, range only 0 to 255
  270.  
  271.  
  272.  Boolean Expressions - Introduction To Decision Making
  273.  =====================================================
  274.     Another important concept in programming is that of  branching,  i.e. 
  275.  coming  to a 'junction' and either going one way or the other - no  buts 
  276.  or maybies!
  277.     A boolean expression is one that is either TRUE or FALSE, for example 
  278.  either age% is 99 or it`s not 99, either surname$ is "smith" or it`s not 
  279.  "smith" - no buts or maybies.   Considering numbers for the  moment,  as 
  280.  well as testing if a variable or value is identical to another,  you can 
  281.  also test:
  282.  
  283.         >   greater than
  284.         <   less than
  285.         >=  greater than or equal to
  286.         <=  less that or equal to
  287.         <>  greater or less than (i.e. not equal to)
  288.  
  289. *   Goto direct mode and type CLS to clear screen if required:
  290.     In GFA,  TRUE has the value (or 'is represented by') -1 and FALSE has 
  291.  the value 0.   Try some of the following and try to predict the returned 
  292.  result (note they don`t have to be entered in capitals):
  293.  
  294. * ? TRUE                    *  PRINT 7>7
  295. * ? FALSE                   *  ? 7>=7
  296. * ? 2=2                     *  ? (3+1)=(2*2)
  297. * ? 2=5                     *  ? 9<=(3+4)
  298. * ? 2<>5                    *  ? (9<=(3+4))=FALSE
  299. * ? 2<5
  300.  
  301.     (As  well as testing if a string is identical to another,  there  are 
  302.  other 'string tests', to be discussed in detail next month.)
  303.     In GFA, to branch a way dependant on the 'truth' of an expression, we 
  304.  use IF ... ENDIF and IF .. ELSE .. ENDIF.
  305.  
  306. *   Return to the editor and have a look at BRANCH_1.LST and BRANCH_2.LST 
  307.  (don`t forget to New before you Merge!)
  308.  
  309.     As well as simple tests (e.g. <> or >=), combinations of tests can be 
  310.  made using the logic gates:  AND,  XOR (exclusive or), OR (and/xor) plus 
  311.  NOT;  for example age%<99 AND NOT(surname$="smith").   I am not going to 
  312.  cover  the  complete set of 'truths' for all gates  (called  the  'truth 
  313.  tables')  because  they are even more boring than this  tutorial  (which 
  314.  does  improve  next  month!) and are  fairly  straight  forward  anyway.  
  315. *However,  I  have included a sample source,  BRANCH_3.LST,  and a  truth 
  316.  table source, TRUTABLE.LST, to have a look at.
  317.     You  can  use  the  latter if you need the  table  for  a  particular 
  318.  expression, and it is set up for '(NOT P) AND Q' where P and Q represent 
  319.  simple  tests such as age%<99 or surname$="smith".   After covering  FOR 
  320.  and  NEXT  (this  month) you`ll be able to add  or  remove  simple  test 
  321.  representatives as required.
  322.  
  323.     Note  in  GFA  3 an ELSE and IF can compress  onto  one  line  (shown 
  324.  right),  thus meaning the second ENDIF and second indent are not needed.  
  325.  During  this  tutorial I shall stick with the GFA  2  compatible  method 
  326.  (shown left):
  327.  
  328.   ELSE
  329.     IF value%<10                    ELSE IF value%<10
  330.       PRINT "Number ~~~~              PRINT "Number ~~~~
  331.     ELSE                            ELSE
  332.       PRINT "Number ~~~~              PRINT "Number ~~~~
  333.     ENDIF                           ENDIF 
  334.   ENDIF
  335.  
  336.  
  337.  Looping - Introduction And FOR ... NEXT Loop
  338.  ============================================
  339.     It is often necessary in programs to repeat a particular part a fixed 
  340.  number of times,  repeat while a condition (boolean expression) is  TRUE 
  341.  or  even repeat until one is TRUE.   One way of doing this could  be  to 
  342.  laboriously  enter  the  part of the  source  500  times!   The  serious 
  343.  solution is to use a loop,  i.e.  to tell GFA to 'loop' around the  part 
  344.  either  a  fixed  number of times or in  collaboration  with  a  boolean 
  345.  condition.   GFA  Basic  actually  offers no fewer  than  four  'looping 
  346.  mechanisms' which allow solutions to be found to any problem where it is 
  347.  necessary (or might be necessary) to repeat part of a program:
  348.  
  349.     The first and simplest loop,  called the FOR ...  NEXT loop,  uses  a 
  350.  counter to repeat the part a fixed number of times - which could be once 
  351.  or a million times.
  352. *   From a 'clean' editor Merge, look at and Run FORNXT_1.LST:
  353.     The loop can be thought of as building a 'table', in this case from 1 
  354.  to  5 (the maximum count),  and each time the loop is executed the  next 
  355.  slot  in  the table is 'ticked off'.   This isn`t quite  how  it  works, 
  356.  inside the processor,  but a good way to think for a simple loop.   Note 
  357.  the value of the counter when you leave the loop, after final execution.
  358. *   Look at and Run FORNXT_2.LST, preferably in low res:
  359.     It  may  be necessary to use a far more complex  count  mechanism  or 
  360.  'STEP' than just 1, 2, 3.  For example 0.2, 0.4, 0.6 (STEP 0.2) or -0.5, 
  361.  -1.0, -1.5 (STEP -0.5).  This source is a perfect demonstration of this, 
  362.  which uses the PLOT command to draw a circle point by point using sine & 
  363.  cosine  waves  [note this mathematical source can be replaced  with  one 
  364.  line;  sine,  cosine,  PLOT  and  graphics will be discussed  in  detail 
  365.  starting next month].  Note also that speed and angle (theta) need to be 
  366.  real,  the  radius(`s) and origin only need to be round to whole  number 
  367.  though.
  368. *   Try  experimenting  with  the parameters  (or  'control  variables'), 
  369.  now discussed in general:    
  370.  
  371.  
  372.  Parameters
  373.  ==========
  374.     [Going off at a tangent for a few minutes (and nothing directly to do 
  375.  with looping!) a brief word about parameters.]
  376.     Parameters  (also  called  operands)  can  be  best  thought  of   as 
  377.  'switches' or,  as I said before,  'control variables'.  In the same way 
  378.  your  TV/monitor  has a stack of knobs on it  (no  innuendoes  please!), 
  379.  anything from a single line or routine upto a procedure (discussed  this 
  380.  month) or complete program can have 'knobs'.   For example the parameter 
  381.  of the line PRINT "Hello" is "Hello" and the parameters of ADD c%,4  are 
  382.  c% and 4.
  383.     If,  in  a routine or program,  you have a size/etc that is  constant 
  384.  (e.g.  4)  then  you  could put 4 everywhere you need it  or  you  could 
  385.  declare size% as 4 and put that everywhere.   If you needed to change it 
  386.  for some reason,  is it easier to change one size% or to search  through 
  387.  the  entire  source and change all 4`s,  hoping you don`t miss  any  and 
  388.  don`t change any 4`s which aren`t the size??
  389.     Listing  all  variable parameters together,  towards the top  of  the 
  390.  program, saves you writing a complex user interface in your utilities at 
  391.  all  and  in  final programs until the actual  'guts'  are  written  and 
  392.  tested.  (I never put proper user interfaces on my utilities - no need!)
  393.     The  use  of  (constant)  parameters in  programs  will  become  more 
  394.  apparent with the use of more complex sources.
  395. *   Experiment with FORNXT_2.LST`s parameters.
  396.  
  397.  
  398.  Looping - Continued
  399.  ===================
  400. *   From a 'clean' editor Merge, look at and Run FORNXT_3.LST:
  401.     Returning  to  the  FOR ...  NEXT loop,  GFA  also  offers  a  DOWNTO 
  402.  facility,  which  is the equivalent to STEP -1 and cannot be  used  with 
  403.  other STEPs.  Therefore in summary:
  404.  
  405.         If you need STEP -1 then use DOWNTO,
  406.         If you need STEP 1 then use TO (without a STEP, 1 is default),
  407.     And if you need any other STEP then use TO with a STEP
  408.  
  409.  ...  obviously  making  sure you get the mincount and  maxcount  in  the 
  410.  correct order whichever version you use!
  411.     Note the value of the counter when you leave the DOWNTO  loop,  after 
  412.  final execution.
  413.  
  414. *   Look  back at TRUTABLE.LST,  mentioned above in Boolean  Expressions.  
  415.  Figure  out  how  the  nested (i.e.  one  inside  another)  loops  work, 
  416.  remembering  the  values of TRUE and FALSE (and not  forgetting  to  New 
  417.  before Merging.)
  418.  
  419.  
  420.     The  next two loops are the REPEAT ...  UNTIL loop and the WHILE  ... 
  421.  WEND  (endwhile)  loop,   which  respectfully  REPEAT  UNTIL  a  boolean 
  422.  condition is TRUE and repeat WHILE one is TRUE (i.e.  until it`s FALSE).  
  423.  These are excellent for any situation where you`re waiting for something 
  424.  to  happen  or  waiting for something to  stop  happening,  for  example 
  425.  waiting for a valid input:
  426. *   Look at and Run WHILE.LST:
  427.     Typical use of a WHILE loop to repeat input until the variable  stops 
  428.  being invalid.  (Note LEN returns the length of a string, functions will 
  429.  be discussed next month.)
  430. *   New, Merge, look at and Run REPEAT_1.LST:
  431.     Note  this  collects  the key  press  (test%)  from  INP(2),  another 
  432.  function,  instead of VOIDing or 'ignoring' it as seen in cases so  far.  
  433.  This loop REPEATs UNTIL test% is ASCII 120, i.e. "x".
  434.     The main difference between REPEAT ...  UNTIL and WHILE ...  WEND is, 
  435.  as can be seen, the positioning of the boolean test to determine whether 
  436.  to go around the loop again (or at all).   In the REPEAT ... UNTIL loop, 
  437.  as  the test is at the end you will always go around the loop  once;  if 
  438.  this isn`t wanted then the loop must be nested inside (placed inside) an 
  439.  IF ...  ENDIF.   In the WHILE ... WEND loop, as the test is at the start 
  440.  the loop will never be executed if it tests FALSE when you first hit the 
  441.  loop;  for example,  in WHILE.LST, you enter a valid name/age first time 
  442.  before the loop.
  443.  
  444.  
  445.     The final 'loop mechanism' which GFA offers, and many other languages 
  446.  don`t,  is  the  DO ...  LOOP loop.   The primary use of this is  as  an 
  447.  infinite loop,  i.e.  once you get in it`s impossible to get out without 
  448.  taking  fatal  measures!   Sounds strange but useful  for  both  testing 
  449.  unfinished programs and final programs with no exit (e.g. game or demo).
  450. *   After Merging, look at and Run DOLOOP_1.LST:
  451.     Once Run, don`t press reset!  The way to break out of any GFA program 
  452.  that  appears  to  have  crashed or gone into an  infinite  loop  is  to 
  453.  simultaneously  hold  down CTRL,  ALT and SHIFT.  (If this fails  for  a 
  454.  crashed  GFA program then do reset!) [Note this break facility does  not 
  455.  work with the compiler (discussed later).]
  456.     In GFA 3 you can also use DO ...  LOOP as a REPEAT ... UNTIL, a WHILE 
  457.  ... WEND, or even a combination of these two:
  458.     Unfortunately  this is GFA 3 only.   If you`re using version  3  then 
  459.  LOAD DOLOOP_2.GFA,  otherwise LOAD DOLOOP_1.BAS.  Note when you Load you 
  460.  don`t have to New first. Load and Save are the conventional way to store 
  461.  and re-call files, Merge and SaveA are conventionally used for appending 
  462.  (merging) and for 'inter-compatibility'.   To GFA 2 users:  DOLOOP_1.BAS 
  463.  is the same as DOLOOP_1.LST,  but I couldn`t not let you try Load!   And 
  464.  if  you want to see what your missing you`ll just have to get a copy  of 
  465.  GFA 3!
  466.     To   users   with  GFA  3:   DOLOOP_2.GFA  uses  two   boolean   test 
  467.  representatives,  P and Q, to show a combination of REPEAT ... UNTIL and 
  468.  WHILE  ...  WEND.   Note,  if doing this combination,  the tests can  be 
  469.  identical or can be different.   In this example, 'P' determines whether 
  470.  the loop is executed the first time and 'P AND NOT(Q)' is the determiner 
  471.  after that.
  472.  
  473.  
  474.  Building Other Loop Combinations
  475.  ================================
  476.     GFA  Basic also has an EXIT IF command which can be attached  to  any 
  477.  loop,  including an 'infinite' DO ... LOOP in GFA 2.  It is bad practice 
  478.  to use this and should be avoided whenever possible, but allows an 'EXIT 
  479.  IF boolean condition' to be added to DO ... LOOPs and FOR ... NEXTs plus 
  480.  extra control to be added to REPEAT ... UNTILs and WHILE ... WENDs.
  481. *   Merge, look at and Run FORNXT_4.LST:
  482.     After  placing  120  (ASCII  of "x") into  key%  and  displaying  the 
  483.  instructions,  this  source goes into a STEPped -1 FOR  ...  NEXT  loop, 
  484.  which  counts  down the number of attempts left to hit  the  right  key, 
  485.  using EXIT to 'jump' out the loop should key% be pressed before attempt% 
  486.  runs out.   If the loop is left 'properly' then attempt% will have  'run 
  487.  out' (i.e.  become 0);  otherwise,  by pressing the EXIT key%,  attempt% 
  488.  will be left 'hanging'.
  489.     This source shows one way of combining a FOR ...  NEXT and REPEAT ... 
  490.  UNTIL.
  491. *   Merge, look at and Run REPEAT_2.LST:
  492.     This does exactly the same job as the previous, but by using a REPEAT 
  493.  UNTIL  and  combining  attributes from FOR  ...  NEXT,  it  handles  the 
  494.  attempt% counter better.
  495.  
  496.     There are *several* methods, even in GFA 2 and without an EXIT IF, to 
  497.  combine all three mechanisms into one basic loop should it be necessary.
  498.  
  499.  
  500.  Introduction To Arrays
  501.  ======================
  502.     Moving  on,  an array is simply a table of variables all of the  same 
  503.  type (e.g. all strings or all reals). 
  504. *   Goto direct mode and type CLS to clear screen if required:
  505.     'Paper  tables'  or  'manual tables'  (e.g.  timetable)  can  be  one 
  506.  dimensional  (i.e.  just  have  one column or one row) and  can  be  two 
  507.  dimensional (i.e. have both rows and columns).  In the same way, for the 
  508.  moment, computerised arrays can be one dimensional or two dimensional.
  509.     To  create  a  new  one dimension (one  column)  array  with  6  rows 
  510.  (numbered 0 to 5) type the following (remembering commands don`t need to 
  511.  be entered in capitals):
  512.  
  513. * DIM value%(5)
  514.  
  515.     To  display  the contents of the first 'box' on the table  ('box'  0) 
  516.  simply type the following, the value 0 should be returned:
  517.  
  518. * PRINT value%(0)
  519.  
  520.     [[NOTE  that some versions,  as far as I know GFA 3 only,  return  an 
  521.  "array  index  to large" error.   If this has happened to you  it`s  not 
  522.  because of my tutorial but a minor bug with Direct mode.  To fix the bug 
  523.  simply return to the editor, New to clear, type 'DIM correct%(0)' in the 
  524.  editor,  Run this line,  return to direct mode,  re-type 'DIM value%(5)' 
  525.  and continue from there.   Please remember even a language as superb  as 
  526.  GFA can only be 99% perfect!]]
  527.  
  528.     Note the contents of all 'boxes' in a new array are initially 0.   To 
  529.  change  the  contents  of the sixth 'box' ('box'  5),  use  one  of  the 
  530.  following just like 'normal' variables:
  531.  
  532. * value%(5)=22
  533. * INPUT value%(5)
  534.  
  535.     Array  elements  (or  array 'boxes') can be treated  just  any  other 
  536.  variables.  Try some of the following, predict what`s happening:
  537.  
  538. * value%(0)=3
  539. * value%(1)=8
  540. * ? value%(0)<value%(1)
  541.  
  542. * INPUT value%(2)
  543. * ? value%(1)+value%(2)
  544. * ? value%(0)*value%(2)
  545.  
  546.     Note, as with variables, when you put a new value into an element the 
  547.  previous  contents are destroyed.   Note also that GFA  starts  counting 
  548.  rows (and columns) from 0.   Therefore if you had a one dimension  array 
  549.  with its last element labelled 9, it has 10 elements in total.
  550.  
  551.     To create a new two dimension array with 3 rows (numbered 0 to 2) and 
  552.  3 columns (0 to 2, thus 9 elements total) type:
  553.  
  554. * DIM text$(2,2)
  555.  
  556.     Once again this can be treated as a stack of string  variables.   Try 
  557.  the following,  once making the comparison between column 0,  row 0  and 
  558.  column 2, row 1 TRUE and once making the result FALSE:
  559.  
  560. * text$(0,0)="professor"
  561. * INPUT text$(2,1)
  562. * ? text$(0,0)=text$(2,1)
  563.  
  564.     Note what happens if you try to access an element ('box') outside the 
  565.  defined table`s range or size:
  566.  
  567. * ? text$(3,4)
  568.  
  569.     (The use and application of arrays will become apparent this month.)
  570.     Computerised arrays,  unlike 'manual tables',  are not restricted  to 
  571.  the  2-D  nature of paper and can have three,  four,  a  dosen  or  more 
  572.  dimensions if necessary.  Here is an example of a 4-D array,  which is 3 
  573.  by 2 by 4 by 3:
  574.  
  575. * DIM array(2,1,3,2)
  576.  
  577.     This meaningless,  'applicationless' array could be used to store and 
  578.  manipulate 72 (i.e. 3*2*4*3) real numbers.
  579.  
  580.  
  581.  Applications Of Arrays (One)
  582.  ============================
  583.     Arrays  are potentially useful whenever you have lists or  tables  of 
  584.  variables of the same type.
  585. *   Return  to  the editor.   Merge and look at  ARRAY_1.LST,  a  trivial 
  586.  example  of  array application.   By this stage you should  be  able  to 
  587.  follow  an understand a GFA source of this complexity  without  Running, 
  588.  using only comments and annotation as aid.
  589. *   After 'dry-running' (i.e.  manually going through the source), Run it 
  590.  for real.  Experiment with the program parameters and source.
  591.  
  592.     (I shall be returning to array application again this month.)
  593.  
  594.  
  595.  Procedures
  596.  ==========
  597.     Often in programs,  it is useful or necessary to use the same routine 
  598.  several  times,  at different points.   Procedures not only allow  this, 
  599.  without needing multiple or repeated copies of routines,  but also allow 
  600.  programmers  to  manage  and structure their  sources  during  creation, 
  601.  testing and implementation.
  602.     A  procedure  is a set of  collective  instructions,  which  normally 
  603.  perform  a single simple task,  to which you give a label.   Humans  use 
  604.  'procedures'  as  well  as computer languages,  and  such  'human  brain 
  605.  procedures'  might  be  called (labelled) "getting  up  in  a  morning", 
  606.  "making  a  cup of tea" or "reacting to a fire alarm" - i.e.  a  set  of 
  607.  instructions which perform a single task.   In the same way that  'human 
  608.  procedures' can be executed (or 'called'),  a GFA program can call (i.e. 
  609.  execute) a procedure.
  610.  
  611. *   Procedure  syntax varies slightly between GFA 2 and  GFA  3.   Either 
  612.  Load PROCED_1.BAS or PROCED_1.GFA, depending on your version (noting you 
  613.  don`t have to New), and look at the source:
  614.     The main program calls (i.e.  runs) a procedure to get all the drinks 
  615.  and  then another procedure to display the  drinks.   Get_all_drinks  in 
  616.  turn repeatedly calls a procedure to get a single drink,  which  RETURNs 
  617.  to  get_all_drinks,  and that RETURNs to the main program after all  the 
  618.  drinks have been entered.   After the last procedure,  i.e. show_drinks, 
  619.  has  finished execution it RETURNs to the main program,  from which  you 
  620.  finish.
  621.     In both GFA 2 and 3,  all procedures are listed,  in any order, after 
  622.  the end of the main program and are conventionally separated with  gaps.  
  623.  The syntactical difference is in the calling:  in GFA 3 you just use the 
  624.  procedure label, but in GFA 2 this must be preceded by an 'at' sign (@).
  625.     Procedures  not only make sources easier to follow,  but  also  allow 
  626.  programs  to be broken down into sections which allows easy testing  and 
  627.  debugging.
  628.  
  629.     As well as using procedures to do *very* specific tasks,  it is  also 
  630.  possible to write more 'general' procedures or procedures which still do 
  631.  one task but offer some freedom in specification.   This is achieved  by 
  632.  'giving' the procedure a set of specification when you call it,  whether 
  633.  from  the main program or another procedure;  or what`s  called  passing 
  634.  parameters  [i.e.  procedure  'control values' - slightly  different  to 
  635.  program 'control values'].
  636. *   The following source in based on FORNXT_2.LST, if necessary look back 
  637.  at this source first.
  638. *   Preferably  in  low res,  either Load  PROCED_2.BAS  or  PROCED_2.GFA 
  639.  depending on your GFA version, and look at the source before Running it:
  640.     This   uses  procedure  oval  to  draw  a  single  ellipse   to   any 
  641.  specification (i.e.  to any origin & radius`s), as seen in FORNXT_2.LST.  
  642.  It  is called oval so as not to conflict with GFA`s own ELLIPSE  command 
  643.  (to be discussed later along with sine, cosine and PLOT).
  644.     (Local and global variables will be discussed in a moment).  The main 
  645.  program  initially fixes the speed,  and then repeatedly calls  oval  in 
  646.  order to draw the face.
  647.  
  648.     The angle (theta) is *only* used in oval and not used anywhere  else.  
  649.  It  is often useful to indicate such variables as LOCAL to a  procedure, 
  650.  as oppose to the default: global to the *entire* program (i.e. both main 
  651.  program and all procedures).
  652.  
  653.  
  654.  Local And Global Variables - A Proper Explanation
  655.  =================================================
  656.     LOCALising  variables  also  allows several programmers  to  work  on 
  657.  different parts of the same application or program - the LOCAL variables 
  658.  used in one procedure won`t interfere with variables used anywhere else.
  659.  
  660. *   From the editor Load PROCED_3, but don`t Run it yet:
  661.     You  can  also LOCAL an already global variable,  in which  case  the 
  662.  variable  will take one (LOCAL) value  inside the procedure and  another 
  663.  (global)  value  in the rest of the program.   This is quite  a  complex 
  664.  concept if you`ve never done it before,  so I shall go through this demo 
  665.  source (dry-run it) step by step:
  666.     First of all variable1,  an integer, is assigned the value 5.  Before 
  667.  calling  procedure one you are informed of this.   Procedure one  (after 
  668.  the main program) then declares variable1 LOCAL,  i.e.  its value inside 
  669.  this procedure does not effect its value anywhere else.  It is important 
  670.  to note all LOCAL variables,  when declared,  initially take the value 0 
  671.  until  assigned  another  value,  in this case  3.   After  leaving  the 
  672.  procedure  and  RETURNing to 'the top',  variable1 re-takes  its  global 
  673.  value,  in  this  case 5.   You are informed of this (and the  value  of 
  674.  variable2 - dealt with in a moment) before the program finishes.
  675. *   Run the program and check this does happen.
  676.  
  677. *   'Activate' the call to two, but don`t Run it yet:
  678.     Procedure  two also uses variable1,  but the global variable1 with  a 
  679.  value  of 5.   Its value is incremented to 6,  you are informed of  this 
  680.  both  before  leaving  this  procedure and when  RETURNed  to  the  main 
  681.  program.
  682. *   Re-Run the program and check procedure two.
  683.  
  684. *   'Activate' the call to three, once again dry-run before doing it 'for 
  685.  real':
  686.     As well as passing values to procedures, variables can also be passed 
  687.  to  procedures;  in  this case a new variable2,  which also must  be  an 
  688.  integer.   Note variable2 is local to this procedure, and if used in the 
  689.  rest of the program would maintain its global value on RETURNing.
  690. *   Re-Run and check the final procedure.
  691.     
  692.     Thus  if  you were to pass variable1 from the call,  and  get  passed 
  693.  variable1  (instead of variable2) in the procedure,  changing  variable1 
  694.  locally in the procedure does not effect the global value.
  695. *   Check this by modifying procedure three accordingly.
  696.  
  697.     Note  also  that  parameter  passing  and  localising  is  not   just 
  698.  restricted to integer variables and values,  reals and strings can  also 
  699.  be passed and localised in the same way.
  700.  
  701.  
  702.  Applications Of Arrays (Two)
  703.  ============================
  704.     1-D  and  2-D arrays can easily be  'visualised',  if  necessary,  by 
  705.  thinking of them as 'paper tables'.   The following example of array use 
  706.  shows  a  good  way of 'visualising' a 4-D  array  for  this  particular 
  707.  application.
  708.     Imagine you`re the owner of two hotels in London, one coded 'hotel 0' 
  709.  and other coded 'hotel 1'.   Each hotel has 5 floors (grounds, first ... 
  710.  fourth)  and each floor has 16 rooms (1 to 8 down the left corridor  and 
  711.  rooms  9  to 16 down the right corridor).   Thus you have 160  rooms  in 
  712.  total (i.e. 2 hotels * 5 floors * 2 corridors * 8 rooms).
  713.     A  very  simple  hotel  management system  (that  can`t  even  handle 
  714.  advanced bookings!)  may need the following three arrays:
  715.  
  716.   DIM surname$(1,4,1,7)
  717.   DIM arrive_date$(1,4,1,7)
  718.   DIM leave_date$(1,4,1,7)
  719.  
  720.     Note I would treat the arrival and departure dates,  for a particular 
  721.  person in a particular room,  as strings and of the form "ddmmyy".   For 
  722.  example  12th May would be "120593".   (Note extraction  of  information 
  723.  from strings and string <--> integer conversion is covered later.)
  724.     The first procedure you would need is one to book somebody in.  After 
  725.  a few months, with people constantly booking, and leaving, this database 
  726.  will  become 'untidy' or 'patchy'.   The book_in procedure will have  to 
  727.  search  through UNTIL it finds an empty room (OR finds both  hotels  are 
  728.  full).   After inputing and somehow validating both name and dates,  the 
  729.  procedure  can allocate the room to the person,  and also possibly  work 
  730.  out their bill.
  731.     The  other main procedure you would need is one to 'vacate the  room' 
  732.  in the database after the person has paid and is ready to leave.  If you 
  733.  didn`t know the room number and only knew the surname, the program would 
  734.  have to search through UNTIL it found a match for surname$().
  735.  
  736.     The procedures would then need linking using either a  command-driven 
  737.  or  menu-driven  system.   This  simple demo of  'visualising'  a  multi 
  738.  dimensional  array (for which I haven`t written a source) is *FAR*  from 
  739.  complete as a hotel system and leaves many problems such as how to  deal 
  740.  with advanced bookings or how to deal with several people with the  same 
  741.  surname.
  742.  
  743.  
  744.  And Finally
  745.  ===========
  746.     I have deliberately set this month`s tutorial at an elementary  level 
  747.  to  give anyone a nice,  gentle introduction to GFA.   I hope you  found 
  748.  some of it (if not most of it!) too easy.   Although I won`t actually be 
  749.  putting GFA through its paces until months 3 and 4,  I do intend to move 
  750.  onto more advanced stuff next month (including my game,  LightMaze!) and 
  751.  hopefully make the tutorial less 'wordy'.
  752.     I am not going to include a summary list of everything you should  be 
  753.  able  to do after going through this tutorial;  but have  included  both 
  754.  source and compiled, executable versions of a simple exam grade program, 
  755.  which includes most of what you should be able to do.
  756. *   Load,  look at and Run EXAMMARK.   Experiment with the source and add 
  757.  an expansion of your choice for next month`s tutorial.
  758.  
  759.  
  760.  ---END---
  761.