home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Global Amiga Experience
/
globalamigaexperience.iso
/
compressed
/
development
/
heliosdemodisk3.dms
/
heliosdemodisk3.adf
/
Tutorials
/
HeliOSLanguageTutorial1.doc
< prev
next >
Wrap
Text File
|
1994-12-18
|
74KB
|
2,079 lines
-----------------------------------
Looking forward and getting started
-----------------------------------
This introductory tutorial is intended to explain a few general ideas
which may help you get started with HeliOS.
Because simple once-only statements of fact are not the best way of
introducing a complex subject, we have provided tutorials which cover
similar ground in different ways.
Some of the ideas in this tutorial will be different expressions of
ideas related in other tutorials, and some of the material will be new.
Hopefully this many-faceted approach will help make some of the more
unfamiliar concepts accessible to most people, and once you are confident
enough to write your own first programs you will be able to pick up
further knowledge directly from the reference material as you need it.
So don't just say "Oh..we've already read this!" and gloss over things,
unless you already are very confident of your understanding, because
there may be some new ideas in here.....
Before explaining the fundamentals of HeliOS programming it is
worthwhile looking briefly at the differences between computer
programming languages. This is important because HeliOS is very
different from other languages with which you may be familiar
and opens up many novel possibilities.
If you are already experienced with a computer language such as BASIC
or PASCAL, you will need to "forget" many of the restrictions imposed
by such languages. HeliOS is a fluid, redefinable, linguistically
oriented language, with much greater freedom of expression and very
different "free form" programming style.
If you already use assembly language you will, in some ways, be
more instantly at home with HeliOS, because it allows direct control
of data storage in memory in a similar fashion to assembly language.
In fact, HeliOS allows the integration of assembly language directly
within "high level" HeliOS code, and HeliOS has many functions which
are close to assembly language in concept. HeliOS is also close to
assembly language in potential speed and efficiency.
If you are new to programming, you will find that HeliOS will be
rather easier to learn than the more restrictive old fashioned
computer languages such as BASIC. Coming fresh to HeliOS with no
preconceptions, you will perhaps be better placed even than already
experienced programmers to take advantage of all the novel new
concepts used by HeliOS.
Since HeliOS as so different from other computer languages, let us
assume you are new to programming and take things from the beginning.
Your first task is to learn a few simple and fundamental aspects of
communication with your computer: think of it as learning to speak to
someone who does not speak your own native language.
You will have to learn a new mode of communication, and interestingly
you can also adapt HeliOS to use a form of linguistic expression chosen
by you. In a sense you could say that HeliOS allows you to train the
computer to speak YOUR personal language. This is quite an advanced
capability which allows HeliOS programmers to develop a high degree
of personal style and creativity.
------------------------------------------------
How HeliOS differs from other computer languages
------------------------------------------------
Using HeliOS you can actually build a "new" language which ideally
suits your own style of programming, and which interfaces to the Amiga
in the most efficient possible way. HeliOS allows you to create new
commands based on your own ideas and incorporating programming methods
which you prefer. Unlike most other computer languages HeliOS is an
EXTENSIBLE language, so you literally program by extending the actual
set of words you use to communicate with the computer.
Notice how much emphasis is being placed upon "communication" and the
use of "words": this is very important, because HeliOS is really about
inventing your own communication channel with the Amiga, based upon a
mutual use of a shared vocabulary which YOU specify. You could almost
say that HeliOS is a "verbally" or "semantically" oriented language
rather than a "number manipulating" purely "computational" one.
Already, if you are a BASIC or "C" programmer, you will perhaps be
intrigued by what is a whole new world of programming possibilities.
There are many computer languages, all of which have strengths and
weaknesses, and of course the computer which you use will have its
own set of individual features. Your task is really twofold: to master
an effective means of communication and then to learn how to control
all the different functions of the particular machine with which you
are working.
Your choice of computer will determine the final results which you can
achieve: some computers are better at certain tasks than others. The
Amiga is possibly the most versatile home computer of all, so you will
certainly have many interesting avenues to explore.
Your choice of language will very much influence the ease and productivity
of the task of programming, and your chosen language might be assessed in
terms of two really vital measures of performance:
1. Is the language capable of flexible control of ALL aspects of your
computer, or is it going to be incapable of performing certain tasks.
For example, most high level languages lack speed, and are therefore
less capable than assembly language when it comes to creating games.
If you want to write game software without having to resort to assembly
language you need to choose a very fast high level language.
2. Is the language flexible and easy to use from YOUR point of view.
For example, ideally you need a language which makes it easy to do the
kinds of things you want to do with the computer. You also need to be
comfortable with the general interface between you and the language in
terms of editing source code and program testing.
Computer languages vary in speed and power: most languages are called
"high level" languages because they insulate you from dealing with "low
level" technicalities to do with the actual operation of the computer
hardware. These languages usually have a certain trade-off of speed
and flexibilty in favour of simplicity of use: they are biased towards
making life easy for the programmer rather than being computer-efficient.
At the other end of the programming language "scale" is assembly language,
which deals directly with the computer hardware and requires the human
programmer to adapt to the needs of the machine rather than vice-versa.
Assembly language is the most powerful language in terms of speed and
efficiency, but it is quite difficult and unforgiving from the point of
view of the programmer.
Another broad difference between languages is whether they are "compilers"
or "interpreters". A "compiler" has to first pre-process a complete set
of program instructions and prepare an executable file which then has to be
run to test the program. This can be a slow and tedious process, and makes
the task of the beginner so much harder because there is no facility for
easy instant testing of small code fragments.
An "interpreter" on the other hand, allows you to type in a command and
get an instant response: the language can instantly interpret what you type.
This is excellent for beginners, because it is easy to test small sections
of code and experiment to get things working correctly.
Traditionally interpreters were slow languages because all the program
instructions were literally being interpreted as the program ran. In
recent times interpretive languages have often been equipped with add-on
compilers which process the final program source code into an "executable"
form which runs faster because it has been "pre-interpreted". Most more
modern and efficient languages are pure "compilers", and the special
advantages of interpretive languages are no longer available to users of
such languages.
So, being unrealistic and "hopeful", ideally you might be looking for an
easy to learn high level language, which is capable of assembly language
speed, full direct computer hardware control if required, and which has
the best features of both a compiler and an interpreter!
Many people will tell you this is an impossible dream.....
Certainly this requirement eliminiates virtually all languages available
for the Amiga, but HeliOS actually does fulfill all these functions!
HeliOS is a very flexible interpreter AND compiler: a high level language
with a natural speed nearly equivalent to assembly language. HeliOS has a
full capacity to control the computer hardware directly, and can even allow
pure assembly language to be written within high level code. Best of all,
HeliOS has the most sophisticated and comfortable "human interface" of ANY
language, so its powerful programming tools are available in an enjoyable
and easily approachable form.
HeliOS will easily allow you to exploit every facility of the Amiga, but do
not try to rush into doing complicated things too early. The Amiga itself
is very complex and sophisticated, and no matter how easily HeliOS allows
you to write programs, you must take care to learn how the Amiga functions
in detail before you can effectively control the computer.
This tutorial will teach you how to work with HeliOS, and you will soon
learn to work with the Amiga operating system and hardware: then you will
be free to create the most ambitious programs you can imagine.
However, that is for the future, and for now we will look at some simple
ways to get to know the HeliOS language.
---------------------------------
Controlling the Amiga with HeliOS
---------------------------------
How does a computer language allow you to control a computer? How do
YOU control your chosen computer language?
In fact......just how does a simple digital machine manage to "come
alive" and produce the fascinating sounds and graphical extravaganzas
which we often see in Amiga software?
It does so, largely, by YOUR creative input, and to provide this you need
tools to enable you to express yourself using this new creative medium.
You then need to learn to use these tools creatively and confidently,
so that you can turn the computer into an instrument for expressing your
ideas effectively.
HeliOS provides you with an excellent toolkit, but if you don't master
the fundamentals well, as in any artistic pursuit, the computer and the
language will impose themselves on you to the point that you are forced
to tread a tedious tightrope of obediance to rigid rules. HeliOS gives
you hundreds of different ways to do any job: the choice is yours, so
learn how to use this range of choice for your own creative ends.
If YOU want to be in control, as you should be, you need first and
foremost to have a good general idea of how the computer works. You
then need to have a sound understanding of the fundamental operation
of your computer language. You will gain experience and detailed
knowledge quite easily and painlessly as you progress, and you should
not try to learn too much in the way of technical details too soon.
Eventually, no doubt about it, you are going to have to do some detailed
learning, but first of all you need an overview of the programming process
and a few simple ground rules to get you started. If you grasp the simple
things and use sound programming practises, you will be able to enjoy
rewarding results from even your first day of HeliOS programming.
Let us take an overview of our journey and then look at a few simple
but fundamentally important programming concepts.
The Amiga computer has many functional sub-systems which can be likened
to groups of people with various talents, each of whom uses a specific
linguistic "dialect" designed to express concepts related to their task.
It will be your job as a programmer to communicate with all these "people",
each in their own idiom, and you will need to develop tools and methods
with which to express your instructions. For example, you would need one
type of knowledge and technique for writing a sound synthesizer program,
and you would need another for writing a graphics-intensive arcade game.
An ideal computer language is an "interface" consisting of pre-designed
commands which are comprehensible to the programmer and which are also
adaptable to meet the demands of communicating with every aspect of the
host computer. HeliOS has many specialised commands to help you deal with
specific functions of the Amiga, and is probably the closest thing to a
"total" Amiga control language which you will find.
Any programming language presents one face to you and another face to the
machine: this is its job. The less "work" that has to be done "in between"
in forcing your commands into direct machine instructions, the better
and more efficient will be the result. HeliOS itself imposes a minimum
of its own "character" and allows you to control all aspects of the Amiga
very directly, in the way in which you choose. This means that you need
to UNDERSTAND what the computer is doing rather than simply entering lists
of predesigned commands. Don't worry: this isn't as hard as it sounds!
Most programming languages have developed over years into fairly rigid
and limited systems which are not ideally adaptable to all aspects of
controlling modern computers. This tends to mean that the language has
a very formal structure, and in fact many languages are only good at
certain particular tasks. HeliOS takes a different approach and allows
you mould your own language for any programming requirement.
HeliOS allows you, the programmer, to recreate the language itself for
any particular task you need to do. In HeliOS, if you want to carry
out a complex task, you first have to break down the task into sensible
small "units", then you EXTEND the language by CREATING new commands to
do the particular things you require.
Your new commands are named however YOU choose, so they instantly make
sense to you and you remember them easily. In other languages you are
required always to remember fixed commands written by someone else, and
to conform to rigidly inflexible command sets.
HeliOS, in short, provides you with a flexible and open ended way of
developing your knowledge of the Amiga and your power to control it.
----------------------
A first HeliOS program
----------------------
Let us take, as a first example, the traditional computer language
introductory program: getting the computer to say "Hello World!".
To do this in "C" you would need to write quite a lot of code to create a
stand-alone program which would first need to set up the capacity for the
computer to display a "screen" and to display text on this screen.
In HeliOS, even to write a "stand alone" program to do this would only be
a matter of a few words: you could actually do it in one line of code!
However, HeliOS includes an "Interpreter" which already has a text display
ready for use, so for a simple example all you need to do is switch to the
HeiOS Interpreter screen and type your commands directly.
Like BASIC, HeliOS has simple commands to output text, but unlike BASIC
HeliOS also has a very wide range of more sophisticated and powerful text
commands to do many special operations. However, for now, all we need use
is a very simple text output function, and this can be done in HeliOS using
the expression:
." Hello World!"
Let us examine this simple expression, and firstly we can look at the
initial two-character word at the start:
."
The first part, the . character, is used by HeliOS to indicate that
something is being "output": it is roughly equivalent to a shorthand form
of the word "print".
The second part, the " character, is used to indicate that this "double
quote mark" will be used to "delimit", or "enclose" the text we want
to print.
This expression as a whole is saying, in a cryptic form, "print the text
following enclosed by double quote marks to the screen".
In computer parlance we have a special name for the double quote character
used to indicate the start and end of our text message: we call this a
DELIMITER, because it "delimits" a text message surrounded by other words
which have a different function.
Notice that we have emphasised the need to "enclose" text messages within
delimiters: we cannot simply say:
." Hello World!
without the final quotation mark.
This is important!
When you are telling the computer to do something with text you need to be
able to define where the text starts and stops, so that the computer can
tell the difference between COMMAND words and the actual words of your
embedded TEXT message.
To understand this, imagine that you had typed a set of commands at the
Interpreter command line, and that one of these commands was an instruction
to print some text to the screen.
You might have something like this:
COMMAND1 COMMAND2 ." This is my text to print" COMMAND3 COMMAND4 etc.
^ ^
First delimiter Second delimiter
= START of text = END of text
You can see how the two " characters are used to enclose and distinguish
the embedded text message from the commands before and after them.
This concept of "delimiters" is one you will meet often when using text
embedded within program code.
Let us go back now to our "Hello World!" program:
." Hello World!"
If you type this at the HeliOS command line, the Amiga will output the
text message "Hello World!". It is as simple as that, so why not try it
now.....
Here you have typed in one single direct command, but you can of course
type in a sequence of commands to do something a little more complicated.
Try typing the following (actually, you do not need to retype every word,
just press "up-arrow" to recall your previous line of text and then edit
the line as required):
SCRCLR ." Hello World!" WAITSPACE
This will do three different things, one after the other:
1. Clear the text screen
2. Print "Hello World!"
3. Wait for you to press space.
Note that all computer programs are essentially simple sequences of
operations, because the computer can actually only perform one function
at any one time.
Now try typing the following:
SCRCLR 12 12 CURPUT ." Hello World!" WAITSPACE
This will set the text cursor position at "column 12, row 12" on the
text screen before printing your message.
You have already written a short HeliOS program, but it is not very
convenient to keep typing all this in at the command line every time.
We are now going to create a new single word command which will become
a part of the HeliOS vocubulary. This single word will the carry out all
the commands in your small new program.
To create a new HeliOS command word we use two HeliOS functions expressed
by use of the colon and semi-colon characters. The colon character tells
HeliOS that the next word will be the name of a new command, followed
by a command definition. The semi-colon character tells HeliOS that the
new command definition is finished.
Let us create a new word called HELLO.
: HELLO SCRCLR 12 12 CURPUT ." Hello World!" WAITSPACE ;
^ ^^^^^ <-----------------------------------------------> ^
Start Name Definition End
This has created a new word called HELLO.
Try entering this command line and then displaying the USER vocablulary.
You will see your new word HELLO listed as a HeliOS command word: you have
already extended the HeliOS language and written a small program.
Now try typing just the word HELLO at the command line and press <Return>.
You will see that your new word does exactly what the original set of
commands did when typed in individually.
************************************
Rules for creating new command words
************************************
Here, then, are the simple rules for creating new words:
1. Place a "colon" (":") symbol with at least one space on each side.
2. Put your new command name, followed by at least one space.
3. Put your list of "internal" commands with spaces separating them.
4. Place a "semicolon" (";") symbol with at least one space on each side.
We refer to a word definition such as this as a "colon definition".
This process of creating new commands is exactly what you do when writing
all HeliOS programs: you keep on extending the language with ever more
powerful commands, until you finally have one "master" command which uses
all your previous constructions to carry out the main program.
Let us now make another command, called PRINT_RED.
: PRINT_RED 6 FPENSET ;
This command sets the text colour to "colour 6", which will be RED unless
you have changed your HeliOS colours.
You can now say:
PRINT_RED HELLO
Getting more ambitious, we can make another new word:
: PRINT_RED_HELLO PRINT_RED HELLO ;
This is a compound word made up from our previous new commands, and you
will see that HeliOS can freely mix any combination of your new words with
its own CORE command set.
Remember: there is no essential difference between HeliOS CORE functions
and the command words which you create yourself using colon definitions.
Can you see what the following expression does?
: PRINT_BOLD_RED_HELLO BOLDON PRINT_RED_HELLO ;
Try it!
And this....
: FANCYHELLO 7 BPENSET PRINT_BOLD_RED_HELLO 2 BPENSET SCRCLR ;
The process of building new HeliOS commands should now be quite clear.
When you come to write a "real" program of course, you will not be using
the command lines: you will be writing programs as text (or "source code")
in an editor.
Many computer languages require source code to be written in a very strict
format, but HeliOS is totally relaxed in its source code format, allowing
you to choose a style which suits your own preference.
It is a good idea to use plenty of "white space" so that your programs
are not cluttered and confusing, and it is best to make use of separate
lines for distinct command sequences.
Look at this example of how you might turn all the above commands into
a short HeliOS program in a text editor:
: HELLO
SCRCLR
12 12 CURPUT
." Hello World!"
WAITSPACE
;
: PRINT_RED
6 FPENSET
;
: PRINT_RED_HELLO
PRINT_RED
HELLO
;
: PRINT_BOLD_RED_HELLO
BOLDON
PRINT_RED_HELLO
;
: FANCYHELLO
7 BPENSET
PRINT_BOLD_RED_HELLO
2 BPENSET
SCRCLR
;
We have used UPPER CASE characters throughout, but you do not need to do so.
You could equally well have written FANCYHELLO as:
: FancyHello
7 BPenSet
Print_Bold_Red_Hello
2 BPenSet
ScrClr
;
or even:
: FancyHello 7 BPenSet Print_Bold_Red_Hello 2 BPenSet ScrClr ;
This last option is actually quite a BAD idea, and with a little thought
we can see why.
It is always best to use the sequence of lines within your source code
to help express the sequential logic of the program: this makes it easy
to follow what the program is doing. The layout of your source code can,
and should, help you comprehend the structure of your program.
There is also another good reason for using a line-by-line text format.
It is very useful in many cases to add notes to your programs, explaining
what is happening at each stage. This is called "commenting", and the
addition of "comments" is vitally important once you start writing big
complicated programs. You may understand what a program is doing when you
write it, but you will surely forget details when you return to it after
some time has elapsed.
It is often very useful to add comments to each line, like this:
: FancyHello \ Print red and yellow "Hello" message
7 BPenSet \ Set background to "yellow"
Print_Bold_Red_Hello \ Clear display and print message
2 BPenSet \ Reset background to white
ScrClr \ Clear display
;
Notice that we use the "\" character to inform HeliOS that all text on
the rest of that line is a comment.
HeliOS source code can also include longer multi-line comments. You do
this by enclosing the long text comment in brackets, like this:
HELLO
( This is a long text comment, which can go on and on for as many lines
as I like. I can carry on writing and HeliOS will ignore all this until
it finds a final ")" character, upon which it will carry on interpreting
the program. )
FANCYHELLO
Perhaps you might have noticed something quite subtle: there was a bracket
character WITHIN the comment which somehow HeliOS was clever enough to
ignore.
How do you think HeliOS knew which bracket to use to determine the end of
the comment?
The answer to this brings us to an important rule:
ALL HELIOS COMMAND WORDS MUST BE DELIMITED BY SPACES
This is very natural really, since it is just how we ourselves communicate.
After all, look what happens if we remove spaces from the line above:
Thisisverynaturalreally,sinceitisjusthowweourselvescommunicate.
HeliOS, like any normal person, requires its communications to be separated
by spaces, and because this is such a natural consideration, it is quite
unlikely that you will make the mistake of forgetting it. However, if you
do miss out a space between two words, HeliOS will merely tell you that
it cannot understand and point out to you where it lost track of what you
were saying.
Try typing this at the command line:
: FancyHello 7 BPenSet Print_Bold_Red_Hello 2 BPenSetScrClr ;
^^
Missing space
You can see that HeliOS is really quite helpful, and pointed out where
you had gone wrong without any untoward problems.
Going back to the case of the bracket within the comment, and indeed to
comment markers in general, you should always remember that after the
first bracket (which must have surrounding spaces) HeliOS will regard
everything as a comment until it finds a final bracket with surrounding
spaces. If you were to place a ) character surrounded by spaces WITHIN
your comment, HeliOS would assume that you wanted the comment to end there.
You should also take care not to write a line like this:
7 BPenSet \Set background to "yellow"
^^
No space
If you miss out the space, HeliOS will not understand that you are writing
a comment. Try it and see......
One final point will lead us to the conclusion of this first lesson.
Perhaps you have noticed already that HeliOS will allow you to make several
new definitions of the same command. In this case HeliOS warns you that
you have made multiple definitions, but will accept the new command in place
of the previous ones.
We will discuss this in more detail elsewhere, but for now we might point
out that if you want to clear all old command definitions you simply type:
FORGET **CORE**
This will cause HeliOS to "forget" all the new commands it has learned,
and revert to its own in-built set of CORE functions.
Notice that once again HeliOS behaves in a fairly "human" way compared with
most computer languages: you teach it new words and use them in expressive
ways similar to our own use of language, then you tell it to "forget".
***************************************************************************
---------------------------
Simple programming strategy
---------------------------
We can now go on to a slightly more complex example, and in doing so we
will look at simple ways of designing programs more efficiently.
Let us say that we want to print to the screen your name and address.
If we asked a person to do this type of task, we would assume that they
knew how to write, how to use a pen, etc. etc., and we would be able to
give them one simple command to do the job.
A computer on the other hand always has to be told explicitly what to
do at each stage of the process.
The art of writing good computer software lies very much in developing
a skillful understanding of how to break down complex tasks into several
simple ones. A good programmer can reduce a complex task to a relatively
"intuitive" set of economical functions, whereas a bad programmer would
probably write twice as much code to do the same job in a clumsy way.
Computer languages have many preset commands to carry out common tasks,
and you need to have at your disposal a list of these commands. This
list of commands, in HeliOS, is called the DICTIONARY, and as you write
programs you actually add commands of your own to this dictionary, thus
effectively building your own personalised version of the language.
Let us assume we want to print this address:
Mr. W. Smith
12, Blitter Street
AmigaTown
ComputerLand
Obviously, no computer language comes with a single built-in command which
with one simple action will print your name and address at a chosen place
on the screen and in chosen text colours and styles. Even this very simple
task requires a program to be written to do it, and our first task must be
to work out a series of simple sub-commands to tell the computer how get the
job done. Then we can create a new master-command called "PrintAddress".
Let us first make a preliminary list of what sort of things we want this
command to do, in the form of a simple explicit step-by-step sequence:
1. Clear the page of previous text.
On a computer the screen/page is not always empty!
2. Move the pen (or text cursor) to a certain place on the page.
It would be nice to be able to specify this position as a parameter to
our new command PrintAddress.
3. It would be nice to be able to specify text style and colour, and for
this example we will use BOLD type in black for the name.
4. Print our name.
5. Move to the next line immediately below the start of the name.
6. It would be nice to be able to specify text style and colour, and for
this example we will use ITALIC type in black for the address.
7. Print the first line of the address.
8. Move to the next line immediately below......
9. Set text style.
10. Print the second line of the address.
11. Move to the next line immediately below......
12. Set text style.
13. Print the third line of the address.
Notice that we break down commands to the computer into very simple
sequential operations.
Let us give names to these operations now.
1. ClearScreen
2. SetNamePosition
3. SetNameTextStyle
4. PrintName
5. SetAdd1Position
6. SetAdd1TextStyle
7. PrintAddress1
8. SetAdd2Position
9. SetAdd2TextStyle
10. PrintAddress2
11. SetAdd3Position
12. SetAdd3TextStyle
13. PrintAddress3
So, our program PrintAddress will look something like this:
: PrintAddress
ClearScreen
SetNamePosition
SetNameTextStyle
PrintName
SetAdd1Position
SetAdd1TextStyle
PrintAddress1
SetAdd2Position
SetAdd2TextStyle
PrintAddress2
SetAdd3Position
SetAdd3TextStyle
PrintAddress3
;
You can imagine issuing these commands to a person (perhaps being a little
more polite), and then watching the sequential series of commands being
performed.
It is exactly the same with the computer.
Before we start issuing these commands we really ought to think a little
to see if we have decided on the best way of doing things. It is all
very well instructing people or computers to do things, but it does make
a tremendous difference if the commands which we issue are sensible. With
people, this makes them happier to carry out our plans, and with computers
we simple get the job done quicker and more easily if we think things out
carefully first.
Look again at our command list:
ClearScreen
SetNamePosition
SetNameTextStyle
PrintName
SetAdd1Position *
SetAdd1TextStyle +
PrintAddress1
SetAdd2Position *
SetAdd2TextStyle +
PrintAddress2
SetAdd3Position *
SetAdd3TextStyle +
PrintAddress3
Look at the lines marked with * and +.
Now look again at another version:
1 ClearScreen
2 SetNamePosition
3 SetNameTextStyle
4 PrintName
5 NextScreenLine *
6 SetAddTextStyle +
7 PrintAddress1
8 NextScreenLine *
9 SetAddTextStyle +
10 PrintAddress2
11 NextScreenLine *
12 SetAddTextStyle +
13 PrintAddress3
Notice that in the new version lines 5, 8, and 11 are all the same command,
which we call NextScreenLine, and lines 6, 9 and 12 are also all the same
command SetAddTextStyle.
This means that we will be able to re-use parts of our program, which will
save time and effort.
We have managed to do this because we noticed that parts of the task could
be described in a way which was repetitive and similar.
This is a very important part of designing computer software!
Now we have reduced the number of DIFFERENT commands we need to create
from 13 to 9, but we can go further still:
1 ClearScreen
2 SetNamePosition
3 SetNameTextStyle
4 PrintName
5 NextScreenLine
6 SetAddTextStyle
7 PrintAddress1
8 NextScreenLine
9 PrintAddress2
10 NextScreenLine
11 PrintAddress3
Here we still have 9 different commands, but we have removed the two last
instances of "SetAddTextStyle" from our final program. We can do this
only because we know that once a text style is set in HeliOS, any further
text will continue to be printed in that style.
We needed SPECIAL KNOWLEDGE to make this particular economy, and you will
find that as you grow in experience you will on many occasions be able to
make your programs more economical by "tricks" such as this.
We could go on making changes, but let us for now settle on this sequence
of commands for our program.
: PrintAddress
ClearScreen
SetNamePosition
SetNameTextStyle
PrintName
NextScreenLine
SetAddTextStyle
PrintAddress1
NextScreenLine
PrintAddress2
NextScreenLine
PrintAddress3
;
Remember that we COULD write this as:
: PrintAddress ClearScreen SetNamePosition SetNameTextStyle PrintName
NextScreenLine SetAddTextStyle PrintAddress1 NextScreenLine PrintAddress2
NextScreenLine PrintAddress3 ;
Notice that this looks much more confused and is harder to read.
As we said above, because computers are sequential devices, operating on
one command at a time, it is most useful to write programs with one command
per line. In this way it is much easier to see what is happening.
If all the sub-commands in PrintScreen were HeliOS CORE words we could
proceed simply to write the program as expressed above. However, looking
at our definition of PrintAddress, we can see that HeliOS is going to need
to know what we mean by several NEW sub-commands before it can carry out
our instructions. For example, we have not yet told HeliOS how to
"ClearScreen", etc.
So, we now need to define all our new sub-command words, one at a time.
Let us do them in order, with ClearScreen first.
Look at this:
: ClearScreen
SCRCLR
;
You can see that ClearScreen has been defined as just one HeliOS CORE
command called SCRCLR.
Actually, we are quite fortunate that HeliOS has this single word SCRCLR to
clear a text screen: this means that our first definition is very simple!
The definition of ClearScreen above will create a new command word in the
HeliOS dictionary called "ClearScreen", which actually does just the same
as SCRCLR. All we have achieved in this case is to make our new name for
an existing word, but this is quite legitimate. Whenever we now type
"ClearScreen", either at the command line or in a program, HeliOS knows
that we are wanting it to clear a text screen using its own command SCRCLR.
Actually, you can use this technique to rename any of the CORE HeliOS
command words if you like.....
Let's now look at our second command:
: SetNamePosition ( Column, Row - - - )
CURPUT
CURSAVE
;
This one is a little more interesting.
We here have two HeliOS internal commands which do the job we require:
CURPUT will set up the text cursor position and CURSAVE will automatically
remember it for future reference.
The HeliOS word CURPUT requires us to tell it where we want the cursor
putting, which is quite reasonable, and we do this by simply writing the
column and row position numbers before the command like this:
20 20 CURPUT
This would place the cursor at column 20 row 20.
Quite easy!
The two numbers required by CURPUT to do its work are called "parameters",
and the process of supplying these numbers is called "passing parameters".
You will soon see that HeliOS command words can pass parameters between
themselves too, with one word passing its result to another, and so on.
Notice, if you are already a programmer in other languages, that HeliOS
requirs no definitions of variables at this stage: you simple place the
numerical parameters immediately before the command.
In fact, HeliOS uses a "Stack" for much of its parameter passing, and for
now we will simply mention that a stack is a general storage place where
any parameters can be stored until they are needed later.
When a HeliOS word requires parameters (in this case Column and Row), we
have a conventional way of expressing this, which we call a "Stack diagram".
You perhaps noticed this in the definition of SetNamePosition:
: SetNamePosition ( Column, Row - - - )
^^^^^^^^^^^^^^^^^^^^^
Stack Diagram
Here is a generalised version of this stack diagram:
( Parameter1, Parameter2 - - - )
This tells us that the command in question takes two parameters and does
not itself return any parameters.
Look at another general example of a Stack Diagram:
( Parameter1, Parameter2 - - - Parameter3, Parameter4 )
^ ^
1st Input 2nd Input Command 1st Result 2nd Result
parameter parameter parameter parameter
The "- - -" represents the operation of the command, the parameters on
the left represent things passed to the command before it operates, and
parameters returned by the command are shown on the right.
You might have a word which takes two parameters and then returns one
parameter itself. For example "+" takes two numbers, adds them, and
returns the sum of the two numbers as its result.
So "+" would have the following stack diagram:
( Parameter1, Parameter2 - - - Parameter3 )
or ( Number1, Number2 - - - Result_Of_Addition )
Going back to CURPUT, which takes two column and row parameters, we can
notice something interesting: by putting CURPUT into our new command word
"SetNamePosition", this new word will also require the two column and row
parameters just like CURPUT.
This is easy to understand, if you realise that when HeliOS interprets
the SetNamePosition command, what it actually does is to perform the
sub-commands CURPUT and CURSAVE sequentially.
HeliOS says to itself "Ah, what do I do for SetNamePosition? First I must
perform the CURPUT command, then the CURSAVE command".
So, "SetNamePosition" will require two parameters, and will have the
following "Stack diagram":
( Column, Row - - - )
just like CURPUT.
You will see later how this works when you run the program.
Let's see how we are doing with our command list.
: PrintAddress
ClearScreen - done
SetNamePosition - done
SetNameTextStyle
PrintName
NextScreenLine
SetAddTextStyle
PrintAddress1
NextScreenLine
PrintAddress2
NextScreenLine
PrintAddress3
;
OK. Now let us make "SetNameTextStyle", something like this:
: SetNameTextStyle
1 FPENSET
BOLDON
;
This time we use two more HeliOS sub-commands to make our new word.
The command FPENSET takes one parameter, which defines the colour of
the foreground text "pen". In this case we set the text colour to "1",
which is BLACK.
Can you work out the stack diagram for FPENSET?
Here it is: FPENSET ( Pen - - - )
The command BOLDON switches HeliOS text mode to BOLD
You can see that SetNameTextStyle does not require any external parameters
The next command we need is "PrintName".
: PrintName
." Mr. W. Smith"
;
This will print the text to the screen in the current text style and
colour.
Here we use again the previous simple method of including text in your
program (there are many other more sophisticated ways of doing this).
Let's look at our command list again.
: PrintAddress
ClearScreen - done
SetNamePosition - done
SetNameTextStyle - done
PrintName - done
NextScreenLine
SetAddTextStyle
PrintAddress1
NextScreenLine
PrintAddress2
NextScreenLine
PrintAddress3
;
Now we need:
: NextScreenLine
CURSET
1 CURDN
CURSAVE
;
This time we have three HeliOS commands.
CURSET - Restores the first CURSOR position we set.
1 CURDN - Moves the cursor down by one position.
CURSAVE - Saves the new cursor position.
Notice that we have specially designed this command so that it can be used
repetitively. It was this "design feature" which allowed us to use this
one command in place of three separate commands in our "first version".
The next command, "SetAddTextStyle", is very similar to "SetNameTextStyle".
: SetAddTextStyle
BOLDOFF
ITALON
;
BOLDOFF - Switches off BOLD text.
ITALON - Switches on ITALIC text.
The commands "PrintAddress1" etc. are all very like "PrintName".
: PrintAddress1
." 12, Blitter Street"
;
: PrintAddress2
." ComputerLand"
;
: PrintAddress3
." AmigaTown"
;
So, we have now created all the elements of our simple program, so let us
collect them all together:
\ ****************
\ Start of program
\ ****************
: ClearScreen
SCRCLR
;
: SetNamePosition
CURPUT
CURSAVE
;
: SetNameTextStyle
1 FPENSET
BOLDON
;
: PrintName
." Mr. W. Smith"
;
: NextScreenLine
CURSET
1 CURDN
CURSAVE
;
: SetAddTextStyle
BOLDOFF
ITALON
;
: PrintAddress1
." 12, Blitter Street"
;
: PrintAddress2
." ComputerLand"
;
: PrintAddress3
." AmigaTown"
;
: PrintAddress
ClearScreen
SetNamePosition
SetNameTextStyle
PrintName
NextScreenLine
SetAddTextStyle
PrintAddress1
NextScreenLine
PrintAddress2
NextScreenLine
PrintAddress3
;
\ **************
\ End of program
\ **************
Try compiling the small program above, either by:
1. Highlighting it and pressing Amiga-e
2. Cutting and pasting it into another editor, and running it from there.
3. Typing it in at the command line or another editor.
Once you have compiled this code you can do a USER-vocabulary listing
and you will see each one of your new commands listed.
To see your new program working, type at the command line:
12 12 PrintAddress WAITSPACE
^^ ^^
Cursor position parameters.
Note that we have supplied the two parameters to PrintAddress.
This is interesting, because you will remember that we actually needed
these parameters originally to satisfy the requirements of the command
word CURPUT.
Then we included CURPUT in "SetNamePosition", so we realised that the
same two parameters would need to be supplied for this word, so that
they could in turn be passed to CURPUT.
Actually "SetNamePosition" is the SECOND command in our program
sequence, with "ClearScreen" coming first. So what happens to the
two parameters now?
Think of it this way: when CURPUT, which is a sub-part of our program,
eventually executes, it will need two parameters, which it will pull out
of the general storage area we call the stack. As far as CURPUT is
concerned, it does not care when or how the parameters got there, and
in fact it will fetch the last two numbers stored on the stack no
matter whether they are the correct ones or not.
It is YOUR job as a programmer to make sure that at the time when CURPUT
executes the last (top) two numbers on the stack are the required cursor
position parameters.
You can place these parameters on the HEliOS stack at any time: in fact
you can choose whether to type them in when you run the program, as above,
or include them in the program.
You COULD do any of these:
: PrintAddress : PrintAddress : PrintAddress
12 12 ClearScreen ClearScreen
ClearScreen 12 12 SetNamePosition
SetNamePosition SetNamePosition 12 12
SetNameTextStyle SetNameTextStyle SetNameTextStyle
PrintName PrintName PrintName
NextScreenLine NextScreenLine NextScreenLine
SetAddTextStyle SetAddTextStyle SetAddTextStyle
PrintAddress1 PrintAddress1 PrintAddress1
NextScreenLine NextScreenLine NextScreenLine
PrintAddress2 PrintAddress2 PrintAddress2
NextScreenLine NextScreenLine NextScreenLine
PrintAddress3 PrintAddress3 PrintAddress3
; ; ;
Can you see why the first two examples are OK but the third one will fail?
Yes...the parameters are NOT on the stack when SetNamePosition executes,
but are placed there afterwards, which is too late.
This brings us to another important thing to remember:
IT IS THE PROGRAMMER'S RESPONSIBILTY ALWAYS TO ENSURE THAT CORRECT
PARAMETERS ARE PLACED ON THE STACK AT ALL TIMES
This is called "stack handling", and is a very vital part of your
initial learning of HeliOS.
HeliOS uses the stack because this is a very fast and efficient way
of passing parameters between commands. You can actually use named
variables, or named constants, as you will soon see, but the stack
is fastest and in many ways easiest once you are used to it.
We will discuss the stack in depth later, but remember for now that
a good HeliOS programmer should always keep a clear idea of just what
is "on the stack" at any part of a program.
You can easily write yourself comments to help you with this if you
like:
: PrintAddress \ Stack = Empty
12 12 \ Stack = 12 12
ClearScreen \ Stack = 12 12
SetNamePosition \ Stack = Empty
SetNameTextStyle
PrintName
NextScreenLine
SetAddTextStyle
PrintAddress1
NextScreenLine
PrintAddress2
NextScreenLine
PrintAddress3
;
Let us now look again at our original command line when typed in the
parameters as we ran the program:
12 12 PrintAddress WAITSPACE
Why WAITSPACE?
The "WAITSPACE" will allow us to observe the results of the program
without anything else printing to the screen until <Space> is pressed.
This is quite useful, and you will probably find it convenient on many
occasions to use this command to halt a program temporarily.
------------------------------------
Order of creation of HeliOS commands
------------------------------------
Notice that when we collected together all our sub-commands into the
small program we constructed our main command "PrintAddress" last,
AFTER we had made all our sub-commands.
If you think about it this is obviously necessary, because you cannot
instruct HeliOS to use any command which you have not yet taught it!
In general using HeliOS you always progress from simple words using
HeliOS CORE functions to more complex compound words using commands
you have created earlier. There are ways to avoid the necessity for
sequential command creation, but don't worry about this for now.
So this is another important rule:
HELIOS COMMANDS CAN ONLY CALL DIRECTLY EITHER CORE COMMANDS OR
COMMAND WORDS YOU HAVE DEFINED EARLIER IN THE PROGRAM
***********************************************************************
--------------------------
Organisation and structure
--------------------------
In the example above we made a small attempt to improve the organisation
of our program between the stages of planning and final implementation.
Although the processing of information in a computer is essentially
sequential in nature, and your early programs will be simple sequences
of commands, it should soon become apparent that some degree of planning
and organisation is necessary to design an efficient program.
The fact is that computer programs contain structure, with small parts
of the whole working together in sometimes complex ways. Once you begin
to write programs which can behave differently with different inputs,
you start to generate quite a high level of complexity.
There is never "only one way" to perform any complex task, and you will
often be faced with many ways of implementing a certain programming
requirement.
Always look carefully at the overall "structure" of your programs, and
at the way you have broken complex operations into smaller tasks. This
is very important, and good organization goes together with sensible
and logical structuring of commands. Of course this is a very personal
thing, and what is sensible to one person is idiotic to another! In
spite of this, there IS often an overall optimum strategy which may be
determined by the constraints of the way the computer works.
In general you should try to balance economy of code with speed and
simplicity of operation: there will always be constraints and tradeoffs,
but you should always be in sufficient control to strike a good balance.
You should always PLAN your programs in such a way that there is minimal
duplication of effort, and you should always try to keep a view of the
greater whole as well as the individual parts.
In HeliOS programs you will:
1. Break down large tasks into smaller sections.
2. Choose appropriate and sensible names for these sub-commands in
order to make your programs comprehensible and easily readable.
3. Break down your sub-commands into still smaller and more manageable
sections until you reach the lowest level of simple CORE commands.
Simple sequential programs are fairly straighforward in terms of logical
design, but you will encounter circumstances where your program has to
behave differently according to external or internal conditions. The
way sequential computer operations can be used to "adapt" with respect
to time and different circumstances lies at the core of the fascination
of computer programming.
Computers would not be capable of nearly so many useful functions if they
could only carry out sequences of preprogrammed tasks. In fact computers
are ingenious in that they can take "decisions" and modify their behaviour
depending upon the results of their own actions.
This "intelligent" behaviour comes, amazingly, from a simple use of
logical operations such as:
Waiting for a certain condition to be "true".
Doing one of several different things depending on a condition.
Repeating "similar" or "modified" actions depending upon conditions.
Counting and performing multiple tasks.
etc. etc.
These considerations of "contingency" allow the simplest of computer
programs to have non-linear structures, and it is here that flexiblity
and intelligence on the part of the programmer come to the fore.
So, we have two forms of "structure" to consider in our early programming
efforts:
1. Structure in terms of the breakdown of tasks into manageable "chunks",
which really means structure in terms of code size and function.
2. Structure in terms of logical behaviour, response to external or
internal conditions, time related constraints etc.
Here is a simple HeliOS conditional construct, showing how a program
can easily interact with the outside world:
: PressSpace?
." Please press a key." \ Ask for user input
CR \ CR = Carriage Return
KEY \ Wait for a keypress
32 \ 32 = Code for <Space>
= \ Key = <Space>?
IF
." Space was pressed!" \ Yes!
ELSE
." Space was not pressed!" \ No!
THEN
CR \ CR = Carriage Return
." Thank you!" \ Finished!
;
Here you can see that one of two different logical paths will be taken
by the program depending on user input.
Look how HeliOS implemented the "conditional" construct of IF...ELSE...
THEN.
Here is what happens in the above program:
1. We print a message and then do a "carriage return". This is easy.
2. We use the HeliOS CORE command KEY, which waits for user input and
returns a numerical value depending upon which key was pressed.
The stack disgram of KEY would be ( - - - KeyValue )
This means that after KEY there is one number, an input code, on
the stack.
3. The next entry in our program is "32", which puts the number 32 onto
the parameter storage stack (on top of the input code).
We now have two numbers on the HeliOS stack.
4. The command "=" is used to compare two numbers which are fetched from
the stack.
As "=" gets the numbers from the stack it removes them, leaving the
stack empty.
When "=" has compared the two numbers, it will place a result code onto
the stack.
A "1" will be left on the stack if the two numbers were equal, and a
"0" will be returned if they were unequal.
The stack diagram of "=" is ( number1 number2 - - - result )
0 or 1
5. Now comes the important part: the use of the conditional "IF" command.
The command "IF" removes a number from the stack and does two different
things according to whether the number is zero or non-zero.
If the number is non-zero, the code immediately after "IF" will be
executed up to the point where either "ELSE" or "THEN" occur.
If the number is zero, the code immediately after "IF" will be skipped
and execution of code will continue immediately after the first occurence
of "ELSE" or "THEN".
6. The "ELSE" and "THEN" determine the code which will be executed after
"IF", depending on conditions following the "=" comparison.
7. The program completes by executing all the code after "THEN", in this
case with a simple exit message.
Here is another way to use IF and THEN.
: PressSpace?
." Please press a key." \ Ask for user input
CR \ CR = Carriage Return
KEY \ Wait for a keypress
32 \ 32 = Code for <Space>
= \ Key = <Space>?
IF
." Space was pressed!" \ Yes!
THEN
CR \ CR = Carriage Return
." Thank you!" \ Finished!
;
This was actually simpler!
We simply used "IF" to determine whether or not to print our message,
and we have no alternative action defined by the "ELSE" command.
Look at these simple conditional constructs and make sure that you really
understand what is happening.
In particular, try to follow exactly what is happening to numbers on the
stack.
Here is the program again with stack comments:
: PressSpace?
." Please press a key." \ Ask for user input Stack = Empty
CR \ CR = Carriage Return Stack = Empty
KEY \ Wait for a keypress Stack = Input
32 \ 32 = Code for <Space> Stack = Input, 32
= \ Key = <Space>? Stack = Result
IF \ Stack = Empty
." Space was pressed!" \ Yes! etc.
ELSE
." Space was not pressed!" \ No!
THEN
CR \ CR = Carriage Return
." Thank you!" \ Finished!
;
----------------------------------
Functions, Data and Error Checking
----------------------------------
Another way of analysing a program is in terms of the way "functions" are
used to operate on "data": whether a command "DOES" something (like the
addition function) or simply "IS" something (like a number which is added).
The syntax of some languages strictly controls how these different
categories are represented, to help you ensure that you write your code
in a way which prevents "incorrect" expressions.
HeliOS has no such enforced constraint, although you can if you wish impose
naming conventions for yourself, by using certain prefixes for certain
types of function etc..
Yet another abstraction is to specify the TYPE of "data/something" which
you are dealing with. In some languages there is a very strict limitation
concerning which types of data each kind of function may operate upon.
This kind of "artificial" abstraction can have its uses, especially in
helping the computer language to "enforce" so-called "correct" programming
techniques. However, checking all these things takes valuable computer
time and also enforces a rigid "straightjacket" on the programmer.
The fact is that all these "human" intellectual abstractions are basically
an imposition upon the way the computer works, since to a computer ALL
data is simply numerical and all processes obey a very simple binary logic.
Not only this, they can also soon become very irksome to an experienced
programmer who is accustomed to greater freedom.
HeliOS keeps things simple and efficient, staying close to the way the
computer CPU works and avoiding too many artificial constraints.
HeliOS, therefore, has no enforcement of such things as "data types", and
does very little by way of enforcement or error checking. (Although since
HeliOS is extensible and user-definable you could build such a system for
yourself if you wished to do so!)
HeliOS provides a comprehensive and powerful set of logical tools such
as looping, timing, and conditional constructs. It provides all the usual
data constructs such as constants, variables, text strings, data structures
and pointers. It then leaves you to your own devices.........
HeliOS does, however, enforce "structured programming" in that it will not
easily allow you to jump from place to place forward and backward in your
code. This is a good thing, because if allowed to do so most beginners
tend to write a tangled web of "spaghetti-logic" code and then often give
up before they have managed to disentangle themselves!
In general HeliOS programs progress logically and sequentially using simple
logical constructs such as IF....ELSE....THEN or BEGIN....UNTIL. HeliOS
keeps things simple, free of constraint, and powerful. It us down to you,
the programmer, to make sure that you use this freedom wisely, because
HeliOS will not waste time checking for your mistakes or forcing you to do
things "right".
---------------------
The HeliOS Dictionary
---------------------
Every command word which you create immediately becomes a fully fledged
part of the HeliOS command set, and can be used exactly like a HeliOS CORE
function. The name of the command is immediately entered in the HeliOS
dictionary, as can be verified by performing a vocabulary listing.
When you create a new command that command is instantly "compiled", which
involves two things:
1. HeliOS creates a special section of code which will be executed when
your new command is called.
2. HeliOS creates a new vocabulary entry.
These two actions, when repeated, build up two sections of information
in the computer's memory, and these two sections of information can be
saved and reloaded.
As you will see later, you can actually dispense with the "vocabulary"
data when "running" a stand-alone HeliOS program. The vocabulary data
is really a simple reference listing of command words which is only
required when you are initially compiling a program or using the HeliOS
interpreter.
Here are two important statements which you should try to understand
and bear in mind as you work with HeliOS:
1. INTERPRETING : When you "interpret" a command, this actually
performs the command function and has no effect
on the dictionary.
2. COMPILING : When you "compile" a command using a colon definition
the command function will NOT be performed.
The code which runs the new command function will be
compiled, along with the command name.
So:
." Hello World!"
- Prints "Hello World!" and does not compile anything.
: HELLO_WORLD ." Hello World!" ;
- Prints nothing but compiles a command called "HELLO_WORLD" which
WHEN EXECUTED will print "Hello World!".
Remember that you can always examine the HeliOS vocabulary by using
the Interpreter menu functions or the command line functions:
VLIST - Display CORE and USER vocabulary.
UVLIST - Display USER vocabulary.
CVLIST - Display CORE vocabulary.
Once a command word is in the dictionary, HeliOS will always understand
this word if you type it in your programs or at the command line. In
fact, just like a person, HeliOS "understands" your instructions by
interpreting words, like this:
1. HeliOS scans everything you write, one space-delimited word at a time.
2. It then looks up the word in its dictionary.
3. If it finds the word, it carries out the associated function.
4. If it does not find the word in the dictionary HeliOS will try to
find a matching symbol in its include files, and if it cannot do
this it tries to interpret the word as a pure number.
If all these options fail HeliOS issues a warning to you and stops
the process of interpreting immediately.
To summarize, here are simple definitions of the "technical" terms
used when referring to program compilation/interpretation:
EXECUTION = HeliOS takes a given word and carries out the
associated code.
INTERPRETATION = HeliOS reads your input and acts upon it by
executing the command.
COMPILATION = HeliOS creates a new command and stores the name
and the associated functional code.
In case you are interested in more details, here is a brief description
of how HeliOS carries out compilation of a colon definition:
* HeliOS reads the input text and finds the colon character.
* It then EXECUTES the COLON command.
* The COLON code, when EXECUTED, does two things:
1. It COMPILES the following word, the command name, into the vocabulary.
2. It sets up an internal operational MODE such that HeliOS will now
COMPILE all following words into the dictionary, until a SEMICOLON
is encountered.
3. It continues to COMPILE each successive word.
4. It finds a SEMICOLON and terminates the new word definition,
reverting back to INTERPRET mode.
-----------------------------------------
The concepts of RUN-TIME and COMPILE-TIME
-----------------------------------------
It will be more apparaent to you what these terms mean when you have
used HeliOS for some time, but even at this early stage we should give
a brief mention to these important concepts.
For any command word
COMPILE-TIME is the time when the word is compiled
RUN-TIME is the time when the word is executed, either when a program
executes or when a word is interpeted at the command line.
This sounds simple but there are subtleties to the situation!
For example, when a new word is being created, it is RUN-TIME for the
HeliOS command words which actually DO THE COMPILING, but COMPILE-TIME
for the new word itself.
In other words, the terms RUN_TIME and COMPILE-TIME relate to states of
particular words at a given time, and NOT the HeliOS system as a whole.
----------------
The HeliOS Stack
----------------
As mentioned above, the stack is a place wjhere HeliOS stores numbers
on a temporary basis.
It is rather as if HeliOS were to say to the stack "Here you are, please
hold these for me while I go and do something else! Please give them to
the next person who asks for them.".
The stack, as its name implies, is rather like a pile of data items,
and each new item simply goes onto the top of the pile.
Look at this simple diagram:
a <---- Top item
b <---- 2nd item
c <---- 3rd item
d <---- 4th item
etc. etc.
Let us put just one number, the number 4, on the stack:
4 <--- Top of stack
Now let us put just another number, the number 8, on the stack:
8 <--- Top of stack
4 <--- 2nd place on stack
Notice how each new number becomes the "top" number and displaces any
other numbers downwards.
If a computer, which is a simple minded creature, wants to do something
like an addition sum, it cannot do this quite so flexibly as we can.
Faced with the problem of adding 4 to 8 to give 12, we clever humans
might think something like this.
"Ah, first I see the number 4: lets see what we need to do with it."
"Oh, a "+" sign, so I need to find another number to add."
"There it is: 8. I will add them together. The result is 12."
"Whether I write 12 down or just remember it, I KNOW the answer was 12".
Or we might look at it differently, like this:
"Ah, two numbers 4 and 8."
"What is it that I have to do with them?"
"Ah, I see, a "+" sign, so I will add them together to get 12"
"Whether I write 12 down or just remember it, I KNOW the answer was 12".
Or we might look at it differently again:
"Ah, a "+" sign."
"This needs two numbers to add, so what are they?"
" I see, 4 and 8, that gives 12."
"Whether I write 12 down or just remember it, I KNOW the answer was 12".
You might think all these are boringly similar and obvious, but a computer
does not even have this limited choice.
Putting it simply:
* A computer has NO choices about how to carry out an operation.
* A computer needs to have its DATA loaded FIRST into its processing
unit's data storage space.
* A computer carries out an operation like "+" by ASSUMING that data
has ALREADY been stored in its processing unit data storage space.
* A computer has no automatic MEMORY or KNOWLEDGE.
* A computer simply places the result of its calculation in its
processing unit's data storage space, then carries on and forgets
what has happened.
So, to perform addition, a computer needs to:
1. Get the first number
2. Get the second number
3. Add then together
4. Store the result
The computer is quite inflexible and can work in no other way.
If you write an addition "sum" like this:
4 + 8
and pass it to the computer (as some computer languages do) the computer
has to be made to carry out various extra manipulations INTERNALLY by
the computer language BEFORE it can do the calculation in the form it
can work with. This is slowing everything down because more work is
having to be done UNNECESSARILY by the computer.
This is something like what the computer language would have to do
internally, unseen by you:
1. Read the first number.
2. It does not know what to do with it yet, so it stores it.
3. Read the "+" command.
4. It looks up the "+" command to see what this command does when it
executes.
5. It sees that two numbers are required for this command.
6. It stores or "remembers" that it is about to do a "+" operation.
7. It gets the second number and stores it.
8. It goes back to recall what command it was performing.
9. It performs the addition.
On the other hand, if YOU supply the computer with its data in the form
in which it can handle it directly, you get much faster operation.
If you write the "sum" above like this:
4 8 +
look how easy it is for the computer.
1. Get a number onto the stack
2. Get a number onto the stack
3. Execute the "+" command, which takes two numbers off the stack and
replaces the result on the stack.
The operation is over quickly and efficiently, the computer can go on
to do something else, and the result is automatically "remembered" on
the stack, where YOU can do something with it.
This means that computers can work more efficently, in general, by being
given numbers first, followed by function commands.
This is how HeliOS always works, because we are only interested in maximum
speed and efficiency: wherever the programmer can save the computer extra
work the program will run quicker.
The stack is a nice quick and simple "universal" storage area which is
organised internally in such a way the HeliOS can feed the computer's
central processing unit directly from the stack very quickly indeed.
The method of putting numbers on the stack BEFORE the operator function
is performed is called POSTFIX notation or REVERSE_POLISH notation.
The method of putting the operator IN-BETWEEN the number parameters
is called INFIX notation.
HeliOS uses postfix notation rather than infix notation for another
reason besides the one mentioned above.
Much of the power of HeliOS is derived from the fact that postfix
notation allows a very elegant and simple mechanism for passing
parameters between command functions.
Look at these examples:
The function + gets two numbers from the stack and adds them.
The function FPENSET gets one number from the stack and sets a pen colour.
The function CURPUT gets two numbers from the stack and sets the cursor.
So we can have a word like this:
: FANCYPRINT 12 + CURPUT FPENSET ." Hello!" ;
with a stack diagram ( Colour, Column, RowOffset - - - )
Look what happens here:
The function FANCYPRINT will expect three numbers already on the stack:
RowOffset <- Top of stack
Column <- 2nd on stack
Colour <- 3rd on stack
It then puts the number 12 on TOP of the others:
12 <- Top of stack
RowOffset <- 2nd on stack
Column <- 3rd on stack
Colour <- 4th on stack
It then adds 12 to the RowOffset value, giving a cursor displacement
offset from "Row 12", which is where we want to place our text.
This "final" calculated Row value is placed back on the stack:
RowOffset+12 (= Calculated Row position) <- Top of stack
Column <- 2nd on stack
Colour <- 3rd on stack
The function CURPUT is then executed, and we know that CURPUT takes
two numbers from the stack and places the cursor at that position.
The stack now looks like this:
Colour <- TOP of stack
The function FPENSET is then executed, and we know that FPENSET takes
one number from the stack and sets the text colour.
Finally the ." function prints the following text.
Look at this carefully to see how simply the parameter passing works,
then try to work out how it might work with INFIX notation.
You will probably agree that although it may be initially "strange"
compared to our habitual "human" use of INFIX notation, POSTFIX
notation is a great way of controlling a computer program!
Since HeliOS is concerned with helping you control your Amiga in the
most efficient way possible, you are going to HAVE to do your share of
the work and learn to use the stack and POSTFIX notation!
You will find this really very easy after the first few HeliOS
programming sessions, and you will notice that the HeliOS Interpreter
has a "real-time" permanent stack display to help you get used to
how the stack operates.
Try doing some simple arithmetic operations in the Interpreter and watch
the way the stack display changes. Stick with this until you really are
confident that you have grasped the way the stack works, because this
understanding is absolutely vital to everything you will do in HeliOS.
You may find it useful to try these simple command words:
. Prints the number on top of the stack and removes it
.s Prints all the stack contents without changing anything
DUP Duplicates the top stack number
SWAP Exchanges the top two stack numbers
ROT Moves the 3rd number on the stack to the top
OVER Duplicates the 2nd number on the stack on top of the stack
The last four words are called stack manipulation words.
There are many of these stack manipulation words in the HeliOS CORE
dictionary.
Look at the dictionary now and read the notes concerning these words,
then try using a variety of them to become accustomed to the way the
stack can be manipulated.
Having done this you will have had some experience of what is called
"stack management".
Stack management is very important in HeliOS: you can imagine that
in any language which uses stack parameter passing you will very often
have the need to adjust and modify the stack.
This can be interesting and often even becomes quite addictive, with
many programmers taking delight in managing very complex stacks.
Do NOT attempt to work with large stack sizes!
The stack is designed for quick and simple parameter passing, and if
you find that things are getting complicated you should either break
your program down into simpler more manageable chunks or resort to
using named CONSTANTS and VARIABLES.
We will explain CONSTANTS and VARIABLES later, but basically these
allow you to manipulate numbers using names rather than simply
referring to a position on the stack. You will find that in some
cases the stack is more efficient, and sometimes using CONSTANTS and
VARIABLES is better. You will soon learn your own programming style
and preferences, but you should NOT try to avoid using the stack
by using methods you might be accustomed to from other programming
languages: the stack is a dynamic and efficient programming tool.
Finally here are two more terms which you will find used in reference
to the stack:
"Stack overflow"
This means that there are too many numbers on the stack.
"Stack underflow"
This means that there are too few numbers on the stack for a given function.