Yabasic
Yet
another Basic
for Unix and Windows
|
Version 2.53
|
This document describes the 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 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.
Unix
Invocation
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
this will make yabasic execute your program. |
2. |
You may start you
yabasic without any filename. Typing
yabasic
makes yabasic start and prompt for commands to execute;
after you have typed in your code, 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 this 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
Invocation
After you have run the setup program,
yabasic can be invoked in three ways:
1. |
Choose "yabasic"
from the start-menu: Yabasic will come up with a console
window and wait for a program to be typed in right away. |
2. |
Click with the right mousebutton
on your desktop. Choose "new"
from the context-menu that appears; this will create a
new icon on your desktop. The context-menu of this icon
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
- Absolut values and signum
- The abs() and
sig() functions return the absolute value and
the signum of their arguments:
print abs(-2.34),abs(2.34),sig(-2.34),sig(0),sig(2.34)
produces: 2.34 2.34 -1 0 1
- 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
- Square
root and square:
- The square root is calculated by sqrt(),
the square by sqr():
print sqrt(2),sqr(2) gives 1.41421 4
- Hexadecimal
numbers:
- To convert a decimal number to hex and
vice versa, use hex$() and dec():
print hex$(255)," is ",dec("ff")
gives ff is 255
- 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 "Your number is bigger than 10"
elsif (a>5) then
print "Your number is bigger than 5 but less or equal 10"
else
print "Your number is less or equal 5"
endif
As you can see, the condition has to be
enclosed in parentheses (...). The else and the elsif-part
of the if-statement are optional and can be
omitted, as in this example:
input "Please enter a number" a
if (a>10 and a<20) then
print "bigger than 10":print "but less than 20"
fi
Note that endif
can be written as fi too.
Just in case you want to write even less,
you may try:
input "Please enter a number" a
if (a>10 and a<20) print "bigger than 10 but less than 20"
Note, that then and endif
(or fi) have been omitted; on the other hand
only a single statement can be executed this way,
i.e. if (a>10 and a<20) print "bigger than 10":print
"but less than 20 (two print-statements) will not
produce what you might expect: The phrase "but less than 20"
is printed for any value of a.
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).
There are some other statements, which can be used within
a condition:
- you may use an open-statement as a condition to check,
if it has been successful.
- eof() checks, if a file contains more
input.
- glob$() checks, if its first
argument matches the pattern supplied as
the second argument.
- 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-loops
- 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. Finally note, that you can leave the for next
loop at any time by simple goto.
You may put the for-loop to some offbeat usage; e.g. for
a=1 to 100 step a:print a:next a prints the
powers off 2 up to 64.
- repeat-until-loop
and while-wend loop
- Of course this for-loop can be
reformulated as repeat-until or while-wend:
input "Please enter a word" a$
a=len(a$):repeat print mid$(a$,a,1);:a=a-1 until(a=0)
print " is ",a$," reversed !"
input "Please enter a word" a$
a=len(a$):while(a>0) print mid$(a$,a,1);:a=a-1 wend
print " is ",a$," reversed !"
- All these loops produce the same
result (as long as you input at least one character !).
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,"##.##") returns the
string 12.12. The second argument has
the same effect as the format of the print using statement.
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".
- Removing
spaces
- ltrim$() and rtrim$()
are two functions to remove leading or trailing spaces
from a string, e.g. ltrim$(" foo ") gives
"foo " and rtrim$(" foo
") gives " foo".
Finally, trim$() is the same as
rtrim$(ltrime$()).
- Splitting a string into tokens
- There are two handy function to split
a string into tokens; an example would be:
l$=" one two three "
label loop:print token$(l$):if (l$<>"") goto loop
- Running this program gives:
one
two
three
- Note, that token$()
automatically removes the tokens from a$.
If you supply a second argument (e.g. token$(a$,":;")),
the tokens are split at the characters given in the
second string.
Closely related with token$() is the
split$() function:
l$="::one::two:three::four"
repeat:print "Token: ",split$(l$,":"):until(l$="")
will produce this output:
Token:
Token:
Token: one
Token:
Token: two
Token: three
Token:
Token: four
- split$() focuses on
the separator (":" in the example) and gives
back one token for every occurence of the separator, even
if the token should be empty. token$()
on the other hand focuses on the tokens and may skip one
or more separators. It doesn't give back an empty token
as long as there are characters left in the string (l$ in
the example).
- Globbing
- glob$() checks, if
its first argument matches the pattern supplied as the
second argument. This second argument may contain the
special characters ? and *,
whereas ? matches any single character
and * matches zero or more arbitrary
characters. Glob can only be used within conditions (e.g.
after if, while or until)
as in if (glob$("Hallo","H*o"))
print "Matches !". Some examples:
glob-condition |
True/False ? |
glob("abcd","abc?") |
true |
glob("abab","*") |
true |
glob("abc","ab??") |
false |
glob("abcdabab","ab*ab") |
true |
glob("abcd","*a") |
false |
-
Back to table
of contents ...
Graphics
and printing
Yabasic provides some simple, general
purpose graphic-commands:
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 any 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).
To specify a certain font for the text within this window,
you may add a third argument, e.g. open window
400,400,"swiss".
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 below) the
window contents is cleared with the clear window-statement.
If you have your printer open (i.e. if you have issued
the open printer-command) clear
window finishes the current page, sends it to
the printer and starts a new one.
The next command in the example is the text-statement,
which writes its text at the specified position. Aligned
with this position is the left lower corner of the text.
To change the alignement, you can add as a third argument
a two character string; The first one specifies the
horizontal alignement and can be "l"
(text is left aligned), "r" (right
aligned) or "c" (centered);
the second character specifies the vertical alignement
and can be "t" (top of text is
aligned), "b" (bottom) or "c"
(center). Some valid arguments would be "ct",
"rb", "lc",
... By the way: Textalignement can also be changed by poking into "textalign".
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 (in the text
console or in the grafic window) 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). Some important 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. 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).
Normally yabasic's inkey$ waits until
the user presses a key; but if you want the inkey$-function
to return even if no key has been pressed, you may add a
timeout (in seconds) argument. E.g. inkey$(2)
returns immediately, if the user hits a key and after 2
seconds (returning an empty string) if not; note that a
timeout of 0 seconds is possible, which is the normal
behaviour of other basics.
If you press a mousebutton in the grafic
window, you will receive a string like "MB1d:0100,0200"
which stands for "Mouse Button 1 has gone down at x=100,
y=200"; likewise "MB2u:0300,0400"
stands for "Mouse Button 2 has gone up at x=300, y=400".
The functions mousex(), mousey()
and mouseb() can be used to extract the
details from the string returned by inkey$:
a$=inkey$:if (left$(a$,2)="MB") print
mousex(a$),mousey(a$),mouseb(a$)
If you omit the argument (e.g. print
mousex) you get the values of the last mouse-event
returned by inkey$. This means, that you
can not use mousex to track the position
of the mouse, because it's value is updated only if a
mousebutton is pressed or released. Finally mouseb
returns a positive value if the button has been pressed
and a negative value if the button has been released.
- 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 ...
Plotting
Yabasics grafic is rather simple: It does
not support color, nor animation; but it does
support plotting. Have a look at the following program, which
plots the sine function, complete with axis and errors:
open window 600,400
open printer
window origin "lb"
rectangle 10,10 to 590,390
map -pi,-1,pi,1 to 40,60,560,330
arrow map(-3.2,0) to map(3.2,0): rem this draws the x-axis
arrow map(0,-1.2) to map(0,1.2): rem this is the y-axis
for x=-3 to 3
if (x<>0) then xtick map(x,0),str$(x): rem these are ticks
if (x<3) then xtick map(x+0.5,0) fi
next x
ytick map(0,-1),"-1"
ytick map(0,1),"+1"
new curve
for x=-3 to 3 step 0.3: rem this loop actually draws the function
y=sin(x)
line to map(x,y)
marker map(x,y),"dot": rem mark the function points with "dots"
rem even plot some made-up errors
marker map(x,y),"err",ran(0.3),ran(0.5)
next x
map 0,0,100,4 to 400,250,590,320
box map(0,2) to map(90,4): rem draw the legend
marker map(10,3),"dot"
marker map(10,3),"err",0.5
text map(20,3),"Sine with errors","lc"
inkey$
close printer
close window
First thing you will notice: The program is
rather long; plotting with yabasic still requires a lot of code,
but at least there are some commands, which reduce the work;
these are explained below:
- window
origin "lb"
- In normal cases the coordinate origin
(i.e. the point 0,0) of any window lies in the upper left
corner; the command window origin can
move this origin to any of the four corners of a window.
The string argument ("lb" in the example)
consists of two chars; the first one can be "l"
(for left) or "r" (for right); the second char
can be "t" (for top) or "b" (for
bottom). This gives you a total of four variants "lb",
"lt", "rb" and "rt", which
correspond with the four corners of a window.
Once the origin has been moved, it applies to any grafic
operation whatsoever.
- rectangle
10,10 to 590,390
- This command simply draws a rectangle,
defined by any two opposite corners and clears the
interior. Closely related with rectangle
are two other commands: frame just draws
the outline of a rectangle, without clearing it's
interior. clear rect finally clears the
given rectangle, outline included; you may use this
command to clear a rectangular region of your window. You
may note that rect produces the same
results as clear rect followd by frame.
- map -pi,-1,pi,1
to 40,60,560,330 and map(10,3)
- The map-command comes
in two variants: The first one (map -pi,-1,pi,1
to 40,60,560,330 in the example) defines a
mapping, the second one (map(10,3) in
the example) may be used at any point,
where a coordinate pair is required (e.g. you may write dot
map(10,10) instead of dot 10,10).
map(x,y) transforms a coordinate pair,
depending on the previously defined mapping; As an
example: After map p1,q1,p2,q2 to x1,y1,x2,y2
the commands dot map(p1,q1) and dot
x1,y1 would draw the same point; also map(p2,q2)
and x2,y2 designate the same point. Any
intermediate point would be interpolated linearly.
As can be seen in the example, the map-command is used to
map the x and y-range (-1 ... +1 and -pi ... +pi in the
example) of a function to the part of the window reserved
for the plot. This mapping saves a lot of trivial
calculations.
Finally note, that there are two additional functions mapx()
and mapy(), both with a single argument,
which transform just one coordinate.
- arrow map(0,-1.2)
to map(0,1.2)
- The arrow-command
draws an arrow between the specified points; the example
employs the map(,)-function, but you
could just as well specify the coordiantes explicitly (e.g.
arrrow 10,10 to 100,100).
- xtick map(x,0),str$(x)
and ytick map(0,-1),"-1"
- The xtick (and ytick) function simply
draw a tick at the specified location (e.g. map(x,0)
or 100,100); if you add a string as a
third argument (str$(x) in the example),
the tick is drawn somewhat longer and the string is
written near its end.
- new
curve and line to map(x,y)
- These functions help to plot a curve
as a sequence of many lines. Let's look at an example: line
to 10,10:line to 100,100; the second
line to-command just draws a line from the point
specified in the first line to-command (i.e.
10,10) to the point specified in the command itself (i.e.
100,100); to add more line segments, you just have to
specify further line to-commands. If you
want to start with a new curve (i.e. a new sequence of
lines) just issue the new curve-command.
- marker
map(x,y),"dot"
- No surprise: The marker-command draws
one of six different markers. The third argument (counting
the map(x,y)-function as two arguments)
specifies, which marker to draw; you can draw "star"
(or "*"), "triangle" (or "tri"),
"square" (or "sq"), "cross"
(or "+"), "circle" (or "o")
and "error" (or "err", which draws a
vertical bar specifying an error).
Additionally you may specify the size of the marker as a
third argument; this would override the default size,
which is half the size of your font. An exception is the
"err" marker, where the third (and optionally
the fourth) argument specify the error of the value to
plot. I.e. if you want to plot a value 12±3 you would
use marker map(x,12),"err",3;
and if you have different positive and negative errors, e.g.
12+3-4, you may write marker map(x,12),"err",3,4.
Finally note, that any defined mapping is implicitly
applied to the last two arguments of the error-marker.
With these language elements it should be
possible to draw a variety of two dimensional plots with (hopefully
!) modest effort.
Back to table
of contents ...
Bitmaps
Yabasic allows to retrieve and change
rectangualr regions of the screen with simple commands:
open window 200,200
for a=0 to 200 step 10
line a,0 to a,200:line 0,a to 200,a: rem draw some pattern on the screen
next a
rem this is a picture of a star
star$="24,24:00c10000e10000f10000f10008f3"
star$=star$+"0008f30008f700fff700ffff30fff"
star$=star$+"fffefffffefffff0ffff70eff700e"
star$=star$+"ff000cff100eff300fff70cfff70e"
star$=star$+"f7ef1ef1cf3e700e3e100c3000000"
for a=50 to 150
saved$=bitblit$(a,150,a+24,150+24): rem save old content of window
bitblit star$ to a,150,"or": rem put star at new location
pause 0.1
bitblit saved$ to a,150: rem restore old window content
next a
This program moves a tiny star across the
window. Yabasic stores bitmaps within ordinary strings, e.g. the
star-bitmap is contained within the variable star$.
The bitblit$()-function returns such a
bitmap-string, if called with the coordinates of a rectangle; in
the example the line saved$=bitblit$(a,150,a+24,150+24)
stores the contents of a 24x24 rectangle with corners (a,150) and
(a+24,150+24) within the variable saved$.
Once you've got a bitmap-string you can put it on the window with
the bitblit-command. E.g. bitblit star$
to a,150,"or" puts the bitmap contained within
star$ onto the screen at position (a,150). The fourth, optional
argument ("or" in the example) specifies, how to
combine the pixels from the window with those from the bitmap:
Mode
|
Action
|
"and" |
The pixel is set, if both window
pixel and the bitmap pixel are set. |
"or" |
The pixel is set, if either the
window pixel or the bitmap pixel are set |
"replace" |
The pixel is set, if the bitmap
pixel is set. This is the default |
"xor" |
The pixel is set, if exactly one
of window and pitmap pixel is set |
"nand" |
The pixel is set, if not both
window pixel and bitmap pixel are set |
"clear" |
If the bitmap pixel is set, the
corrosponding window pixel is cleared |
"1" |
The window pixel is set, without
regarding the bitmap |
"0" |
The window pixel is cleared,
without regarding the bitmap |
If you omit the mode argument, the default
"replace" applies.
Having said all this, there is a big but: You
can put bitmaps on the window, but you can't
print them ! Hope this is not a real problem, because it would be
much work to make bitmaps print (at least under Unix !).
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. The exit
statements is quite similar in ending your program, but
you may add an argument (e.g. exit(2))
which will be returned to the underlying operating system.
Furthermore exit terminates you program
immediately, even if a grafic window is open.
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$
line input 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 |
-
- You may also try "rb",
"wb", "ab";
the character "b" stands for binary mode, which allows to open and read files
with non-text contents;
If you are done with a file, you should close
it, making the file number available for another open-statement.
There is a special variant of the open-statement,
which allows to check, if the statement has been
successful:
if (not open #1,"test.dat","r") print "Can't open the file !"
- 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. As a special case you may use
eof(0) to test if there are characters waiting
on standard input; this probably makes sense only if
yabasic runs as a script.
- 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;
this depends on the type of input-statement actually used:
- input reads
input until it encounters a space; leading and
trailing spaces are skipped.
- line input
reads input until it encounters the end of a line.
- This applies regardless of whether you
read from a file (e.g. input a$) or from
the terminal (e.g. input #1 a$)
- Binary
files
- If you need to process binary files
you have to resort to peek and poke.
-
Back to table
of contents ...
Interaction
with the Operating System
The system()-function
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:
Datentraeger in Laufwerk C: heisst 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 windows
installation).
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").
date$
and time$
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.
Back to table
of contents ...
Peek and Poke
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 few 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 few peek's and poke's
right now, so they may be fully enumerated:
- peek$("infolevel")
- Gives back the current infolevel.
- poke "infolevel",
"error"
- Sets the infolevel to
any of "diagnostic", "note", "warning",
"error" or "fatal".
- peek("fontheight")
- Gives back the height in pixels of the
font used for graphic-text.
- peek$("os")
- Gives back the operating
system (either "windows" or
"unix")
- poke "textalign","cc"
- This changes the way text is aligned
with respect to the point given within the text-command (see there, for further explanation).
- peek$("textalign")
- Gives back a string specifying the
current mode of text alignement; among possible return
values are "cb", "rc",
"cc", ...
- peek("version")
- This returns the version of yabasic (e.g.
2.47).
- peek("argument")
- Returns the number of arguments given
to your yabasic-program. This might be useful, if you
call yabasic from the command-line only; let's say you
type yabasic test.yab 1 2 3. This would
start yabasic to execute the program test.yab; within
test.yab you could then query peek("argument")
to get the number of arguments given on the
command line. In the example peek("argument")
would return 3, because there are three
different arguments ("1", "2" and
"3") on the command line (the name of the
program "test.yab" doesn't count as an argument).
To retrieve the arguments, use peek$("argument");
every call to peek$("argument") reduces
the value returned by peek("argument") by
one.
- peek$("argument")
- Every call to peek$("argument")
returns one of the command-line arguments handed
to your yabasic program. E.g.: if you call
yabasic test.yab 1 2 3, then the first call to
peek$("argument") would return "1",
the second call would return "2", the third
"3" and any further call would return an empty
string ("").
Yabasic offers limited
support for processing binary files:
- peek(#1)
- This returns the next byte
from the file #1 (#2 ... #9 are possible too of
course). Note that there are no quotes
around #1.
- poke #1,byte
- Writes the specified byte to
file #1. byte can be any number
within the range 0...255
- poke #1,string
- Writes the content of string$
to file #1.
These peek's and poke's for binary
files should not be mixed with normal file I/O through print
and input (you might get trouble with yabasic's internal
buffering).
Additionally it is wise to open such files with a filemode containing "b"
Back to table
of contents ...
Pretty
printing: print at() and print using
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
erases your screen.
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.
print
using
To control the way numbers are printed, use
the print using statement: print 12.34
using "###.####" produces 12.3400.
The format string ("###.####")
consists of hashes (#) with one optional dot and it pictures the
appearance of the number to print. Some examples:
Command |
Output |
Remarks |
print "=",12.34
using "###.####","=" |
= 12.3400= |
The output is filled up with
spaces (from the left) and zeros (from the right) as the
format requires. |
print "=",12.36
using ##.#,"=" |
=12.4= |
Last digit of output is rounded. |
print "=",12.34
using #.#,"=" |
=***= |
The number can not be formatted as
required. |
This way of formatting is straightforward
and simple, but not very flexible; e.g. it is not possible to
print numbers left-aligned or with leading zeroes. To get such
effects, the print using statement allows for
format strings as used by the printf()-function
of 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 == |
More about these formats can be found in
any book on the C-language.
All these formats can be used for the str$()-function too.
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: abs() acos() and arrow asc() asin() at() atan()
B: beep bell bitblit bitblit$() box break
C: chr$() circle clear rect clear
screen clear
window close close printer close
window continue cos() curve
D: date$ data dec() dim dot
E: else elsif end endif eof() euler exit exp()
F: fi for frac()
G: glob$() gosub goto
H: hex$()
I: if inkey$ input input
at input
# instr() int() interrupt
J:
K:
L: label left$() len() line line input line to log() lower$() ltrim$()
M: map() mapx() mapy() marker max() mid$() min() mod() mouseb mousex mousey
N: new curve next not
O: on gosub on goto open open printer open
window or origin
P: pause peek peek$ pi poke print print
at print using print
# printer
Q:
R: ran() rectangle read rem repeat restore return reverse right$() rtrim$()
S: sig() sin() step split$() sqr() sqrt() str$() system() system$()
T: tan() text then time$ to token$() trim$()
U: until upper$() using
V: val()
W: wait wend while window
X: xtick
Y: ytick
Z:
Back to table
of contents ...
Index of
concepts
Arrays
Binary files
Case of Keywords
and Variables
Command
line arguments
Conditions in
the if-statement
Escape
Sequences within strings
Formatting
numbers
Getting
mouse input
Globbing
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
Yabasic started 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 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 ...