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 !
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:
will make yabasic execute your program and terminate if done. |
| 2. | You may start you yabasic without any
filename. Typing just
makes yabasic start and prompt for a program to
execute; after you have typed in your program, press |
| 3. | You may put your program into a file and
insert the following text as the very first line:
This is only an example and you should substitute for |
-h-help
or -? are accepted as well.
-fg foreground-color-bg background-color
-geometry geometry-string
+10+10),
but any window size will be ignored.-display Name-of-Display
-font Name-of-font-iw
contains f and e)
and can be one of: d nw e f The default infolevel is w.
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.
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. |
-h -help
or -? are accepted as well.
-geometry geometry-string
+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-fontdecorative, dontcare, modern, roman,
script, swiss -iw
contains f and e)
and can be one of: d nw e f The default infolevel is w.
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.
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:
Furthermore some general properties of yabasic should be noted:
Variables (with the exception of arrays) need not be declared, their initial values are "" (for string variables) and 0.0 (for numerical variables).
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.
This section demonstrates and explains the arithmetic functions of yabasic.
print sin(1.0),cos(pi),tan(3) print asin(0.5),acos(0.7) print atan(2),atan(1,2)
0.841471 -1 -0.142547 0.523599 0.795399 1.10715 0.463648
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:
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 !
Within the for-next-loop above the string-functions len() and mid$() are applied, but there are many more string functions:
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).
| 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 |
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.
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
open window 200,200 open printer circle 100,100,80 close printer close window
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
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.
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
| 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 |
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"
This behaviour is the same regardless of whether you read from a file (using input #1 a$) or from the terminal (using input a$).
Although yabasic is by no means designed as a scripting-language, it can interact with the Operating System in a limited way:
if (peek$("os")="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:
Datenträger in Laufwerk C: heißt WIN95
Seriennummer des Datenträgers: 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 (especially if you don't have a german installation of Windows).
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 type of operating system ("unix" or "windows"), the program employs the command peek$("os").
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").
To print the current date and time you may write:
print date$," ",time$
This gave me the following output (your output will be different of course, because the times they are changing):
5-08-28-1998-Fri-Aug 13-51-53-0
The date$-string has six fields: 5 is the day of the week (0-6, 0 is sunday, 6 saturday), 08 is the month (01-12), 28 is the day of the month (01-31), 1998 is the year, Fri is the name of the day and Aug is the name of the month.
The time$-string has four fields: 13 is the hour (00-23), 51 is the minute (00-59), 53 is the second (00-59) and 0 is the time, that has elapsed since the program started.
As most fields of date$ and time$ (except the last field within time$) are fixed length, it is easy to extract fields with the mid$-function.
peek and poke are an interface to some of yabasics internals and allow to query and change yabasics states and behaviour. Unlike early homecomputers, you can't peek and poke around anywhere in memory; just a view predefined variants are allowed. An example would be:
print peek$("infolevel")
poke "infolevel","diagnostic"
Which would print the current infolevel and change it to "diagnostic".
From this example you see: peek and poke accept string arguments (some poke-commands except an integer argument too) and peek may return a string (in this case it appears as peek$).
Anyway there are very few peek's and poke's right now, and they may be fully enumerated:
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.
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:
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:
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.
+,-,*,/,^ ? @ : #
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: date$ 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$() ltrim$()
M: max() mid$() min() mod()
N: next not
O: on gosub on goto open open printer open window or
P: pause peek peek$ pi poke print print at print # printer
Q:
R: ran() read rem restore return reverse right$() rtrim$()
S: sin() step sqrt() str$() system() system$()
T: tan() text then time$ to
U: upper$()
V: val()
W: wait window
X:
Y:
Z:
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
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.
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 !
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.
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.
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.