
                yabasic, yet another basic for Unix and Windows
                                       
Current Version: 2.20

   This document describes the syntax and features of yabasic.
   
   In short, yabasic implements the most common (and simple) elements of
   the basic-language, plus some graphic facilities; anyone, who has ever
   written basic-programs on a C64 should feel at home.
   
   This page covers all the features of yabasic, you don't need any other
   text to learn it. In fact, there is no other text about yabasic,
   neither a unix-man-page nor a Windows-helpfile.
   
   This text doesn't teach basic from scratch, it rather assumes some
   experience with the basic-programming-language.
   
   Special thanx to Michael Cwikel for editing this document !
   
     _________________________________________________________________
                                      
Table of contents

     * Yabasic under Unix
          + Usage
          + Options
          + Setting Defaults
     * Yabasic under Windows 95 and Windows NT
          + Usage
          + Options
          + Setting Defaults
     * Yabasic explained by examples
          + A simple Program with input and print
          + Arithmetic: Operators and Functions
          + Making decisions: The if-statement
          + Strings and loops
          + Graphics and printing
          + Data and Arrays
          + Files and more on input
          + Calling the Operating System
          + Fancy Printing
          + Loose Ends
     * Index
          + Index of Keywords
          + Index of Concepts
     * Yabasic background
     * Copyleft 
       
     _________________________________________________________________
                                      
                                     Unix
                                       
Starting

   There are three way to start yabasic:
   
   1. You may write your basic-program to a file (e.g. foo.yab) and call
   yabasic with this file as an argument:
   
     yabasic foo.yab
     
   will make yabasic execute your program and terminate if done.
   
   2. You may start you yabasic without any filename. Typing just
   
     yabasic
     
   makes yabasic start and prompt for a program to execute; after you
   have typed in your program, press RETURN twice and yabasic will
   execute your commands. This behavior allows yabasic to be used as some
   sort of fancy desktop calculator.
   
   3. You may put your program into a file and insert the following text
   as the very first line:
   
     #!/usr/bin/yabasic
     
   This is only an example and you should substitute for /usr/bin/yabasic
   the full pathname of yabasic on your computer. Yabasic will treat the
   line starting with #! as a comment, but Unix will invoke yabasic to
   execute this program.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Options

   -h
          Prints out a short help message; -help or -? are accepted as
          well.
          
   -fg foreground-color
          Sets the foreground color for graphics. The usual X colornames
          like red, green are accepted.
          
   -bg background-color 
          Sets the background color.
          
   -geometry geometry-string 
          The usual X geometry-string will work (e.g. +10+10), but any
          window size will be ignored.
          
   -display Name-of-Display 
          Name of the Display, where the window should appear.
          
   -font Name-of-font
          Name of the font, which will be used for graphics text.
          
   -i
          Sets the initial infolevel. This controls the amount of
          information one gets about the progress of program execution,
          Every level contains all lower levels (e.g. w contains f and e)
          and can be one of:
          
        d 
                Set the infolevel to diagnostic : This gives detailed
                debugging information; much more output than you'd
                probably like to read.
                
        n
                note : Useful information; e.g. about execution time and
                memory consumption.
                
        w
                warning : Gives you warnings, that something has gone
                wrong (e.g. division by zero); nevertheless execution
                proceeds.
                
        e
                error : A serious error (e.g. an array boundary
                violation) has occurred, stopping the program.
                
        f
                fatal : Something has gone wrong and cannot be fixed; the
                interpreter exits immediately. This happens most often in
                the course of an arithmetic fault (floating point
                exception) but can also be a sign of an internal error
                within yabasic.
                
          The default infolevel is w.
          
   -licence
          This makes yabasic print out its copyleft; have a look and you
          will see, that almost anything is allowed.
          
   
          
   Back to table of contents ...
          
     _________________________________________________________________
                                      
Setting defaults

   The colors, text-font and the window position should be set on the
   command-line , or specified in the users resource file (this is
   usually the file .Xresources in your home-directory); e.g.:
   
  yabasic*foreground: blue
  yabasic*background: gold
  yabasic*geometry: +10+10
  yabasic*font: 9x15

   This sets the foreground of the graphics-window to blue, the
   background to gold, the window will appear at position 10,10 and the
   text-font will be 9x15.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
                           Windows 95 and Windows NT
                                       
