498 lines
19 KiB
Plaintext
498 lines
19 KiB
Plaintext
@database beginner.guide
|
|
|
|
@Master beginner
|
|
|
|
@Width 75
|
|
|
|
|
|
This is the AmigaGuide® file beginner.guide, produced by Makeinfo-1.55 from
|
|
the input file beginner.
|
|
|
|
|
|
@NODE "main" "Common Problems"
|
|
@Next "Other Information"
|
|
@Prev "Examples.guide/Recursion Example"
|
|
@Toc "Contents.guide/main"
|
|
|
|
Common Problems
|
|
***************
|
|
|
|
If you are new to programming or the Amiga E language then you might
|
|
appreciate some help locating problems (or @{fg shine }bugs@{fg text }) in your programs. This
|
|
Appendix details some of the most common mistakes people make.
|
|
|
|
|
|
@{" Assignment and Copying " Link "Assignment and Copying" }
|
|
@{" Pointers and Memory Allocation " Link "Pointers and Memory Allocation" }
|
|
@{" String and List Misuse " Link "String and List Misuse" }
|
|
@{" Initialising Data " Link "Initialising Data" }
|
|
@{" Freeing Resources " Link "Freeing Resources" }
|
|
@{" Pointers and Dereferencing " Link "Pointers and Dereferencing" }
|
|
@{" Mathematics Functions " Link "Mathematics Functions" }
|
|
@{" Signed and Unsigned Values " Link "Signed and Unsigned Values" }
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Assignment and Copying" "Assignment and Copying"
|
|
@Next "Pointers and Memory Allocation"
|
|
@Toc "main"
|
|
|
|
Assignment and Copying
|
|
======================
|
|
|
|
This is probably the most common problem encountered by people who are
|
|
used to languages like BASIC. Strings, lists, arrays and objects cannot
|
|
be initialised using an assignment statement: data must be copied. Unlike
|
|
BASIC, this kind of data is represented by a pointer (see @{"PTR Type" Link "Types.guide/PTR Type" }), so
|
|
only the pointer would be copied by an assignment statement, not the data
|
|
it points to. The following examples all copy a pointer rather than the
|
|
data, and so the memory for the data is shared (and this is probably not
|
|
what was intended).
|
|
|
|
DEF s[30]:STRING, t[30]:STRING,
|
|
l[10]:LIST, m[10]:LIST,
|
|
x:myobj, y:myobj,
|
|
a[25]:ARRAY OF INT, b[25]:ARRAY OF INT
|
|
|
|
/* You probably don't want to do any of these */
|
|
s:='Some text in a string'
|
|
l:=[-6,4,-9]
|
|
x:=[1,2,3]:myobj
|
|
a:=[1,-3,8,7]:INT
|
|
|
|
t:=s
|
|
m:=l
|
|
y:=x
|
|
b:=a
|
|
|
|
All the declarations allocate memory for the appropriate data. The first
|
|
four assignments replace the pointers to this memory with pointers to some
|
|
statically allocated memory. The memory allocated by the declarations is
|
|
probably now unreachable, because the only pointers to it have been
|
|
over-written. BASIC programmers might expect, say, the assignment to @{b }s@{ub } to
|
|
have copied the string into the memory allocated for @{b }s@{ub } by its declaration,
|
|
but this is not the case (only the pointer to the string is copied).
|
|
|
|
For the E-string, @{b }s@{ub }, and E-list, @{b }l@{ub }, there is another, disastrous
|
|
side-effect. The assignment to @{b }s@{ub }, for example, means that @{b }s@{ub } will point to
|
|
a normal string, not an E-string. So, @{b }s@{ub } can no longer be used with any of
|
|
the E-string functions. The same considerations apply to the E-list, @{b }l@{ub },
|
|
as well.
|
|
|
|
The final four assignments also copy only the pointers. This means
|
|
that @{b }s@{ub } and @{b }t@{ub } will point to exactly the same memory. So they will
|
|
represent exactly the same string, and any change to one of them (by a
|
|
@{b }StrAdd@{ub }, for example) will appear to change both (of course, only one lump
|
|
of memory is being changed, but there are two references to it). This is
|
|
called memory @{fg shine }sharing@{fg text }, and is only a problem if you didn't intend to do
|
|
it!
|
|
|
|
To get the result that a BASIC programmer might have intended you need
|
|
to copy the appropriate data. For E-strings and E-lists the functions to
|
|
use are, respectively, @{b }StrCopy@{ub } and @{b }ListCopy@{ub }. All other data must be
|
|
copied using a function like @{b }CopyMem@{ub } (an Amiga system function from the
|
|
Exec library). (Normal strings can be copied using @{b }AstrCopy@{ub } built-in
|
|
function, see the `Reference Manual'.) Here's the revised forms of the
|
|
above assignments:
|
|
|
|
DEF s[30]:STRING, t[30]:STRING,
|
|
l[10]:LIST, m[10]:LIST,
|
|
x:myobj, y:myobj,
|
|
a[25]:ARRAY OF INT, b[25]:ARRAY OF INT
|
|
|
|
StrCopy(s, 'Some text in a string') /* Defaults to ALL */
|
|
ListCopy(l, [-6,4,-9]) /* Defaults to ALL */
|
|
CopyMem([1,2,3]:myobj, x, SIZEOF myobj)
|
|
CopyMem([1,-3,8,7]:INT, a, 4*SIZEOF INT)
|
|
|
|
StrCopy(t, s) /* Defaults to ALL */
|
|
ListCopy(m, l) /* Defaults to ALL */
|
|
CopyMem(x, y, SIZEOF myobj)
|
|
CopyMem(a, b, 4*SIZEOF INT)
|
|
|
|
Notice that you need to supply the size (in bytes) of the data being
|
|
copied when you use @{b }CopyMem@{ub }. The parameters are also given in a slightly
|
|
different order to the E-string and E-list copying functions (i.e., the
|
|
source must be the first parameter and the destination the second). The
|
|
@{b }CopyMem@{ub } function does a byte-by-byte copy, something like this:
|
|
|
|
PROC copymem(src, dest, size)
|
|
DEF i
|
|
FOR i:=1 TO size DO dest[]++:=src[]++
|
|
ENDPROC
|
|
|
|
Of course, you can use string constants and lists to give initialised
|
|
arrays, but in this case you should be initialising an appropriately typed
|
|
pointer. You must also be careful not to run into a static data problem
|
|
(see @{"Static data" Link "Types.guide/Static data" }).
|
|
|
|
DEF s:PTR TO CHAR, l:PTR TO LONG, x:PTR TO myobj, a:PTR TO INT
|
|
s:='Some text in a string'
|
|
l:=[-6,4,-9]
|
|
x:=[1,2,3]:myobj
|
|
a:=[1,-3,8,7]:INT
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Pointers and Memory Allocation" "Pointers and Memory Allocation"
|
|
@Next "String and List Misuse"
|
|
@Prev "Assignment and Copying"
|
|
@Toc "main"
|
|
|
|
Pointers and Memory Allocation
|
|
==============================
|
|
|
|
Another common error is to declare a pointer (usually a pointer to an
|
|
object) and then use it without the memory for the target data being
|
|
allocated.
|
|
|
|
/* You don't want to do this */
|
|
DEF p:PTR TO object
|
|
p.element:=99
|
|
|
|
There are two ways of correcting this: either dynamically allocate the
|
|
memory using @{b }NEW@{ub } or, more simply, let an appropriate declaration allocate
|
|
it. See @{"Memory Allocation" Link "Memory.guide/main" }.
|
|
|
|
DEF p:PTR TO object
|
|
NEW p
|
|
p.element:=99
|
|
|
|
DEF p:object
|
|
p.element:=99
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "String and List Misuse" "String and List Misuse"
|
|
@Next "Initialising Data"
|
|
@Prev "Pointers and Memory Allocation"
|
|
@Toc "main"
|
|
|
|
String and List Misuse
|
|
======================
|
|
|
|
Some of the string functions can only be used with E-strings.
|
|
Generally, these are the ones that might extend the string. If you use a
|
|
normal string instead you can run into some serious (but subtle) problems.
|
|
Commonly misused functions are @{b }ReadStr@{ub }, @{b }MidStr@{ub } and @{b }RightStr@{ub }. Similar
|
|
problems can arise by using a list when an E-list is required by a list
|
|
function.
|
|
|
|
String constants and normal lists are static data, so you shouldn't try
|
|
to alter their contents unless you know what you're doing (see
|
|
@{"Static data" Link "Types.guide/Static data" }).
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Initialising Data" "Initialising Data"
|
|
@Next "Freeing Resources"
|
|
@Prev "String and List Misuse"
|
|
@Toc "main"
|
|
|
|
Initialising Data
|
|
=================
|
|
|
|
Probably one of the most common mistakes that even seasoned programmers
|
|
make is to forget to initialise variables (especially pointers). The
|
|
rules in the `Reference Manual' state which declarations initialise
|
|
variables to zero values, but it is often wise to make even these explicit
|
|
(using initialised declarations). Variable initialisation becomes even
|
|
more important when using automatic exceptions.
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Freeing Resources" "Freeing Resources"
|
|
@Next "Pointers and Dereferencing"
|
|
@Prev "Initialising Data"
|
|
@Toc "main"
|
|
|
|
Freeing Resources
|
|
=================
|
|
|
|
Unlike a Unix operating system, the Amiga operating system requires the
|
|
programmer to release or free any resources used by a program. In
|
|
practice, this means that all windows, screens, libraries, etc., that are
|
|
successfully opened must be closed before the program terminates. Amiga E
|
|
provides some help, though: the four most commonly used libraries (Dos,
|
|
Exec, Graphics and Intuition) are opened before the start of an E program
|
|
and closed at the end (or when @{b }CleanUp@{ub } is called). Also, memory allocated
|
|
using any of @{b }List@{ub }, @{b }String@{ub }, @{b }New@{ub }, @{b }NEW@{ub }, @{b }NewR@{ub }, @{b }NewM@{ub } and @{b }FastNew@{ub } is
|
|
automatically freed at the end of a program.
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Pointers and Dereferencing" "Pointers and Dereferencing"
|
|
@Next "Mathematics Functions"
|
|
@Prev "Freeing Resources"
|
|
@Toc "main"
|
|
|
|
Pointers and Dereferencing
|
|
==========================
|
|
|
|
C programmers may think that the @{b } ^@{ub }@{fg shine }var@{fg text }@{b }@{ub } and @{b }{@{ub }@{fg shine }var@{fg text } @{b } }@{ub } expressions
|
|
are the direct equivalent of C's @{b } &@{ub }@{fg shine }var@{fg text }@{b }@{ub } and @{b } *@{ub }@{fg shine }var@{fg text }@{b }@{ub } expressions.
|
|
However, in E dereferencing is normally achieved using array and object
|
|
element selection, and pointers to large amounts of data (like E-strings
|
|
or objects) are made by declarations. This means that the @{b } ^@{ub }@{fg shine }var@{fg text }@{b }@{ub } and
|
|
@{b }{@{ub }@{fg shine }var@{fg text } @{b } }@{ub } expressions are rarely used, whilst @{b }@{ub }@{fg shine }var@{fg text }@{b }[]@{ub } is very
|
|
common.
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Mathematics Functions" "Mathematics Functions"
|
|
@Next "Signed and Unsigned Values"
|
|
@Prev "Pointers and Dereferencing"
|
|
@Toc "main"
|
|
|
|
Mathematics Functions
|
|
=====================
|
|
|
|
The standard mathematical operators @{b }/@{ub } and @{b }*@{ub } do not use full 32-bit
|
|
values in their calculations, as noted previously (see
|
|
@{"Maths and logic functions" Link "BuiltIns.guide/Maths and logic functions" }). A common problem is to forget this and use
|
|
them where the values will exceed the 16-bit limit. A typical example is
|
|
the position calculations used with proportional gadgets. See
|
|
@{"Signed and Unsigned Values" Link "Signed and Unsigned Values" }.
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Signed and Unsigned Values" "Signed and Unsigned Values"
|
|
@Prev "Mathematics Functions"
|
|
@Toc "main"
|
|
|
|
Signed and Unsigned Values
|
|
==========================
|
|
|
|
This is a quite advanced topic, but might be the cause of some strange
|
|
bugs in your programs. Basically, E does not have a way of
|
|
differentiating signed and unsigned values from, say, the @{b }LONG@{ub } type. That
|
|
is, all values from the 32-bit, @{b }LONG@{ub } type are considered to be signed
|
|
values, so the range of values is from -2,147,483,648 to 2,147,483,647.
|
|
If the values from this type were taken to be unsigned then no negative
|
|
values would be allowed but more positive values would be possible (i.e.,
|
|
the range of values would be from zero to 4,294,967,295). This
|
|
distinction would also affect the mathematical operators.
|
|
|
|
In practice, though, it is not the @{b }LONG@{ub } type that can cause problems.
|
|
Instead, it is the 16-bit, @{b }INT@{ub } type, which again is considered to be
|
|
signed. This means that the range of values is -32,768 to 32,767.
|
|
However, the Amiga system objects contain a number of 16-bit, @{b }INT@{ub } elements
|
|
which are actually interpreted as unsigned, ranging from zero to 65,535.
|
|
A prominent example is the proportional gadget which forms a part of a
|
|
scroll-bar on a window (for example, a drawer window on Workbench). This
|
|
works with unsigned 16-bit values, which is at odds with the @{b }INT@{ub } type in E.
|
|
These values are commonly used in calculations to determine the position
|
|
of something displayed in a window, and if the @{b }INT@{ub } type is used without
|
|
taking into account this signed/unsigned problem the results can be quite
|
|
wrong. Luckily it is very simple to convert the signed @{b }INT@{ub } values into
|
|
unsigned values if they are part of some expression, since the value of
|
|
any expression is taken from the @{b }LONG@{ub } type (and unsigned @{b }INT@{ub } values fit
|
|
well within the range of even signed @{b }LONG@{ub } values).
|
|
|
|
PROC unsigned_int(x) IS x AND $FFFF
|
|
|
|
The function @{b }unsigned_int@{ub }, above, is very specific to the way the Amiga
|
|
handles values internally, so to understand how it works is beyond the
|
|
scope of this Guide. It should be used wherever an unsigned 16-bit value
|
|
is stored in an @{b }INT@{ub } element of, say, an Amiga system object. For example,
|
|
the position of the top of a (vertical) proportional gadget as a
|
|
percentage (zero to one hundred) of its size can be calculated like this:
|
|
|
|
/* propinfo is from the module 'intuition/intuition' */
|
|
DEF gad:PTR TO propinfo, pct
|
|
/* Set up gad... */
|
|
/* Calculate percentage (MAXPOT is from 'intuition/intuition') */
|
|
pct:=Div(Mul(100,unsigned_int(gad.vertpot)),MAXPOT)
|
|
|
|
Notice that the full 32-bit functions @{b }Div@{ub } and @{b }Mul@{ub } need to be used since
|
|
the arithmetic may be well over the normal 16-bits used in the @{b }/@{ub } and @{b }*@{ub }
|
|
operators.
|
|
|
|
The remaining type, @{b }CHAR@{ub }, is not, in practice, a problem. It is the
|
|
only unsigned type, with a range of values from zero to 255. There is a
|
|
fairly simple way to convert these values to signed values (and again this
|
|
is particular to the way the Amiga stores values internally). One good
|
|
example of a signed @{b }CHAR@{ub } value is the priority value associated with a
|
|
node of an Amiga list (i.e., the @{b }pri@{ub } element of an @{b }ln@{ub } object from the
|
|
module @{b }exec/nodes@{ub }).
|
|
|
|
PROC signed_char(x) IS IF x<128 THEN x ELSE x-256
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Other Information" "Other Information"
|
|
@Next "EIndex.guide/main"
|
|
@Prev "main"
|
|
@Toc "Contents.guide/main"
|
|
|
|
Other Information
|
|
*****************
|
|
|
|
This Appendix contains some useful, miscellaneous information.
|
|
|
|
|
|
@{" Amiga E Versions " Link "Amiga E Versions" }
|
|
@{" Further Reading " Link "Further Reading" }
|
|
@{" Amiga E Author " Link "Amiga E Author" }
|
|
@{" Guide Author " Link "Guide Author" }
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Amiga E Versions" "Amiga E Versions"
|
|
@Next "Further Reading"
|
|
@Toc "Other Information"
|
|
|
|
Amiga E Versions
|
|
================
|
|
|
|
As I write, the current version of Amiga E is version 3.2e (which is
|
|
minor update of v3.2a). This edition of the Guide is based primarily on
|
|
that version, but the majority still applies to the older versions,
|
|
including the last Public Domain version (v2.1b). Version 3.3 is
|
|
imminent, and the new `Reference Manual' will contain details of the new
|
|
features and changes.
|
|
|
|
Please note that, as of v3.0a, Amiga E is a commercial product so you
|
|
must pay a fee to get a version of the full compiler (which will be
|
|
registered to you). The Public Domain distribution contains only a
|
|
demonstration version of the compiler, with limited functionality. See
|
|
the `Reference Manual' for more details.
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Further Reading" "Further Reading"
|
|
@Next "Amiga E Author"
|
|
@Prev "Amiga E Versions"
|
|
@Toc "Other Information"
|
|
|
|
Further Reading
|
|
===============
|
|
|
|
`Amiga E Language Reference'
|
|
Referred to as the `Reference Manual' in this Guide. This is one of
|
|
the documents that comes with the Amiga E package, and is essential
|
|
reading since it was written by Wouter (the author of Amiga E). It
|
|
contains a lot of extra information.
|
|
|
|
`Rom Kernel Reference Manual' (Addison-Wesley)
|
|
This is the official Commodore documentation on the Amiga system
|
|
functions and is a must if you want to use these functions properly.
|
|
At the time of writing the Third Edition is the most current and it
|
|
covers the Amiga system functions up to Release 2 (i.e., AmigaDOS
|
|
2.04 and KickStart 37). Because there is so much information it
|
|
comes in three separate volumes: `Libraries', `Includes and
|
|
Autodocs', and `Devices'. The `Libraries' volume is probably the
|
|
most useful as it contains many examples and a lot of tutorial
|
|
material. However, the examples are written mainly in C (the
|
|
remainder are in Assembly). To alleviate this problem I have
|
|
undertaken to re-code them in E, and Part One and Part Two of this
|
|
effort should be available from Aminet or good PD houses (the archive
|
|
names will be something like @{b }JRH-RKRM-1@{ub } and @{b }JRH-RKRM-2@{ub }).
|
|
(Unfortunately, it seems that the actual manuals may be hard to find
|
|
since there are now out-of-print.)
|
|
|
|
`The AmigaDOS Manual' (Bantam Books)
|
|
This is the companion to the `Rom Kernel Reference Manual' and is the
|
|
official Commodore book on AmigaDOS (both the AmigaDOS programs and
|
|
the DOS library functions). Again, the Third Edition is the most
|
|
current.
|
|
|
|
Example sources
|
|
Amiga E comes with a large collection of example programs. When
|
|
you're familiar with the language you should be able to learn quite a
|
|
bit from these. There are a lot of small, tutorial programs and a
|
|
few large, complicated programs.
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Amiga E Author" "Amiga E Author"
|
|
@Next "Guide Author"
|
|
@Prev "Further Reading"
|
|
@Toc "Other Information"
|
|
|
|
Amiga E Author
|
|
==============
|
|
|
|
In case you didn't know the author and creator of Amiga E is Wouter van
|
|
Oortmerssen (or @{b }$#%!@{ub }). You can reach him by normal mail at the following
|
|
address:
|
|
|
|
Wouter van Oortmerssen (@{b }$#%!@{ub })
|
|
Levendaal 87
|
|
2311 JG Leiden
|
|
HOLLAND
|
|
|
|
However, he much prefers to chat by E-mail, and you can reach him at the
|
|
following addresses:
|
|
|
|
@{b }Wouter@alf.let.uva.nl@{ub } (E-programming support)
|
|
@{b }Wouter@mars.let.uva.nl@{ub } (personal)
|
|
@{b }Oortmers@gene.fwi.uva.nl@{ub } (other)
|
|
|
|
Better still, if your problem or enquiry is of general interest to Amiga E
|
|
users you may find it useful joining the Amiga E mailing list. Wouter
|
|
regularly contributes to this list and there are a number of good
|
|
programmers who are at hand to help or discuss problems. To join send a
|
|
message to:
|
|
|
|
@{b }amigae-request@bkhouse.cts.com@{ub }
|
|
|
|
Once you're subscribed, you will receive a copy of each message mailed to
|
|
the list. You will also receive a message telling you how you can
|
|
contribute (i.e., ask questions!).
|
|
|
|
|
|
@ENDNODE
|
|
|
|
@NODE "Guide Author" "Guide Author"
|
|
@Prev "Amiga E Author"
|
|
@Toc "Other Information"
|
|
|
|
Guide Author
|
|
============
|
|
|
|
This Guide was written by Jason Hulance, with a lot of help and
|
|
guidance from Wouter. The original aim was to produce something that
|
|
might be a useful introduction to Amiga E for beginners, so that the
|
|
language could (rightly) become more widespread. The hidden agenda was to
|
|
free Wouter from such a task so that he could concentrate his efforts on
|
|
improving Amiga E.
|
|
|
|
You can reach me by normal mail most easily at the following (work)
|
|
address:
|
|
|
|
Jason R. Hulance
|
|
Formal Systems (Europe) Ltd.
|
|
3 Alfred Street
|
|
Oxford
|
|
OX1 4EH
|
|
ENGLAND
|
|
|
|
Alternatively, you can find me on the Amiga E mailing list, or E-mail me
|
|
directly at one of the following addresses:
|
|
|
|
@{b }jason@fsel.com@{ub }
|
|
@{b }m88jrh@ecs.oxford.ac.uk@{ub }
|
|
|
|
If you have any changes or additions you'd like to see then I'd be very
|
|
happy to consider them. Criticism of the text is also welcome, especially
|
|
if you can suggest a better way of explaining things. I am also keen to
|
|
hear from people who can highlight areas that are particularly confusing
|
|
or badly worded!
|
|
|
|
|
|
@ENDNODE
|
|
|