Usage

   After you have run the setup program, yabasic can be invoked in three
   ways:
   
   1. Choose "yabasic" within the start-menu: Yabasic will come up with a
   console window and will wait for a program to be typed in directly.
   2. Click with the right mousebutton on your desktop. Choose "new"
   within the context-menu that appears; this will yield a new icon on
   your desktop. This icons context-menu has the two entries "execute"
   and "edit"; a double-click executes the program.
   3. Create a file containing your yabasic-program. This file should
   have the extension ".yab". Double-click on this file then invokes
   yabasic, to execute your program.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Options

   -h 
          Prints out a short help message; -help or -? are accepted as
          well.
          
   -geometry geometry-string
          E.g. +20+10 will place the graphic-window 10 pixels below and
          20 pixels left of the upper left corner of the screen.
          
   -font Name-of-font
          Name of the font which will be used for graphics text. Can be
          any of:
          decorative, dontcare, modern, roman, script, swiss
          You can append (without space) a fontsize to any of these
          identifiers, i.e. swiss30 chooses a swiss font, 30 pixels high.
          
   -i
          Sets the initial infolevel. This controls the amount of
          information one gets about the progress of program execution,
          Every level contains all lower levels (e.g. w contains f and e)
          and can be one of:
          
        d 
                Set the inoflevel to diagnostic : This gives detailed
                debugging information; much more output than you'd
                probably like to read.
                
        n
                note : Useful information; e.g. about execution time and
                memory consumption.
                
        w
                warning : Gives you warnings, that something has gone
                wrong (e.g. division by zero); nevertheless execution
                proceeds.
                
        e
                error : A serious error (e.g. an array boundary
                violation) has occurred, stopping the program.
                
        f
                fatal : Something has gone wrong and cannot be fixed; the
                interpreter exits immediately. This happens most often in
                the course of an arithmetic fault (floating point
                exception) but can also be a sign of an internal error
                within yabasic.
                
          The default infolevel is w.
          
   -licence
          This makes yabasic print out its copyleft; have a look and you
          will see, that almost anything is allowed.
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Setting defaults

   To choose the default-values for graphic-font, fontsize and window
   position, you have to edit the registry.
   
   Yabasic stores its defaults under:
   
     HKEY_LOCAL_MACHINE/SOFTWARE/Yabasic
     
   You may edit the subkeys "font" and "geometry"; these subkeys accept
   the same values as the corresponding command line options -font and
   -geometry. Command line options take precedence over registry
   defaults.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
                         Yabasic explained by examples
                                       
A simple Program

   This is the first example:
   
REM this is the first yabasic-program
input "Enter two numbers:" a,b
print a,"+",b,"=",a+b
print "Please enter your Name:";
INPUT a$
print "Hello ",a$," !"

   This program produces the following output (user input is displayed
   like this):
   
Enter two numbers: 2 3
2+3=5
Please enter your Name: Bill
Hello Bill !

   This simple program contains three different commands:
   
   REM
          The REM-statement introduces comments; everything after REM up
          to the end of the line is ignored.
          
   input
          This statement reads one or more variables from the user. The
          optional prompt-string after the input-statement ("Enter a
          number:") is printed on the terminal prior to reading any
          input. Note that there is no semicolon after this
          prompt-string. To learn more about, how input chops a line into
          pieces you may refer to the section More on Input. To learn,
          how to read input from the keyboard without delay, check out
          Getting a key from the keyboard.
          
   print
          The print-statement writes all its arguments to the screen;
          after writing its last argument, print goes to the next line
          (as in print "Hello ",a$," !"); to avoid this automatic
          newline, place a colon after the last argument (as in print
          "Please enter your Name:";). Note that print can be abbreviated
          with a single question mark (?). If you want to print (or
          input) at a specific location, you may go to the section
          Prining on your Screen.
          
   Furthermore some general properties of yabasic should be noted:
   
   Case
          Commands can be entered in any case: input is the same as INPUT
          and even as InPUt. This applies to every command in yabasic but
          not to variables, i.e. a$ and A$ are different variables.
          
   Variables
          Variable names are case sensitive (i.e. types of variables: a$
          and A$ are different) and can be of any length. There are two
          sorts of variables:
          
   
        String variables
                e.g. a$, b12$ or VeryLongName$ may contain strings of any
                length. String variables always have a Dollar-sign ($) as
                the last character of their names.
                
        Numerical variables
                e.g. a, c3po or ThisIsAnEvenLongerName contain real
                numbers like 2, -1.3, 15.3e44 or 0.
                
          Variables (with the exception of arrays) need not be declared,
          their initial values are "" (for string variables) and 0.0 (for
          numerical variables).
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Arithmetic

  Operators
  
   Yabasic has five arithmetic operators: + (addition), - (subtraction),
   * (multiplication), / (division) and ^ (power); they all behave as
   expected, i.e. this line of code
   
print 1+2,2*3,4/2,2^3

   produces this line of output:
   
3 6 2 8

   Note that the power operator (^) handles fractional powers: 8^(1/3)
   gives 2 as a result.
   
  Functions
  
   This section demonstrates and explains the arithmetic functions of
   yabasic.
   
   Trigonometric functions:
          There are 6 trigonometric functions:
          
        
print sin(1.0),cos(pi),tan(3)
print asin(0.5),acos(0.7)
print atan(2),atan(1,2)

          
          These lines produce this output:
          
        
0.841471 -1 -0.142547
0.523599 0.795399
1.10715 0.463648

          
          As you can see yabasic can calculate sine, cosine, tangent and
          their inverses. And, if you have an eye for trigonometry, you
          may have noticed that all these functions expect their argument
          in radians; to facilitate the transformation from degrees to
          radians (radian=degree*pi/180), there is a predefined variable
          named pi (or PI) which has an initial value of 3.14159.
          
   
          Finally note that the atan()-function comes in two flavors:
          Called with a single argument (e.g. atan(2)) atan()returns a
          value between -pi/2 ... +pi/2. Called with two arguments (e.g.
          atan(2,-1)) atan() returns a value between -pi and +pi; (This
          can be useful e.g. when transforming from cartesian to polar
          coordinates).
          
   Exponentiation:
          The exp() functions comes with its inverse. the log()-function:
          
          print exp(1),log(2),log(euler) 
          log() and exp() operate with the base e (=2.17828), which comes
          as a predefined variable named euler. Knowing this you won't be
          surprised to get the following output:
          2.71828 0.693147 1
          
   Integer and fractional parts:
          The functions int() and frac() split their argument at the
          decimal point:
          print int(2.34),frac(2.34) produces: 2 0.34
          
   Remainder
          To get the remainder of a division employ the mod()-function;
          e.g. mod(11,4) produces 3, because when dividing 11 by 4 you
          get 2 and a remainder of 3.
          
   Minimum and Maximum:
          Return the lower and higher value of their two arguments:
          print min(2,3),max(2,3) gives: 2 3
          
   The square root:
          is calculated by the sqrt()-function: print sqrt(2) gives
          1.41421
          
   Random numbers:
          are returned by the ran()-function; this function comes in two
          flavours: Called without arguments (e.g. print ran()) you will
          get a random number between 0 and 1. Called with a single
          argument (e.g. print ran(2)) you will get a random number
          between 0 and the supplied argument.
          The ran()-function of yabasic uses the ran()-function of the C
          standard library, so you had better not expect too much
          randomness ...
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Making decisions: The if-statement

   To make decisions you have to use the if-statement:
   
input "Please enter a number" a
if (a>10) then
  print "Hello":print "Your number is bigger than 10"
else
  print "Byebye":print "Your number is less or equal 10"
endif

   As you can see, the condition has to be enclosed in parentheses (...).
   The else-part of the if-statement is optional and can be omitted, as
   in this example:
   
input "Please enter a number" a
if a>10 and a<20 then :  rem  parantheses are optional ...<
  print "bigger than 10":print "but less than 20"
fi

   Note that endif can be written as fi too.
   
   Next, have a look at the condition (a>10 and a<20)of the if-statement:
   
   Conditions:
          Numbers or arithmetic expressions can be compared with the
          usual relational operators: = (equal), <> (not equal), < (less
          than), <= (less or equal), > (greater than) and >= (greater or
          equal).
          Strings can be compared with just the same set of operators,
          where characters are ordered according to the ascii-charset;
          e.g. ("a"<"b") is true (because "a" precedes "b" within the
          ascii-charset) and likewise ("a"="b") is false.
          More than one comparison can be combined with parentheses ()
          and these keywords: or, and, not; Note that not precedes and,
          which in turn precedes or (in the same way as * precedes +
          within arithmetic expressions).
          Finally, the enclosing parantheses can be omitted, i.e. if a<10
          then ... is a valid statement.
          
   Multiple commands on one line
          Note that more than one command can appear on one line, as in 
          print "bigger than 10":print "but less than 20"
          as long as you separate them with colons (:).
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Strings and loops

   Basic has always been simple and strong in string-processing; and
   yabasic also tries to continue in this tradition:
   
input "Please enter a word" a$
for a=len(a$) to 1 step -1:print mid$(a$,a,1);:next a
print " is ",a$," reversed !"

   If you try this program, you will get this output:
   
Please enter a word: hello
olleh is hello reversed !

   for-next-loop
          The heart of the above program is the for-loop: everything from
          for to next is repeated, while the variable (a) goes from its
          initial value len(a$) to its final value 1. As you might have
          anticipated, len(a$) returns the length of its string-argument.
          Note the step-clause: the number after step (here: -1) is added
          to a after every repetition; in the example the step-clause
          makes a go down with every iteration. If you omit the
          step-clause, step 1 is assumed.
          
   Within the for-next-loop above the string-functions len() and mid$()
   are applied, but there are many more string functions:
   
   Getting pieces out of a string:
          There are three functions which give back parts of a string:
          a$="123456"
          print left$(a$,2),"-",mid$(a$,2,3),"-",right$(a$,3)
          gives you the following output:
          12-234-456
          As you see left$() cuts off as many characters as specified by
          its second argument from the left of your string. right$() cuts
          from the right, and mid$() cuts in the middle, where the first
          argument is the starting point and the second one is the length
          of the string to be cut out.
          Furthermore mid$() and its friends can even be used to
          selectively change parts of a string:
          a$="123456":left$(a$,2)="abcd":print a$
          results in
          ab3456
          As you see only the two leftmost characters are changed (even
          though the string "abcd" contains four characters); the same
          can be done with mid$() or right$().
          
   strings to numbers (and reverse):
          The function str$()converts its numeric argument to a string:
          print str$(12) gives the string "12" as a result. The
          formatting of the number can be influenced by an optional
          second argument:
          print str$(12.123455,"%08.5f") returns the string 12.12346. The
          second argument is essentially a format-string as used by the
          printf()-function within the C-language, some examples:
          Print-statement
          
          Output produced 
          
 print "==",str$(12.123455,"%08.3f"),"==" 

 ==0012.123== 

 print "==",str$(12.123455,"%8.2f"),"==" 

 ==   12.12== 

 print "==",str$(12.123455,"%-6.2f"),"==" 

 ==12.12 == 

          Further information can be found in any textbook on the
          C-language.
          
          Just the opposite is done by the function val(): print
          2+val("23") gives 25 as a result, whereas print val("e2")
          delivers 0 (because "e2" is not a valid number).
          
   The ascii-charset:
          yabasic offers two functions to work with the ascii-charset.
          asc() gives you a specific ascii-character: print asc("e")
          gives 101 as a result, because the character "e" has position
          101 within the ascii-charset. Likewise the function chr$()
          returns the ascii-char for a given position within the charset,
          e.g. chr$(98) returns "b".
          
   Escape-sequences
          Nevertheless you won't use chr$() as often as you might think,
          because the most important nonprintable characters can be
          constructed using escape-sequences with the \-character: You
          might use \n instead of chr$(10) wherever you want to use the
          newline-character.
          The following table lists all escape sequences of yabasic (of
          course, these are just the sequences known within the
          C-language):
          
          Escape-sequence Resulting Char
          \n newline
          \t tabulator
          \v vertical tabulator
          \b backspace
          \r carriage return
          \f formfeed
          \a alert
          \\ backslash
          \` single quote
          \" double quote
          
          These escape sequences are replaced within every pair of
          doublequotes (""), i.e. within literal strings; user input read
          with the input-statement is not affected in any way.
          Finally note, that escape sequences have a profound impact,
          when specifying Window-pathnames.
          
          
   Here is another example which introduces the rest of yabasic's
   string-functions:
   
   
label loop
  print "Please enter a string containing the word \"yabasic\""
  input a$
if (instr(lower$(a$),"yabasic")<>0) then
  gosub thanx
else
  print "No, please try again !"
endif
goto loop

label thanx
  print "Thanks a lot !"
return

   If you run this program you will receive the following output:
   
   
Please enter a string containing the word "yabasic"
?thequickbrownfox
No, please try again !
Please enter a string containing the word "yabasic"
?jumpedyabasicoverthelazydog
Thanx.

   Marking locations in a program
          The first line in the example-program (label loop) is a label:
          As yabasic has no line-numbers, you need labels to mark a
          specific location within your program. You can compose labels
          out of letters and digits; the keyword label is required and
          the label itself should be unique within your program. Note
          that yabasic allows for line numbers too.
          
   Jumping around in your program
          A label by itself causes no special action. Only in conjunction
          with the goto-statement (or gosub or restore) does a label have
          any function. If yabasic encounters a goto-statement (here:
          goto loop) then it searches for the matching label (here: label
          loop) and proceeds to execute at the position of the label.
          Note that you can even leave (and enter !) a for-next loop with
          goto.
          
          Closely related to the goto-command is the gosub-command; if
          yabasic encounters a gosub-statement then it searches for the
          matching label (label thanx in the example) and proceeds with
          execution at the position of the label, until it finds a
          return-statement. return makes yabasic return to the position
          of the original gosub and proceed from there.
          
          Note that both goto and gosub can be used as on goto and on
          gosub.
          
   Finding strings in strings
          The example program above checks whether the user input
          contains the string "yabasic"; this is done with the help of
          the instr()-function; instr() gives back the position of its
          second string-argument within the first or zero, if it can't be
          found. E.g. instr("Hallo","al") gives back 2, because "al"
          appears at position 2 within "Hallo"; whereas
          instr("Hallo","Al") returns 0, because "Al" is not contained in
          "Hallo" (the case doesn't match).
          
   Changing the case of strings
          The sample-program contains some further string-functions:
          lower$() and its counterpart upper$() convert their
          string-argument to all lower or all upper case characters
          respectively, i.e. lower$("aBcD12fG") gives back "abcd12fg".
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Graphics and printing

   Yabasic provides some functions for simple graphics:
   
open window 400,400
line 0,0 to 400,400
circle 200,200,150
dot 200,200
a$=inkey$
clear window
text 100,200,"Hello !"
print "Press a key to close the window"
inkey$
close window

   Drawing
          If you run this program, you will see a window with size of 400
          pixels in x- and y-direction (the window size is given along
          with the open window-statement). Not surprising: The
          line-command draws a line, the circle-command draws a circle
          (the arguments determine x- and y-position of the center and
          the radius of the circle) and the dot-command draws a single
          dot at the specified location.
          
          After the user has pressed a key (see the next paragraph) the
          window contents is cleared with the clear window-statement.
          Afterwards the text-statement writes its text at the specified
          position.
          
          Finally close window closes the graphics-window.
          
   Getting a key from the keyboard
          But before the window is closed, the inkey$-statement waits,
          until the user presses any key and returns this key as a
          string. In this example the key, which is actually pressed is
          not important, so you may just write inkey$ (without
          assignment). Unlike other versions of basic, yabasic's inkey$
          waits until the user presses a key, so that you will never
          receive an empty string. Many nonprintable keys (e.g. the
          function or cursor keys) are returned as strings: up, down,
          left, right, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12,
          esc, ins, del, home, end, scrnup, scrndown, enter, tab,
          backspace, ctrl-w, ctrl-e, ctrl-r, ctrl-t, ctrl-u, ctrl-o,
          ctrl-p, ctrl-a, ctrl-d, ctrl-f, ctrl-g, ctrl-h, ctrl-j, ctrl-k,
          ctrl-l, ctrl-y, ctrl-x, ctrl-v, ctrl-b, ctrl-n. If your
          keyboard gives other keycodes than mine, or if you press a key,
          which is unknown to yabasic, you will receive a rather lengthy
          string (e.g. key1b5b31317e).
          
   Printing
          Getting a hardcopy of your graphics involves two new commands:
          
open window 200,200
open printer
circle 100,100,80
close printer
close window

   
          Everything between open printer and close printer appears on
          paper. If you prefer sending your hardcopy to a file, you may
          add a filename, e.g. open printer "foo" sends the output to the
          file foo. Note that the open printer statement has to appear
          after the window has been opened. close printer can be omitted;
          it is done automatically, if the window is closed.
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Data and Arrays

   Now and then the need arises to supply a program with initial data.
   The next sample-program converts numbers to strings:
   
restore names
read maxnum
dim names$(maxnum)
for a=1 to maxnum:read names$(a):next a
label loop
  input "Please enter a number: " number:number=int(number)
  if (number>=1 and number<=maxnum) then
    print number,"=",names$(number)
    goto loop
  endif
print "Sorry, can't convert ",number

label names
data 9,"one","two","three","four","five","six"
data "seven","eight","nine"

   If you run this program, it goes like this:
   
Please enter a number: 2
2=two
Please enter a number: 3
3=three
Please enter a number: 8
8=eight
Please enter a number: 12
Sorry, can't convert 12

   Reading Data
          As you see this program just converts numbers to their textual
          representation; for this purpose, it needs to know the numbers
          from 1 to 9 as text. This information is stored in the
          data-lines at the bottom of the program: With the read-command
          the program gets one piece of data after the other.
          If you want to deviate from the linear ordering while reading
          the data-statements, you may use the restore-statement: In the
          example above restore names makes sure, that the next
          read-statement reads its data after the label names.
          
   Arrays
          In the example above the words "one" ... "nine" are stored
          within a string-array names$(). You may use arrays to process
          large quantities of data. There are numerical arrays as well as
          a string-arrays, but both sorts of arrays need to be declared
          prior to their first use; this is necessary, because yabasic
          needs to know, how much memory has to be reserved for the
          array. The example uses dim names$(maxnum) to declare a string
          array, another example would be dim numbers(200) to create a
          numerical array with 200 elements.
          More complex tasks may even require multidimensional arrays
          with more than one index: dim matrix(10,10) defines a two
          dimensional array. Array-dimension can be up to ten, if needed.
          
   It should be mentioned, that the functionality of the above
   sample-program can be achieved by using totally different
   language-constructs:
   
label loop
  input "Please enter a number: " number:number=int(number)
  on number+1 gosub sorry,one,two,three,four,five,sorry
goto loop
label sorry:print "Sorry, can't convert ",number:end
label one:print "1=one":return
label two:print "2=two":return
label three:print "3=three":return
label four:print "4=four":return
label five:print "5=five":return

   This program produces the same output as the example above.
   
   on gosub, on goto
          The heart of this sample is the on gosub-statement, which is
          followed by a list of labels (sorry,one,two,...). Depending on
          the value of the expression (number+1) the corresponding label
          in the list is chosen: E.g. if number+1 gives 3, the third
          label (three) is selected and a gosub to this label is
          performed.
          A gosub is always performed, regardless of the value of the
          expression. More specifically, if number+1 gives anything less
          or equal to 1, then the first label (sorry) is chosen; if
          number+1 gives anything greater or equal to the number of
          elements in the list (which is 7 in the example), then the last
          label (sorry) is chosen. Therefore the label sorry is chosen
          whenever the program can't convert the given number.
          
          Finally, note that the on-construct can be used as on goto too.
          
   End of your program
          Another new appearance in the above sample is the
          end-statement, which ends your program immediately.
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Files and more on input

   To understand the examples in this section, let us assume that a file
   named test.dat exists in the current directory and that it contains
   the following three lines:
   
one two three
four five
six seven eight nine

   The next example opens that file and prints out its content:
   
open 1,"test.dat","r"
label loop
if (eof(1)) then end fi
input #1 a$,b$
print "a$=\"",a$,"\", b$=\"",b$,"\""
goto loop

   Opening a file
          The first thing to do if you want to use a file is to open it:
          open 1,"test.dat","r" opens the file test.dat and gives it the
          file number 1. This file number is used to refer to the file
          later on (e.g. input #1). File numbers can range from #1 to #9,
          the hash is traditionally required. The optional third argument
          ("r") of the open-statement gives the filemode; depending on
          whether you want to open a file for reading or writing you
          should choose a different mode. Filemodes are borrowed from the
          C-language; here are the possible choices:
          Filemode Result
          "r" Open file for reading, start reading at the beginning of
          the file
          "w" Open file for writing, overwrite old contents
          "a" Append to an existing file for writing or open a new one if
          no file with the specified name exists
          
          If you are done with a file, you should close it, making the
          file number available for another open-statement.
          
   Specifying Window-pathnames
          Be careful, when specifying an absolute pathname:
          "C:\yabasic\test.dat" is not a valid pathname, because the
          sequence "\t" within this string is interpreted as an escape
          sequence, and will be translated into the Tab-character. To
          avoid problems like these, you should always double your
          backslashes like "C:\\yabasic\\test.dat", because "\\" is an
          escape sequence and translated into "\".
          
   Reading and Writings
          You can write to file just the same way as you would write to
          your screen; the only difference is the file number, that comes
          with the print-statement: print #1 "Hello" writes the string
          "Hello" to the file with file number #1; note that there is no
          comma between the file number (#1) and the text to be written
          ("Hello"). Reading works the same way: input #1 a$, reads the
          variable a$ from the file with file number #1.
          
   Back to our sample program. If your run it, you will get the following
   output:
   
a$="one", b$="two three"
a$="four", b$="five"
a$="six", b$="seven eight nine"

   End of File
          As you can see, the program loops until the file has been fully
          read; this is achieved by means of the end-of-file-function
          eof(1), which returns false, if there are more characters in
          the file, whose file number is given as an argument, and
          returns true if the end of the file has been reached.
          
   More on input
          You may already have been wondering about how the three lines
          of test.dat are distributed among the variables of the
          input-statement; There are three rules:
          
          + Every input-statement reads exactly one line; (e.g. "one two
            three")
          + The contents of this line is chopped into words separated by
            spaces or tabs; in the example the line consists of three
            words: "one", "two", "three"
          + Every variable gets one word, except for the last one, which
            receives all of what is left of the line: a$ receives "one"
            and b$ (which is the last variable of the input-statement)
            receives the rest of the line, i.e. "two three". As a special
            case of these rules, if the input-statement contains just one
            variable (e.g. input #1 a$) this variable receives the whole
            line unmodified.
            
          This behaviour is the same regardless of whether you read from
          a file (using input #1 a$) or from the terminal (using input
          a$).
          
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Calling the Operating System

   Although yabasic is by no means designed as a scripting-language, it
   can interact with the Operating System in a limited way:
   
if (yabos$="unix") then
  command$="ls"
else
  command$="dir /w"
endif
cont$=system$(command$)
print "This is the contents of the current directory:"
print cont$
print len(cont$)," characters have been printed."

   The system$()-function is the heart of this program: It hands its
   argument over for execution to the shell of the underlying operating
   system; under Unix it is the bourne-shell sh and under Windows it is
   command.com, which will execute the argument of the system()-function.
   
   If I run this program under Windows95, I receive the following output:
   
This is the contents of the current directory:

 Datentrger in Laufwerk C: heit WIN95
 Seriennummer des Datentrgers: 0B1D-10F8
 Verzeichnis von C:\WINDOWS\Desktop

[.]             [..]            FLOPPY.LNK      EMACS.LNK       DRUCKER.LNK
T.YAB           TELNET.LNK      TEST.YAB        MICROS~1.LNK    CD.LNK
PLATTE.LNK      WATCOM~1.LNK    [YABDOK~1]      TEST.DAT        WINDOW~1.LNK
[KINO]
        12 Datei(en)                 2.693 Bytes
         4 Verzeichnis(se)     199.753.728 Bytes frei

456 characters have been printed.

   Of course, you may get something different on your system.
   
   As this yabasic-program runs under Unix, as well as under Windows, the
   argument of the system$()-function (command$) has to be chosen
   according to the operating system. To find out, what the operating
   system is, there is a predefined variable named yabos$, which either
   contains "unix" or "windows".
   
   Finally, there is a very similar command named system() (without a
   trailing $), which doesn't catch the output of the executed command,
   which instead goes directly to your terminal. system() returns a
   numerical value, which is generated by the executed command. If you
   don't care about this value, you can safely ignore it; e.g.
   system("dir") (without assignment) is just as valid as
   a=system("dir").
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Fancy Printing

   For interactive programs you might want to print output at specific
   locations. Try the next example:
   
clear screen
print at(10,5) "1 -- Setup"
print at(10,7) "2 -- Save"
print reverse at(10,9) "3 -- Quit"
input at(5,12) "Your choice: " a$

   If you run this program, you will get a screen resembling the
   following layout (note that the third line will be displayed in
   reverse video):
   
        1 -- Setup

        2 -- Save

        3 -- Quit      This line is displayed in reverse !


   Your choice:

   This is not a very fancy screen layout, but it might be enough for
   many tasks. Before you can do any such things, you have to call clear
   screen , which leaves your terminal blank.
   
   Afterwards, you may use the at()-clause in print or input-statements
   to move to any location (specified by the two arguments of the
   at()-clause) on your screen. Note that at() can be written as @() too.
   
   Since not all terminals have the same size (of course 80x25 is the
   most common size), you might want to know what are the actual
   dimensions of your screen; There are two predefined variables for this
   purpose: The width of your screen can be found in yabscreenwidth, its
   height in yabscreenheight; both variables have meaningful values only
   after the first call to clear screen.
   
   To emphasize a piece of text you may use the keyword reverse, which
   prints the line in reverse video.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Loose Ends

   Some properties of yabasic are still left to explain; here is a sample
   program, that employs them:
   
10 beep
  pause 1
goto 10

   This program beeps once every second:
   
     * beep does the beeping (can be written as bell too) and
     * pause does the waiting (can be written as wait too), its argument
       is the delay in seconds
       
   Finally, the program employs a line number (10) to mark a specific
   line; this feature makes yabasic more compatible with traditional
   basics. Line numbers are just special types of labels; they have the
   following properties:
   
     * Line numbers can appear only at the beginning of a line.
     * Not every line needs a number and line numbers need not be
       consecutive.
     * Line numbers can be used with the restore-statement too.
       
  Keyboard interrupts
  
   A feature you might need is the ability to suppress
   keyboard-interrupts (i.e. pressing of Ctrl-C); normally yabasic
   terminates immediately, if the user presses Ctrl-C. This can be
   suppressed like this:
   
on interrupt continue

   After processing of this statement keyboard interrupts are completely
   ignored. The default behaviour is restored with the command on
   interrupt break.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
                                     Index
                                       
Index of keywords

     +,-,*,/,^ ? @ : #
     
     A: acos() and asc() asin() at() atan()
     B: beep bell break
     C: chr$() circle clear screen clear window close close printer
     close window continue cos()
     D: data dim dot
     E: else end endif eof() euler exp()
     F: fi for frac()
     G: gosub goto
     H:
     I: if inkey$ input input at input # instr() int() interrupt
     J:
     K:
     L: label left$() len() line log() lower$()
     M: max() mid$() min() mod()
     N: next not
     O: on gosub on goto open open printer open window or
     P: pause pi print print at print # printer
     Q:
     R: ran() read rem restore return reverse right$()
     S: sin() step sqrt() str$() system() system$()
     T: tan() text then to
     U: upper$()
     V: val()
     W: wait window
     X:
     Y: yabos$ yabscreenheight yabscreenwidth
     Z:
     
   Back to table of contents ...
   
     _________________________________________________________________
                                      
Index of concepts

     Arrays
     Case of Keywords and Variables
     Conditions in the if-statement
     Escape Sequences within strings
     How the input-statement chops a line into pieces
     Keyboard interrupts
     Line numbers
     Multiple commands in one line
     Specifying Windows-pathnames
     Variables
     
   Back to table of contents ...
   
     _________________________________________________________________
                                      
                                   Internals
                                       
History

   I started off with yabasic sometime around eastern 1995; a first
   version was completed about one month later, still missing many
   features. After this quick start a long period of adding features and
   squashing bugs followed, which has more or less persisted until today.
   
   The only interruption during those peaceful days came in the summer of
   1996, when I got my Windows95-machine: Porting yabasic took two weeks
   and writing an installation program took me a month.
   
Flex and Bison

   You may have noticed from the previous section, that yabasic made
   quite a rapid start; this is mainly due to flex and bison, the prime
   tools, used to implement yabasic.
   
   Bison and flex take the grammar (written in a simple,
   Backus-Nauer-style notation) and produce a C-program, which implements
   this grammar. The only thing left to the programmer is to put flesh on
   this skeleton.
   
   This process is remarkably efficient: 17 KBytes of flex and bison
   instructions generate 129 KBytes of C-code, which has to be compared
   with the 108 KBytes of C-code which I wrote. Together these implement
   the functionality of yabasic. So actually most of the code has been
   generated by flex and bison !
   
Execution of a program

   Although yabasic behaves mostly like an interpreter, in fact it is
   not. Rather it's a compiler: If you give it any basic-code for
   execution, the code is compiled, yielding instructions for a simple
   stack-machine; these instructions are then interpreted immediately, so
   that you will never get in touch with the stack-machine. You can find
   out the time needed for this process if you invoke yabasic with
   infolevel set to note.
   
   Back to table of contents ...
   
     _________________________________________________________________
                                      
                                   Copyleft
                                       
   Yabasic is subject to the GNU copyleft, which (in a nutshell) gives
   you every freedom to use modify or redistribute this software, except
   the right to restrict other people's freedom. To get an idea of it I
   just reproduce the preamble of the GNU copyleft; the exact terms can
   be found in the file COPYING which comes along as part of the
   distribution, or can be obtained from the Free Software Foundation,
   Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   
Preamble

   The licenses for most software are designed to take away your freedom
   to share and change it. By contrast, the GNU General Public License is
   intended to guarantee your freedom to share and change free
   software--to make sure the software is free for all its users. This
   General Public License applies to most of the Free Software
   Foundation's software and to any other program whose authors commit to
   using it. (Some other Free Software Foundation software is covered by
   the GNU Library General Public License instead.) You can apply it to
   your programs, too.
   
   When we speak of free software, we are referring to freedom, not
   price. Our General Public Licenses are designed to make sure that you
   have the freedom to distribute copies of free software (and charge for
   this service if you wish), that you receive source code or can get it
   if you want it, that you can change the software or use pieces of it
   in new free programs; and that you know you can do these things.
   
   To protect your rights, we need to make restrictions that forbid
   anyone to deny you these rights or to ask you to surrender the rights.
   These restrictions translate to certain responsibilities for you if
   you distribute copies of the software, or if you modify it.
   
   For example, if you distribute copies of such a program, whether
   gratis or for a fee, you must give the recipients all the rights that
   you have. You must make sure that they, too, receive or can get the
   source code. And you must show them these terms so they know their
   rights.
   
   We protect your rights with two steps: (1) copyright the software, and
   (2) offer you this license which gives you legal permission to copy,
   distribute and/or modify the software.
   
   Also, for each author's protection and ours, we want to make certain
   that everyone understands that there is no warranty for this free
   software. If the software is modified by someone else and passed on,
   we want its recipients to know that what they have is not the
   original, so that any problems introduced by others will not reflect
   on the original authors' reputations.
   
   Finally, any free program is threatened constantly by software
   patents. We wish to avoid the danger that redistributors of a free
   program will individually obtain patent licenses, in effect making the
   program proprietary. To prevent this, we have made it clear that any
   patent must be licensed for everyone's free use or not licensed at
   all.
   
   Back to table of contents ...
