diff --git a/amigae33a/E_v3.3a/Bin/AGSplit b/amigae33a/E_v3.3a/Bin/AGSplit new file mode 100644 index 0000000..4f5aaee Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/AGSplit differ diff --git a/amigae33a/E_v3.3a/Bin/AProf b/amigae33a/E_v3.3a/Bin/AProf new file mode 100644 index 0000000..558bb43 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/AProf differ diff --git a/amigae33a/E_v3.3a/Bin/Ag2Txt b/amigae33a/E_v3.3a/Bin/Ag2Txt new file mode 100644 index 0000000..855bd7f Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Ag2Txt differ diff --git a/amigae33a/E_v3.3a/Bin/Ag2Txt13 b/amigae33a/E_v3.3a/Bin/Ag2Txt13 new file mode 100644 index 0000000..e5f453e Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Ag2Txt13 differ diff --git a/amigae33a/E_v3.3a/Bin/ECDEMO b/amigae33a/E_v3.3a/Bin/ECDEMO new file mode 100644 index 0000000..ed492a1 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/ECDEMO differ diff --git a/amigae33a/E_v3.3a/Bin/EFindHit b/amigae33a/E_v3.3a/Bin/EFindHit new file mode 100644 index 0000000..0dfa5a4 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/EFindHit differ diff --git a/amigae33a/E_v3.3a/Bin/EYacc b/amigae33a/E_v3.3a/Bin/EYacc new file mode 100644 index 0000000..2589466 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/EYacc differ diff --git a/amigae33a/E_v3.3a/Bin/FindModule b/amigae33a/E_v3.3a/Bin/FindModule new file mode 100644 index 0000000..4dc0281 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/FindModule differ diff --git a/amigae33a/E_v3.3a/Bin/FindString b/amigae33a/E_v3.3a/Bin/FindString new file mode 100644 index 0000000..5a5ccfa Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/FindString differ diff --git a/amigae33a/E_v3.3a/Bin/FlushCache b/amigae33a/E_v3.3a/Bin/FlushCache new file mode 100644 index 0000000..5d97886 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/FlushCache differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/E.font b/amigae33a/E_v3.3a/Bin/Fonts/E.font new file mode 100644 index 0000000..b990246 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/E.font differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/E/11 b/amigae33a/E_v3.3a/Bin/Fonts/E/11 new file mode 100644 index 0000000..f4f85e4 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/E/11 differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/ELSE.font b/amigae33a/E_v3.3a/Bin/Fonts/ELSE.font new file mode 100644 index 0000000..871aa47 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/ELSE.font differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/ELSE/11 b/amigae33a/E_v3.3a/Bin/Fonts/ELSE/11 new file mode 100644 index 0000000..959696c Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/ELSE/11 differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/README b/amigae33a/E_v3.3a/Bin/Fonts/README new file mode 100644 index 0000000..29261f2 --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Fonts/README @@ -0,0 +1,6 @@ +These fonts were especially designed to make E sources look good :-), +E/11 (and ELSE/11, the proportional version) were designed for non-interlaced +resolutions on 1084-type (fuzzy) monitors. +end/10 and 11 (monospaced) and except/12 and 13 (proportional) were designed +for square-pixel resolutions (such as DBLPAL) on a multisync/VGA type +monitor. Sizes 10 and 12 are relatively thin. diff --git a/amigae33a/E_v3.3a/Bin/Fonts/end.font b/amigae33a/E_v3.3a/Bin/Fonts/end.font new file mode 100644 index 0000000..81075be Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/end.font differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/end/10 b/amigae33a/E_v3.3a/Bin/Fonts/end/10 new file mode 100644 index 0000000..8b0916d Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/end/10 differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/end/11 b/amigae33a/E_v3.3a/Bin/Fonts/end/11 new file mode 100644 index 0000000..c648ba5 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/end/11 differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/except.font b/amigae33a/E_v3.3a/Bin/Fonts/except.font new file mode 100644 index 0000000..fc69872 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/except.font differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/except/11 b/amigae33a/E_v3.3a/Bin/Fonts/except/11 new file mode 100644 index 0000000..b47463f Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/except/11 differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/except/12 b/amigae33a/E_v3.3a/Bin/Fonts/except/12 new file mode 100644 index 0000000..eed9160 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/except/12 differ diff --git a/amigae33a/E_v3.3a/Bin/Fonts/except/13 b/amigae33a/E_v3.3a/Bin/Fonts/except/13 new file mode 100644 index 0000000..61a86c7 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Fonts/except/13 differ diff --git a/amigae33a/E_v3.3a/Bin/Iconvert b/amigae33a/E_v3.3a/Bin/Iconvert new file mode 100644 index 0000000..7936d4c Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Iconvert differ diff --git a/amigae33a/E_v3.3a/Bin/O2M b/amigae33a/E_v3.3a/Bin/O2M new file mode 100644 index 0000000..2f48f49 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/O2M differ diff --git a/amigae33a/E_v3.3a/Bin/README b/amigae33a/E_v3.3a/Bin/README new file mode 100644 index 0000000..8a2380e --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/README @@ -0,0 +1,4 @@ +Here you'll find most of the executables that come with E. Documentation for +the functioning of most of these can be found in 'Docs/E.doc'. The Tools +'Explorer', 'Aprof' and 'EYacc' have their respective directories in the +Tools directory. diff --git a/amigae33a/E_v3.3a/Bin/Rexx/Ecompile.ced b/amigae33a/E_v3.3a/Bin/Rexx/Ecompile.ced new file mode 100644 index 0000000..0ab47eb --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Rexx/Ecompile.ced @@ -0,0 +1,37 @@ +/* Ecompile.rexx: run E compiler from ced. + thanks to Rick Younie for improvements. */ + +epath = 'e:bin/' /* homedir of EC */ + +OPTIONS RESULTS +ADDRESS COMMAND + +IF ~EXISTS('ram:ec') THEN 'copy 'epath'ec ram:' /* for slow sys: devices */ + +ADDRESS 'rexx_ced' + +'status 19' /* ask ced filename */ +file = result + +'status 18' +IF result ~= 0 THEN DO /* save if changed */ + 'save' file + SAY 'saving changes..' +END +ELSE SAY 'no changes..' + +PARSE VAR file comparg '.e' /* strip the extension */ +SAY 'invoking E compiler with file' comparg'.e' + +ADDRESS +OPTIONS FAILAT 1000000 +'ram:ec -E' comparg /* run compiler */ +ebyte = rc + +IF EXISTS(comparg) THEN comparg /* run exe */ + +ADDRESS +pull /* wait for a */ +'cedtofront' +IF ebyte>0 THEN 'jump to byte' ebyte /* jump to spot of error */ +exit 0 diff --git a/amigae33a/E_v3.3a/Bin/Rexx/Ecompile.ged b/amigae33a/E_v3.3a/Bin/Rexx/Ecompile.ged new file mode 100644 index 0000000..1919244 --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Rexx/Ecompile.ged @@ -0,0 +1,101 @@ +/* $VER: CompileE.ged v0.5 (8.8.94) + by Leon Woestenberg (leon@stack.urc.tue.nl) + + This is an ARexx script for GoldED (© Dietmar Eilert), and enables + you to compile E programs from the editor. Just add a menu item, + and in the 'Command' window select this ARexx script. Also, set + the output to 'NIL:'. You might as well add keybindings, window + gadgets, a shortcut key or even API to call this script. + + Now just edit your source in the active window, and select the + menu item (or key, gadget etc.) you added. The compiler will be + invoked, and feedback will be showed in the status line of the + active window. If necessary, unsaved changes will be saved first. + After compilation, the status line will show the result. If there + was an error, the cursor will jump exactly to the spot of error, + and the error message of the compiler will be shown in the status + line. Warnings or unreferences (not both) will also be shown but + will not jump, nor beep, as this would get annoying very soon. + Also, cursor slot (bookmark) 9 will contain the spot of trouble. + +*/ + +/* adjust your EC filename here, especially after registering :) */ +ec='ECDEMO' + +OPTIONS RESULTS + +IF (LEFT(ADDRESS(),6)~="GOLDED") THEN ADDRESS 'GOLDED.1' +'LOCK CURRENT QUIET' +IF rc THEN EXIT + +options='ERRBYTE' 'QUIET' + +'QUERY ANYTEXT' +IF (result='TRUE') THEN +DO + 'QUERY DOC VAR FILEPATH' + IF (UPPER(RIGHT(result,2))='.E') THEN + DO + 'QUERY MODIFY' + IF (result='TRUE') THEN + DO + 'REQUEST STATUS="Saving changes..."' + 'SAVE ALL' + END + 'REQUEST STATUS="Compiling source..."' + ADDRESS COMMAND ec filepath options '>T:EC_Report' + errorbyte=rc + IF errorbyte>0 THEN + DO + 'FOLD OPEN=TRUE ALL' + 'GOTO UNFOLD=TRUE BYTE=' || errorbyte + 'PING 9' + END + IF OPEN(filehandle,'T:EC_Report','Read')~=0 THEN + DO + importance=0 + DO WHILE ~EOF(filehandle) & importance~='ERROR' + lastline=READLN(filehandle) + /* messages ordered in accending importance */ + IF (INDEX(lastline,'UNREFERENCED:')~=0) & (importance<1) THEN + DO + importance=1 + message=lastline + END + IF (INDEX(lastline,'WARNING:')~=0) & (importance<2) THEN + DO + importance=2 + message=lastline + END + IF (INDEX(lastline,'ERROR:')~=0) & (importance<3) THEN + DO + importance=3 + message=lastline + END + IF (INDEX(lastline,'EC INTERNAL ERROR')~=0) & (importance<4) THEN + DO + importance=4 + message=lastline + END + END + ok=CLOSE(filehandle) + IF importance=0 THEN message='Compilation succesful.' + IF importance>=3 THEN 'BEEP' + message=TRANSLATE(message,'''','"') + 'FIX VAR message' + 'REQUEST STATUS="' || message ||'"' + END + END + ELSE + DO + 'REQUEST STATUS="Source has no .e extension!"' + END +END +ELSE +DO + 'REQUEST STATUS="Say what?! Try typing some e source first :)"' +END +'UNLOCK' +EXIT + diff --git a/amigae33a/E_v3.3a/Bin/SetPatch/SetPatch43_6.lha b/amigae33a/E_v3.3a/Bin/SetPatch/SetPatch43_6.lha new file mode 100644 index 0000000..f774f33 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/SetPatch/SetPatch43_6.lha differ diff --git a/amigae33a/E_v3.3a/Bin/ShowCache b/amigae33a/E_v3.3a/Bin/ShowCache new file mode 100644 index 0000000..4eec974 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/ShowCache differ diff --git a/amigae33a/E_v3.3a/Bin/ShowHunk b/amigae33a/E_v3.3a/Bin/ShowHunk new file mode 100644 index 0000000..e7dc49d Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/ShowHunk differ diff --git a/amigae33a/E_v3.3a/Bin/ShowModule b/amigae33a/E_v3.3a/Bin/ShowModule new file mode 100644 index 0000000..93fbb2e Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/ShowModule differ diff --git a/amigae33a/E_v3.3a/Bin/Tools/AProf/AProf.guide b/amigae33a/E_v3.3a/Bin/Tools/AProf/AProf.guide new file mode 100644 index 0000000..03554e7 --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Tools/AProf/AProf.guide @@ -0,0 +1,867 @@ +@DATABASE "AProf.guide" + +@remark Profiler Dokumentation für Version 3.3 +@remark +@remark $RCSfile: AProf.guide $ +@remark +@remark $Revision: 1.7 $ $Date: 1994/10/04 11:28:35 $ + + + + +@remark ****************** +@remark * Main +@remark ****************** +@NODE Main "AProf.guide" + + Documentation for Amiga Profiler V3.30 + © 1993,94 Michael G. Binz + + @{" What is a profiler? " link l-what} + + @{" System requirements " link l-sysrequ } + @{" Installation procedure " link l-install } + + @{" Starting the profiler " link l-start } + @{" User interface " link l-ui } + @{" Configurability " link l-config } + + @{" Notes " link l-notes } + @{" Tested Systems " link l-systeme } + @{" Caveats " link l-caveats } + @{" StripB " link l-stripb } + + @{" Feedback " link l-feedback } + @{" AProf needs you..." link l-enforcer-blah } + @{" Copyright " link l-copyright} + + @{" Changes " link l-changes } + @{" Q+A " link frageantwort } +@ENDNODE + + + +@remark ****************** +@remark * Was isses??? +@remark ****************** +@NODE l-what "AProf:What is a profiler" + + A profiler is a development tool supporting the developer in code + optimization. A specified program is executed by the profiler + which collects several informations (ie. call counts, time values) + while execution. This data can be used to locate the so-called + hot spots in your code - functions where most of the execution time + is spent and optimization will gain most effect. + + The following articles supply further information on profilers: + + o Dr. Dobb's Journal, January 1993 + Joseph Newcomer, 'Profiling for Performance', pp. 80 + + o Dr. Dobb's Journal, November 1993 + Michael R. Dunlavey, 'Performance Tuning: Slugging it out', pp. 18 +@ENDNODE + + + +@remark ****************** +@remark * Installation & Systemanforderungen +@remark ****************** +@NODE l-sysrequ "AProf: System requirements" + + o Hardware requirements + + The profiler needs at least Workbench/Kickstart 2.04 and a minimum + of 500K available memory (depends on profilees sizes). + + It has been tested successfully with Amiga 500, 2000, 3000, 4000 + and OS versions 2.04, 2.1, 3.0. + + + o Software requirements + + Your compiler must be able to create Amiga symbol hunks. Code + symbols included in this hunks should only address the starting + addresses of functions in your code. No intermediate jump + labels must be defined. (See @{ "Clean symbol tables" link frageantwort}, @{ "Tested compilers" link l-systeme }) +@ENDNODE + +@NODE l-install "AProf:Installation procedure" + + Copy all files included in AProf3_30.lha into a directory and add + this directory to your PATH. + + Do not delete AProf's icon (AProf.info), since configuration data + is located in this file (See @{"Configurability" link l-config}). +@ENDNODE + + + +@remark ****************** +@remark * Start & Oberfläche +@remark ****************** +@NODE l-start "AProf: Starting the profiler" + + From CLI the profiler is started with + + 1.> AProf [application] + + The profiler starts up, displays its user interface, loads the + symbol tables from the file 'application' if specified and waits + for your actions. + + From Workbench, doubleclick the AProf icon. + + If no filename was specified or if started from workbench, you can + load a file from the menu @{ "[Files/Open]" link m-files }. + + See also: @{ "User interface" link l-ui } +@ENDNODE + +@NODE l-ui "AProf:User interface" + + Title: Name of loaded profilee + + Menus: @{ " Files " link m-files } @{ " Action " link m-action } @{ " Data " link m-data } @{ " Move " link m-move } @{ " Misc " link m-misc } + Displays: @{ " Mode " link gad-inex } @{ " Time unit " link gad-percmil } @{ " Sort " link gad-sort } @{ " Time " link gad-xtime } + Buttons: [ Shortcuts for often needed menu entrys ] + + Description of table entrys: + + Function HitCnt Per Call Over Min/Max + | | | | | + Symbol names* | | | | + | | | | + Call count** | | | + | | | + Average execution time per call | | + | | + Overall execution time for that function | + | + Minimum/maximum execution time per call + + * The symbol *ENTRY*, if displayed, is generated by AProf if the symbol + table of the profilee contains no symbol sitting at the very first + executed address of its seglist. + + ** A call count value of -1 is shown for symbols being no function entrys. + Safe profiling must be active. + + [ Status and error messages are displayed in the bottom window border ] +@ENDNODE + +@NODE m-files "AProf:Menu: Files" + + Menu: Files + Reading and writing profiler data. + + + Open: Read a new file (also accessable via button) + Save: Save report to file with same basename and suffix .pro + Save as: Save report to selectable file + Reset: Reset all timing values + Print: Print report + Exit: Leave the program +@ENDNODE + +@NODE m-action "AProf:Menu: Action" + + Menu: Action + Start the profiling process. + + + Start: Starts the profile run. If you restart a profilee, then times + are added. + If you want to run a profilee several times without adding the + times and hit counts, you must reset the timer and hitcounts + with @{ " Files/Reset " link m-files }. + (also accessable via button row) +@ENDNODE + +@NODE m-data "AProf:Menu: Data" + + Menu: Data + Runtime configuration and execution control. + + + Exec details: + Provide a command line and stack size for the profilee + See: @{ "Exec dialog" link dialog-exec } + + Preferences: + Configure the profiler. + See: @{ "Preferences dialog" link dialog-preferences }, @{ "Configurability" link l-config }. +@ENDNODE + +@NODE m-move "AProf:Menu: Move" + + Menu: Move + Moving in the display area. + + + Find: Enter a search string and start search + Find next: Search for next occurence + Top: Go to top of symbol table + Bottom: Go to bottom of symbol table + Page up/down: One page up/down +@ENDNODE + +@NODE m-misc "AProf:Menu: Misc" + + Menu: Misc + Other functions + + + Help: + Start the AmigaGuide(TM) hypertext help system (if available) + + Refresh Window: + Redisplay symbol table + + About: + Display version and copyright information +@ENDNODE + +@NODE gad-inex "AProf: Profiler mode: Separate/Combined" + + Separate/Combined: (Mode) + Displays how function timing values are accumulated. If combined + is selected, the time value for a function includes the times of + all functions that are called by this function. Separate excludes + the times of called functions. + + Note that if your code includes recursive procedure you must use + separate mode. If combined is used, the time for the recursive + procedure is wrong. + + Example: + + int main( void ) + { + foo( 2 ); /* foo needs 2secs execution time */ + + bar( 3 ); /* bar needs 3secs execution time */ + + ...burn 1sec proc. time in main()... + + return 0; + } + + If 'Separate' is selected, the profile list will look like this: + Symbol HitCnt Per Call + main 1 1000 The timing values are updated for + foo 1 2000 each funktion separate. + bar 1 3000 + + Now if 'Combined' is selected: + Symbol HitCnt Per Call + main 1 6000 The timing values for foo() and + foo 1 2000 bar() are added to main(), since + bar 1 3000 main() calls both. +@ENDNODE + +@NODE gad-percmil "AProf: Cycle: Percentual/Millisecond timevalues" + + Millisecond/Percentual time units: (Units) + Displays the units used for for timing values. If percentual is + active, times shown are fractions of overall execution time in + percent. +@ENDNODE + +@NODE gad-xtime "AProf: XTime" + + Overall execution time of profilee. Units are seconds or milli- + seconds depending on execution time. Times longer than 1000 ms are + displayed in seconds (s), below in milliseconds (ms). +@ENDNODE + +@NODE l-config "AProf: Configurability" + + All configurable items of AProf must be set as ToolTypes in AProf's + .info file, which must reside in the same directory as the profiler. + + +------------------------------------------------------------------+ + | Never delete AProf.info! All configuration data will be | + | written to this file! | + +------------------------------------------------------------------+ + + Beginning with version 3.30 one can save AProf's current settings + with the 'Save' button in 'Preferences'. It is recommended to use + this instead of setting the ToolTypes manually. + + + o WINDIM=left/top/width/height + Use this to set size and position for the profiler window. + + o TUNITS=(PERCENTUAL | MILLISECOND) + Default time units. + + o PMODE=(COMBINED|SEPARATE) + Profiling mode + + o PATTERN=(AmigaPattern) + Amiga pattern for symbols to hide. + Look in your Amiga User Manual for a description of pattern syntax + + o SORT=(NONE | NAME | HIT | AVERAGE | OVER) + Specify the sort order you prefer. + + o SAFE=(TRUE | FALSE) + Safe profiling on or off +@ENDNODE + + + +@REMARK **************** +@REMARK * Allgemein Blah... +@REMARK **************** +@NODE l-notes "AProf: Notes" + + Implementation + -------------- + AProf is an active profiler. This means, hit counts and timing values + are measured by employing a sophisticated breakpoint scheme. + + Before a profilee is executed by AProf, all function entry points + are marked with breakpoints. + + After execution is started, AProf receives the breakpoint hits and + places additional breakpoints at the function return points. + + The address for function return points is derived from the stack. This + should make it clear why AProf needs a 'clean' symbol table: There is + no foolproof way to figure out the function return address if there + are any function local data on top of stack. + + Actually some testing can be undergone to ensure the correct values + are read from the stack. This can be activated in AProf versions + > 3.22 by the checkmark 'safe profiling' in AProf preferences. + Although this is not foolproof as stated, it works unexpected good + with most compilers. The disadvatage of this technique is the + additional time spent in the checking routines. + + + Profilee environment + -------------------- + Wether AProf is started from CLI or workbench, the profilee's + environment is always a shell. If started from wb, a shell window will + be supplied for profilee IO. + + ARexx port + ---------- + In the current version AProf provides no additional functions for + ARexx hosts. +@ENDNODE + +@NODE l-caveats "AProf: Caveats" + + Here is a list of known constructs which can result in problems if + you try to profile programs including them + + o Non-standard startup code + ------------------------- + The profilees must be able to run in the same process environment + as the profiler. It's not possible to use special startup codes for + detaching a program or making it resident. + + + o recursive procedures + -------------------- + Use only '@{ "separate" link gad-inex }' profiling mode if your code includes recursive + procedures. In combined mode the time for the recursive procedure + is wrong. + + + o setjmp()/longjmp() + ------------------ + If setjmp()/longjmp() combinations are used in the profilee, the + time span between calling longjmp() and the next RTS instruction + will add to the function calling longjmp(). + + + o signal()/raise() + ---------------- + Most compiler libraries contain signal()/raise() functions which + are not compatible with AProf. + + + o CIA Timer + --------- + CIA timers are not available for profilees. + + + o Overlays + -------- + Profiling of overlayed programs is not possible. + + + o Runtime limitation + ------------------ + Profiler timers can measure maximum time spans of about 99 mins. + + + o Static functions + ---------------- + Functions to be measured must be in the symbol table. This is not + the case for static (module local) functions in most programming + environments. + + + o Traphandlers + ------------ + If your program uses a private trap handler, traps not handled must + be propagated to the previous handler. Used traps must be allocated + with AllocTrap(). + Profiling is NOT possible if you are using trace traps (#9). + + + o Switch- and Launchfunctions + --------------------------- + Profilees using members tc_Switch and tc_Launch in Exec's Task + structure must propagate execution to previous defined handlers. +@ENDNODE + + + +@NODE l-stripb "AProf: StripB" + + StripB is a command line utility which can be used to remove all + HUNK_SYMBOL- and HUNK_DEBUG-hunks from an Amiga executable. + + Command line: StripB infile outfile +@ENDNODE + + + +@NODE l-systeme "AProf: Tested systems" + + This is a list of systems I have tested the profiler with. If you + find an error or if you have tested a system not included here, + send a message please. + + @{ " Amiga E " link amiga-e } + @{ " Aztec C " link manx-c } + @{ " DICE C " link dice-c } + @{ " GNU C/C++ " link gnu-cpp} + @{ " SAS C 6.3 " link sas-c } + @{ " Maxon C++ V1.2.1 " link maxon-cpp } + @{ " Assemblers " link assemblers } + + @{ " Other systems... " link other } +@ENDNODE + + +@NODE amiga-e "AProf: Tested systems: Amiga E" + + AProf works with all versions of Amiga E >2.1b. + + Problems: + Profiling of programs using exeptions leads to meaningless results + + Creation of symbol hunks: + Use -s switch +@ENDNODE + +@NODE manx-c "AProf: Tested systems: Aztec C" + + Manx Aztec C V3.4 - V5.2b + + Creation of symbol hunks: + Use option -w for the linker + + Problems: + + o Remove symbols named '_H#[0-9]_org' + + o Don't use detach.o with programs you want to profile. + + o ANSI C functions signal() and raise() don't handle traps + the way they should. (see @{"Caveats" link l-caveats}, custom trap-handlers) +@ENDNODE + +@NODE sas-c "AProf: Tested systems: SAS C" + + SAS C ? + +@ENDNODE + +@NODE maxon-cpp "AProf: Tested systems: Maxon C++" + + Maxon C++ V1.2.1 + + Problems: + Code and data symbols in link libraries reside in the same hunk. According + to Jens Gelhar this will change in future versions of the library. The + beta version of the updated compiler writes symbol hunks as needed by Aprof + so the library problem requires a simple recompile. + + Compiler is adding labels named L'num' to symbol table. This must be + removed (Pattern: L#[0-9]) or you must activate 'save profiling'. + + Creation of symbol hunks: + For command line compiler use option -bs. + In the integrated environment use menu 'Compiler options'. + + Other: + Test the procedure rexx/maxoncpp.aprof for unmangling of c++ symbol names. +@ENDNODE + + +@NODE dice-c "AProf: Tested systems: DICE C" + + DICE C V2.06.21 unregistered version + + Problems: + Dice generates dirty symbol tables, activate 'Safe profiling'. + + Creation of symbol hunks: + Use option -s for DCC. + + Information about the commercial DICE system welcome. +@ENDNODE + +@NODE gnu-cpp "AProf: Tested systems: GNU C/C++" + + GNU gcc - 2.3.3 + + Problems: + Profiling programs using ixemul.library is not possible, use static linking. + Activate 'Safe profiling'. + + Creation of symbol hunks: + Always created, to not create them use -s or @{ " StripB " link l-stripb }, which is + included in this AProf distribution. +@ENDNODE + +@NODE assemblers "AProf: Tested systems: Assemblers" + + AProf is tested with a number of assemblers (Aztec as, asm68, DevPack). + There seem to be no problems as long as the following rules are obeyed: + + o If you export code symbols other than function labels, activate + 'Safe profiling' in [Data/Prefs]. + + o Don't be too creative with your control flow, eg. several starting + points for functions etc. Although this will not crash AProf, the + results provided will be a bit random :) + + o Do not mix data and code in one hunk. + + o Do not use self modifying code. +@ENDNODE + +@NODE other "AProf: Tested systems: Other..." + + Here is a little strategy to test if your system is able to cooperate + with AProf. + + Step 0. + ------- + First, try to find out if your system can generate executables with + Amiga symbol hunks. You should find this information in your compiler + documentation. + + Then after successfully creating a executable version of the program + to test, first check if your program is at least stable enough to run + stand-alone without crashing the machine. + + Close all applications so that if a crash happens no data is lost! + + Step 1. + ------- + Start AProf and load your program. Then specify in [Data/Prefs] the + symbol pattern '#?' (without quotation marks). This removes the complete + symbol table, which results in a reduced protocol between AProf and + your program. + + When this is done, close your eyes and start your program (if you + have problems in finding the right keys you can keep your eyes open). + If your machine crashed, then Aprof is definitely incompatible with + this programming system. The only thing to do is to reboot your machine + an delete AProf. If there was no problems and your program is running, + take all steps needed to stop your program. + + Step 2. + ------- + Next step is to remove all symbols but one, which should be generated by + you. If your programm contains a function 'foo' written by you then + open the prefs request and insert ~(foo) as symbol pattern. After selecting + 'use', this should be the only symbol displayed (it is possible, that + there is an second symbol called *ENTRY* - this is used by AProf, ignore + it). + + Start execution. If everything works, then again stop your program or + wait for termination. Now Aprof should display the function timings. + + A crash is a sign for incompatibility. Forget AProf. + + Step 3. + ------- + Now remove the pattern in [Data/Prefs] and activate 'Save profiling'. + Then take a look at the symbol list. Remove temporary labels or + line number labels. + + Examples: + _L0001, _L0002, _L0003, _L0004, ... + _H0_org, _H0_end, _H1_org, _H1_end, ... + @0001, @0002, @0003, ... + + Then again start execution of your program. If everything works as it + should you did it. Exit your program and AProf will generate the + timing report. AProf seems to be compatible with your programming + system. Save the pattern created in the preceding step and use it + in future profiling sessions. + + If your program crashed, the hard work begins. As we saw in Step 2, + your programming system basically should work with AProf. So there + must be one or several data objects in your code hunks. You will + have to find and remove them. + + Step 4. + ------- + Save all settings. +@ENDNODE + + + +@NODE l-feedback "AProf: Feedback" + + Contact me under + + EMail: michab@informatik.fh-augsburg.de + + If it's not possible to use EMail, write to: + + Michael Binz + Bahnhofstr. 11 + D-86459 Gessertshausen + + If you made tests with a compiler not listed in 'systems', please + send me a small demo source file, the translated executable (with + symbol hunk) and some information about creating symbol hunks with + your compiler. If needed, send a description of problems and actions + you performed to solve them, too. +@ENDNODE + +@NODE l-enforcer-blah "AProf needs you..." + + ... if you have access to an Amiga with MMU! + + Since I'm developing AProf on an Amiga 2000 with 68000 I can't check + for ENFORCER HITS! Although much care was taken to keep this nasty + sort of bugs out of my code, there must be some. Anywhere. + + So man, read the following! + + if ( found_enforcer_hit() ) + { + if ( have_access_to_email() ) + + Send_Micha_An_Email_Report( ); /* Really! */ + + else if ( !too_lazy() ) + + Send_Micha_SnailMail_Report(); /* Cool... */ + + else + + GuruForever(); /* Gnah... */ + } + + @{ " Micha's address? " link l-feedback } +@ENDNODE + +@NODE l-copyright "AProf: Copyright" + This software is freeware. You are allowed to copy, distribute and + use it, as long as you don't change the software and distribute only + the packed file (AProf3_30.lha). + + You are not allowed to charge a fee higher than Fred Fish's for copy- + ing and distributing. + + These files and their related documentation, utilities and examples + are provided "AS-IS" and subject to change without notice; no warran- + ties are made. All use is at your own risk. No liability or respon- + sibility is assumed. + + This software, the included utilities and documentation are + © 1993-94 Michael G. Binz +@ENDNODE + + + + +@remark ************* +@remark * Abgesang +@remark ************* +@NODE l-changes "AProf: Changes" + +V 3.34 + Bugs fixed: + o Screen updates caused enforcer hits + o Shell display of command line caused enforcer hit + + Changes: + o Console window opened when started from WB now has close gadget + o XTime display uses [s] if [ms] value exceeds 1000 + + +V 3.30 + Future: + o Passive (interrupt controlled) profiling mode + + Known Problems: + o AmigaGuide needs 'topaz' or maybe another fixed width font + to be the system default font. If another font is used, + AmigaGuide fails silently. + + Changes: + o If run from WB the profiler acts as shell for profilees + o System default font is used + o Added sorting functions + o Extended configurability + o Maximum command line length is now 256 chars + o Special 'safe' profiling mode added + o ARexx Port for custom symbol name unmangling + + Bugs fixed: + o Use of other fonts than topaz.8 trashed window + o Catched some enforcer hits + o Initial window size was wrong + o Syntax error in a pattern led to an endless loop + + +V 3.20 + o First released +@ENDNODE + +@NODE frageantwort "AProf: Question and Answer" + + o What is an 'clean' symbol table? + + Clean symbol tables include only function entry addresses. Neither + intermediate labels are defined nor data symbols in code hunks. + +@ENDNODE + + + + +@remark ******* +@remark * Hilfeseiten für Dialoge. Aufruf erfolgt direkt aus AProf +@remark * +@remark * Texte werden in diesem Hilfedokument mehrfach verwendet. +@remark ******* + +@NODE dialog-preferences "AProf: Preferences dialog" + + APROF: PREFERENCES DIALOG @{ " Exit help " close } + ------------------------- + + Symbol pattern: + Provide a regular expression for symbols you want to exclude from + profiling. For a description of Amiga regular expressions see + your dos manual. + Patterns can be used to remove compiler generated intermediate + labels or functions you aren't interested in. One advantage of + removing functions from the symbol table is faster profiling. + + Example: 'L#[0-9]' removes symbols starting with an 'L' followed + by any number of digits (L1 L00 L4711). + + + Separate/Combined: (Mode) + Specifies how function timing values are accumulated. If combined + is selected, the time value for a function includes the times of + all functions that are called by this function. Separate excludes + the times of called functions. + + Note that if your code includes recursive procedure you must use + separate mode. If combined is used, the time for the recursive + procedure is wrong. + + See @{ "example" link gad-inex }. + + + Millisecond/Percentual time units: (Units) + Selects the units used for for timing values. If percentual is + active, times shown are fractions of overall execution time in + percent. + + + Safe profiling: + If safe profiling is on (selected), then while profiling, every + breakpoint must pass additional tests to ensure that it belongs + to a function entry or exit (See @{ "dirty symbol tables" link frageantwort }). + If off, this tests are not done, resulting in faster profiling. + Since it is hard to notice the time spent in doing the tests, it + is recommended to activate safe profiling. + + + Rexx Unmangler: + Specifiy the filename of the Rexx procedure to be used for name + unmangling. + Some programming languages (eg. C++) offer 'type-safe linking', + which is often implemented by coding the argument types into the + symbol names (this process is called symbol mangling). Since for + humans this symbol names are then hard to read, it is possible + to specify a Rexx procedure for translating the symbol back in + a more readable form. + + See @{ "example Rexx unmangler" link rexxample }. + + + Sort order: + Specify the preferred sort order. +@ENDNODE + +@NODE rexxample "AProf: Rexx example" + + /* Dummy C Unmangler + * + * This demonstrates the basics for AProf unmanglers written in Rexx + * + * Don't use this in real life, since this is included in AProf + * as standard unmangler (No mangler selected in preferences) + * + * This unmangler removes a leading '_', if one exists + */ + + /* Get the symbol name from AProf and put it in 'symnam' */ + parse arg symnam + + /* Check if there is a leading '_' */ + if "_" = left( symnam, 1 ) then + /* Remove first char */ + symnam = right( symnam, length( symnam ) -1 ) + + /* Return result */ + exit symnam + +@ENDNODE + + +@NODE dialog-exec "AProf: Exec dialog" + + APROF: EXEC DIALOG @{ " Exit help " close } + ------------------ + + Command line: + A command line for the profilee can be specified. The command + name must not be given. + + Example: You have written a program named 'foo', which needs one + argument 'bar' to be specified on the command line. The following + steps are needed to get an execution profile of 'foo': + + o Start AProf: aprof foo + o Select 'Data...' and insert 'bar' as command line + o Select 'Use' + o Select 'Start' + + + Stack size: + Provide a stack size for the profilee. +@ENDNODE + + diff --git a/amigae33a/E_v3.3a/Bin/Tools/AProf/AProf.info b/amigae33a/E_v3.3a/Bin/Tools/AProf/AProf.info new file mode 100644 index 0000000..98be63a Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/Tools/AProf/AProf.info differ diff --git a/amigae33a/E_v3.3a/Bin/Tools/AProf/README b/amigae33a/E_v3.3a/Bin/Tools/AProf/README new file mode 100644 index 0000000..3b80770 --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Tools/AProf/README @@ -0,0 +1,33 @@ +AProf has been included in the Amiga E distribution with the +approval of the author, Michael G. Binz. Thanks Michael! + +[the AProf executable itself can be found in the bin directory] + +usage of AProf with Amiga E is dead simple: + +compile your source (say, 'bla.e') with the '-s' switch (SYM/S) +(= add symbols): + +1> ec sym bla + +as you can check with ShowHunk, bla now has a symbolhunk +added to it. Now, load 'bla' into AProf: + +1> aprof bla + +if everything went ok, you'll be seeing a GUI with some +buttons. You'll probably want to toggle 'inclusive subroutines' +off. now start the profile by pressing 'Start'. After your +program has finished, you'll see the amount of time spend +in each PROC. Especially the 'Average' column is interesting. +This will give you a clue which part of your program needs +optimising. + +notes: +- as you might have noticed, E system functions CAN be profiled + seperatedly, but library calls CANNOT, i.e. the'll always + be added to the PROC that calls them. Be aware of this. +- AProf is not always reliable when the executation time + of the whole program is very short. + +For further infos, check AProf.guide diff --git a/amigae33a/E_v3.3a/Bin/Tools/README b/amigae33a/E_v3.3a/Bin/Tools/README new file mode 100644 index 0000000..1e918f0 --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Tools/README @@ -0,0 +1,5 @@ +Here you'll find the distributions/docs of currently only +Aprof (a profiler), and the docs for Explorer (an object browser) +and EFindHit (an enforcer tool). Mac2E has been removed due to the +new internal macro-preprocessor in E v3.1a, EE is not being updated +anymore, and the EYacc stuff has moved to the Src/Lang directory. diff --git a/amigae33a/E_v3.3a/Bin/Tools/efindhit.readme b/amigae33a/E_v3.3a/Bin/Tools/efindhit.readme new file mode 100644 index 0000000..6cb8a32 --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Tools/efindhit.readme @@ -0,0 +1,197 @@ +Short: EFindHit v1.2 (for Enforcer output) +Type: dev/e +Author: jason@fsel.com (Jason R. Hulance) + +EFindHit can be used to find the line number of an Enforcer hit in an +E program, given the offset information that Enforcer produces. +Unlike normal FindHit programs, EFindHit reports the line numbers of +hits in E modules, too (i.e., not just the main program). And it can +also tell you which function the code was in. + + +Usage +----- + +To use EFindHit, the main source file *must* be compiled with the +LINEDEBUG or DEBUG switches. And if you want to track hits in modules +used by the program, they too must be compiled with one of these +switches. + +If you want to see the names of functions as well, then you need to +use the SYM switch, too, but only on the main source file. This is +especially useful for tracking hits in E internal functions. If you +don't use the SYM switch when compiling your source then EFindHit +cannot reliably identify hits that occur in E internal functions (it +may report them as coming from the last line of one of the sources, +and flag those offsets that appear to be too far beyond the last +line). + +EFindHit takes the following arguments: + + EXECUTABLE/A,DEBUG/S,OFFSETS/M + +So, you can supply a list of offsets. Hexadecimal offsets can be +specified using a leading '$' or '0x'. Without these prefixes the +offset is interpreted as decimal. + +New to v1.2 is the DEBUG switch: see below for an illustrative +example. + + +Example +------- + +For example, consider the following output from Enforcer (when +SegTracker is running): + + BYTE-READ from 00000000 PC: 7833432C + USP: 7834B4B0 SR: 0004 SW: 0751 (U0)(-)(-) TCB: 7828F188 + Data: 00000000 0000000D 78348FB8 7829016C 00000001 1E0CCF39 78348FB8 00000001 + Addr: 00000000 7828F1E4 783343AE 7829016C 7834B6C0 7834B4B4 78019864 -------- + Stck: 00000000 7829016C 78334306 783341F2 00000000 00000000 00000000 00000000 + Stck: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 + ----> 7833432C - "xxx" Hunk 0000 Offset 00000244 + Name: "Shell Process" CLI: "xxx" Hunk 0000 Offset 00000244 + +The interested lines are the first and last. The first line says the +hit was a byte read from $00000000 (probably from dereferencing a NIL +pointer). The last line says that the culprit was the program "xxx" +and that the hit happened at offset $00000244. (You might also +consider using the STACKCHECK option of Enforcer to get the backtrace +of the call stack.) + +If "xxx" has been compiled with LINEDEBUG (or DEBUG) then you can run +EFindHit on it to find the line number of the hit in one of the source +files: + + 1.System:> efindhit xxx $244 + EFindHit works better if you compile with the SYM option + Offset $244: "xxx.e" line 5 [$242] + +The first line of output is a reminder that using SYM makes EFindHit +work better, then the information about the offset. The trailing +"[$242]" indicates the offset of the start of the code for line 5. + +If you've compiled "xxx" with the SYM option too, then things get a +bit better: + + 1.System:> efindhit xxx $244 + Offset $244: "xxx.e" line 5 [$242], in "fun()" [$238] + +This also states the function the hit occurred in, and gives the +offset of the start of code for that function ($238). + +If you don't trust the output of EFindHit (???), then you can use the +DEBUG switch to dump all the information from the executable that +EFindHit uses. (If this switch is specified then any supplied offsets +are ignored.) For example: + + 1.System:> efindhit xxx debug + $00000000 *** Startup1 *** + $00000196 *** End of startup1 *** + $00000374 *** End of code *** + $00000236 fun() + $000001D2 zzz() + $00000196 external() + $00000284 main() + $000002DA WriteF() + $0000036A Char() + $0000023A 14 xxx.e + $00000240 15 xxx.e + $00000244 16 xxx.e + $00000288 22 xxx.e + $0000028E 23 xxx.e + $000001D6 4 zzz.e + $0000019A 8 xyz.e + $000001EE *** Startup2 *** + $00000200 *** End of Startup2 *** + +The first column is the offset, the second (if present) is the line +number and the last column is the name of the file, the function or +another significant part of the executable. You could sort this +output if you have pipes set up: + + 1.System:> efindhit xxx debug | sort in: out: + $00000000 *** Startup1 *** + $00000196 *** End of startup1 *** + $00000196 external() + $0000019A 8 xyz.e + $000001D2 zzz() + $000001D6 4 zzz.e + $000001EE *** Startup2 *** + $00000200 *** End of Startup2 *** + $00000236 fun() + $0000023A 14 xxx.e + $00000240 15 xxx.e + $00000244 16 xxx.e + $00000284 main() + $00000288 22 xxx.e + $0000028E 23 xxx.e + $000002DA WriteF() + $0000036A Char() + $00000374 *** End of code *** + +Now it's really easy to see where any particular offset lies... + + +Possible output +--------------- + +As well as complaining about errors (like you forgot to compile with +LINEDEBUG), EFindHit might report: + +1) Offset $244: "xxx.e" line 5 [$242], in "fun()" [$238] + +The offset is in the identified function in the main source. + +2) Offset $200: "xyz.e" line 11 [$1E8], near EXPORTed "external()" [$196] + +The line number information for code in modules is more accurate than +the function information, since only EXPORTed functions can be +followed. So EFindHit reminds you that the code at the offset is only +"near" the EXPORTed function (i.e., some point after it but before the +next EXPORTed function). + +3) Offset $280: E internal function "Char()" + +The hit has occurred in an E internal function. You probably want the +backtrace in this case (the STACKCHECK option of Enforcer), so you can +spot which function this was called from. + +4) Offset $190: E startup code + +The hit has occurred outside user code, either when starting or +cleaning up. This didn't ought to happen unless your code has +scribbled all over the place. (These offsets will show up in the +backtrace produced by the STACKCHECK option of Enforcer, as E code +always starts in the startup code!) + +5) Invalid offset $330: not in code part + +The hit didn't occur within the code of the executable being analysed. +This might happen if you're running EFindHit on the wrong program or a +different version from that which produced the hit. + +6) No line number for offset $200 + +EFindHit couldn't find a line number (but might still be able to +identify a function, nonetheless, and this will be reported as "in" or +"near" as appropriate [assuming you've compiled with the SYM option]). + + +Limitations +----------- + +There's no symbol information (currently?) for any methods or for +functions which are not EXPORTed from modules. So it's not possible +to put names to offsets in these bits of code (the line numbers should +be sufficicient in these cases). And offsets in methods/INCBIN/other +data in the main source file will be reported as being "in" the +nearest function before it. + +The startup code recognition is pretty much specific to EC v3.2e. +It's likely to change in future... + + + +Have fun! diff --git a/amigae33a/E_v3.3a/Bin/Tools/explorer.readme b/amigae33a/E_v3.3a/Bin/Tools/explorer.readme new file mode 100644 index 0000000..474525a --- /dev/null +++ b/amigae33a/E_v3.3a/Bin/Tools/explorer.readme @@ -0,0 +1,249 @@ +Short: Amazing System Browser and Debugger +Type: dev/e +Author: jason@fsel.com (Jason R. Hulance) + + +Explorer 2.2j +============= +Allows you to browse around memory as E objects (which are like C structs). + + +Basic Function +-------------- +You enter an address and then select the object which is (supposed to be?) +at that address. You can then see the value that each element of the +object takes, and follow pointers etc. by double-clicking on the element (a +single click changes the address to the element's address, which is an +offset from the address you specified for the object). + +A double-click may therefore change the object being browsed, so there is a +way of returning to the original object via the "Back Up" button. As you +double-click and select new objects your choices are recorded. The current +depth of this path is shown as the 'Depth:' text. The action of the "Back +Up" button is duplicated by the "Back Up" menu item on the "Selections" +menu. There is also an option to clear the current path on this menu. + +The list of objects may be created in several ways (these are found on the +"Project" menu): + + 1) "Open" Opens a previously saved config file, containing any number of + objects. By default, when Explorer starts it tries to load + objects from "explorer.config" in the current directory, and + then "s:explorer.config" if that fails. The supplied + "explorer.config" file contains all the standard Amiga OS + objects. (This file was created by using "Load Modules" on the + "Emodules:" directory and then saving the config using the next + option.) + 2) "Save" Saves the current list of objects as an Explorer config file. + 3) "Load Modules" Scan the selected module or all the modules in the + selected directory and its sub-directories. The found objects + will replace any current list of objects. This operation can + take a long time, especially if you try to load all the modules + in "Emodules:". You can interrupt it at any time by closing the + status window. + 4) "Merge Modules" Same as 3) but any objects found are added to the + current list of objects rather than replacing them. + 5) "Load Cache" Same as 3) but the current E module cache is scanned. + This is most useful when Explorer is used to help debug your + programs. + +The address and object can also be specified via ARexx, making Explorer an +extremely useful debugging tool as well as a system browser! In fact, EDBG +v3.3a+ makes use of Explorer to analyse typed variables. (A module is +supplied to show how easy it is to integrate the appropriate ARexx call +into your program.) + + +Object Layout +------------- +The elements of the selected object are listed in order. If you choose to +see the value of element it will be displayed in hex in parenthesis after +the element, and if you choose to see the element address (an offset from +the object address) it will be displayed after an '@'. (Use the +"Selections" menu to decide which, if any, you want to see.) + + +Where to Start +-------------- +Explorer starts off with the address of an internal hail and copyright +string. The items on the "Presets" menu give some other, interesting +starting points: + + 1) "Dos" Views the address stored in the 'dosbase' global variable as a + 'doslibrary' object. The dos.library is one of the fundamental + Amiga system libraries, and 'dosbase' is its corresponding + library base object. + 2) "Exec" Same as 1) but for the 'execbase' variable and object for the + exec.library (the most fundamental Amiga system library). + 3) "Graphics" Same as 1) but for the 'gfxbase' variable and object for the + graphics.library. + 4) "Intuition." Same as 1) but for the 'intuitionbase' variable and + object for the intuition.library. + 5) "This Process." Views the 'process' object for the running Explorer + program! + +For a typical Explorer session, you would probably start at one of these +points and then double-click on elements and use the "Back Up" button to +browse around. You never really need to set the address explicitly on the +GUI (at worst you'd do it by ARexx), but the option is there if you really +want to... + + +Simple Types +------------ +The "CHAR", "INT" and "LONG" buttons view the contents of the address as if +it were a pointer to the corresponding type, and fills in the 'Hex:', +'Decimal:' and 'String:' texts with the value(s) being pointed at. + +"BSTR" is similar to "CHAR" but it first converts the address from a BCPL +pointer and then skips over the length byte. "BADDR" just converts the +address to a BCPL pointer. + +"--" and "++" treat the address as if it were pointing to an array of the +type last requested (i.e., an object or simple type). "--" moves the +address back to the previous element in the array, and "++" moves it on to +the next. The size of the last requested type is shown as the 'Size:' +text. (Note: "--" can be activated also by the "p" key and "++" by the "n" +key.) + + +Display Beeps! +-------------- +The screen will flash (or you'll get a beep or whatever your Workbench is +set up to do) if you do one of the following: + + 1) Select something when the address is NIL (zero). A NIL address is not + valid (although Explorer will behave as if it were). + 2) Select an element which is a NIL pointer or a LONG that is NIL. + 3) Select an element with object or PTR TO object type, where the object + is not in the current list of objects. + 4) Try to backup past a depth of zero. + + +Command Line Options +-------------------- +The command line template is: + + OBJECT,ADDR,ALL/S,CACHE/S,NONE/S,CONFIG/K,SCREEN/K,NOAUTOREPLY/S + + 1) OBJECT Specify an initial object to be displayed (to be useful, the + appropriate module must also be loaded using 'ALL' or 'CACHE'). + 2) ADDR Specify an initial address to be displayed (NIL is ignored!). + 3) ALL Load all objects from the modules in Emodules: and its + sub-directories (overrides 'CACHE' and 'CONFIG'). + 4) CACHE Load all objects from the modules in the current E module cache + (overrides 'CONFIG'). + 5) NONE Start with no objects (overrides 'ALL', 'CACHE' and 'CONFIG'). + 6) CONFIG Specify the config file to load. If this load fails then + Explorer will try "s:explorer.config". + 7) SCREEN Specify the public screen to open on. Normally Explorer will + open on the default public screen. + 8) NOAUTOREPLY Specifies that the "Auto Reply" option (described below) + should start as off rather than on. + +By default, Explorer will try to load the "explorer.config" in the current +directory (as if you'd used the CONFIG option -- so it will fall back to +trying "s:explorer.config"). The starting address will be that of an +internal hail and copyright string (which will be displayed as the +'String:' text). + + +ARexx +----- +The "Reply" menu item on the "ARexx" menu manually replies to an ARexx +message that may have been received. You can also let Explorer +automatically reply to these messages by checking the "Auto Reply" option, +but the manual method is best since you can be sure that the pointers +remain valid while you browse (since the calling program is halted). Once +you've replied to a message the calling program is free to scribble all +over the memory at the address it just gave you... + +A module 'sendexplorer' is supplied to simplify the debugging facilities of +Explorer. It defines several functions: + +1) PROC sendExplorer(addr,obj=NIL,repPort=NIL,message=NIL,quiet=FALSE) + + 'addr' is the address you wish to use. + 'obj' is the name of the object you are interested in. + 'repPort' is a message port for replies. If you don't supply this then a + temporary port is created for the duration of the function call. + (The purpose of this parameter is to allow you to re-use the + same port during your program if you call 'sendExplorer' a lot.) + 'message' is a short string to be displayed in the 'Message:' part of + Explorer. Use this to communicate some information about the + address and object (EDBG uses this to give the name, type and + scope of the variable being explored). + 'quiet' is a boolean to say whether Explorer should complain if the + object is not loaded. + +The result is TRUE if the message was successfully delivered and did +not cause an ARexx error, and FALSE otherwise. + +An example call is: + + sendExplorer(packet, 'dospacket') + +To browse using your own objects you'd separate them out into modules and +load these modules in your program. Compiling your program would add these +to the E module cache, which can then be used to set-up Explorer (using the +"Load Cache" menu item). Alternatively, you could "Load" or "Merge" the +appropriate module directly, or use a config file if the objects don't +change very often. + +2) PROC quitExplorer(repPort=NIL) + + 'repPort' is as above. + +This sends a 'QUIT' message to Explorer. Again, it returns TRUE if +everything succeeded. + +3) PROC isExplorerRunning() + +Returns TRUE if Explorer is running. It works this out by testing for +the presence of Explorer's ARexx port, so it may be fooled.. + + +Altering Data +------------- +By popular demand, if you hold down the shift key when you click on an +element of an object or on the 'CHAR', 'INT' or 'LONG' buttons, then a +small window pops up which allows you to edit the appropriate value. It's +not very safe to randomly edit data (especially system data), so use of +this feature is discouraged unless you really know what you're doing... + + +Example Program +--------------- +To show how useful Explorer can be, there is a modified version of the +'empty' handler supplied. This uses the above call to 'sendExplorer' to +communicate the value of the packet currently being processed. Since the +handler is not a full process (it's just a task) there would normally be no +simple way of debugging it or examining the packets as they arrive (none of +the DOS functions, such as printing text, are available to simple tasks). +However, the handler can send messages to ARexx and thus to Explorer. + +To try it out: + + 1) Make sure ARexx is up (by running RexxMast, if necessary). + 2) Start up Explorer using, + run explorer all + 3) Now copy the 'empty-handler' to L:, + copy empty-handler L: + 4) Mount it using, + mount empty: from empty.mountlist + 5) Use the handler, + type empty:10 + 6) Look at Explorer. It will be displaying the first packet. Browse + around it, remembering that most elements will be BCPL strings. + 7) Select "Reply" from the ARexx menu (or press RAmiga-R) to reply to this + message. + 8) Another packet arrives and the message is sent to Explorer. + 9) Repeat 6)-8) until the 'type' command finishes and you get the Shell + prompt back. + + +EDBG +---- +EDBG v3.3a+ communicates data about a variable if you hold down the shift +key and double-click on a variable that's within the current scope (EDBG +also adds it to the list of watched variables, if necessary). diff --git a/amigae33a/E_v3.3a/Bin/build b/amigae33a/E_v3.3a/Bin/build new file mode 100644 index 0000000..19cbba7 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/build differ diff --git a/amigae33a/E_v3.3a/Bin/d b/amigae33a/E_v3.3a/Bin/d new file mode 100644 index 0000000..86be850 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/d differ diff --git a/amigae33a/E_v3.3a/Bin/edbg b/amigae33a/E_v3.3a/Bin/edbg new file mode 100644 index 0000000..fcd700a Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/edbg differ diff --git a/amigae33a/E_v3.3a/Bin/explorer b/amigae33a/E_v3.3a/Bin/explorer new file mode 100644 index 0000000..2007c0f Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/explorer differ diff --git a/amigae33a/E_v3.3a/Bin/patch_v30a_to_v33a b/amigae33a/E_v3.3a/Bin/patch_v30a_to_v33a new file mode 100644 index 0000000..e4dee14 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/patch_v30a_to_v33a differ diff --git a/amigae33a/E_v3.3a/Bin/patch_v31a_to_v33a b/amigae33a/E_v3.3a/Bin/patch_v31a_to_v33a new file mode 100644 index 0000000..e141b6a Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/patch_v31a_to_v33a differ diff --git a/amigae33a/E_v3.3a/Bin/patch_v32a_to_v33a b/amigae33a/E_v3.3a/Bin/patch_v32a_to_v33a new file mode 100644 index 0000000..07bd0cc Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/patch_v32a_to_v33a differ diff --git a/amigae33a/E_v3.3a/Bin/pragma2module b/amigae33a/E_v3.3a/Bin/pragma2module new file mode 100644 index 0000000..12fd994 Binary files /dev/null and b/amigae33a/E_v3.3a/Bin/pragma2module differ diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Appendices.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Appendices.guide new file mode 100644 index 0000000..a4145f8 --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Appendices.guide @@ -0,0 +1,497 @@ +@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 + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/BuiltIns.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/BuiltIns.guide new file mode 100644 index 0000000..c8885aa --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/BuiltIns.guide @@ -0,0 +1,1002 @@ +@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" "E Built-In Constants Variables and Functions" +@Next "Modules.guide/main" +@Prev "MoreExpressions.guide/main" +@Toc "Contents.guide/main" + +E Built-In Constants, Variables and Functions +********************************************* + + This chapter describes the constants, variables and functions which are +built in to the E language. You can add more by using modules, but that's +a more advanced topic (see @{"Modules" Link "Modules.guide/main" }). + + + @{" Built-In Constants " Link "Built-In Constants" } + @{" Built-In Variables " Link "Built-In Variables" } + @{" Built-In Functions " Link "Built-In Functions" } + + +@ENDNODE + +@NODE "Built-In Constants" "Built-In Constants" +@Next "Built-In Variables" +@Toc "main" + +Built-In Constants +================== + + We've already met several built-in constants. Here's the complete list: + +@{b }TRUE@{ub }, @{b }FALSE@{ub } + The boolean constants. As numbers, @{b }TRUE@{ub } is -1 and @{b }FALSE@{ub } is zero. + +@{b }NIL@{ub } + The bad pointer value. Several functions produce this value for a + pointer if an error occurred. As a number, @{b }NIL@{ub } is zero. + +@{b }ALL@{ub } + Used with string and list functions to indicate that all the string + or list is to be used. As a number, @{b }ALL@{ub } is -1. + +@{b }GADGETSIZE@{ub } + The minimum number of bytes required to hold all the data for one + gadget. See @{"Intuition support functions" Link "Intuition support functions" }. + +@{b }OLDFILE@{ub }, @{b }NEWFILE@{ub } + Used with @{b }Open@{ub } to open an old or new file. See the `AmigaDOS Manual' + for more details. + +@{b }STRLEN@{ub } + The length of the last string constant used. Remember that a string + constant is something between @{b }'@{ub } characters, so, for example, the + following program prints the string @{b }s@{ub } and then its length: + + PROC main() + DEF s:PTR TO CHAR, len + s:='12345678' + len:=STRLEN + WriteF(s) + WriteF('\\nis \\d characters long\\n', len) + ENDPROC + + +@ENDNODE + +@NODE "Built-In Variables" "Built-In Variables" +@Next "Built-In Functions" +@Prev "Built-In Constants" +@Toc "main" + +Built-In Variables +================== + + The following variables are built in to E and are called @{fg shine }system +variables@{fg text }. They are global so can be accessed from any procedure. + +@{b }arg@{ub } + This is a string which contains the @{fg shine }command line@{fg text } arguments passed + your program when it was run (from the Shell or CLI). For instance, + if your program were called @{b }fred@{ub } and you ran it like this: + + fred file.txt "a big file" another + + then @{b }arg@{ub } would the string: + + file.txt "a big file" another + + If you have AmigaDOS 2.0 (or greater) you can use the system routine + @{b }ReadArgs@{ub } to parse the command line in a much more versatile way. + There is a worked example on argument parsing in Part Three (see + @{"Argument Parsing" Link "Examples.guide/Argument Parsing" }). + +@{b }wbmessage@{ub } + This contains @{b }NIL@{ub } if your program was started from the Shell/CLI, + otherwise it's a pointer to the Workbench message which contains + information about the icons selected when you started the program + from Workbench. So, if you started the program from Workbench + @{b }wbmessage@{ub } will not be @{b }NIL@{ub } and it will contain the Workbench + arguments, but if you started the program from the Shell/CLI + @{b }wbmessage@{ub } will be @{b }NIL@{ub } and the argments will be in @{b }arg@{ub } (or via + @{b }ReadArgs@{ub }). There is a worked example on argument parsing in Part + Three (see @{"Argument Parsing" Link "Examples.guide/Argument Parsing" }). + +@{b }stdin@{ub }, @{b }stdout@{ub }, @{b }conout@{ub } + The @{b }stdin@{ub } and @{b }stdout@{ub } variables contain the standard input and output + filehandles. If your program was started from the Shell/CLI they + will be filehandles on the Shell/CLI window (and @{b }conout@{ub } will be @{b }NIL@{ub }). + However, if your program was started from Workbench these will both + be @{b }NIL@{ub }, and in this case the first call to @{b }WriteF@{ub } will open an output + @{b }CON:@{ub } window and store the file handle for the window in @{b }stdout@{ub } and + @{b }conout@{ub }. The file handle stored in @{b }conout@{ub } will be closed using @{b }Close@{ub } + when the program terminates, so you can set up your own @{b }CON:@{ub } window + or file for use by the output functions and have it automatically + closed. See @{"Input and output functions" Link "Input and output functions" }. + +@{b }stdrast@{ub } + The raster port used by E built-in graphics functions such as @{b }Box@{ub } and + @{b }Plot@{ub }. This can be changed so that these functions draw on different + screens etc. See @{"Graphics functions" Link "Graphics functions" }. + +@{b }dosbase@{ub }, @{b }execbase@{ub }, @{b }gfxbase@{ub }, @{b }intuitionbase@{ub } + These are pointers to the appropriate library base, and are + initialised by the E startup code, i.e., the Dos, Exec, Graphics and + Intuition libraries are all opened by E so you don't need to do it + yourself. These libraries are also automatically closed by E, so you + shouldn't close them yourself. However, you must explicitly open and + close all other Amiga system libraries that you want to use. The + other library base variables are defined in the accompanying module + (see @{"Modules" Link "Modules.guide/main" }). + + +@ENDNODE + +@NODE "Built-In Functions" "Built-In Functions" +@Prev "Built-In Variables" +@Toc "main" + +Built-In Functions +================== + + There are many built-in functions in E. We've already seen a lot of +string and list functions, and we've used @{b }WriteF@{ub } for printing. The +remaining functions are, generally, simplifications of complex Amiga +system functions, or E versions of support functions found in languages +like C and Pascal. + + To understand the graphics and Intuition support functions completely +you really need to get something like the `Rom Kernel Reference Manual +(Libraries)'. However, if you don't want to do anything too complicated +you should be able to get by. + + + @{" Input and output functions " Link "Input and output functions" } + @{" Intuition support functions " Link "Intuition support functions" } + @{" Graphics functions " Link "Graphics functions" } + @{" Maths and logic functions " Link "Maths and logic functions" } + @{" System support functions " Link "System support functions" } + + +@ENDNODE + +@NODE "Input and output functions" "Input and output functions" +@Next "Intuition support functions" +@Toc "Built-In Functions" + +Input and output functions +-------------------------- + +@{b }WriteF(@{ub }@{fg shine }string@{fg text }@{b },@{ub }@{fg shine }param1@{fg text }@{b },@{ub }@{fg shine }param2@{fg text }@{b },...)@{ub } + Writes a string to the standard output and returns the number of + characters written. If place-holders are used in the string then the + appropriate number of parameters must be supplied after the string in + the order they are to be printed as part of the string. So far we've + only met the @{b }\\d@{ub } place-holder for decimal numbers. The complete list + is: + + @{i }Place-Holder@{ui } @{i }Parameter Type@{ui } @{i }Prints@{ui } + ------------------------------------------------- + \\c Number Character + \\d Number Decimal number + \\h Number Hexadecimal number + \\s String String + + So to print a string you use the @{b }\\s@{ub } place-holder in the string and + supply the string (i.e., a @{b }PTR TO CHAR@{ub }) as a parameter. Try the + following program (remember @{b }\\a@{ub } prints an apostrophe character): + + PROC main() + DEF s[30]:STRING + StrCopy(s, 'Hello world', ALL) + WriteF('The third element of s is "\\c"\\n', s[2]) + WriteF('or \\d (decimal)\\n', s[2]) + WriteF('or \\h (hexadecimal)\\n', s[2]) + WriteF('and s itself is \\a\\s\\a\\n', s) + ENDPROC + + This is the output it generates: + + The third element of s is "l" + or 108 (decimal) + or 6C (hexadecimal) + and s itself is 'Hello world' + + You can control how the parameter is formatted in the @{b }\\d@{ub }, @{b }\\h@{ub } and + @{b }\\s@{ub } fields using another collection of special character + sequences before the place-holder and size specifiers after it. If + no size is specified the field will be as big as the data requires. + A fixed field size can be specified using @{b } [@{ub }@{fg shine }number@{fg text }@{b }]@{ub } after the + place-holder. For strings you can also use the size specifier + @{b } (@{ub }@{fg shine }min@{fg text }@{b },@{ub }@{fg shine }max@{fg text }@{b })@{ub } which specifies the minimum and + maximum sizes of the field. By default the data is right justified + in the field and the left part of the field is filled, if necessary, + with spaces. The following sequences before the place-holder can + change this: + + @{i }Sequence@{ui } @{i }Meaning@{ui } + ----------------------------------- + \\l Left justify in field + \\r Right justify in field + \\z Set fill character to "0" + + See how these formatting controls affect this example: + + PROC main() + DEF s[30]:STRING + StrCopy(s, 'Hello world', ALL) + WriteF('The third element of s is "\\c"\\n', s[2]) + WriteF('or \\d[4] (decimal)\\n', s[2]) + WriteF('or \\z\\h[4] (hexadecimal)\\n', s[2]) + WriteF('\\a\\s[5]\\a are the first five elements of s \\n', s) + WriteF('and s in a very big field \\a\\s[20]\\a\\n', s) + WriteF('and s left justified in it \\a\\l\\s[20]\\a\\n', s) + ENDPROC + + Here's the output it should generate: + + The third element of s is "l" + or 108 (decimal) + or 006C (hexadecimal) + 'Hello' are the first five elements of s + and s in a very big field ' Hello world' + and s left justified in it 'Hello world ' + + @{b }WriteF@{ub } uses the standard output, and this file handle is stored in + the @{b }stdout@{ub } variable. If your program is started from Workbench this + variable will contain @{b }NIL@{ub }. In this case, the first call to @{b }WriteF@{ub } + will open a special output window and put the file handle in the + variables @{b }stdout@{ub } and @{b }conout@{ub }, as outlined above (see + @{"Built-In Variables" Link "Built-In Variables" }). + +@{b }PrintF(@{ub }@{fg shine }string@{fg text }@{b },@{ub }@{fg shine }param1@{fg text }@{b },@{ub }@{fg shine }param2@{fg text }@{b },...)@{ub } + @{b }PrintF@{ub } works just like @{b }WriteF@{ub } except it uses the more efficient, + buffered output routines only available if your Amiga is using + Kickstart version 37 or greater (i.e., AmigaDOS 2.04 and above). + +@{b }StringF(@{ub }@{fg shine }e-string@{fg text }@{b },@{ub }@{fg shine }string@{fg text }@{b },@{ub }@{fg shine }arg1@{fg text }@{b },@{ub }@{fg shine }arg2@{fg text }@{b },...)@{ub } + The same as @{b }WriteF@{ub } except that the result is written to @{fg shine }e-string@{fg text } + instead of being printed. For example, the following code fragment + sets @{b }s@{ub } to @{b }00123 is a@{ub } (since the E-string is not long enough for the + whole string): + + DEF s[10]:STRING + StringF(s, '\\z\\d[5] is a number', 123) + +@{b }Out(@{ub }@{fg shine }filehandle@{fg text }@{b },@{ub }@{fg shine }char@{fg text }@{b })@{ub } + Outputs a single character, @{fg shine }char@{fg text }, to the file or console window + denoted by @{fg shine }filehandle@{fg text }, and returns -1 to indicate success (so any + other return value means an error occurred). For instance, + @{fg shine }filehandle@{fg text } could be @{b }stdout@{ub }, in which case the character is written + to the standard output. (You need to make sure @{b }stdout@{ub } is not @{b }NIL@{ub }, + and you can do this by using a @{b }WriteF('')@{ub } call.) In general, you + obtain a filehandle using the Amiga system function @{b }Open@{ub } from the + @{b }dos.library@{ub } (see @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" }). + +@{b }Inp(@{ub }@{fg shine }filehandle@{fg text }@{b })@{ub } + Reads and returns a single character from @{fg shine }filehandle@{fg text }. If -1 is + returned then the end of the file (EOF) was reached, or there was an + error. + +@{b }ReadStr(@{ub }@{fg shine }filehandle@{fg text }@{b },@{ub }@{fg shine }e-string@{fg text }@{b })@{ub } + Reads a whole string from @{fg shine }filehandle@{fg text } and returns -1 if EOF was + reached or an error occurred. Characters are read up to a linefeed + or the size of the string, whichever is sooner. Therefore, the + resulting string may be only a partial line. If -1 is returned then + EOF was reached or an error occurred, and in either case the string + so far is still valid. So, you still need to check the string even + if -1 is returned. (This will most commonly happen with files that + do not end with a linefeed.) The string will be empty (i.e., of zero + length) if nothing more had been read from the file when the error or + EOF happened. + + This next little program reads continually from its input until an + error occurs or the user types @{b }quit@{ub }. It echoes the lines that it + reads in uppercase. If you type a line longer than ten characters + you'll see it reads it in more than one go. Because of the way + normal console windows work, you need to type a return before a line + gets read by the program (but this allows you to edit the line before + the program sees it). If the program is started from Workbench then + @{b }stdin@{ub } would be @{b }NIL@{ub }, so @{b }WriteF('')@{ub } is used to force @{b }stdout@{ub } to be + valid, and in this case it will be a new console window which can be + used to accept input! (To make the compiled program into a Workbench + program you simply need to create a tool icon for it. A quick way of + doing this is to copy an existing tool's icon.) + + PROC main() + DEF s[10]:STRING, fh + WriteF('') + fh:=IF stdin THEN stdin ELSE stdout + WHILE ReadStr(fh, s)<>-1 + UpperStr(s) + EXIT StrCmp(s, 'QUIT', ALL) + WriteF('Read: \\a\\s\\a\\n', s) + ENDWHILE + WriteF('Finished\\n') + ENDPROC + + There are some worked examples in Part Three (see + @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" }) which also show how to use @{b }ReadStr@{ub }. + +@{b }FileLength(@{ub }@{fg shine }string@{fg text }@{b })@{ub } + Returns the length of the file named in @{fg shine }string@{fg text }, or -1 if the file + doesn't exist or an error occurred. Notice that you don't need to + @{b }Open@{ub } the file or have a filehandle, you just supply the filename. + There is a worked example in Part Three (see @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" }) + which shows how to use this function. + +@{b }SetStdIn(@{ub }@{fg shine }filehandle@{fg text }@{b })@{ub } + Returns the value of @{b }stdin@{ub } before setting it to @{fg shine }filehandle@{fg text }. + Therefore, the following code fragments are equivalent: + + oldstdin:=SetStdIn(newstdin) + + oldstdin:=stdin + stdin:=newstdin + +@{b }SetStdOut(@{ub }@{fg shine }filehandle@{fg text }@{b })@{ub } + Returns the value of @{b }stdout@{ub } before setting it to @{fg shine }filehandle@{fg text }, and is + otherwise just like @{b }SetStdIn@{ub }. + + +@ENDNODE + +@NODE "Intuition support functions" "Intuition support functions" +@Next "Graphics functions" +@Prev "Input and output functions" +@Toc "Built-In Functions" + +Intuition support functions +--------------------------- + + The functions in this section are simplified versions of Amiga system +functions (in the Intuition library, as the title suggests). To make best +use of them you are probably going to need something like the `Rom Kernel +Reference Manual (Libraries)', especially if you want to understand the +Amiga specific things like IDCMP and raster ports. + + The descriptions given here vary slightly in style from the previous +descriptions. All function parameters can be expressions which represent +numbers or addresses, as appropriate. Because many of the functions take +several parameters they have been named (fairly descriptively) so they can +be more easily referenced. + +@{b }OpenW(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }wid@{fg text }@{b },@{ub }@{fg shine }hgt@{fg text }@{b },@{ub }@{fg shine }idcmp@{fg text }@{b },@{ub }@{fg shine }wflgs@{fg text }@{b },@{ub }@{fg shine }title@{fg text }@{b },@{ub }@{fg shine }scrn@{fg text }@{b },@{ub }@{fg shine }sflgs@{fg text }@{b },@{ub }@{fg shine }gads@{fg text }@{b },@{ub }@{fg shine }tags@{fg text }@{b }=NIL)@{ub } + Opens and returns a pointer to a window with the supplied properties. + If for some reason the window could not be opened @{b }NIL@{ub } is returned. + + @{fg shine }x@{fg text }, @{fg shine }y@{fg text } + The position on the screen where the window will appear. + + @{fg shine }wid@{fg text }, @{fg shine }hgt@{fg text } + The width and height of the window. + + @{fg shine }idcmp@{fg text }, @{fg shine }wflgs@{fg text } + The IDCMP and window specific flags. + + @{fg shine }title@{fg text } + The window title (a string) which appears on the title bar of + the window. + + @{fg shine }scrn@{fg text }, @{fg shine }sflgs@{fg text } + The screen on which the window should open. If @{fg shine }sflgs@{fg text } is 1 the + window will be opened on Workbench, and @{fg shine }scrn@{fg text } is ignored (so it + can be @{b }NIL@{ub }). If @{fg shine }sflgs@{fg text } is @{b }$F@{ub } (i.e., 15) the window will open + on the custom screen pointed to by @{fg shine }scrn@{fg text } (which must then be + valid). See @{b }OpenS@{ub } to see how to open a custom screen and get a + screen pointer. + + @{fg shine }gads@{fg text } + A pointer to a gadget list, or @{b }NIL@{ub } if you don't want any gadgets. + These are not the standard window gadgets, since they are + specified using the window flags. A gadget list can be created + using the @{b }Gadget@{ub } function. + + @{fg shine }tags@{fg text } + A tag-list of other options available under Kickstart version 37 + or greater. This can normally be omitted since it defaults to + @{b }NIL@{ub }. See the `Rom Kernel Reference Manual (Libraries)' for + details about the available tags and their meanings. + + There's not enough space to describe all the fine details about + windows and IDCMP (see the `Rom Kernel Reference Manual (Libraries)' + for complete details), but a brief description in terms of flags + might be useful. Here's a small table of common IDCMP flags: + + @{i }IDCMP Flag@{ui } @{i }Value@{ui } + -------------------------- + IDCMP_NEWSIZE $2 + IDCMP_REFRESHWINDOW $4 + IDCMP_MOUSEBUTTONS $8 + IDCMP_MOUSEMOVE $10 + IDCMP_GADGETDOWN $20 + IDCMP_GADGETUP $40 + IDCMP_MENUPICK $100 + IDCMP_CLOSEWINDOW $200 + IDCMP_RAWKEY $400 + IDCMP_DISKINSERTED $8000 + IDCMP_DISKREMOVED $10000 + + Here's a table of useful window flags: + + @{i }Window Flag@{ui } @{i }Value@{ui } + -------------------------- + WFLG_SIZEGADGET $1 + WFLG_DRAGBAR $2 + WFLG_DEPTHGADGET $4 + WFLG_CLOSEGADGET $8 + WFLG_SIZEBRIGHT $10 + WFLG_SIZEBBOTTOM $20 + WFLG_SMART_REFRESH 0 + WFLG_SIMPLE_REFRESH $40 + WFLG_SUPER_BITMAP $80 + WFLG_BACKDROP $100 + WFLG_REPORTMOUSE $200 + WFLG_GIMMEZEROZERO $400 + WFLG_BORDERLESS $800 + WFLG_ACTIVATE $1000 + + All these flags are defined in the module @{b }intuition/intuition@{ub }, so if + you use that module you can use the constants rather than having to + write the less descriptive value (see @{"Modules" Link "Modules.guide/main" }). Of course, you can + always define your own constants for the values that you use. + + You use the flags by @{b }OR@{ub }-ing the ones you want together, in a similar + way to using sets (see @{"Sets" Link "Constants.guide/Sets" }). However, you should supply only IDCMP + flags as part of the @{fg shine }idcmp@{fg text } parameter, and you should supply only + window flags as part of the @{fg shine }wflgs@{fg text } parameter. So, to get IDCMP + messages when a disk is inserted and when the close gadget is clicked + you specify both of the flags @{b }IDCMP_DISKINSERTED@{ub } and + @{b }IDCMP_CLOSEWINDOW@{ub } for the @{fg shine }idcmp@{fg text } parameter, either by @{b }OR@{ub }-ing the + constants or (less readably) by using the calculated value @{b }$8200@{ub }. + + Some of the window flags require some of IDCMP flags to be used as + well, if an effect is to be complete. For example, if you want your + window to have a close gadget (a standard window gadget) you need to + use @{b }WFLG_CLOSEGADGET@{ub } as one of the window flags. If you want that + gadget to be useful then you need to get an IDCMP message when the + gadget is clicked. You therefore need to use @{b }IDCMP_CLOSEWINDOW@{ub } as + one of the IDCMP flags. So the full effect requires both a window + and an IDCMP flag (a gadget is pretty useless if you can't tell when + it's been clicked). The worked example in Part Three illustrates how + to use these flags in this way (see @{"Gadgets" Link "Examples.guide/Gadgets" }). + + If you only want to output text to a window (and maybe do some input + from a window), it may be better to use a @{fg shine }console@{fg text } window. These + provide a text based input and output window, and are opened using + the Dos library function @{b }Open@{ub } with the appropriate @{b }CON:@{ub } file name. + See the `AmigaDOS Manual' for more details about console windows. + +@{b }CloseW(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } + Closes the window which is pointed to by @{fg shine }winptr@{fg text }. It's safe to give + @{b }NIL@{ub } for @{fg shine }winptr@{fg text }, but in this case, of course, no window will be + closed! The window pointer is usually a pointer returned by a + matching call to @{b }OpenW@{ub }. You @{i }must@{ui } remember to close any windows you + may have opened before terminating your program. + +@{b }OpenS(@{ub }@{fg shine }wid@{fg text }@{b },@{ub }@{fg shine }hgt@{fg text }@{b },@{ub }@{fg shine }depth@{fg text }@{b },@{ub }@{fg shine }scrnres@{fg text }@{b },@{ub }@{fg shine }title@{fg text }@{b },@{ub }@{fg shine }tags@{fg text }@{b }=NIL)@{ub } + Opens and returns a pointer to a custom screen with the supplied + properties. If for some reason the screen could not be opened @{b }NIL@{ub } is + returned. + + @{fg shine }wid@{fg text }, @{fg shine }hgt@{fg text } + The width and height of the screen. + + @{fg shine }depth@{fg text } + The depth of the screen, i.e., the number of bit-planes. This + can be a number in the range 1-8 for AGA machines, or 1-6 for + pre-AGA machines. A screen with depth 3 will be able to show 2 + to the power 3 (i.e., 8) different colours, since it will have 2 + to the power 3 different pens (or colour registers) available. + You can set the colours of pens using the @{b }SetColour@{ub } function. + + @{fg shine }scrnres@{fg text } + The screen resolution flags. + + @{fg shine }title@{fg text } + The screen title (a string) which appears on the title bar of + the screen. + + @{fg shine }tags@{fg text } + A tag-list of other options available under Kickstart version 37 + or greater. See the `Rom Kernel Reference Manual (Libraries)' + for more details. + + The screen resolution flags control the screen mode. The following + (common) values are taken from the module @{b }graphics/view@{ub } (see @{"Modules" Link "Modules.guide/main" }). + You can, if you want, define your own constants for the values that + you use. Either way it's best to use descriptive constants rather + than directly using the values. + + @{i }Mode Flag@{ui } @{i }Value@{ui } + ------------------------ + V_LACE $4 + V_SUPERHIRES $20 + V_PFBA $40 + V_EXTRA_HALFBRITE $80 + V_DUALPF $400 + V_HAM $800 + V_HIRES $8000 + + So, to get a hires, interlaced screen you specify both of the flags + @{b }V_HIRES@{ub } and @{b }V_LACE@{ub }, either by @{b }OR@{ub }-ing the constants or (less readably) + by using calculated value @{b }$8004@{ub }. There is a worked example using + this function in Part Three (see @{"Screens" Link "Examples.guide/Screens" }). + +@{b }CloseS(@{ub }@{fg shine }scrnptr@{fg text }@{b })@{ub } + Closes the screen which is pointed to by @{fg shine }scrnptr@{fg text }. It's safe to + give @{b }NIL@{ub } for @{fg shine }scrnptr@{fg text }, but in this case, of course, no screen will + be closed! The screen pointer is usually a pointer returned by a + matching call to @{b }OpenS@{ub }. You @{i }must@{ui } remember to close any screens you + may have opened before terminating your program. Also, you @{i }must@{ui } + close all windows that you opened on your screen before you can close + the screen. + +@{b }Gadget(@{ub }@{fg shine }buf@{fg text }@{b },@{ub }@{fg shine }glist@{fg text }@{b },@{ub }@{fg shine }id@{fg text }@{b },@{ub }@{fg shine }flags@{fg text }@{b },@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }width@{fg text }@{b },@{ub }@{fg shine }text@{fg text }@{b })@{ub } + Creates a new gadget with the supplied properties and returns a + pointer to the next position in the (memory) buffer that can be used + for a gadget. + + @{fg shine }buf@{fg text } + This is the memory buffer, i.e., a chunk of allocated memory. + The best way of allocating this memory is to declare an array of + size n*GADGETSIZE, where @{fg shine }n@{fg text } is the number of gadgets which are + going to be created. The first call to @{b }Gadget@{ub } will use the + array as the buffer, and subsequent calls use the result of the + previous call as the buffer (since this function returns the + next free position in the buffer). + + @{fg shine }glist@{fg text } + This is a pointer to the gadget list that is being created, + i.e., the array used as the buffer. When you create the first + gadget in the list using an array @{b }a@{ub }, this parameter should be + @{b }NIL@{ub }. For all other gadgets in the list this parameter + should be the array @{b }a@{ub }. + + @{fg shine }id@{fg text } + A number which identifies the gadget. It is best to give a + unique number for each gadget; that way you can easily identify + them. This number is the only way you can identify which gadget + has been clicked. + + @{fg shine }flags@{fg text } + The type of gadget to be created. Zero represents a normal + gadget, one a boolean gadget (a toggle) and three a boolean that + starts selected. + + @{fg shine }x@{fg text }, @{fg shine }y@{fg text } + The position of the gadget, relative to the top, left-hand + corner of the window. + + @{fg shine }width@{fg text } + The width of the gadget (in pixels, not characters). + + @{fg shine }text@{fg text } + The text (a string) which will centred in the gadget, so the + @{fg shine }width@{fg text } must be big enough to hold this text. + + Once a gadget list has been created by possibly several calls to this + function the list can be passed as the @{fg shine }gads@{fg text } parameter to @{b }OpenW@{ub }. + There is a worked example using this function in Part Three (see + @{"Gadgets" Link "Examples.guide/Gadgets" }). + +@{b }Mouse()@{ub } + Returns the state of the mouse buttons (including the middle mouse + button if you have a three-button mouse). This is a set of flags, + and the individual flag values are: + + @{i }Button Pressed@{ui } @{i }Value@{ui } + ---------------------- + Left %001 + Right %010 + Middle %100 + + So, if this function returns @{b }%001@{ub } you know the left button is being + pressed, and if it returns @{b }%110@{ub } you know the middle and right buttons + are both being pressed. + + This mouse function is not strictly the proper way to do things. It + is suggested you use this function only for small tests or demo-like + programs. @{b }LeftMouse@{ub } and @{b }WaitLeftMouse@{ub } can be used to do things in a + friendly way, but are restricted to seeing when the left mouse button + is pressed. More generally, the proper way of getting mouse details + is to use the appropriate IDCMP flags for your window, wait for + events (using @{b }WaitIMessage@{ub }, for example) and decode the received + information. + +@{b }MouseX(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } + Returns the @{fg shine }x@{fg text } coordinate of the mouse pointer, relative to the + window pointed to by @{fg shine }winptr@{fg text }. + + As above, this mouse function is not strictly the proper way to do + things. + +@{b }MouseY(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } + Returns the @{fg shine }y@{fg text } coordinate of the mouse pointer, relative to the + window pointed to by @{fg shine }winptr@{fg text }. + + As above, this mouse function is not strictly the proper way to do + things. + +@{b }LeftMouse(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } + Returns @{b }TRUE@{ub } if left mouse button has been clicked in the window + pointed to by @{fg shine }winptr@{fg text }, and @{b }FALSE@{ub } otherwise. In order for this to + work sensibly the window must have the IDCMP flag @{b }IDCMP_MOUSEBUTTONS@{ub } + set (see above). + + This function does things in a proper, Intuition-friendly manner and + so is a good alternative to the @{b }Mouse@{ub } function. + +@{b }WaitIMessage(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } + This function waits for a message from Intuition for the window + pointed to by @{fg shine }winptr@{fg text } and returns the class of the message (which is + an IDCMP flag). If you did not specify any IDCMP flags when the + window was opened, or the specified messages could never happen + (e.g., you asked only for gadget messages and you have no gadgets), + then this function may wait forever. When you've got a message you + can use the @{b }MsgXXX@{ub } functions to get some more information about the + message. See the `Rom Kernel Reference Manual (Libraries)' for more + details on Intuition and IDCMP. There is a worked example using this + function in Part Three (see @{"IDCMP Messages" Link "Examples.guide/IDCMP Messages" }). + + This function is basically equivalent to the following function, + except that the @{b }MsgXXX@{ub } functions can also access the message data + held in the variables @{b }code@{ub }, @{b }qual@{ub } and @{b }iaddr@{ub }. + + PROC waitimessage(win:PTR TO window) + DEF port,msg:PTR TO intuimessage,class,code,qual,iaddr + port:=win.userport + IF (msg:=GetMsg(port))=NIL + REPEAT + WaitPort(port) + UNTIL (msg:=GetMsg(port))<>NIL + ENDIF + class:=msg.class + code:=msg.code + qual:=msg.qualifier + iaddr:=msg.iaddress + ReplyMsg(msg) + ENDPROC class + +@{b }MsgCode()@{ub } + Returns the @{b }code@{ub } part of the message returned by @{b }WaitIMessage@{ub }. + +@{b }MsgIaddr()@{ub } + Returns the @{b }iaddr@{ub } part of the message returned by @{b }WaitIMessage@{ub }. + There is a worked example using this function in Part Three (see + @{"IDCMP Messages" Link "Examples.guide/IDCMP Messages" }). + +@{b }MsgQualifier()@{ub } + Returns the @{b }qual@{ub } part of the message returned by @{b }WaitIMessage@{ub }. + +@{b }WaitLeftMouse(@{ub }@{fg shine }winptr@{fg text }@{b })@{ub } + This function waits for the left mouse button to be clicked in the + window pointed to by @{fg shine }winptr@{fg text }. It is advisable to have the IDCMP + flag @{b }IDCMP_MOUSEBUTTONS@{ub } set for the window (see above). + + This function does things in a proper, Intuition-friendly manner and + so is a good alternative to the @{b }Mouse@{ub } function. + + +@ENDNODE + +@NODE "Graphics functions" "Graphics functions" +@Next "Maths and logic functions" +@Prev "Intuition support functions" +@Toc "Built-In Functions" + +Graphics functions +------------------ + + The functions in this section use the standard raster port, the address +of which is held in the variable @{b }stdrast@{ub }. Most of the time you don't need +to worry about this because the E functions which open windows and screens +set up this variable (see @{"Intuition support functions" Link "Intuition support functions" }). So, by default, +these functions affect the last window or screen opened. When you close a +window or screen, @{b }stdrast@{ub } becomes @{b }NIL@{ub } and calls to these functions have no +effect. There is a worked example using these functions in Part Three +(see @{"Graphics" Link "Examples.guide/Graphics" }). + + The descriptions in this section follow the same style as the previous +section. + +@{b }Plot(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b }=1)@{ub } + Plots a single point (@{fg shine }x@{fg text },@{fg shine }y@{fg text }) in the specified pen colour. The + position is relative to the top, left-hand corner of the window or + screen that is the current raster port (normally the last screen or + window to be opened). The range of pen values available depend on + the screen setup, but are at best 0-255 on AGA machines and 0-31 on + pre-AGA machines. As a guide, the background colour is usually pen + zero, and the main foreground colour is pen one (and this is the + default pen). You can set the colours of pens using the @{b }SetColour@{ub } + function. + +@{b }Line(@{ub }@{fg shine }x1@{fg text }@{b },@{ub }@{fg shine }y1@{fg text }@{b },@{ub }@{fg shine }x2@{fg text }@{b },@{ub }@{fg shine }y2@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b }=1)@{ub } + Draws the line (@{fg shine }x1@{fg text },@{fg shine }y1@{fg text }) to (@{fg shine }x2@{fg text },@{fg shine }y2@{fg text }) in the specified pen colour. + +@{b }Box(@{ub }@{fg shine }x1@{fg text }@{b },@{ub }@{fg shine }y1@{fg text }@{b },@{ub }@{fg shine }x2@{fg text }@{b },@{ub }@{fg shine }y2@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b }=1)@{ub } + Draws the (filled) box with vertices (@{fg shine }x1@{fg text },@{fg shine }y1@{fg text }), (@{fg shine }x2@{fg text },@{fg shine }y1@{fg text }), + (@{fg shine }x1@{fg text },@{fg shine }y2@{fg text }) and (@{fg shine }x2@{fg text },@{fg shine }y2@{fg text }) in the + specified pen colour. + +@{b }Colour(@{ub }@{fg shine }fore-pen@{fg text }@{b },@{ub }@{fg shine }back-pen@{fg text }@{b }=0)@{ub } + Sets the foreground and background pen colours. As mentioned above, + the background colour is normally pen zero and the main foreground is + pen one. You can change these defaults with this function, and if + you stick to having the background pen as pen zero then calling this + function with one argument changes just the foreground pen. + +@{b }TextF(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b },@{ub }@{fg shine }format-string@{fg text }@{b },@{ub }@{fg shine }arg1@{fg text }@{b },@{ub }@{fg shine }arg2@{fg text }@{b },...)@{ub } + This works just like @{b }WriteF@{ub } except the resulting string is drawn on + the current raster port (usually the last window or screen to be + opened) ,starting at point (@{fg shine }x@{fg text },@{fg shine }y@{fg text }). Take care not to use any + line-feed, carriage return, tab or escape characters in the + string--they don't behave like they do in @{b }WriteF@{ub }. + +@{b }SetColour(@{ub }@{fg shine }scrnptr@{fg text }@{b },@{ub }@{fg shine }pen@{fg text }@{b },@{ub }@{fg shine }r@{fg text }@{b },@{ub }@{fg shine }g@{fg text }@{b },@{ub }@{fg shine }b@{fg text }@{b })@{ub } + Sets the colour of colour register @{fg shine }pen@{fg text } for the screen pointed to by + @{fg shine }scrnptr@{fg text } to be the appropriate RGB value (i.e., red value @{fg shine }r@{fg text }, green + value @{fg shine }g@{fg text } and blue value @{fg shine }b@{fg text }). The @{b }pen@{ub } can be anything up to 255, + depending on the screen depth. Regardless of the chipset being used, + @{fg shine }r@{fg text }, @{fg shine }g@{fg text } and @{fg shine }b@{fg text } are taken from the range zero to 255, so 24-bit + colours are always specified. In operation, though, the values are + scaled to 12-bit colour for non-AGA machines. + +@{b }SetStdRast(@{ub }@{fg shine }newrast@{fg text }@{b })@{ub } + Returns the value of @{b }stdrast@{ub } before setting it to the new value. The + following code fragments are equivalent: + + oldstdrast:=SetStdRast(newstdrast) + + oldstdrast:=stdrast + stdrast:=newstdrast + +@{b }SetTopaz(@{ub }@{fg shine }size@{fg text }@{b }=8)@{ub } + Sets the text font for the current raster port to Topaz at the + specified size, which defaults to the standard size eight. + + +@ENDNODE + +@NODE "Maths and logic functions" "Maths and logic functions" +@Next "System support functions" +@Prev "Graphics functions" +@Toc "Built-In Functions" + +Maths and logic functions +------------------------- + + We've already seen the standard arithmetic operators. The addition, @{b }+@{ub }, +and subtraction, @{b }-@{ub }, operators use full 32-bit integers, but, for +efficiency, multiplication, @{b }*@{ub }, and division, @{b }/@{ub }, use restricted values. +You can use @{b }*@{ub } only to multiply 16-bit integers, and the result will be a +32-bit integer. Similarly, you can use @{b }/@{ub } only to divide a 32-bit integer +by a 16-bit integer, and the result will be a 16-bit integer. The +restrictions do not affect most calculations, but if you really need to +use all 32-bit integers (and you can cope with overflows, etc.) you can +use the @{b }Mul@{ub } and @{b }Div@{ub } functions. @{b }Mul(a,b)@{ub } corresponds to @{b }a*b@{ub }, and @{b }Div(a,b)@{ub } +corresponds to @{b }a/b@{ub }. + + We've also met the logic operators @{b }AND@{ub } and @{b }OR@{ub }, which we know are really +bit-wise operators. You can also use the functions @{b }And@{ub } and @{b }Or@{ub } to do +exactly the same as @{b }AND@{ub } and @{b }OR@{ub } (respectively). So, for instance, @{b }And(a,b)@{ub } +is the same as @{b }a AND b@{ub }. The reason for these functions is because there +are @{b }Not@{ub } and @{b }Eor@{ub } (bit-wise) functions, too (and there aren't operators for +these). @{b }Not(a)@{ub } swaps one and zero bits, so, for instance, @{b }Not(TRUE)@{ub } is +@{b }FALSE@{ub } and @{b }Not(FALSE)@{ub } is @{b }TRUE@{ub }. @{b }Eor(a,b)@{ub } is the exclusive version of @{b }Or@{ub } and +does almost the same, except that @{b }Eor(1,1)@{ub } is 0 whereas @{b }Or(1,1)@{ub } is 1 (and +this extends to all the bits). So, basically, @{b }Eor@{ub } tells you which bits +are different, or, logically, if the truth values are different. +Therefore, @{b }Eor(TRUE,TRUE)@{ub } is @{b }FALSE@{ub } and @{b }Eor(TRUE,FALSE)@{ub } is @{b }TRUE@{ub }. + + There's a collection of other functions related to maths, logic or +numbers in general: + +@{b }Abs(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns the absolute value of @{fg shine }expression@{fg text }. The absolute value of a + number is that number without any minus sign (i.e., its the size of a + number, disregarding its sign). So, @{b }Abs(9)@{ub } is 9, and @{b }Abs(-9)@{ub } is also + 9. + +@{b }Sign(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns the sign of @{fg shine }expression@{fg text }, which is the value one if it is + (strictly) positive, -1 if it is (strictly) negative and zero if it + is zero. + +@{b }Even(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns @{b }TRUE@{ub } if @{fg shine }expression@{fg text } represents an even number, and @{b }FALSE@{ub } + otherwise. Obviously, a number is either odd or even! + +@{b }Odd(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns @{b }TRUE@{ub } if @{fg shine }expression@{fg text } represents an odd number, and @{b }FALSE@{ub } + otherwise. + +@{b }Max(@{ub }@{fg shine }exp1@{fg text }@{b }, @{ub }@{fg shine }exp2@{fg text }@{b })@{ub } + Returns the maximum of @{fg shine }exp1@{fg text } and @{fg shine }exp2@{fg text }. + +@{b }Min(@{ub }@{fg shine }exp1@{fg text }@{b }, @{ub }@{fg shine }exp2@{fg text }@{b })@{ub } + Returns the minimum of @{fg shine }exp1@{fg text } and @{fg shine }exp2@{fg text }. + +@{b }Bounds(@{ub }@{fg shine }exp@{fg text }@{b }, @{ub }@{fg shine }minexp@{fg text }@{b }, @{ub }@{fg shine }maxexp@{fg text }@{b })@{ub } + Returns the value of @{fg shine }exp@{fg text } bounded to the limits @{fg shine }minexp@{fg text } (minimum + bound) and @{fg shine }maxexp@{fg text } (maximum bound). That is, if @{fg shine }exp@{fg text } lies between + the bounds then @{fg shine }exp@{fg text } is returned, but if it is less than @{fg shine }minexp@{fg text } + then @{fg shine }minexp@{fg text } is returned or if it is greater than @{fg shine }maxexp@{fg text } then + @{fg shine }maxexp@{fg text } is returned. This is useful for, say, constraining a + calculated value to be a valid (integer) percentage (i.e., a value + between zero and one hundred). + + The following code fragments are equivalent: + + y:=Bounds(x, min, max) + + y:=IF xmax THEN max ELSE x + +@{b }Mod(@{ub }@{fg shine }exp1@{fg text }@{b },@{ub }@{fg shine }exp2@{fg text }@{b })@{ub } + Returns the 16-bit remainder (or modulus) of the division of the + 32-bit @{fg shine }exp1@{fg text } by the 16-bit @{fg shine }exp2@{fg text } as the regular return value (see + @{"Multiple Return Values" Link "Procedures.guide/Multiple Return Values" }), and the 16-bit result of the division as the + first optional return value. For example, the first assignment in + the following code sets @{b }a@{ub } to 5 (since 26=(7*3)+5), @{b }b@{ub } to 3, @{b }c@{ub } to -5 + and @{b }d@{ub } to -3. It is important to notice that if @{fg shine }exp1@{fg text } is negative + then the modulus will also be negative. This is because of the way + integer division works: it simply discards fractional parts rather + rounding. + + a,b:=Mod(26,7) + c,d:=Mod(-26,7) + +@{b }Rnd(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns a random number in the range 0 to (n-1), where @{fg shine }expression@{fg text } + represents the value n. These numbers are pseudo-random, so although + you appear to get a random value from each call, the sequence of + numbers you get will probably be the same each time you run your + program. Before you use @{b }Rnd@{ub } for the first time in your program you + should call it with a negative number. This decides the starting + point for the pseudo-random numbers. + +@{b }RndQ(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns a random 32-bit value, based on the seed @{fg shine }expression@{fg text }. This + function is quicker than @{b }Rnd@{ub }, but returns values in the 32-bit range, + not a specified range. The seed value is used to select different + sequences of pseudo-random numbers, and the first call to @{b }RndQ@{ub } should + use a large value for the seed. + +@{b }Shl(@{ub }@{fg shine }exp1@{fg text }@{b },@{ub }@{fg shine }exp2@{fg text }@{b })@{ub } + Returns the value represented by @{fg shine }exp1@{fg text } shifted @{fg shine }exp2@{fg text } bits to the + left. For example, @{b }Shl(%0001110,2)@{ub } is @{b }%0111000@{ub } and @{b }Shl(%0001011,3)@{ub } + is @{b }%1011000@{ub }. Shifting a number one bit to the left is generally the + same as multiplying it by two (although this isn't true when you + shift large positive or large negative values). (The new bits + shifted in at the right are always zeroes.) + +@{b }Shr(@{ub }@{fg shine }exp1@{fg text }@{b },@{ub }@{fg shine }exp2@{fg text }@{b })@{ub } + Returns the value represented by @{fg shine }exp1@{fg text } shifted @{fg shine }exp2@{fg text } bits to the + right. For example, @{b }Shr(%0001110,2)@{ub } is @{b }%0000011@{ub } and @{b }Shr(%1011010,3)@{ub } + is @{b }%0001011@{ub }. For positive @{fg shine }exp1@{fg text }, shifting one bit to the right is + the same as dividing by two. (The new bits shifted in at the left + are zeroes if @{fg shine }exp1@{fg text } is positive, and ones otherwise, hence + preserving the @{fg shine }sign@{fg text } of the expression.) + +@{b }Long(@{ub }@{fg shine }addr@{fg text }@{b }), Int(@{ub }@{fg shine }addr@{fg text }@{b }), Char(@{ub }@{fg shine }addr@{fg text }@{b })@{ub } + Returns the @{b }LONG@{ub }, @{b }INT@{ub } or @{b }CHAR@{ub } value at the address @{fg shine }addr@{fg text }. These + functions should be used only when setting up a pointer and + dereferencing it in the normal way would make your program cluttered + and less readable. Use of functions like these is often called + @{fg shine }peeking@{fg text } memory (especially in dialects of the BASIC language). + +@{b }PutLong(@{ub }@{fg shine }addr@{fg text }@{b },@{ub }@{fg shine }exp@{fg text }@{b }), PutInt(@{ub }@{fg shine }addr@{fg text }@{b },@{ub }@{fg shine }exp@{fg text }@{b }), PutChar(@{ub }@{fg shine }addr@{fg text }@{b },@{ub }@{fg shine }exp@{fg text }@{b })@{ub } + Writes the @{b }LONG@{ub }, @{b }INT@{ub } or @{b }CHAR@{ub } value represented by @{fg shine }exp@{fg text } to the + address @{fg shine }addr@{fg text }. Again, these functions should be used only when + really necessary. Use of functions like these is often called + @{fg shine }poking@{fg text } memory. + + +@ENDNODE + +@NODE "System support functions" "System support functions" +@Prev "Maths and logic functions" +@Toc "Built-In Functions" + +System support functions +------------------------ + +@{b }New(@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } + Returns a pointer to a newly allocated chunk of memory, which is + @{fg shine }bytes@{fg text } number of bytes. If the memory could not be allocated @{b }NIL@{ub } is + returned. The memory is initialised to zero in each byte, and taken + from any available store (Fast or Chip memory, in that order of + preference). When you've finished with this memory you can use + @{b }Dispose@{ub } to free it for use elsewhere in your program. You don't have + to @{b }Dispose@{ub } with memory you allocated with @{b }New@{ub } because your program + will automatically free it when it terminates. This is @{i }not@{ui } true for + memory allocated using the normal Amiga system routines. + +@{b }NewR(@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } + The same as @{b }New@{ub } except that if the memory could not be allocated then + the exception @{b }"MEM"@{ub } is raised (and so, in this case, the function + does not return). See @{"Exception Handling" Link "Exceptions.guide/main" }. + +@{b }NewM(@{ub }@{fg shine }bytes@{fg text }@{b },@{ub }@{fg shine }type@{fg text }@{b })@{ub } + The same as @{b }NewR@{ub } except that the @{fg shine }type@{fg text } of memory (Fast or Chip) to + be allocated can be specified using flags. The flags are defined in + the module @{b }exec/memory@{ub } (see @{"Amiga System Modules" Link "Modules.guide/Amiga System Modules" }). See the `Rom + Kernel Reference Manual (Libraries)' for details about the system + function @{b }AllocMem@{ub } which uses these flags in the same way. + + As useful example, here's a small program which allocates some + cleared (i.e., zeroed) Chip memory. + + MODULE 'exec/memory' + + PROC main() + DEF m + m:=NewM(20, MEMF_CHIP OR MEMF_CLEAR) + WriteF('Allocation succeeded, m = $\\h\\n', m) + EXCEPT + IF exception="NEW" THEN WriteF('Failed\\n') + ENDPROC + +@{b }Dispose(@{ub }@{fg shine }address@{fg text }@{b })@{ub } + Used to free memory allocated with @{b }New@{ub }, @{b }NewR@{ub } or @{b }NewM@{ub }. You should + rarely need to use this function because the memory is automatically + freed when the program terminates. + +@{b }DisposeLink(@{ub }@{fg shine }complex@{fg text }@{b })@{ub } + Used to free the memory allocated with @{b }String@{ub } (see @{"String functions" Link "Types.guide/String functions" }) + or @{b }List@{ub } (see @{"List functions" Link "Types.guide/List functions" }). Again, you should rarely need to use + this function because the memory is automatically freed when the + program terminates. + +@{b }FastNew(@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } + The same as @{b }NewR@{ub } except it uses a very fast, recycling method of + allocating memory. The memory allocated using @{b }FastNew@{ub } is, as ever, + deallocated automatically at the end of a program, and can be + deallocated before then using @{b }FastDispose@{ub }. Note that only + @{b }FastDispose@{ub } can be used and that it differs slightly from the + @{b }Dispose@{ub } and @{b }DisposeLink@{ub } functions (you have to specify the number of + bytes again when deallocating). + +@{b }FastDispose(@{ub }@{fg shine }address@{fg text }@{b },@{ub }@{fg shine }bytes@{fg text }@{b })@{ub } + Used to free the memory allocated using @{b }FastNew@{ub }. The @{fg shine }bytes@{fg text } + parameter must be the same as the @{fg shine }bytes@{fg text } used when the memory was + allocated with @{b }FastNew@{ub }, but the benefit is much faster allocation and + deallocation, and generally more efficient use of memory. + +@{b }CleanUp(@{ub }@{fg shine }expression@{fg text }@{b }=0)@{ub } + Terminates the program at this point, and does the normal things an E + program does when it finishes. The value denoted by @{fg shine }expression@{fg text } is + returned as the error code for the program. It is the replacement + for the AmigaDOS @{b }Exit@{ub } routine which should @{i }never@{ui } be used in an E + program. This is the only safe way of terminating a program, other + than reaching the (logical) end of the @{b }main@{ub } procedure (which is by + far the most common way!). + +@{b }CtrlC()@{ub } + Returns @{b }TRUE@{ub } if control-C has been pressed since the last call, and + @{b }FALSE@{ub } otherwise. This is really sensible only for programs started + from the Shell/CLI. + +@{b }FreeStack()@{ub } + Returns the current amount of free stack space for the program. Only + complicated programs need worry about things like stack. Recursion + is the main thing that eats a lot of stack space (see @{"Recursion" Link "Recursion.guide/main" }). + +@{b }KickVersion(@{ub }@{fg shine }expression@{fg text }@{b })@{ub } + Returns @{b }TRUE@{ub } if your Kickstart revision is at least that given by + @{fg shine }expression@{fg text }, and @{b }FALSE@{ub } otherwise. For instance, @{b }KickVersion(37)@{ub } + checks whether you're running with Kickstart version 37 or greater + (i.e., AmigaDOS 2.04 and above). + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Constants.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Constants.guide new file mode 100644 index 0000000..d62873b --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Constants.guide @@ -0,0 +1,254 @@ +@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" "Constants" +@Next "Types.guide/main" +@Prev "Procedures.guide/main" +@Toc "Contents.guide/main" + +Constants +********* + + A @{fg shine }constant@{fg text } is a value that does not change. A (literal) number like +121 is a good example of a constant--its value is always 121. We've +already met another kind of constant: string constants (see @{"Strings" Link "Introduction.guide/Strings" }). As +you can doubtless tell, constants are pretty important things. + + + @{" Numeric Constants " Link "Numeric Constants" } + @{" String Constants Special Character Sequences " Link "String Constants Special Character Sequences" } + @{" Named Constants " Link "Named Constants" } + @{" Enumerations " Link "Enumerations" } + @{" Sets " Link "Sets" } + + +@ENDNODE + +@NODE "Numeric Constants" "Numeric Constants" +@Next "String Constants Special Character Sequences" +@Toc "main" + +Numeric Constants +================= + + We've met a lot of numbers in the previous examples. Technically +speaking, these were numeric constants (constant because they don't change +value like a variable might). They were all decimal numbers, but you can +use hexadecimal and binary numbers as well. There's also a way of +specifying a number using characters. To specify a hexadecimal number you +use a @{b }$@{ub } before the digits (and after the optional minus sign @{b }-@{ub } to +represent a negative value). To specify a binary number you use a @{b }%@{ub } +instead. + + Specifying numbers using characters is more complicated, because the +base of this system is 256 (the base of decimal is ten, that of +hexadecimal is 16 and that of binary is two). The digits are enclosed in +double-quotes (the " character), and there can be at most four digits. +Each digit is a character representing its ASCII value. Therefore, the +character @{b }A@{ub } represents 65 and the character @{b }0@{ub } (zero) represents 48. This +upshot of this is that character @{b }A@{ub } has ASCII value @{b }"A"@{ub } in E, and @{b }"0z"@{ub } +represents ("0" * 256) + "z" = (48 * 256) + 122 = 12,410. However, you +probably don't need to worry about anything other than the single +character case, which gives you the ASCII value of the character. + + The following table shows the decimal value of several numeric +constants. Notice that you can use upper- or lower-case letters for the +hexadecimal constants. Obviously the case of characters is significant +for character numbers. + + @{i }Number@{ui } @{i }Decimal value@{ui } + ---------------------- + 21 21 + -143 -143 + $1a 26 + -$B1 -177 + %1110 14 + -%1010 -10 + "z" 122 + "Je" 19,045 + -"A" -65 + + +@ENDNODE + +@NODE "String Constants Special Character Sequences" "String Constants Special Character Sequences" +@Next "Named Constants" +@Prev "Numeric Constants" +@Toc "main" + +String Constants: Special Character Sequences +============================================= + + We have seen that in a string the character sequence @{b }\\n@{ub } means a +linefeed (see @{"Strings" Link "Introduction.guide/Strings" }). There are several other similar such special +character sequences which represent useful characters that can't be typed +in a string. The following table shows all these sequences. Note that +there are some other similar sequences which are used to control +formatting with built-in procedures like @{b }WriteF@{ub }. These are listed where +@{b }WriteF@{ub } and similar procedures are described (see +@{"Input and output functions" Link "BuiltIns.guide/Input and output functions" }). + + @{i }Sequence@{ui } @{i }Meaning@{ui } + -------------------------------------- + \\0 A null (ASCII zero) + \\a An apostrophe ' + \\b A carriage return (ASCII 13) + \\e An escape (ASCII 27) + \\n A linefeed (ASCII 10) + \\q A double quote (ASCII 34) + \\t A tab (ASCII 9) + \\\\ A backslash \\ + +An apostrophe can also be produced by typing two apostrophes in a row in a +string. It's best to use this only in the middle of a string, where it's +nice and obvious: + + WriteF('Here\\as an apostrophe.\\n') /* Using \\a */ + + WriteF('Here''s another apostrophe.\\n') /* Using '' */ + + +@ENDNODE + +@NODE "Named Constants" "Named Constants" +@Next "Enumerations" +@Prev "String Constants Special Character Sequences" +@Toc "main" + +Named Constants +=============== + + It is often nice to be able to give names to certain constants. For +instance, as we saw earlier, the truth value @{b }TRUE@{ub } actually represents the +value -1, and @{b }FALSE@{ub } represents zero (see @{"Logic and comparison" Link "Introduction.guide/Logic and comparison" }). These are +our first examples of named constants. To define your own you use the +@{b }CONST@{ub } keyword as follows: + + CONST ONE=1, LINEFEED=10, BIG_NUM=999999 + +This has defined the constant @{b }ONE@{ub } to represent one, @{b }LINEFEED@{ub } ten and +@{b }BIG_NUM@{ub } 999,999. Named constants must begin with two uppercase letters, +as mentioned before (see @{"Identifiers" Link "Format.guide/Identifiers" }). + + You can use previously defined constants to give the value of a new +constant, but in this case the definitions must occur on different @{b }CONST@{ub } +lines. + + CONST ZERO=0 + CONST ONE=ZERO+1 + CONST TWO=ONE+1 + +The expression used to define the value of a constant can use only simple +operators (no function calls) and constants. + + +@ENDNODE + +@NODE "Enumerations" "Enumerations" +@Next "Sets" +@Prev "Named Constants" +@Toc "main" + +Enumerations +============ + + Often you want to define a whole lot of constants and you just want +them all to have a different value so you can tell them apart easily. For +instance, if you wanted to define some constants to represent some famous +cities and you only needed to know how to distinguish one from another +then you could use an @{fg shine }enumeration@{fg text } like this: + + ENUM LONDON, MOSCOW, NEW_YORK, PARIS, ROME, TOKYO + +The @{b }ENUM@{ub } keyword begins the definitions (like the @{b }CONST@{ub } keyword does for +an ordinary constant definition). The actual values of the constants +start at zero and stretch up to five. In fact, this is exactly the same +as writing: + + CONST LONDON=0, MOSCOW=1, NEW_YORK=2, PARIS=3, ROME=4, TOKYO=5 + + The enumeration does not have to start at zero, though. You can change +the starting value at any point by specifying a value for an enumerated +constant. For example, the following constant definitions are equivalent: + + ENUM APPLE, ORANGE, CAT=55, DOG, GOLDFISH, FRED=-2, + BARNEY, WILMA, BETTY + + CONST APPLE=0, ORANGE=1, CAT=55, DOG=56, GOLDFISH=57, + FRED=-2, BARNEY=-1, WILMA=0, BETTY=1 + + +@ENDNODE + +@NODE "Sets" "Sets" +@Prev "Enumerations" +@Toc "main" + +Sets +==== + + Yet another kind of constant definition is the @{fg shine }set@{fg text } definition. This +useful for defining flag sets, i.e., a number of options each of which can +be on or off. The definition is like a simple enumeration, but using the +@{b }SET@{ub } keyword and this time the values start at one and increase as powers +of two (so the next value is two, the next is four, the next eight, and so +on). Therefore, the following definitions are equivalent: + + SET ENGLISH, FRENCH, GERMAN, JAPANESE, RUSSIAN + + CONST ENGLISH=1, FRENCH=2, GERMAN=4, JAPANESE=8, RUSSIAN=16 + +However, the significance of the values it is best shown by using binary +constants: + + CONST ENGLISH=%00001, FRENCH=%00010, GERMAN=%00100, + JAPANESE=%01000, RUSSIAN=%10000 + +If a person speaks just English then we can use the constant @{b }ENGLISH@{ub }. If +they also spoke Japanese then to represent this with a single value we'd +normally need a new constant (something like @{b }ENG_JAP@{ub }). In fact, we'd +probably need a constant for each combination of languages a person might +know. However, with the set definition we can @{b }OR@{ub } the @{b }ENGLISH@{ub } and @{b }JAPANESE@{ub } +values together to get a new value, @{b }%01001@{ub }, and this represents a set +containing both @{b }ENGLISH@{ub } and @{b }JAPANESE@{ub }. On the other hand, to find out if +someone speaks French we would @{b }AND@{ub } the value for the languages they know +with @{b }%00010@{ub } (or the constant @{b }FRENCH@{ub }). (As you might have guessed, @{b }AND@{ub } and +@{b }OR@{ub } are really bit-wise operators, not simply logical operators. See +@{"Bitwise AND and OR" Link "MoreExpressions.guide/Bitwise AND and OR" }.) + + Consider this program fragment: + + speak:=GERMAN OR ENGLISH OR RUSSIAN /* Speak any of these */ + IF speak AND JAPANESE + WriteF('Can speak in Japanese\\n') + ELSE + WriteF('Unable to speak in Japanese\\n') + ENDIF + IF speak AND (GERMAN OR FRENCH) + WriteF('Can speak in German or French\\n') + ELSE + WriteF('Unable to speak in German or French\\n') + ENDIF + +The assignment sets @{b }speak@{ub } to show that the person can speak in German, +English or Russian. The first @{b }IF@{ub } block tests whether the person can speak +in Japanese, and the second tests whether they can speak in German or +French. + + When using sets be careful you don't get tempted to add values instead +of @{b }OR@{ub }-ing them. Adding two different constants from the same set is the +same as @{b }OR@{ub }-ing them, but adding the same set constant to itself isn't. +This is not the only time addition doesn't give the same answer, but it's +the most obvious. If you to stick to using @{b }OR@{ub } you won't have a problem. + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Contents.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Contents.guide new file mode 100644 index 0000000..a2cfc16 --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Contents.guide @@ -0,0 +1,69 @@ +@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" "beginner.guide" + + + + Copyright (c) 1994-1997, Jason R. Hulance. + +A Beginner's Guide to Amiga E +***************************** + + This Guide gives an introduction to the Amiga E programming language +and, to some extent, programming in general. + + +Part One: Getting Started + + @{" Introduction to Amiga E " Link "Introduction.guide/main" } + @{" Understanding a Simple Program " Link "Introduction.guide/Understanding a Simple Program" } + @{" Variables and Expressions " Link "Introduction.guide/Variables and Expressions" } + @{" Program Flow Control " Link "Introduction.guide/Program Flow Control" } + @{" Summary " Link "Introduction.guide/Summary" } + +Part Two: The E Language + + @{" Format and Layout " Link "Format.guide/main" } + @{" Procedures and Functions " Link "Procedures.guide/main" } + @{" Constants " Link "Constants.guide/main" } + @{" Types " Link "Types.guide/main" } + @{" More About Statements and Expressions " Link "MoreExpressions.guide/main" } + @{" E Built-In Constants Variables and Functions " Link "BuiltIns.guide/main" } + @{" Modules " Link "Modules.guide/main" } + @{" Exception Handling " Link "Exceptions.guide/main" } + @{" Memory Allocation " Link "Memory.guide/main" } + @{" Floating-Point Numbers " Link "FloatingPoint.guide/main" } + @{" Recursion " Link "Recursion.guide/main" } + @{" Object Oriented E " Link "OOE.guide/main" } + +Part Three: Worked Examples + + @{" Introduction to the Examples " Link "Examples.guide/main" } + @{" String Handling and I-O " Link "Examples.guide/String Handling and I-O" } + @{" Timing Expressions " Link "Examples.guide/Timing Expressions" } + @{" Argument Parsing " Link "Examples.guide/Argument Parsing" } + @{" Gadgets IDCMP and Graphics " Link "Examples.guide/Gadgets IDCMP and Graphics" } + @{" Recursion Example " Link "Examples.guide/Recursion Example" } + +Part Four: Appendices + + @{" Common Problems " Link "Appendices.guide/main" } + @{" Other Information " Link "Appendices.guide/Other Information" } + +Indices + + @{" E Language Index " Link "EIndex.guide/main" } + @{" Main Index " Link "Index.guide/main" } + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Contents.guide.info b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Contents.guide.info new file mode 100644 index 0000000..1618f28 Binary files /dev/null and b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Contents.guide.info differ diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/EIndex.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/EIndex.guide new file mode 100644 index 0000000..54bc2a6 --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/EIndex.guide @@ -0,0 +1,294 @@ +@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" "E Language Index" +@Next "Index.guide/main" +@Prev "Appendices.guide/Other Information" +@Toc "Contents.guide/main" + +E Language Index +**************** + + This index should be used to find detailed information about the +keywords, functions, variables and constants which are part of the Amiga E +language. There is a separate index which deals with concepts etc. (see +@{"Main Index" Link "Index.guide/main" }). + + + + @{" Symbol, close curly brace " Link "Types.guide/Finding addresses (making pointers)" 0 } Finding addresses (making pointers) + @{" Symbol, double-quote " Link "Constants.guide/Numeric Constants" 11 } Numeric Constants + @{" Symbol, open curly brace " Link "Types.guide/Finding addresses (making pointers)" 0 } Finding addresses (making pointers) + @{" Symbol, ! " Link "FloatingPoint.guide/Floating-Point Calculations" 0 } Floating-Point Calculations + @{" Symbol, $ " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Symbol, % " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Symbol, ' .. ' (string) " Link "Types.guide/Normal strings and E-strings" 0 } Normal strings and E-strings + @{" Symbol, * " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Symbol, + " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Symbol, + (strings) " Link "Format.guide/Statements" 58 } Statements + @{" Symbol, ++ " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Symbol, - " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Symbol, -- " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Symbol, -> " Link "Format.guide/Comments" 0 } Comments + @{" Symbol, / " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Symbol, /* .. */ " Link "Format.guide/Comments" 0 } Comments + @{" Symbol, : " Link "MoreExpressions.guide/Labelling and the JUMP statement" 0 } Labelling and the JUMP statement + @{" Symbol, := " Link "Introduction.guide/Assignment" 0 } Assignment + @{" Symbol, ; " Link "Format.guide/Statements" 18 } Statements + @{" Symbol, < " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Symbol, <= " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Symbol, <=> " Link "MoreExpressions.guide/Unification" 0 } Unification + @{" Symbol, <> " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Symbol, = " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Symbol, > " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Symbol, >= " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Symbol, [ .. , .. ] (list) " Link "Types.guide/Lists and E-lists" 12 } Lists and E-lists + @{" Symbol, [ .. , .. ]:type (typed list) " Link "Types.guide/Typed lists" 0 } Typed lists + @{" Symbol, [ .. ] (array) " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Symbol, [] (array) " Link "Types.guide/Accessing array data" 55 } Accessing array data + @{" Symbol, \0 " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \a " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \b " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \c " Link "BuiltIns.guide/Input and output functions" 16 } Input and output functions + @{" Symbol, \d " Link "BuiltIns.guide/Input and output functions" 16 } Input and output functions + @{" Symbol, \d " Link "Introduction.guide/Changing the example" 0 } Changing the example + @{" Symbol, \e " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \h " Link "BuiltIns.guide/Input and output functions" 16 } Input and output functions + @{" Symbol, \l " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Symbol, \n " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \n " Link "Introduction.guide/Strings" 0 } Strings + @{" Symbol, \q " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \r " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Symbol, \s " Link "BuiltIns.guide/Input and output functions" 16 } Input and output functions + @{" Symbol, \t " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, \z " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Symbol, \\ " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Symbol, ^ " Link "Types.guide/Extracting data (dereferencing pointers)" 0 } Extracting data (dereferencing pointers) + @{" Symbol, ` (backquote) " Link "MoreExpressions.guide/Quoted Expressions" 0 } Quoted Expressions + @{" Abs " Link "BuiltIns.guide/Maths and logic functions" 30 } Maths and logic functions + @{" ALL " Link "BuiltIns.guide/Built-In Constants" 12 } Built-In Constants + @{" And " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" AND " Link "MoreExpressions.guide/Bitwise AND and OR" 0 } Bitwise AND and OR + @{" arg " Link "BuiltIns.guide/Built-In Variables" 7 } Built-In Variables + @{" ARRAY " Link "Types.guide/Tables of data" 0 } Tables of data + @{" ARRAY OF type " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Bounds " Link "BuiltIns.guide/Maths and logic functions" 55 } Maths and logic functions + @{" Box " Link "BuiltIns.guide/Graphics functions" 30 } Graphics functions + @{" BUT " Link "MoreExpressions.guide/BUT expression" 0 } BUT expression + @{" CASE " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" CASE " Link "Introduction.guide/SELECT block" 0 } SELECT block + @{" CASE ..TO.. " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" CHAR " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Char " Link "BuiltIns.guide/Maths and logic functions" 116 } Maths and logic functions + @{" CHAR " Link "MoreExpressions.guide/Static memory" 0 } Static memory + @{" CleanUp " Link "BuiltIns.guide/System support functions" 65 } System support functions + @{" CloseS " Link "BuiltIns.guide/Intuition support functions" 178 } Intuition support functions + @{" CloseW " Link "BuiltIns.guide/Intuition support functions" 122 } Intuition support functions + @{" Colour " Link "BuiltIns.guide/Graphics functions" 35 } Graphics functions + @{" conout " Link "BuiltIns.guide/Built-In Variables" 34 } Built-In Variables + @{" CONST " Link "Constants.guide/Named Constants" 0 } Named Constants + @{" CtrlC " Link "BuiltIns.guide/System support functions" 74 } System support functions + @{" DEC " Link "MoreExpressions.guide/INC and DEC statements" 0 } INC and DEC statements + @{" DEF " Link "Introduction.guide/Variable declaration" 0 } Variable declaration + @{" DEFAULT " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" DEFAULT " Link "Introduction.guide/SELECT block" 0 } SELECT block + @{" Dispose " Link "BuiltIns.guide/System support functions" 39 } System support functions + @{" DisposeLink " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Div " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" DO, (FOR loop) " Link "Introduction.guide/FOR loop" 55 } FOR loop + @{" DO, (WHILE loop) " Link "Introduction.guide/WHILE loop" 57 } WHILE loop + @{" dosbase " Link "BuiltIns.guide/Built-In Variables" 51 } Built-In Variables + @{" ELSE " Link "Introduction.guide/IF block" 0 } IF block + @{" ELSEIF " Link "Introduction.guide/IF block" 0 } IF block + @{" EMPTY " Link "OOE.guide/Inheritance in E" 275 } Inheritance in E + @{" end " Link "OOE.guide/Methods in E" 118 } Methods in E + @{" END " Link "Memory.guide/NEW and END Operators" 0 } NEW and END Operators + @{" ENDFOR " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" ENDIF " Link "Introduction.guide/IF block" 0 } IF block + @{" ENDLOOP " Link "MoreExpressions.guide/LOOP block" 0 } LOOP block + @{" ENDOBJECT " Link "Types.guide/Example object" 23 } Example object + @{" ENDPROC " Link "Introduction.guide/Procedure Definition" 0 } Procedure Definition + @{" ENDPROC value " Link "Procedures.guide/Functions" 23 } Functions + @{" ENDSELECT " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" ENDSELECT " Link "Introduction.guide/SELECT block" 0 } SELECT block + @{" ENDWHILE " Link "Introduction.guide/WHILE loop" 0 } WHILE loop + @{" ENUM " Link "Constants.guide/Enumerations" 0 } Enumerations + @{" Eor " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" EstrLen " Link "Types.guide/String functions" 125 } String functions + @{" Eval " Link "MoreExpressions.guide/Evaluation" 0 } Evaluation + @{" Even " Link "BuiltIns.guide/Maths and logic functions" 41 } Maths and logic functions + @{" EXCEPT " Link "Exceptions.guide/Procedures with Exception Handlers" 0 } Procedures with Exception Handlers + @{" EXCEPT DO " Link "Exceptions.guide/Raising an Exception" 73 } Raising an Exception + @{" exception " Link "Exceptions.guide/Raising an Exception" 36 } Raising an Exception + @{" exceptioninfo " Link "Exceptions.guide/Raising an Exception" 50 } Raising an Exception + @{" execbase " Link "BuiltIns.guide/Built-In Variables" 51 } Built-In Variables + @{" Exists " Link "MoreExpressions.guide/Lists and quoted expressions" 46 } Lists and quoted expressions + @{" EXIT " Link "MoreExpressions.guide/EXIT statement" 0 } EXIT statement + @{" Fabs " Link "FloatingPoint.guide/Floating-Point Functions" 55 } Floating-Point Functions + @{" FALSE " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" FALSE " Link "BuiltIns.guide/Built-In Constants" 5 } Built-In Constants + @{" FastDispose " Link "BuiltIns.guide/System support functions" 59 } System support functions + @{" FastDisposeList " Link "Memory.guide/List and typed list allocation" 66 } List and typed list allocation + @{" FastNew " Link "BuiltIns.guide/System support functions" 50 } System support functions + @{" Fceil " Link "FloatingPoint.guide/Floating-Point Functions" 59 } Floating-Point Functions + @{" Fcos " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Fexp " Link "FloatingPoint.guide/Floating-Point Functions" 66 } Floating-Point Functions + @{" Ffloor " Link "FloatingPoint.guide/Floating-Point Functions" 59 } Floating-Point Functions + @{" FileLength " Link "BuiltIns.guide/Input and output functions" 154 } Input and output functions + @{" Flog " Link "FloatingPoint.guide/Floating-Point Functions" 73 } Floating-Point Functions + @{" Flog10 " Link "FloatingPoint.guide/Floating-Point Functions" 73 } Floating-Point Functions + @{" FOR " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" ForAll " Link "MoreExpressions.guide/Lists and quoted expressions" 29 } Lists and quoted expressions + @{" Forward " Link "Types.guide/Linked Lists" 56 } Linked Lists + @{" Fpow " Link "FloatingPoint.guide/Floating-Point Functions" 66 } Floating-Point Functions + @{" FreeStack " Link "BuiltIns.guide/System support functions" 79 } System support functions + @{" Fsin " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Fsqrt " Link "FloatingPoint.guide/Floating-Point Functions" 63 } Floating-Point Functions + @{" Ftan " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Gadget " Link "BuiltIns.guide/Intuition support functions" 187 } Intuition support functions + @{" GADGETSIZE " Link "BuiltIns.guide/Built-In Constants" 16 } Built-In Constants + @{" gfxbase " Link "BuiltIns.guide/Built-In Variables" 51 } Built-In Variables + @{" HANDLE " Link "Exceptions.guide/Procedures with Exception Handlers" 0 } Procedures with Exception Handlers + @{" IF " Link "Introduction.guide/IF block" 0 } IF block + @{" IF, (expression) " Link "Introduction.guide/IF expression" 0 } IF expression + @{" INC " Link "MoreExpressions.guide/INC and DEC statements" 0 } INC and DEC statements + @{" INCBIN " Link "MoreExpressions.guide/Static memory" 0 } Static memory + @{" Inp " Link "BuiltIns.guide/Input and output functions" 109 } Input and output functions + @{" InStr " Link "Types.guide/String functions" 156 } String functions + @{" Int " Link "BuiltIns.guide/Maths and logic functions" 116 } Maths and logic functions + @{" INT " Link "MoreExpressions.guide/Static memory" 0 } Static memory + @{" INT " Link "Types.guide/Indirect types" 0 } Indirect types + @{" intuitionbase " Link "BuiltIns.guide/Built-In Variables" 51 } Built-In Variables + @{" IS " Link "Procedures.guide/One-Line Functions" 0 } One-Line Functions + @{" JUMP " Link "MoreExpressions.guide/Labelling and the JUMP statement" 0 } Labelling and the JUMP statement + @{" KickVersion " Link "BuiltIns.guide/System support functions" 84 } System support functions + @{" LeftMouse " Link "BuiltIns.guide/Intuition support functions" 273 } Intuition support functions + @{" Line " Link "BuiltIns.guide/Graphics functions" 27 } Graphics functions + @{" Link " Link "Types.guide/Linked Lists" 23 } Linked Lists + @{" LIST " Link "Types.guide/Lists and E-lists" 35 } Lists and E-lists + @{" List " Link "Types.guide/List functions" 12 } List functions + @{" ListAdd " Link "Types.guide/List functions" 47 } List functions + @{" ListCmp " Link "Types.guide/List functions" 28 } List functions + @{" ListCopy " Link "Types.guide/List functions" 37 } List functions + @{" ListItem " Link "Types.guide/List functions" 65 } List functions + @{" ListLen " Link "Types.guide/List functions" 55 } List functions + @{" ListMax " Link "Types.guide/List functions" 59 } List functions + @{" Long " Link "BuiltIns.guide/Maths and logic functions" 116 } Maths and logic functions + @{" LONG " Link "Types.guide/LONG Type" 0 } LONG Type + @{" LONG " Link "MoreExpressions.guide/Static memory" 0 } Static memory + @{" LONG, preliminary " Link "Introduction.guide/Variable types" 0 } Variable types + @{" LOOP " Link "MoreExpressions.guide/LOOP block" 0 } LOOP block + @{" LowerStr " Link "Types.guide/String functions" 169 } String functions + @{" main " Link "Introduction.guide/Procedures" 0 } Procedures + @{" MapList " Link "MoreExpressions.guide/Lists and quoted expressions" 8 } Lists and quoted expressions + @{" Max " Link "BuiltIns.guide/Maths and logic functions" 49 } Maths and logic functions + @{" MidStr " Link "Types.guide/String functions" 144 } String functions + @{" Min " Link "BuiltIns.guide/Maths and logic functions" 52 } Maths and logic functions + @{" Mod " Link "BuiltIns.guide/Maths and logic functions" 70 } Maths and logic functions + @{" MODULE " Link "Modules.guide/Using Modules" 0 } Using Modules + @{" Mouse " Link "BuiltIns.guide/Intuition support functions" 235 } Intuition support functions + @{" MouseX " Link "BuiltIns.guide/Intuition support functions" 259 } Intuition support functions + @{" MouseY " Link "BuiltIns.guide/Intuition support functions" 266 } Intuition support functions + @{" MsgCode " Link "BuiltIns.guide/Intuition support functions" 313 } Intuition support functions + @{" MsgIaddr " Link "BuiltIns.guide/Intuition support functions" 316 } Intuition support functions + @{" MsgQualifier " Link "BuiltIns.guide/Intuition support functions" 321 } Intuition support functions + @{" Mul " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" NEW " Link "Memory.guide/NEW and END Operators" 0 } NEW and END Operators + @{" New " Link "BuiltIns.guide/System support functions" 0 } System support functions + @{" NEWFILE " Link "BuiltIns.guide/Built-In Constants" 20 } Built-In Constants + @{" NewM " Link "BuiltIns.guide/System support functions" 19 } System support functions + @{" NewR " Link "BuiltIns.guide/System support functions" 14 } System support functions + @{" Next " Link "Types.guide/Linked Lists" 38 } Linked Lists + @{" NIL " Link "BuiltIns.guide/Built-In Constants" 8 } Built-In Constants + @{" Not " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" OBJECT " Link "Types.guide/Example object" 23 } Example object + @{" OBJECT..OF " Link "OOE.guide/Inheritance in E" 0 } Inheritance in E + @{" Odd " Link "BuiltIns.guide/Maths and logic functions" 45 } Maths and logic functions + @{" OLDFILE " Link "BuiltIns.guide/Built-In Constants" 20 } Built-In Constants + @{" OpenS " Link "BuiltIns.guide/Intuition support functions" 129 } Intuition support functions + @{" OpenW " Link "BuiltIns.guide/Intuition support functions" 16 } Intuition support functions + @{" OR " Link "MoreExpressions.guide/Bitwise AND and OR" 0 } Bitwise AND and OR + @{" Or " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" Out " Link "BuiltIns.guide/Input and output functions" 99 } Input and output functions + @{" Plot " Link "BuiltIns.guide/Graphics functions" 16 } Graphics functions + @{" PrintF " Link "BuiltIns.guide/Input and output functions" 85 } Input and output functions + @{" PRIVATE " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" PROC " Link "Introduction.guide/Procedure Definition" 0 } Procedure Definition + @{" PROC..OF " Link "OOE.guide/Methods in E" 0 } Methods in E + @{" PTR TO type " Link "Types.guide/PTR Type" 0 } PTR Type + @{" PUBLIC " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" PutChar " Link "BuiltIns.guide/Maths and logic functions" 123 } Maths and logic functions + @{" PutInt " Link "BuiltIns.guide/Maths and logic functions" 123 } Maths and logic functions + @{" PutLong " Link "BuiltIns.guide/Maths and logic functions" 123 } Maths and logic functions + @{" Raise " Link "Exceptions.guide/Raising an Exception" 0 } Raising an Exception + @{" RAISE " Link "Exceptions.guide/Automatic Exceptions" 25 } Automatic Exceptions + @{" ReadStr " Link "BuiltIns.guide/Input and output functions" 114 } Input and output functions + @{" RealF " Link "FloatingPoint.guide/Floating-Point Functions" 19 } Floating-Point Functions + @{" RealVal " Link "FloatingPoint.guide/Floating-Point Functions" 10 } Floating-Point Functions + @{" REPEAT " Link "Introduction.guide/REPEAT..UNTIL loop" 0 } REPEAT..UNTIL loop + @{" ReThrow " Link "Exceptions.guide/Raise within an Exception Handler" 68 } Raise within an Exception Handler + @{" RETURN " Link "Procedures.guide/Functions" 32 } Functions + @{" RightStr " Link "Types.guide/String functions" 136 } String functions + @{" Rnd " Link "BuiltIns.guide/Maths and logic functions" 84 } Maths and logic functions + @{" RndQ " Link "BuiltIns.guide/Maths and logic functions" 93 } Maths and logic functions + @{" SELECT " Link "Introduction.guide/SELECT block" 0 } SELECT block + @{" SELECT " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" SELECT..OF " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" SelectList " Link "MoreExpressions.guide/Lists and quoted expressions" 62 } Lists and quoted expressions + @{" self " Link "OOE.guide/Methods in E" 67 } Methods in E + @{" SET " Link "Constants.guide/Sets" 0 } Sets + @{" SetColour " Link "BuiltIns.guide/Graphics functions" 49 } Graphics functions + @{" SetList " Link "Types.guide/List functions" 62 } List functions + @{" SetStdIn " Link "BuiltIns.guide/Input and output functions" 161 } Input and output functions + @{" SetStdOut " Link "BuiltIns.guide/Input and output functions" 170 } Input and output functions + @{" SetStdRast " Link "BuiltIns.guide/Graphics functions" 58 } Graphics functions + @{" SetStr " Link "Types.guide/String functions" 178 } String functions + @{" SetTopaz " Link "BuiltIns.guide/Graphics functions" 67 } Graphics functions + @{" Shl " Link "BuiltIns.guide/Maths and logic functions" 100 } Maths and logic functions + @{" Shr " Link "BuiltIns.guide/Maths and logic functions" 108 } Maths and logic functions + @{" Sign " Link "BuiltIns.guide/Maths and logic functions" 36 } Maths and logic functions + @{" SIZEOF " Link "MoreExpressions.guide/SIZEOF expression" 0 } SIZEOF expression + @{" stdin " Link "BuiltIns.guide/Built-In Variables" 34 } Built-In Variables + @{" stdout " Link "BuiltIns.guide/Built-In Variables" 34 } Built-In Variables + @{" stdrast " Link "BuiltIns.guide/Built-In Variables" 46 } Built-In Variables + @{" STEP " Link "Introduction.guide/FOR loop" 37 } FOR loop + @{" StrAdd " Link "Types.guide/String functions" 99 } String functions + @{" StrCmp " Link "Types.guide/String functions" 40 } String functions + @{" StrCopy " Link "Types.guide/String functions" 58 } String functions + @{" STRING " Link "Types.guide/Normal strings and E-strings" 49 } Normal strings and E-strings + @{" String " Link "Types.guide/String functions" 14 } String functions + @{" StringF " Link "BuiltIns.guide/Input and output functions" 90 } Input and output functions + @{" StrLen " Link "Types.guide/String functions" 108 } String functions + @{" STRLEN " Link "BuiltIns.guide/Built-In Constants" 24 } Built-In Constants + @{" StrMax " Link "Types.guide/String functions" 131 } String functions + @{" SUPER " Link "OOE.guide/Inheritance in E" 110 } Inheritance in E + @{" TextF " Link "BuiltIns.guide/Graphics functions" 42 } Graphics functions + @{" THEN " Link "Introduction.guide/IF block" 29 } IF block + @{" Throw " Link "Exceptions.guide/Raising an Exception" 0 } Raising an Exception + @{" TO " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" TO, (CASE range) " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" TO, (FOR loop) " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" TrimStr " Link "Types.guide/String functions" 161 } String functions + @{" TRUE " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" TRUE " Link "BuiltIns.guide/Built-In Constants" 5 } Built-In Constants + @{" UNTIL " Link "Introduction.guide/REPEAT..UNTIL loop" 0 } REPEAT..UNTIL loop + @{" UpperStr " Link "Types.guide/String functions" 174 } String functions + @{" Val " Link "Types.guide/String functions" 199 } String functions + @{" VOID " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" WaitIMessage " Link "BuiltIns.guide/Intuition support functions" 282 } Intuition support functions + @{" WaitLeftMouse " Link "BuiltIns.guide/Intuition support functions" 324 } Intuition support functions + @{" wbmessage " Link "BuiltIns.guide/Built-In Variables" 23 } Built-In Variables + @{" WHILE " Link "Introduction.guide/WHILE loop" 0 } WHILE loop + @{" WriteF " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/EIndex.guide.info b/amigae33a/E_v3.3a/Docs/BeginnersGuide/EIndex.guide.info new file mode 100644 index 0000000..2ebbabd Binary files /dev/null and b/amigae33a/E_v3.3a/Docs/BeginnersGuide/EIndex.guide.info differ diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Examples.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Examples.guide new file mode 100644 index 0000000..2192ffe --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Examples.guide @@ -0,0 +1,1189 @@ +@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" "Introduction to the Examples" +@Next "String Handling and I-O" +@Prev "OOE.guide/main" +@Toc "Contents.guide/main" + +Introduction to the Examples +**************************** + + In this part we shall go through some slightly larger examples than +those in the previous parts. However, none of them are too big, so they +should still be easy to understand. The note-worthy parts of each example +are described, and you may even find the odd comment in the code. Large, +complicated programs benefit hugely from the odd well-placed and +descriptive comment. This fact can't be stressed enough. + + All the examples will run on a standard Amiga, except for the one which +uses @{b }ReadArgs@{ub } (an AmigaDOS 2.0 function). It is really worth upgrading +your system to AmigaDOS 2.0 (or above) if you are still using previous +versions. The @{b }ReadArgs@{ub } example can only hint at the power and +friendliness of the newer system functions. If you are fortunate enough +to have an A4000 or an accelerated machine, then the timing example will +give better (i.e., quicker) results. + + Supplied with this Guide should be a directory of sources of most of +the examples. Here's a complete catalogue: + +@{b }simple.e@{ub } + The simple program from the introduction. See @{"A Simple Program" Link "Introduction.guide/A Simple Program" }. + +@{b }while.e@{ub } + The slightly complicated @{b }WHILE@{ub } loop. See @{"WHILE loop" Link "Introduction.guide/WHILE loop" }. + +@{b }address.e@{ub } + The program which prints the addresses of some variables. See + @{"Finding addresses (making pointers)" Link "Types.guide/Finding addresses (making pointers)" }. + +@{b }static.e@{ub } + The static data problem. See @{"Static data" Link "Types.guide/Static data" }. + +@{b }static2.e@{ub } + The first solution to the static data problem. See @{"Static data" Link "Types.guide/Static data" }. + +@{b }except.e@{ub } + An exception handler example. See @{"Raising an Exception" Link "Exceptions.guide/Raising an Exception" }. + +@{b }except2.e@{ub } + Another exception handler example. See @{"Raising an Exception" Link "Exceptions.guide/Raising an Exception" }. + +@{b }static3.e@{ub } + The second solution to the static data problem, using @{b }NEW@{ub }. See + @{"List and typed list allocation" Link "Memory.guide/List and typed list allocation" }. + +@{b }float.e@{ub } + The floating-point example program. See @{"Floating-Point Functions" Link "FloatingPoint.guide/Floating-Point Functions" }. + +@{b }bintree.e@{ub } + The binary tree example. See @{"Binary Trees" Link "Recursion.guide/Binary Trees" }. + +@{b }tree.e@{ub } + The @{b }tree@{ub } and @{b }integer_tree@{ub } classes, as a module. See @{"Inheritance in E" Link "OOE.guide/Inheritance in E" }. + +@{b }tree-use.e@{ub } + A program to use the @{b }integer_tree@{ub } class. See @{"Inheritance in E" Link "OOE.guide/Inheritance in E" }. + +@{b }set.e@{ub } + The simple, inefficient @{b }set@{ub } class, as a module. See @{"Data-Hiding in E" Link "OOE.guide/Data-Hiding in E" }. + +@{b }set-use.e@{ub } + A program to use the @{b }set@{ub } class. See @{"Data-Hiding in E" Link "OOE.guide/Data-Hiding in E" }. + +@{b }csv-estr.e@{ub } + The CSV reading program using E-strings. See @{"String Handling and I-O" Link "String Handling and I-O" }. + +@{b }csv-norm.e@{ub } + The CSV reading program using normal strings. See + @{"String Handling and I-O" Link "String Handling and I-O" }. + +@{b }csv-buff.e@{ub } + The CSV reading program using normal strings and a large buffer. See + @{"String Handling and I-O" Link "String Handling and I-O" }. + +@{b }csv.e@{ub } + The CSV reading program using normal strings, a large buffer, and an + exception handler. See @{"String Handling and I-O" Link "String Handling and I-O" }. + +@{b }timing.e@{ub } + The timing example. See @{"Timing Expressions" Link "Timing Expressions" }. + +@{b }args.e@{ub } + The argument parsing example for any AmigaDOS. See @{"Any AmigaDOS" Link "Any AmigaDOS" }. + +@{b }args20.e@{ub } + The argument parsing example for any AmigaDOS 2.0 and above. See + @{"AmigaDOS 2.0 (and above)" Link "AmigaDOS 2.0 (and above)" }. + +@{b }gadgets.e@{ub } + The gadgets example. See @{"Gadgets" Link "Gadgets" }. + +@{b }idcmp.e@{ub } + The IDCMP and gadgets example. See @{"IDCMP Messages" Link "IDCMP Messages" }. + +@{b }graphics.e@{ub } + The graphics example. See @{"Graphics" Link "Graphics" }. + +@{b }screens.e@{ub } + The screens example, without an exception handler. See @{"Screens" Link "Screens" }. + +@{b }screens2.e@{ub } + The screens example again, but this time with an exception handler. + See @{"Screens" Link "Screens" }. + +@{b }dragon.e@{ub } + The dragon curve recursion example. See @{"Recursion Example" Link "Recursion Example" }. + + +@ENDNODE + +@NODE "String Handling and I-O" "String Handling and I-O" +@Next "Timing Expressions" +@Prev "main" +@Toc "Contents.guide/main" + +String Handling and I/O +*********************** + + This chapter shows how to use normal strings and E-strings, and also +how to read data from a file. The programs use a number of the string +functions and make effective (but different) use of memory where possible. +The key points to understand are: + + @{b }*@{ub } The difference between normal strings and E-strings. + + @{b }*@{ub } The two methods of reading data from a file (line-by-line or all at + once). + + @{b }*@{ub } The necessary allocation of memory for E-strings. + + @{b }*@{ub } The unnecessary, but advisable, deallocation of the E-string memory + once it is no longer needed. The deallocation could be left to the + automatic deallocation at the end of the program, but that would + waste an increasing amount of memory whilst the program was running. + If the input data was large then memory could easily be exhausted. + + @{b }*@{ub } The way in which sections of an E-string (or a normal string, for + that matter) can easily be turned into normal strings. + + @{b }*@{ub } The way exception handlers can tidy up programs. + + The problem to solve is reading of a CSV (comma separated variables) +file, which is a standard format file for databases and spreadsheets. The +format is very simple: each record is a line (i.e., terminated with a +line-feed) and each field in a record is separated by a comma. To make +this example a lot simpler, we will forbid a field to contain a comma +(normally this would require the field to be quoted). So, a typical input +file would look like this: + + Field1,Field2,Field3 + 10,19,-3 + fred,barney,wilma + ,,last + first,, + +In this example all records have three fields, as is well illustrated by +the first line (i.e., the first record). The last two records may seem a +bit strange, but they just show how fields can be blank. In the last +record all but the first field are blank, and in the previous record all +but the last are blank. + + So now we know the format of the file to be read. To operate on a file +we must first open it using the @{b }Open@{ub } function (from the @{b }dos.library@{ub }), and +to read the lines from the file we will use the @{b }ReadStr@{ub } (built-in) +function. There will be four versions of a program to read a CSV file: +two of which read data line-by-line and two which read all the file at +once. Of the two which read line-by-line, one manipulates the read lines +as E-strings and the other uses normal strings. The use of normal strings +is arguably more advanced than the use of E-strings, since cunning tricks +are employed to make effective use of memory. However, the programs are +not meant to show that E-strings are better than normal strings (or vice +versa), rather they are meant to show how to use strings properly. + + /* A suitably large size for the record buffer */ + CONST BUFFERSIZE=512 + + PROC main() + DEF filehandle, status, buffer[BUFFERSIZE]:STRING, filename + filename:='datafile' + IF filehandle:=Open(filename, OLDFILE) + REPEAT + status:=ReadStr(filehandle, buffer) + /* This is the way to check ReadStr() actually read something */ + IF buffer[] OR (status<>-1) THEN process_record(buffer) + UNTIL status=-1 + /* If Open() succeeded then we must Close() the file */ + Close(filehandle) + ELSE + WriteF('Error: Failed to open "\\s"\\n', filename) + ENDIF + ENDPROC + + PROC process_record(line) + DEF i=1, start=0, end, len, s + /* Show the whole line being processed */ + WriteF('Processing record: "\\s"\\n', line) + REPEAT + /* Find the index of a comma after the start index */ + end:=InStr(line, ',', start) + /* Length is end index minus start index */ + len:=(IF end<>-1 THEN end ELSE EstrLen(line))-start + IF len>0 + /* Allocate an E-string of the correct length */ + IF s:=String(len) + /* Copy the portion of the line to the E-string s */ + MidStr(s, line, start, len) + /* At this point we could do something useful... */ + WriteF('\\t\\d) "\\s"\\n', i, s) + /* We've finished with the E-string so deallocate it */ + DisposeLink(s) + ELSE + /* It's a non-fatal error if the String() call fails */ + WriteF('\\t\\d) Memory exhausted! (len=\\d)\\n', len) + ENDIF + ELSE + WriteF('\\t\\d) Empty Field\\n', i) + ENDIF + /* The new start is after the end we found */ + start:=end+1 + INC i + /* Once a comma is not found we've finished */ + UNTIL end=-1 + ENDPROC + + There are a couple of points worth noting about this program: + + @{b }*@{ub } A large E-string, @{b }buffer@{ub }, is used to hold each line before it is + processed. If a record exceeds the size of this E-string then + @{b }ReadStr@{ub } will only read a partial record, and the next @{b }ReadStr@{ub } + will read some more this record. However, the program considers each + call to @{b }ReadStr@{ub } to read a whole record, so it will get the records + slightly wrong in this case. This is a limitation of the program and + it should be documented so that users know to constrain themselves to + datafiles without long lines. + + @{b }*@{ub } The file name is `hard-wired' to be @{b }datafile@{ub }. A more flexible + program would allow this to be passed as an argument (see + @{"Argument Parsing" Link "Argument Parsing" }). + + @{b }*@{ub } @{b }ReadStr@{ub } may return -1 to indicate an error (usually when the end + of the file has been reached), but the E-string read so far may still + be valid. The check on the E-string and error value is the proper + way of deciding whether @{b }ReadStr@{ub } actually read anything from the file. + + @{b }*@{ub } Look carefully at the manipulation of the string indexes @{b }start@{ub } and + @{b }end@{ub }, and the calculation of the length of a portion of a string. + + @{b }*@{ub } @{b }MidStr@{ub } is used to copy a field from a record, so an E-string must + be used to hold the field. + + @{b }*@{ub } The E-string @{b }s@{ub } is only valid between the successful allocation by + @{b }string@{ub } and the @{b }DisposeLink@{ub }. It would be incorrect to try to, for + instance, print it at any other point. On the other hand, a more + complicated program may want to store up all the data, and so it may + be inappropriate to deallocate the E-string at this point. In this + case, the pointer to the E-string could be stored and it might be + valid for the rest of the program. + + @{b }*@{ub } The allocation using @{b }String@{ub } is very closely followed by deallocation + using @{b }DisposeLink@{ub }. This suggests that a single E-string could be + allocated and used repeatedly (like @{b }buffer@{ub } is), due to the simple + nature of this example. + + To change this to use normal strings (in a very memory efficient way), +we need to alter only the @{b }process_record@{ub } procedure. Some note-worthy +differences are: + + @{b }*@{ub } Small parts of the E-string @{b }buffer@{ub } are turned into normal strings by + terminating them with @{b }NIL@{ub } when necessary. This involves changing a + comma that is found. + + @{b }*@{ub } No new memory is allocated, rather the @{b }buffer@{ub } memory is reused (as + described above). This is fine for this example, although if the + fields were needed after a record had been processed they would need + to be copied, since the contents of @{b }buffer@{ub } are changed by @{b }ReadStr@{ub }. + + PROC process_record(line) + DEF i=1, start=0, end, s + /* Show the whole line being processed */ + WriteF('Processing record: "\\s"\\n', line) + REPEAT + /* Find the index of a comma after the start index */ + end:=InStr(line, ',', start) + /* If a comma was found then terminate with a NIL */ + IF end<>-1 THEN line[end]:=NIL + /* Point to the start of the field */ + s:=line+start + IF s[] + /* At this point we could do something useful... */ + WriteF('\\t\\d) "\\s"\\n', i, s) + ELSE + WriteF('\\t\\d) Empty Field\\n', i) + ENDIF + /* The new start is after the end we found */ + start:=end+1 + INC i + /* Once a comma is not found we've finished */ + UNTIL end=-1 + ENDPROC + + The next two versions of the program are basically the same: they both +read the whole file into one large, dynamically allocated buffer and then +process the data. The second of the two versions also uses exceptions to +make the program much more readable. The differences from the above +version which uses normal strings are: + + @{b }*@{ub } The @{b }main@{ub } procedure calculates the length of the data in the file and + then uses @{b }New@{ub } to dynamically allocate some memory to hold it. + + @{b }*@{ub } The read data is terminated with a @{b }NIL@{ub } so that it can safely be + treated as a (very long) normal string. + + @{b }*@{ub } The @{b }process_buffer@{ub } procedure splits the read data up into lots of + normal strings, one for each line of data. + + PROC main() + DEF buffer, filehandle, len, filename + filename:='datafile' + /* Get the length of data in the file */ + IF 0<(len:=FileLength(filename)) + /* Allocate just enough room for the data + a terminating NIL */ + IF buffer:=New(len+1) + IF filehandle:=Open(filename, OLDFILE) + /* Read whole file, checking amount read */ + IF len=Read(filehandle, buffer, len) + /* Terminate buffer with a NIL just in case... */ + buffer[len]:=NIL + process_buffer(buffer, len) + ELSE + WriteF('Error: File reading error\\n') + ENDIF + /* If Open() succeeded then we must Close() the file */ + Close(filehandle) + ELSE + WriteF('Error: Failed to open "\\s"\\n', filename) + ENDIF + /* Deallocate buffer (not really necessary in this example) */ + Dispose(buffer) + ELSE + WriteF('Error: Insufficient memory to load file\\n') + ENDIF + ELSE + WriteF('Error: "\\s" is an empty file\\n', filename) + ENDIF + ENDPROC + + /* buffer is like a normal string since it's NIL-terminated */ + PROC process_buffer(buffer, len) + DEF start=0, end + REPEAT + /* Find the index of a linefeed after the start index */ + end:=InStr(buffer, '\\n', start) + /* If a linefeed was found then terminate with a NIL */ + IF end<>-1 THEN buffer[end]:=NIL + process_record(buffer+start) + start:=end+1 + /* We've finished if at the end or no more linefeeds */ + UNTIL (start>=len) OR (end=-1) + ENDPROC + + PROC process_record(line) + DEF i=1, start=0, end, s + /* Show the whole line being processed */ + WriteF('Processing record: "\\s"\\n', line) + REPEAT + /* Find the index of a comma after the start index */ + end:=InStr(line, ',', start) + /* If a comma was found then terminate with a NIL */ + IF end<>-1 THEN line[end]:=NIL + /* Point to the start of the field */ + s:=line+start + IF s[] + /* At this point we could do something useful... */ + WriteF('\\t\\d) "\\s"\\n', i, s) + ELSE + WriteF('\\t\\d) Empty Field\\n', i) + ENDIF + /* The new start is after the end we found */ + start:=end+1 + INC i + /* Once a comma is not found we've finished */ + UNTIL end=-1 + ENDPROC + + The program is now quite messy, with many error cases in the @{b }main@{ub } +procedure. We can very simply change this by using an exception handler +and a few automatic exceptions. + + /* Some constants for exceptions (ERR_NONE is zero: no error) */ + ENUM ERR_NONE, ERR_LEN, ERR_NEW, ERR_OPEN, ERR_READ + + /* Make some exceptions automatic */ + RAISE ERR_LEN IF FileLength()<=0, + ERR_NEW IF New()=NIL, + ERR_OPEN IF Open()=NIL + + PROC main() HANDLE + /* Note the careful initialisation of buffer and filehandle */ + DEF buffer=NIL, filehandle=NIL, len, filename + filename:='datafile' + /* Get the length of data in the file */ + len:=FileLength(filename) + /* Allocate just enough room for the data + a terminating NIL */ + buffer:=New(len+1) + filehandle:=Open(filename, OLDFILE) + /* Read whole file, checking amount read */ + IF len<>Read(filehandle, buffer, len) THEN Raise(ERR_READ) + /* Terminate buffer with a NIL just in case... */ + buffer[len]:=NIL + process_buffer(buffer, len) + EXCEPT DO + /* Both of these are safe thanks to the initialisations */ + IF buffer THEN Dispose(buffer) + IF filehandle THEN Close(filehandle) + /* Report error (if there was one) */ + SELECT exception + CASE ERR_LEN; WriteF('Error: "\\s" is an empty file\\n', filename) + CASE ERR_NEW; WriteF('Error: Insufficient memory to load file\\n') + CASE ERR_OPEN; WriteF('Error: Failed to open "\\s"\\n', filename) + CASE ERR_READ; WriteF('Error: File reading error\\n') + ENDSELECT + ENDPROC + +The code is now much clearer, and the majority of errors can be caught +automatically. Notice that the exception handler is called even if the +program succeeds (thanks to the @{b }DO@{ub } after the @{b }EXCEPT@{ub }). This is because +when the program terminates it needs to deallocate the resources it +allocated in every case (successful or otherwise), so the code is the same. +Conditional deallocation (of the buffer, for example) is made safe by an +appropriate initialisation. + + If you feel like a small exercise, try to write a similar program but +this time using the @{b }tools/file@{ub } module which comes in the standard Amiga E +distribution. Of course, you'll first need to read the accompanying +documentation, but you should find that this module makes file interaction +very simple. + + +@ENDNODE + +@NODE "Timing Expressions" "Timing Expressions" +@Next "Argument Parsing" +@Prev "String Handling and I-O" +@Toc "Contents.guide/main" + +Timing Expressions +****************** + + You may recall the outline of a timing procedure in Part Two (see +@{"Evaluation" Link "MoreExpressions.guide/Evaluation" }). This chapter gives the complete version of this example. +The information missing from the outline was how to determine the system +time and use this to calculate the time taken by calls to @{b }Eval@{ub }. So the +things to notice about this example are: + + @{b }*@{ub } Use of the Amiga system function @{b }DateStamp@{ub } (from the @{b }dos.library@{ub }). + (You really need the `Rom Kernel Reference Manuals' and the `AmigaDOS + Manual' to understand the system functions.) + + @{b }*@{ub } Use of the module @{b }dos/dos@{ub } to include the definitions of the object + @{b }datestamp@{ub } and the constant @{b }TICKS_PER_SECOND@{ub }. (There are fifty ticks + per second.) + + @{b }*@{ub } Use of the @{b }repeat@{ub } procedure to do @{b }Eval@{ub } a decent number of times for + each expression (so that some time is taken up by the calls!). + + @{b }*@{ub } The timing of the evaluation of 0, to calculate the overhead of the + procedure calls and loop. This value is stored in the variable + @{b }offset@{ub } the first time the @{b }test@{ub } procedure is called. The + expression 0 should take a negligible amount of time, so the number + of ticks timed is actually the time taken by the procedure calls and + loop calculations. Subtracting this time from the other times gives + a fair view of how long the expressions take, relative to one another. + (Thanks to Wouter for this offset idea.) + + @{b }*@{ub } Use of @{b }Forbid@{ub } and @{b }Permit@{ub } to turn off multi-tasking temporarily, + making the CPU calculate only the expressions (rather than dealing + with screen output, other programs, etc.). + + @{b }*@{ub } Use of @{b }CtrlC@{ub } and @{b }CleanUp@{ub } to allow the user to stop the program if it + gets too boring... + + @{b }*@{ub } Use of the option @{b }LARGE@{ub } (using @{b }OPT@{ub }) to produce an executable that + uses the large data and code model. This seems to help make the + timings less susceptible variations due to, for instance, + optimisations, and so better for comparison. See the `Reference + Manual' for more details. + + Also supplied are some example outputs. The first was from an A1200 +with 2MB Chip RAM and 4MB Fast RAM. The second was from an A500Plus with +2MB Chip RAM. Both used the constant @{b }LOTS_OF_TIMES@{ub } as 500,000, but you +might need to increase this number to compare, for instance, an A4000/040 +to an A4000/030. However, 500,000 gives a pretty long wait for results on +the A500. + + MODULE 'dos/dos' + + CONST TICKS_PER_MINUTE=TICKS_PER_SECOND*60, LOTS_OF_TIMES=500000 + + DEF x, y, offset + + PROC fred(n) + DEF i + i:=n+x + ENDPROC + + /* Repeat evaluation of an expression */ + PROC repeat(exp) + DEF i + FOR i:=0 TO LOTS_OF_TIMES + Eval(exp) /* Evaluate the expression */ + ENDFOR + ENDPROC + + /* Time an expression, and set-up offset if not done already */ + PROC test(exp, message) + DEF t + IF offset=0 THEN offset:=time(`0) /* Calculate offset */ + t:=time(exp) + WriteF('\\s:\\t\\d ticks\\n', message, t-offset) + ENDPROC + + /* Time the repeated calls, and calculate number of ticks */ + PROC time(x) + DEF ds1:datestamp, ds2:datestamp + Forbid() + DateStamp(ds1) + repeat(x) + DateStamp(ds2) + Permit() + IF CtrlC() THEN CleanUp(1) + ENDPROC ((ds2.minute-ds1.minute)*TICKS_PER_MINUTE)+ds2.tick-ds1.tick + + PROC main() + x:=9999 + y:=1717 + test(`x+y, 'Addition') + test(`y-x, 'Subtraction') + test(`x*y, 'Multiplication') + test(`x/y, 'Division') + test(`x OR y, 'Bitwise OR') + test(`x AND y, 'Bitwise AND') + test(`x=y, 'Equality') + test(`xIDCMP_CLOSEWINDOW + gad:=MsgIaddr() /* Our gadget clicked? */ + IF (class=IDCMP_GADGETUP) AND (gad.userdata=OURGADGET) + TextF(10,60, + IF gad.flags=0 THEN 'Gadget off ' ELSE 'Gadget on ') + ENDIF + ENDWHILE + CloseW(wptr) /* Close the window */ + ELSE + WriteF('Error -- could not open window!') + ENDIF + ENDPROC + +The gadget reports its state when you click on it, using the @{b }TextF@{ub } +function (see @{"Graphics functions" Link "BuiltIns.guide/Graphics functions" }). The only way to quit the program is +using the close gadget of the window. The @{b }gadget@{ub } object is defined in the +module @{b }intuition/intuition@{ub } and the @{b }iaddr@{ub } part of the IDCMP message is a +pointer to our gadget if the message was a gadget message. The @{b }userdata@{ub } +element of the gadget identifies the gadget that was clicked, and the +@{b }flags@{ub } element is zero if the boolean gadget is off (unselected) or +non-zero if the boolean gadget is on (selected). + + +@ENDNODE + +@NODE "Graphics" "Graphics" +@Next "Screens" +@Prev "IDCMP Messages" +@Toc "Gadgets IDCMP and Graphics" + +Graphics +======== + + The following program illustrates how to use the various graphics +functions. + + MODULE 'intuition/intuition' + + PROC main() + DEF wptr, i + wptr:=OpenW(20,50,200,100,IDCMP_CLOSEWINDOW, + WFLG_CLOSEGADGET OR WFLG_ACTIVATE, + 'Graphics demo window',NIL,1,NIL) + IF wptr /* Check to see we opened a window */ + Colour(1,3) + TextF(20,30,'Hello World') + SetTopaz(11) + TextF(20,60,'Hello World') + FOR i:=10 TO 150 STEP 8 /* Plot a few points */ + Plot(i,40,2) + ENDFOR + Line(160,40,160,70,3) + Line(160,70,170,40,2) + Box(10,75,160,85,1) + WHILE WaitIMessage(wptr)<>IDCMP_CLOSEWINDOW + ENDWHILE + CloseW(wptr) + ELSE + WriteF('Error -- could not open window!\\n') + ENDIF + ENDPROC + +First of all a small window is opened with a close gadget and activated +(so it is the selected window). Clicks on the close gadget will be +reported via IDCMP, and this is the only way to quit the program. The +graphics functions are used as follows: + + @{b }*@{ub } @{b }Colour@{ub } is used to set the foreground colour to pen one and the + background colour to pen three. This will make the text nicely + highlighted. + + @{b }*@{ub } Text is output in the standard font. + + @{b }*@{ub } The font is set to Topaz 11. + + @{b }*@{ub } More text is output (probably now in a different font). + + @{b }*@{ub } The @{b }FOR@{ub } loop plots a dotted line in pen two. + + @{b }*@{ub } A vertical line in pen three is drawn. + + @{b }*@{ub } A diagonal line in pen two is drawn. This and the previous line + together produce a vee shape. + + @{b }*@{ub } A filled box is drawn in pen one. + + +@ENDNODE + +@NODE "Screens" "Screens" +@Prev "Graphics" +@Toc "Gadgets IDCMP and Graphics" + +Screens +======= + + This next example uses parts of the previous example, but also opens a +custom screen. Basically, it draws coloured lines and boxes in a big +window opened on a 16 colour, high resolution screen. + + MODULE 'intuition/intuition', 'graphics/view' + + PROC main() + DEF sptr=NIL, wptr=NIL, i + sptr:=OpenS(640,200,4,V_HIRES,'Screen demo') + IF sptr + wptr:=OpenW(0,20,640,180,IDCMP_CLOSEWINDOW, + WFLG_CLOSEGADGET OR WFLG_ACTIVATE, + 'Graphics demo window',sptr,$F,NIL) + IF wptr + TextF(20,20,'Hello World') + FOR i:=0 TO 15 /* Draw a line and box in each colour */ + Line(20,30,620,30+(7*i),i) + Box(10+(40*i),140,30+(40*i),170,1) + Box(11+(40*i),141,29+(40*i),169,i) + ENDFOR + WHILE WaitIMessage(wptr)<>IDCMP_CLOSEWINDOW + ENDWHILE + WriteF('Program finished successfully\\n') + ELSE + WriteF('Could not open window\\n') + ENDIF + ELSE + WriteF('Could not open screen\\n') + ENDIF + IF wptr THEN CloseW(wptr) + IF sptr THEN CloseS(sptr) + ENDPROC + +As you can see, the error-checking @{b }IF@{ub } blocks can make the program hard to +read. Here's the same example written with an exception handler: + + MODULE 'intuition/intuition', 'graphics/view' + + ENUM WIN=1, SCRN + + RAISE WIN IF OpenW()=NIL, + SCRN IF OpenS()=NIL + + PROC main() HANDLE + DEF sptr=NIL, wptr=NIL, i + sptr:=OpenS(640,200,4,V_HIRES,'Screen demo') + wptr:=OpenW(0,20,640,180,IDCMP_CLOSEWINDOW, + WFLG_CLOSEGADGET OR WFLG_ACTIVATE, + 'Graphics demo window',sptr,$F,NIL) + TextF(20,20,'Hello World') + FOR i:=0 TO 15 /* Draw a line and box in each colour */ + Line(20,30,620,30+(7*i),i) + Box(10+(40*i),140,30+(40*i),170,1) + Box(11+(40*i),141,29+(40*i),169,i) + ENDFOR + WHILE WaitIMessage(wptr)<>IDCMP_CLOSEWINDOW + ENDWHILE + EXCEPT DO + IF wptr THEN CloseW(wptr) + IF sptr THEN CloseS(sptr) + SELECT exception + CASE 0 + WriteF('Program finished successfully\\n') + CASE WIN + WriteF('Could not open window\\n') + CASE SCRN + WriteF('Could not open screen\\n') + ENDSELECT + ENDPROC + +It's much easier to see what's going on here. The real part of the +program (the bit before the @{b }EXCEPT@{ub }) is no longer cluttered with error +checking, and it's easy to see what happens if an error occurs. Notice +that if the program successfully finishes it still has to close the screen +and window properly, so it's often sensible to use @{b }EXCEPT DO@{ub } to raise a +zero exception and deal with all the tidying up in the handler. + + +@ENDNODE + +@NODE "Recursion Example" "Recursion Example" +@Next "Appendices.guide/main" +@Prev "Gadgets IDCMP and Graphics" +@Toc "Contents.guide/main" + +Recursion Example +***************** + + This next example uses a pair of mutually recursive procedures to draw +what is known as a dragon curve (a pretty, space-filling pattern). + + MODULE 'intuition/intuition', 'graphics/view' + + /* Screen size, use SIZEY=512 for a PAL screen */ + CONST SIZEX=640, SIZEY=400 + + /* Exception values */ + ENUM WIN=1, SCRN, STK, BRK + + /* Directions (DIRECTIONS gives number of directions) */ + ENUM NORTH, EAST, SOUTH, WEST, DIRECTIONS + + RAISE WIN IF OpenW()=NIL, + SCRN IF OpenS()=NIL + + /* Start off pointing WEST */ + DEF state=WEST, x, y, t + + /* Face left */ + PROC left() + state:=Mod(state-1+DIRECTIONS, DIRECTIONS) + ENDPROC + + /* Move right, changing the state */ + PROC right() + state:=Mod(state+1, DIRECTIONS) + ENDPROC + + /* Move in the direction we're facing */ + PROC move() + SELECT state + CASE NORTH; draw(0,t) + CASE EAST; draw(t,0) + CASE SOUTH; draw(0,-t) + CASE WEST; draw(-t,0) + ENDSELECT + ENDPROC + + /* Draw and move to specified relative position */ + PROC draw(dx, dy) + /* Check the line will be drawn within the window bounds */ + IF (x>=Abs(dx)) AND (x<=SIZEX-Abs(dx)) AND + (y>=Abs(dy)) AND (y<=SIZEY-10-Abs(dy)) + Line(x, y, x+dx, y+dy, 2) + ENDIF + x:=x+dx + y:=y+dy + ENDPROC + + PROC main() HANDLE + DEF sptr=NIL, wptr=NIL, i, m + /* Read arguments: [m [t [x [y]]]] */ + /* so you can say: dragon 16 */ + /* or: dragon 16 1 */ + /* or: dragon 16 1 450 */ + /* or: dragon 16 1 450 100 */ + /* m is depth of dragon, t is length of lines */ + /* (x,y) is the start position */ + m:=Val(arg, {i}) + t:=Val(arg:=arg+i, {i}) + x:=Val(arg:=arg+i, {i}) + y:=Val(arg:=arg+i, {i}) + /* If m or t is zero use a more sensible default */ + IF m=0 THEN m:=5 + IF t=0 THEN t:=5 + sptr:=OpenS(SIZEX,SIZEY,4,V_HIRES OR V_LACE,'Dragon Curve Screen') + wptr:=OpenW(0,10,SIZEX,SIZEY-10, + IDCMP_CLOSEWINDOW,WFLG_CLOSEGADGET, + 'Dragon Curve Window',sptr,$F,NIL) + /* Draw the dragon curve */ + dragon(m) + WHILE WaitIMessage(wptr)<>IDCMP_CLOSEWINDOW + ENDWHILE + EXCEPT DO + IF wptr THEN CloseW(wptr) + IF sptr THEN CloseS(sptr) + SELECT exception + CASE 0 + WriteF('Program finished successfully\\n') + CASE WIN + WriteF('Could not open window\\n') + CASE SCRN + WriteF('Could not open screen\\n') + CASE STK + WriteF('Ran out of stack in recursion\\n') + CASE BRK + WriteF('User aborted\\n') + ENDSELECT + ENDPROC + + /* Draw the dragon curve (with left) */ + PROC dragon(m) + /* Check stack and ctrl-C before recursing */ + IF FreeStack()<1000 THEN Raise(STK) + IF CtrlC() THEN Raise(BRK) + IF m>0 + dragon(m-1) + left() + nogard(m-1) + ELSE + move() + ENDIF + ENDPROC + + /* Draw the dragon curve (with right) */ + PROC nogard(m) + IF m>0 + dragon(m-1) + right() + nogard(m-1) + ELSE + move() + ENDIF + ENDPROC + + If you write this to the file @{b }dragon.e@{ub } and compile it to the executable +@{b }dragon@{ub } then some good things to try are: + + dragon 5 9 300 100 + dragon 10 4 250 250 + dragon 11 3 250 250 + dragon 15 1 300 100 + dragon 16 1 400 150 + + If you want to understand how the program works you need to study the +recursive parts. Here's an overview of the program, outlining the +important aspects: + + @{b }*@{ub } The constants @{b }SIZEX@{ub } and @{b }SIZEY@{ub } are the width and height (respectively) + of the custom screen (and window). As the comment suggests, change + @{b }SIZEY@{ub } to 512 if you want a bigger screen and you have a PAL Amiga. + + @{b }*@{ub } The @{b }state@{ub } variable holds the current direction (north, south, east or + west). + + @{b }*@{ub } The @{b }left@{ub } and @{b }right@{ub } procedures turn the current direction to the left + and right (respectively) by using some modulo arithmetic trickery. + + @{b }*@{ub } The @{b }move@{ub } procedure uses the @{b }draw@{ub } procedure to draw a line (of length + @{b }t@{ub }) in the current direction from the current point (stored in @{b }x@{ub } + and @{b }y@{ub }). + + @{b }*@{ub } The @{b }draw@{ub } procedure draws a line relative to the current point, but + only if it fits within the boundaries of the window. The current + point is moved to the end of the line (even if it isn't drawn). + + @{b }*@{ub } The @{b }main@{ub } procedure reads the command line arguments into the + variables @{b }m@{ub }, @{b }t@{ub }, @{b }x@{ub } and @{b }y@{ub }. The depth/size of the dragon is given by @{b }m@{ub } + (the first argument) and the length of each line making up the dragon + is given by @{b }t@{ub } (the second argument). The starting point is given by + @{b }x@{ub } and @{b }y@{ub } (the final two arguments). The defaults are five for @{b }m@{ub } + and @{b }t@{ub }, and zero for @{b }x@{ub } and @{b }y@{ub }. + + @{b }*@{ub } The @{b }main@{ub } procedure also opens the screen and window, and sets the + dragon drawing. + + @{b }*@{ub } The @{b }dragon@{ub } and @{b }nogard@{ub } procedures are very similar, and these are + responsible for creating the dragon curve by calling the @{b }left@{ub }, @{b }right@{ub } + and @{b }move@{ub } procedures. + + @{b }*@{ub } The @{b }dragon@{ub } procedure contains a couple of checks to see if the user + has pressed Control-C or if the program has run out of stack space, + raising an appropriate exception if necessary. These exceptions are + handled by the @{b }main@{ub } procedure. + +Notice the use of @{b }Val@{ub } and the exception handling. Also, the important +base case of the recursion is when @{b }m@{ub } reaches zero (or becomes negative, +but that shouldn't happen). If you start off a big dragon and want to +stop it you can press Control-C and the program tidies up nicely. If it +has finished drawing you simply click the close gadget on the window. + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Exceptions.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Exceptions.guide new file mode 100644 index 0000000..3c16f6c --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Exceptions.guide @@ -0,0 +1,405 @@ +@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" "Exception Handling" +@Next "Memory.guide/main" +@Prev "Modules.guide/main" +@Toc "Contents.guide/main" + +Exception Handling +****************** + + Often your program has to check the results of functions and do +different things if errors have occurred. For instance, if you try to +open a window (using @{b }OpenW@{ub }), you may get a @{b }NIL@{ub } pointer returned which +shows that the window could not be opened for some reason. In this case +you normally can't continue with the program, so you must tidy up and +terminate. Tidying up can sometimes involve closing windows, screens and +libraries, so sometimes your error cases can make your program cluttered +and messy. This is where exceptions come in--an @{fg shine }exception@{fg text } is simply an +error case, and @{fg shine }exception handling@{fg text } is dealing with error cases. The +exception handling in E neatly separates error specific code from the real +code of your program. + + + @{" Procedures with Exception Handlers " Link "Procedures with Exception Handlers" } + @{" Raising an Exception " Link "Raising an Exception" } + @{" Automatic Exceptions " Link "Automatic Exceptions" } + @{" Raise within an Exception Handler " Link "Raise within an Exception Handler" } + + +@ENDNODE + +@NODE "Procedures with Exception Handlers" "Procedures with Exception Handlers" +@Next "Raising an Exception" +@Toc "main" + +Procedures with Exception Handlers +================================== + + A procedure with an exception handler looks like this: + + PROC fred(params...) HANDLE + /* Main, real code */ + EXCEPT + /* Error handling code */ + ENDPROC + +This is very similar to a normal procedure, apart from the @{b }HANDLE@{ub } and +@{b }EXCEPT@{ub } keywords. The @{b }HANDLE@{ub } keyword means the procedure is going to have +an exception handler, and the @{b }EXCEPT@{ub } keyword marks the end of the normal +code and the start of the exception handling code. The procedure works +just as normal, executing the code in the part before the @{b }EXCEPT@{ub }, but when +an error happens you can pass control to the exception handler (i.e., the +code after the @{b }EXCEPT@{ub } is executed). + + +@ENDNODE + +@NODE "Raising an Exception" "Raising an Exception" +@Next "Automatic Exceptions" +@Prev "Procedures with Exception Handlers" +@Toc "main" + +Raising an Exception +==================== + + When an error occurs (and you want to handle it), you @{fg shine }raise@{fg text } an +exception using either the @{b }Raise@{ub } or @{b }Throw@{ub } function. You call @{b }Raise@{ub } with a +number which identifies the kind of error that occurred. The code in the +exception handler is responsible for decoding the number and then doing +the appropriate thing. @{b }Throw@{ub } is very similar to @{b }Raise@{ub }, and the following +description of @{b }Raise@{ub } also applies to @{b }Throw@{ub }. The difference is that @{b }Throw@{ub } +takes a second argument which can be used to pass extra information to a +handler (usually a string). The terms `raising' and `throwing' an +exception can be used interchangeably. + + When @{b }Raise@{ub } is called it immediately stops the execution of the current +procedure code and passes control to the exception handler of most recent +procedure which has a handler (which may be the current procedure). This +is a bit complicated, but you can stick to raising exceptions and handling +them in the same procedure, as in the next example: + + CONST BIG_AMOUNT = 100000 + + ENUM ERR_MEM=1 + + PROC main() HANDLE + DEF block + block:=New(BIG_AMOUNT) + IF block=NIL THEN Raise(ERR_MEM) + WriteF('Got enough memory\\n') + EXCEPT + IF exception=ERR_MEM + WriteF('Not enough memory\\n') + ELSE + WriteF('Unknown exception\\n') + ENDIF + ENDPROC + +This uses an exception handler to print a message saying there wasn't +enough memory if the call to @{b }New@{ub } returns @{b }NIL@{ub }. The parameter to @{b }Raise@{ub } is +stored in the special variable @{b }exception@{ub } in the exception handler part of +the code, so if @{b }Raise@{ub } is called with a number other than @{b }ERR_MEM@{ub } a message +saying "Unknown exception" will be printed. + + Try running this program with a really large @{b }BIG_AMOUNT@{ub } constant, so +that the @{b }New@{ub } can't allocate the memory. Notice that the "Got enough +memory" is not printed if @{b }Raise@{ub } is called. That's because the execution +of the normal procedure code stops when @{b }Raise@{ub } is called, and control +passes to the appropriate exception handler. When the end of the +exception handler is reached the procedure is finished, and in this case +the program terminates because the procedure was the @{b }main@{ub } procedure. + + If @{b }Throw@{ub } is used instead of @{b }Raise@{ub } then, in the handler, the special +variable @{b }exceptioninfo@{ub } will contain the value of the second parameter. +This can be used in conjunction with @{b }exception@{ub } to provide the handler with +more information about the error. Here's the above example re-written to +use @{b }Throw@{ub }: + + CONST BIG_AMOUNT = 100000 + + ENUM ERR_MEM=1 + + PROC main() HANDLE + DEF block + block:=New(BIG_AMOUNT) + IF block=NIL THEN Throw(ERR_MEM, 'Not enough memory\\n') + WriteF('Got enough memory\\n') + EXCEPT + IF exception=ERR_MEM + WriteF(exceptioninfo) + ELSE + WriteF('Unknown exception\\n') + ENDIF + ENDPROC + + An enumeration (using @{b }ENUM@{ub }) is a good way of getting different +constants for various exceptions. It's always a good idea to use +constants for the parameter to @{b }Raise@{ub } and in the exception handler, because +it makes everything a lot more readable: @{b }Raise(ERR_MEM)@{ub } is much clearer +than @{b }Raise(1)@{ub }. The enumeration starts at one because zero is a special +exception: it usually means that no error occurred. This is useful when +the handler does the same cleaning up that would normally be done when the +program terminates successfully. For this reason there is a special form +of @{b }EXCEPT@{ub } which automatically raises a zero exception when the code in the +procedure successfully terminates. This is @{b }EXCEPT DO@{ub }, with the @{b }DO@{ub } +suggesting to the reader that the exception handler is called even if no +error occurs. Also, the argument to the @{b }Raise@{ub } function defaults to zero +if it is omitted (see @{"Default Arguments" Link "Procedures.guide/Default Arguments" }). + + So, what happens if you call @{b }Raise@{ub } in a procedure without an exception +handler? Well, this is where the real power of the handling mechanism +comes to light. In this case, control passes to the exception handler of +the most @{fg shine }recent@{fg text } procedure with a handler. If none are found then the +program terminates. `Recent' means one of the procedures involved in +calling your procedure. So, if the procedure @{b }fred@{ub } calls @{b }barney@{ub }, then when +@{b }barney@{ub } is being executed @{b }fred@{ub } is a recent procedure. Because the @{b }main@{ub } +procedure is where the program starts it is a recent procedure for every +other procedure in the program. This means, in practice: + + @{b }*@{ub } If you define @{b }fred@{ub } to be a procedure with an exception handler then + any procedures called by @{b }fred@{ub } will have their exceptions handled by + the handler in @{b }fred@{ub } if they don't have their own handler. + + @{b }*@{ub } If you define @{b }main@{ub } to be a procedure with an exception handler then + any exceptions that are raised will always be dealt with by some + exception handling code (i.e., the handler of @{b }main@{ub } or some other + procedure). + + Here's a more complicated example: + + ENUM FRED=1, BARNEY + + PROC main() + WriteF('Hello from main\\n') + fred() + barney() + WriteF('Goodbye from main\\n') + ENDPROC + + PROC fred() HANDLE + WriteF(' Hello from fred\\n') + Raise(FRED) + WriteF(' Goodbye from fred\\n') + EXCEPT + WriteF(' Handler fred: \\d\\n', exception) + ENDPROC + + PROC barney() + WriteF(' Hello from barney\\n') + Raise(BARNEY) + WriteF(' Goodbye from barney\\n') + ENDPROC + +When you run this program you get the following output: + + Hello from main + Hello from fred + Handler fred: 1 + Hello from barney + +This is because the @{b }fred@{ub } procedure is terminated by the @{b }Raise(FRED)@{ub } call, +and the whole program is terminated by the @{b }Raise(BARNEY)@{ub } call (since +@{b }barney@{ub } and @{b }main@{ub } do not have handlers). + + Now try this: + + ENUM FRED=1, BARNEY + + PROC main() + WriteF('Hello from main\\n') + fred() + WriteF('Goodbye from main\\n') + ENDPROC + + PROC fred() HANDLE + WriteF(' Hello from fred\\n') + barney() + Raise(FRED) + WriteF(' Goodbye from fred\\n') + EXCEPT + WriteF(' Handler fred: \\d\\n', exception) + ENDPROC + + PROC barney() + WriteF(' Hello from barney\\n') + Raise(BARNEY) + WriteF(' Goodbye from barney\\n') + ENDPROC + +When you run this you get the following output: + + Hello from main + Hello from fred + Hello from barney + Handler fred: 2 + Goodbye from main + +Now the @{b }fred@{ub } procedure calls @{b }barney@{ub }, so @{b }main@{ub } and @{b }fred@{ub } are recent +procedures when @{b }Raise(BARNEY)@{ub } is executed, and therefore the @{b }fred@{ub } +exception handler is called. When this handler finishes the call to @{b }fred@{ub } +in @{b }main@{ub } is finished, so the @{b }main@{ub } procedure is completed and we see the +`Goodbye' message. In the previous program the @{b }Raise(BARNEY)@{ub } call did not +get handled and the whole program terminated at that point. + + +@ENDNODE + +@NODE "Automatic Exceptions" "Automatic Exceptions" +@Next "Raise within an Exception Handler" +@Prev "Raising an Exception" +@Toc "main" + +Automatic Exceptions +==================== + + In the previous section we saw an example of raising an exception when +a call to @{b }New@{ub } returned @{b }NIL@{ub }. We can re-write this example to use +@{fg shine }automatic@{fg text } exception raising: + + CONST BIG_AMOUNT = 100000 + + ENUM ERR_MEM=1 + + RAISE ERR_MEM IF New()=NIL + + PROC main() HANDLE + DEF block + block:=New(BIG_AMOUNT) + WriteF('Got enough memory\\n') + EXCEPT + IF exception=ERR_MEM + WriteF('Not enough memory\\n') + ELSE + WriteF('Unknown exception\\n') + ENDIF + ENDPROC + +The only difference is the removal of the @{b }IF@{ub } which checked the value of +@{b }block@{ub }, and the addition of a @{b }RAISE@{ub } part. This @{b }RAISE@{ub } part means that +whenever the @{b }New@{ub } function is called in the program, the exception @{b }ERR_MEM@{ub } +will be raised if it returns @{b }NIL@{ub } (i.e., the exception @{b }ERR_MEM@{ub } is +automatically raised). This unclutters the program by removing a lot of +error checking @{b }IF@{ub } statements. + + The precise form of the @{b }RAISE@{ub } part is: + + RAISE @{fg shine }exception@{fg text } IF @{fg shine }function@{fg text }() @{fg shine }compare@{fg text } @{fg shine }value@{fg text } , + @{fg shine }exception2@{fg text } IF @{fg shine }function2@{fg text }() @{fg shine }compare2@{fg text } @{fg shine }value2@{fg text } , + ... + @{fg shine }exceptionN@{fg text } IF @{fg shine }functionN@{fg text }() @{fg shine }compareN@{fg text } @{fg shine }valueN@{fg text } + +The @{fg shine }exception@{fg text } is a constant (or number) which represents the exception +to be raised, @{fg shine }function@{fg text } is the E built-in or system function to be +automatically checked, @{fg shine }value@{fg text } is the return value to be checked against, +and @{fg shine }compare@{fg text } is the method of checking (i.e., @{b }=@{ub }, @{b }<>@{ub }, @{b }<@{ub }, @{b }<=@{ub }, @{b }>@{ub } or @{b }>=@{ub }). +This mechanism only exists for built-in or library functions because they +would otherwise have no way of raising exceptions. The procedures you +define yourself can, of course, use @{b }Raise@{ub } to raise exceptions in a much +more flexible way. + + +@ENDNODE + +@NODE "Raise within an Exception Handler" "Raise within an Exception Handler" +@Prev "Automatic Exceptions" +@Toc "main" + +@{b }Raise@{ub } within an Exception Handler +================================= + + If you call @{b }Raise@{ub } within an exception handler then control passes to +the next most recent handler. In this way you can write procedures which +have handlers that perform local tidying up. By using @{b }Raise@{ub } at the end of +the handler code you can invoke the next layer of tidying up. + + As an example we'll use the Amiga system functions @{b }AllocMem@{ub } and @{b }FreeMem@{ub } +which are like the built-in function @{b }New@{ub } and @{b }Dispose@{ub }, but the memory +allocated by @{b }AllocMem@{ub } @{i }must@{ui } be deallocated (using @{b }FreeMem@{ub }) when it's +finished with, before the end of the program. + + CONST SMALL=100, BIG=123456789 + + ENUM ERR_MEM=1 + + RAISE ERR_MEM IF AllocMem()=NIL + + PROC main() + allocate() + ENDPROC + + PROC allocate() HANDLE + DEF mem=NIL + mem:=AllocMem(SMALL, 0) + morealloc() + FreeMem(mem, SMALL) + EXCEPT + IF mem THEN FreeMem(mem, SMALL) + WriteF('Handler: deallocating "allocate" local memory\\n') + ENDPROC + + PROC morealloc() HANDLE + DEF more=NIL, andmore=NIL + more:=AllocMem(SMALL, 0) + andmore:=AllocMem(BIG, 0) + WriteF('Allocated all the memory!\\n') + FreeMem(andmore, BIG) + FreeMem(more, SMALL) + EXCEPT + IF andmore THEN FreeMem(andmore, BIG) + IF more THEN FreeMem(more, SMALL) + WriteF('Handler: deallocating "morealloc" local memory\\n') + Raise(ERR_MEM) + ENDPROC + +The calls to @{b }AllocMem@{ub } are automatically checked, and if @{b }NIL@{ub } is returned +the exception @{b }ERR_MEM@{ub } is raised. The handler in the @{b }allocate@{ub } procedure +checks to see if it needs to free the memory pointed to by @{b }mem@{ub }, and the +handler in the @{b }morealloc@{ub } checks @{b }andmore@{ub } and @{b }more@{ub }. At the end of the +@{b }morealloc@{ub } handler is the call @{b }Raise(ERR_MEM)@{ub }. This passes control to the +exception handler of the @{b }allocate@{ub } procedure, since @{b }allocate@{ub } called +@{b }morealloc@{ub }. + + There's a couple of subtle points to notice about this example. +Firstly, the memory variables are all initialised to @{b }NIL@{ub }. This is because +the automatic exception raising on @{b }AllocMem@{ub } will result in the variables +not being assigned if the call returns @{b }NIL@{ub } (i.e., the exception is raised +before the assignment takes place), and the handler needs them to be @{b }NIL@{ub } +if @{b }AllocMem@{ub } fails. Of course, if @{b }AllocMem@{ub } does not return @{b }NIL@{ub } the +assignments work as normal. + + Secondly, the @{b }IF@{ub } statements in the handlers check the memory pointer +variables do not contain @{b }NIL@{ub } by using their values as truth values. Since +@{b }NIL@{ub } is actually zero, a non-@{b }NIL@{ub } pointer will be non-zero, i.e., true in +the @{b }IF@{ub } check. This shorthand is often used, and so you should be aware of +it. + + It is quite common that an exception handler will want to raise the +same exception after it has done its processing. The function @{b }ReThrow@{ub } +(which has no arguments) can be used for this purpose. It will re-raise +the exception, but only if the exception is not zero (since this special +value means that no error occurred). If the exception is zero then this +function has no effect. In fact, the following code fragments (within a +handler) are equivalent: + + ReThrow() + + IF exception THEN Throw(exception, exceptioninfo) + + There are two examples, in Part Three, of how to use an exception +handler to make a program more readable: one deals with using data files +(see @{"String Handling and I-O" Link "Examples.guide/String Handling and I-O" }) and the other deals with opening screens and +windows (see @{"Screens" Link "Examples.guide/Screens" }). + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/FloatingPoint.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/FloatingPoint.guide new file mode 100644 index 0000000..c9396ea --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/FloatingPoint.guide @@ -0,0 +1,358 @@ +@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" "Floating-Point Numbers" +@Next "Recursion.guide/main" +@Prev "Memory.guide/main" +@Toc "Contents.guide/main" + +Floating-Point Numbers +********************** + + @{fg shine }Floating-point@{fg text } or @{fg shine }real@{fg text } numbers can be used to represent both very +small fractions and very large numbers. However, unlike a @{b }LONG@{ub } which can +hold every integer in a certain range (see @{"Variable types" Link "Introduction.guide/Variable types" }), floating-point +numbers have limited @{fg shine }accuracy@{fg text }. Be warned, though: using floating-point +arithmetic in E is quite complicated and most problems can be solved +without using floating-point numbers, so you may wish to skip this chapter +until you really need to use them. + + + @{" Floating-Point Values " Link "Floating-Point Values" } + @{" Floating-Point Calculations " Link "Floating-Point Calculations" } + @{" Floating-Point Functions " Link "Floating-Point Functions" } + @{" Accuracy and Range " Link "Accuracy and Range" } + + +@ENDNODE + +@NODE "Floating-Point Values" "Floating-Point Values" +@Next "Floating-Point Calculations" +@Toc "main" + +Floating-Point Values +===================== + + Floating-point values in E are written just like you might expect and +are stored in @{b }LONG@{ub } variables: + + DEF x + x:=3.75 + x:=-0.0000367 + x:=275.0 + +You must remember to use a decimal point (without any spaces around it) in +the number if you want it to be considered a floating-point number, and +this is why a trailing @{b }.0@{ub } was used on the number in the last assignment. +At present you can't express every floating-point value in this way; the +compiler may complain that the value does not fit in 32-bits if you try to +use more than about nine digits in a single number. You can, however, use +the various floating-point maths functions to calculate any value you want +(see @{"Floating-Point Functions" Link "Floating-Point Functions" }). + + +@ENDNODE + +@NODE "Floating-Point Calculations" "Floating-Point Calculations" +@Next "Floating-Point Functions" +@Prev "Floating-Point Values" +@Toc "main" + +Floating-Point Calculations +=========================== + + Since a floating-point number is stored in a @{b }LONG@{ub } variable it would +normally be interpreted as an integer, and this interpretation will +generally not give a number anything like the intended floating-point +number. To use floating-point numbers in expressions you must use the +(rather complicated) floating-point conversion operator, which is the @{b }!@{ub } +character. This converts expressions and the normal maths and comparison +operators to and from floating-point. + + All expressions are, by default, integer expressions. That is, they +represent @{b }LONG@{ub } integer values, rather than floating-point values. The +first time a @{b }!@{ub } occurs in an expression the value of the expression so far +is converted to floating-point and all the operators and variables after +this point are considered floating-point. The next time it occurs the +(floating-point) value of the expression so far is converted to an +integer, and the following operators and variables are considered integer +again. You can use @{b }!@{ub } as often as necessary within an expression. Parts +of an expression in parentheses are treated as separate expressions, so +are, by default, integer expressions (this, includes function call +arguments). + + The integer/floating-point conversions performed by @{b }!@{ub } are not simple. +They involve rounding and also bounding. Conversion, for example, from +integer to floating-point and back again will generally not result in the +original integer value. + + Here's a few commented examples, where @{b }f@{ub } always holds a floating-point +number, and @{b }i@{ub } and @{b }j@{ub } always hold integers: + + DEF f, i, j + i:=1 + f:=1.0 + f:=i! -> i converted to floating-point (1.0) + f:=6.2 + i:=!f! -> the expression f is floating-point, + -> then converted to integer (6) + +In the first assignment, the integer value one is assigned to @{b }i@{ub }. In the +second, the floating-point value 1.0 is assigned to @{b }f@{ub }. The expression on +the right-hand side of third assignment is considered to be an integer +until the @{b }!@{ub } is met, at which point it is converted to the nearest +floating-point value. So, @{b }f@{ub } is assigned the floating-point value of one +(i.e., 1.0), just like it is by the second assignment. The expression in +the final assignment needs to start off as floating-point in order to +interpret the value stored in @{b }f@{ub } as floating-point. The expression +finishes by converting back to integer. The overall result is to turn the +floating-point value of @{b }f@{ub } into the nearest integer (in this case, six). + + The assignments below are more complicated, but should be +straight-forward to follow. Again, @{b }f@{ub } always holds a floating-point +number, and @{b }i@{ub } and @{b }j@{ub } always hold integers. + + f:=!f*f -> the whole expression is floating-point, + -> and f is squared (6.2*6.2) + f:=!f*(i!) -> the whole expression is floating-point, + -> i is converted to floating-point and + -> multiplied by f + j:=!f/(i!)! -> the whole division is floating-point, + -> with the result converted to integer + j:=!f!/i -> floating-point f is converted to integer + -> and is (integer) divided by i + IF !f<230.0 THEN RETURN 0 -> floating-point comparison < + IF !f>(i!) THEN RETURN 0 -> i converted to floating-point, + -> then compared to f + +If the @{b }!@{ub } were omitted from the first assignment, then not only would the +value in @{b }f@{ub } be interpreted (incorrectly) as integer, but the multiplication +performed would be integer multiplication, rather than floating-point. In +the second assignment, the parentheses around the expression involving @{b }i@{ub } +are crucial. Without the parentheses the value stored in @{b }i@{ub } would be +interpreted as floating-point. This would be wrong because @{b }i@{ub } actually +stores an integer value, so parentheses are used to start a new expression +(which defaults to being integer). The value of @{b }i@{ub } is then interpreted +correctly, and finally converted to floating-point (by the @{b }!@{ub } just before +the closing parenthesis). The (floating-point) multiplication then takes +place with two floating-point values, and the result is stored in @{b }f@{ub }. In +the last two assignments (using division), @{b }j@{ub } is assigned roughly the same +value. However, the expression in the first assignment allows for greater +accuracy, since it uses floating-point division. This means the result +will be rounded, whereas it is truncated when integer division is used. + + One important thing to know about floating-point numbers in E is that +the following assignments store the same value in @{b }g@{ub } (again, @{b }f@{ub } stores a +floating-point number). This is because no computation is performed and +no conversion happens: the value in @{b }f@{ub } is simply copied to @{b }g@{ub }. This is +especially important for function calls, as we shall see in the next +section. Strictly speaking, however, the second version is better, since +it shows (to the reader of the code) that the value in @{b }f@{ub } is meant to be +floating-point. + + g:=f + g:=!f + + +@ENDNODE + +@NODE "Floating-Point Functions" "Floating-Point Functions" +@Next "Accuracy and Range" +@Prev "Floating-Point Calculations" +@Toc "main" + +Floating-Point Functions +======================== + + There are functions for formatting floating-point numbers to E-strings +(so that they can be printed) and for decoding floating-point numbers from +strings. There are also a number of built-in, floating-point functions +which compute some of the less common mathematical functions, such as the +various trigonometric functions. + +@{b }RealVal(@{ub }@{fg shine }string@{fg text }@{b })@{ub } + This works in a similar way to @{b }Val@{ub } for extracting integers from a + string. The decoded floating-point value is returned as the regular + return value, and the number of characters of @{fg shine }string@{fg text } that were read + to make the number is returned as the first optional return value. + If a floating-point value could not be decoded from the string then + zero is returned as the optional return value and the regular return + value will be zero (i.e., 0.0). + +@{b }RealF(@{ub }@{fg shine }e-string@{fg text }@{b },@{ub }@{fg shine }float@{fg text }@{b },@{ub }@{fg shine }digits@{fg text }@{b })@{ub } + Converts the floating-point value @{b }float@{ub } into a string which is stored + in @{fg shine }e-string@{fg text }. The number of digits to use after the decimal point + is specified by @{fg shine }digits@{fg text }, which can be zero to eight. The + floating-point value is rounded to the specified number of digits. A + value of zero for @{fg shine }digits@{fg text } gives a result with no fractional part and + no decimal point. The @{fg shine }e-string@{fg text } is returned by this function, and + this makes it easy to use with @{b }WriteF@{ub }. + + PROC main() + DEF s[20]:STRING, f, i + f:=21.60539 + FOR i:=0 TO 8 + WriteF('f is \\s (using digits=\\d)\\n', RealF(s, f, i), i) + ENDFOR + ENDPROC + + Notice that the floating-point argument, @{b }f@{ub }, to @{b }RealF@{ub } does not need a + leading @{b }!@{ub } because we are simply passing its value and not performing + a computation with it. The program should generate the following + output: + + f is 22 (using digits=0) + f is 21.6 (using digits=1) + f is 21.61 (using digits=2) + f is 21.605 (using digits=3) + f is 21.6054 (using digits=4) + f is 21.60539 (using digits=5) + f is 21.605390 (using digits=6) + f is 21.6053900 (using digits=7) + f is 21.60539000 (using digits=8) + +@{b }Fsin(@{ub }@{fg shine }float@{fg text }@{b })@{ub }, @{b }Fcos(@{ub }@{fg shine }float@{fg text }@{b })@{ub }, @{b }Ftan(@{ub }@{fg shine }float@{fg text }@{b })@{ub } + These compute the sine, cosine and tangent (respectively) of the + supplied @{fg shine }float@{fg text } angle, which is specified in radians. + +@{b }Fabs(@{ub }@{fg shine }float@{fg text }@{b })@{ub } + Returns the absolute value of @{fg shine }float@{fg text }, much like @{b }Abs@{ub } does for + integers. + +@{b }Ffloor(@{ub }@{fg shine }float@{fg text }@{b })@{ub }, @{b }Fceil(@{ub }@{fg shine }float@{fg text }@{b })@{ub } + The @{b }Ffloor@{ub } function rounds a floating-point value down to the + nearest, whole floating-point value. The @{b }Fceil@{ub } function rounds it up. + +@{b }Fsqrt(@{ub }@{fg shine }float@{fg text }@{b })@{ub } + Returns the square root of @{fg shine }float@{fg text }. + +@{b }Fpow(@{ub }@{fg shine }x@{fg text }@{b },@{ub }@{fg shine }y@{fg text }@{b })@{ub }, @{b }Fexp(@{ub }@{fg shine }float@{fg text }@{b })@{ub } + The @{b }Fpow@{ub } function returns the value of @{fg shine }x@{fg text } raised to the power of @{fg shine }y@{fg text } + (which are both floating-point values). The @{b }Fexp@{ub } function returns + the value of e raised to the power of @{fg shine }float@{fg text }, where e is the + mathematically special value (roughly 2.718282). `Raising to a + power' is known as @{fg shine }exponentiation@{fg text }. + +@{b }Flog10(@{ub }@{fg shine }float@{fg text }@{b })@{ub }, @{b }Flog(@{ub }@{fg shine }float@{fg text }@{b })@{ub } + The @{b }Flog10@{ub } function returns the log to base ten of @{fg shine }float@{fg text } (the + @{fg shine }common logarithm@{fg text }). The @{b }Flog@{ub } function returns the log to base e of + @{fg shine }float@{fg text } (the @{fg shine }natural logarithm@{fg text }). @{b }Flog10@{ub } and @{b }Fpow@{ub } are linked in the + following way (ignoring floating-point inaccuracies): + + x = Fpow(10.0, Flog10(x)) + + @{b }Flog@{ub } and @{b }Fexp@{ub } are similarly related (@{b }Fexp@{ub } could be used again, using + 2.718282 as the first argument in place of 10.0). + + x = Fexp(Flog(x)) + + Here's a small program which uses a few of the above functions, and +shows how to define functions which use and/or return floating-point +values. + + DEF f, i, s[20]:STRING + + PROC print_float() + WriteF('\\tf is \\s\\n', RealF(s, !f, 8)) + ENDPROC + + PROC print_both() + WriteF('\\ti is \\d, ', i) + print_float() + ENDPROC + + /* Square a float */ + PROC square_float(f) IS !f*f + + /* Square an integer */ + PROC square_integer(i) IS i*i + + /* Converts a float to an integer */ + PROC convert_to_integer(f) IS Val(RealF(s, !f, 0)) + + /* Converts an integer to a float */ + PROC convert_to_float(i) IS RealVal(StringF(s, '\\d', i)) + + /* This should be the same as Ftan */ + PROC my_tan(f) IS !Fsin(!f)/Fcos(!f) + + /* This should show float inaccuracies */ + PROC inaccurate(f) IS Fexp(Flog(!f)) + + PROC main() + WriteF('Next 2 lines should be the same\\n') + f:=2.7; i:=!f! + print_both() + f:=2.7; i:=convert_to_integer(!f) + print_both() + + WriteF('Next 2 lines should be the same\\n') + i:=10; f:=i! + print_both() + i:=10; f:=convert_to_float(i) + print_both() + + WriteF('f and i should be the same\\n') + i:=square_integer(i) + f:=square_float(f) + print_both() + + WriteF('Next 2 lines should be the same\\n') + f:=Ftan(.8) + print_float() + f:=my_tan(.8) + print_float() + + WriteF('Next 2 lines should be the same\\n') + f:=.35 + print_float() + f:=inaccurate(f) + print_float() + ENDPROC + +The @{b }convert_to_integer@{ub } and @{b }convert_to_float@{ub } functions perform similar +conversions to those done by @{b }!@{ub } when it occurs in an expression. To make +things more explicit, there are a lot of unnecessary uses of @{b }!@{ub }, and these +are when @{b }f@{ub } is passed directly as a parameter to a function (in these +cases, the @{b }!@{ub } could safely be omitted). All of the examples have the +potential to give different results where they ought to give the same, and +this is due to the inaccuracy of floating-point numbers. The last example +has been carefully chosen to show this. + + +@ENDNODE + +@NODE "Accuracy and Range" "Accuracy and Range" +@Prev "Floating-Point Functions" +@Toc "main" + +Accuracy and Range +================== + + A floating-point number is just another 32-bit value, so can be stored +in @{b }LONG@{ub } variables. It's just the interpretation of the 32-bits which +makes them different. A floating-point number can range from numbers as +small as 1.3E-38 to numbers as large as 3.4E+38 (that's very small and +very large if you don't understand the scientific notation!). However, +not every number in this range can @{fg shine }accurately@{fg text } be represented, since the +number of significant digits is roughly eight. + + Accuracy is an important consideration when trying to compare two +floating-point numbers and when combining floating-point values after +dividing them. It is usually best to check that a floating-point value is +in a small range of values, rather than just a particular value. And when +combining values, allow for a small amount of error due to rounding etc. +See the `Reference Manual' for more details about the implementation of +floating-point numbers. + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Format.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Format.guide new file mode 100644 index 0000000..c42cf0c --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Format.guide @@ -0,0 +1,208 @@ +@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" "Format and Layout" +@Next "Procedures.guide/main" +@Prev "Introduction.guide/Summary" +@Toc "Contents.guide/main" + +Format and Layout +***************** + + In this chapter we'll look at the rules which govern the format and +layout of E code. In the previous Part we saw examples of E code that +were quite nicely indented and the structure of the program was easily +visible. This was just a convention and the E language does not constrain +you to write code in this way. However, there are certain rules that must +be followed. (This chapter refers to some concepts and parts of the E +language which were not covered in Part One. Don't let this put you +off--those things will be dealt with in later chapters, and it's maybe a +good idea to read this chapter again when they have been.) + + + @{" Identifiers " Link "Identifiers" } + @{" Statements " Link "Statements" } + @{" Spacing and Separators " Link "Spacing and Separators" } + @{" Comments " Link "Comments" } + + +@ENDNODE + +@NODE "Identifiers" "Identifiers" +@Next "Statements" +@Toc "main" + +Identifiers +=========== + + An @{fg shine }identifier@{fg text } is a word which the compiler must interpret rather than +treating literally. For instance, a variable is an identifier, as is a +keyword (e.g., @{b }IF@{ub }), but anything in a string is not (e.g., @{b }fred@{ub } in @{b }'fred +and wilma'@{ub } is not an identifier). Identifiers can be made up of upper- or +lower-case letters, numbers and underscores (the @{b }_@{ub } character). There are +only two constraints: + + 1. The first character cannot be a number (this would cause confusion + with numeric constants). + + 2. The case of the first few characters of identifiers is significant. + +For keywords (e.g., @{b }ENDPROC@{ub }), constants (e.g., @{b }TRUE@{ub }) and assembly +mnemonics (e.g., @{b }MOVE.L@{ub }) the first two characters must both be uppercase. +For E built-in or Amiga system procedures/functions the first character +must be uppercase and the second must be lowercase. For all other +identifiers (i.e., local, global and procedure parameter variables, object +names and element names, procedure names and code labels) the first +character must be lowercase. + + Apart from these constraints you are free to write identifiers how you +like, although it's arguably more tasteful to use all lowercase for +variables and all uppercase for keywords and constants. + + +@ENDNODE + +@NODE "Statements" "Statements" +@Next "Spacing and Separators" +@Prev "Identifiers" +@Toc "main" + +Statements +========== + + A @{fg shine }statement@{fg text } is normally a single instruction to the computer, and +each statement normally occupies a single line. If you think of a +procedure as a paragraph then a statement is a sentence. Using the same +analogy, variables, expressions and keywords are the words which make up +the sentence. + + So far in our examples we have met only two kinds of statement: the +single line statement and the multi-line statement. The assignments we +have seen were single line statements, and the vertical form of the @{b }IF@{ub } +block is a multi-line statement. The horizontal form of the @{b }IF@{ub } block was +actually the single line statement form of the @{b }IF@{ub } block. Notice that +statements can be built up from other statements, as is the case for @{b }IF@{ub } +blocks. The code parts between the @{b }IF@{ub }, @{b }ELSEIF@{ub }, @{b }ELSE@{ub } and @{b }ENDIF@{ub } lines are +sequences of statements. + + Single line statements can often be very short, and you may be able to +fit several of them onto an single line without the line getting too long. +To do this in E you use a semi-colon (the @{b };@{ub } character) to separate each +statement on the line. For example, the following code fragments are +equivalent: + + fred(y,z) + y:=x + x:=z+1 + + fred(y,z); y:=x; x:=z+1 + + On the other hand you may want to split a long statement over several +lines. This is a bit more tricky because the compiler needs to see that +you haven't finished the statement when it gets to the end of a line. +Therefore you can only break a statement at certain places. The most +common place is after a comma that is part of the statement (like in a +procedure call with more than one parameter), but you can also split a +line after binary operators and anywhere between opening and closing +brackets. The following examples are rather silly but show some allowable +line breaking places. + + fred(a, b, c, + d, e, f) /* After a comma */ + + x:=x+ + y+ + z /* After a binary operator */ + + x:=(1+2 + +3) /* Between open...close brackets */ + + list:= [ 1,2, + [3,4] + ] /* Between open...close brackets */ + +The simple rule is this: if a complete line can be interpreted as a +statement then it will be, otherwise it will be interpreted as part of a +statement which continues on the following lines. + + Strings may also get a bit long. You can split them over several lines +by breaking them into several separate strings and using @{b }+@{ub } between them. +If a line ends with a @{b }+@{ub } and the previous thing on the line was a string +then the E compiler takes the next string to be a continuation. The +following calls to @{b }WriteF@{ub } print the same thing: + + WriteF('This long string can be broken over several lines.\\n') + + WriteF('This long string ' + + 'can be broken over several lines.\\n') + + WriteF('This long' + + ' string can be ' + + 'broken over several ' + + 'lines.\\n') + + +@ENDNODE + +@NODE "Spacing and Separators" "Spacing and Separators" +@Next "Comments" +@Prev "Statements" +@Toc "main" + +Spacing and Separators +====================== + + The examples we've seen so far used a rigid indentation convention +which was intended to illuminate the structure of the program. This was +just a convention, and the E language places no constraints on the amount +of @{fg shine }whitespace@{fg text } (spaces, tabs and linefeeds) you place between statements. +However, within statements you must supply enough spacing to make the +statement readable. This generally means that you must put whitespace +between adjacent identifiers which start or end with a letter, number or +underscore (so that the compiler does not think it's one big identifier!). +So, in practice, you should put a space after a keyword if it might run +into a variable or procedure name. Most other times (like in expressions) +identifiers are separated by non-identifier characters (a comma, +parenthesis or other symbol). + + +@ENDNODE + +@NODE "Comments" "Comments" +@Prev "Spacing and Separators" +@Toc "main" + +Comments +======== + + A @{fg shine }comment@{fg text } is something that the E compiler ignores and is only there +to help the reader. Remember that one day in the future you may be the +reader, and it may be quite hard to decipher your own code without a few +decent comments! Comments are therefore pretty important. + + You can write comments anywhere you can write whitespace that isn't +part of a string. There are two kinds of comment: one uses @{b }/*@{ub } to mark the +start of the comment text and @{b }*/@{ub } to mark the end, and the other uses @{b }->@{ub } to +mark the start, with the comment text continuing to the end of the line. +You must be careful not to write @{b }/*@{ub }, @{b }*/@{ub } or @{b }->@{ub } as part of the comment text, +unless part of a nested comment. In practice a comment is best put on a +line by itself or after the end of the code on a line. + + /* This line is a comment */ + x:=1 /* This line contains an assignment then a comment */ + /* y:=2 /* This whole line is a comment with a nested comment */*/ + + x:=1 -> Assignment then a comment + -> y:=2 /* A nested comment comment */ + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Index.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Index.guide new file mode 100644 index 0000000..e1b358c --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Index.guide @@ -0,0 +1,1024 @@ +@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" "Main Index" +@Prev "EIndex.guide/main" +@Toc "Contents.guide/main" + +Main Index +********** + + This index should be used to find detailed information about particular +concepts. There is a separate index which deals with the keywords, +variables, functions and constants which are part of Amiga E (see +@{"E Language Index" Link "EIndex.guide/main" }). + +@Index "main" + + + + @{" A4 register " Link "MoreExpressions.guide/Things to watch out for" 11 } Things to watch out for + @{" A5 register " Link "MoreExpressions.guide/Things to watch out for" 11 } Things to watch out for + @{" Absolute value " Link "BuiltIns.guide/Maths and logic functions" 30 } Maths and logic functions + @{" Absolute value (floating-point) " Link "FloatingPoint.guide/Floating-Point Functions" 55 } Floating-Point Functions + @{" Abstract class " Link "OOE.guide/Inheritance in E" 173 } Inheritance in E + @{" Abstract method " Link "OOE.guide/Inheritance in E" 275 } Inheritance in E + @{" Access array outside bounds " Link "Types.guide/Accessing array data" 25 } Accessing array data + @{" Accessing array data " Link "Types.guide/Accessing array data" 0 } Accessing array data + @{" Accuracy of floating-point numbers " Link "FloatingPoint.guide/Accuracy and Range" 0 } Accuracy and Range + @{" Addition " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Address " Link "Types.guide/Addresses" 0 } Addresses + @{" Address " Link "Types.guide/Memory addresses" 0 } Memory addresses + @{" Address, finding " Link "Types.guide/Finding addresses (making pointers)" 0 } Finding addresses (making pointers) + @{" Algebra " Link "Introduction.guide/Variables and Expressions" 0 } Variables and Expressions + @{" Alignment " Link "MoreExpressions.guide/SIZEOF expression" 17 } SIZEOF expression + @{" Allocating an object " Link "OOE.guide/Objects in E" 17 } Objects in E + @{" Allocating memory " Link "BuiltIns.guide/System support functions" 0 } System support functions + @{" Allocation, dynamic memory " Link "Memory.guide/Dynamic Allocation" 0 } Dynamic Allocation + @{" Allocation, memory " Link "Memory.guide/main" 0 } Memory Allocation + @{" Allocation, static memory " Link "Memory.guide/Static Allocation" 0 } Static Allocation + @{" Allocation, typed memory dynamically " Link "Memory.guide/NEW and END Operators" 0 } NEW and END Operators + @{" Allowable assignment left-hand sides " Link "MoreExpressions.guide/Assignments" 33 } Assignments + @{" Amiga E author " Link "Appendices.guide/Amiga E Author" 0 } Amiga E Author + @{" Amiga system module " Link "Modules.guide/Amiga System Modules" 0 } Amiga System Modules + @{" Amiga system objects " Link "Types.guide/Amiga system objects" 0 } Amiga system objects + @{" Analogy, pointers " Link "Types.guide/Addresses" 10 } Addresses + @{" And " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" AND, bit-wise " Link "MoreExpressions.guide/Bitwise AND and OR" 0 } Bitwise AND and OR + @{" AND-ing flags " Link "Constants.guide/Sets" 19 } Sets + @{" Apostrophe " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Append to a list " Link "Types.guide/List functions" 47 } List functions + @{" Append to an E-string " Link "Types.guide/String functions" 99 } String functions + @{" arg, using " Link "Examples.guide/Any AmigaDOS" 0 } Any AmigaDOS + @{" Argument " Link "Introduction.guide/Parameters" 0 } Parameters + @{" Argument parsing " Link "Examples.guide/Argument Parsing" 0 } Argument Parsing + @{" Argument, default " Link "Procedures.guide/Default Arguments" 0 } Default Arguments + @{" Array " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Array and array pointer declaration " Link "Types.guide/Array pointers" 46 } Array pointers + @{" Array diagram " Link "Types.guide/Array pointers" 71 } Array pointers + @{" Array pointer, decrementing " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Array pointer, incrementing " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Array pointer, next element " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Array pointer, previous element " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Array size " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Array, access outside bounds " Link "Types.guide/Accessing array data" 25 } Accessing array data + @{" Array, accessing data " Link "Types.guide/Accessing array data" 0 } Accessing array data + @{" Array, first element short-hand " Link "Types.guide/Accessing array data" 55 } Accessing array data + @{" Array, initialised " Link "Types.guide/Typed lists" 0 } Typed lists + @{" Array, pointer " Link "Types.guide/Array pointers" 0 } Array pointers + @{" Array, procedure parameter " Link "Types.guide/Array procedure parameters" 0 } Array procedure parameters + @{" ASCII character constant " Link "Constants.guide/Numeric Constants" 11 } Numeric Constants + @{" Assembly and E constants " Link "MoreExpressions.guide/Assembly and the E language" 15 } Assembly and the E language + @{" Assembly and E variables " Link "MoreExpressions.guide/Assembly and the E language" 0 } Assembly and the E language + @{" Assembly and labels " Link "MoreExpressions.guide/Assembly and the E language" 28 } Assembly and the E language + @{" Assembly and procedures " Link "MoreExpressions.guide/Assembly and the E language" 28 } Assembly and the E language + @{" Assembly and static memory " Link "MoreExpressions.guide/Static memory" 0 } Static memory + @{" Assembly statements " Link "MoreExpressions.guide/Assembly Statements" 0 } Assembly Statements + @{" Assembly, calling system functions " Link "MoreExpressions.guide/Assembly and the E language" 39 } Assembly and the E language + @{" Assembly, potential problems " Link "MoreExpressions.guide/Things to watch out for" 0 } Things to watch out for + @{" Assignment expression " Link "MoreExpressions.guide/Assignments" 0 } Assignments + @{" Assignment versus copying " Link "Types.guide/String functions" 70 } String functions + @{" Assignment, := " Link "Introduction.guide/Assignment" 0 } Assignment + @{" Assignment, allowable left-hand sides " Link "MoreExpressions.guide/Assignments" 33 } Assignments + @{" Assignment, Emodules: " Link "Modules.guide/Using Modules" 0 } Using Modules + @{" Assignment, multiple " Link "Procedures.guide/Multiple Return Values" 12 } Multiple Return Values + @{" Automatic exceptions " Link "Exceptions.guide/Automatic Exceptions" 0 } Automatic Exceptions + @{" Automatic exceptions and initialisation " Link "Exceptions.guide/Raise within an Exception Handler" 54 } Raise within an Exception Handler + @{" Automatic voiding " Link "MoreExpressions.guide/Turning an Expression into a Statement" 20 } Turning an Expression into a Statement + @{" Background pen, setting colour " Link "BuiltIns.guide/Graphics functions" 35 } Graphics functions + @{" Backslash " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Base case " Link "Recursion.guide/Factorial Example" 44 } Factorial Example + @{" Base class " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" Beginner's Guide author " Link "Appendices.guide/Guide Author" 0 } Guide Author + @{" Binary constant " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Binary tree " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Bit shift left " Link "BuiltIns.guide/Maths and logic functions" 100 } Maths and logic functions + @{" Bit shift right " Link "BuiltIns.guide/Maths and logic functions" 108 } Maths and logic functions + @{" Bit-wise AND and OR " Link "MoreExpressions.guide/Bitwise AND and OR" 0 } Bitwise AND and OR + @{" Black box " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Block, conditional " Link "Introduction.guide/Conditional Block" 0 } Conditional Block + @{" Block, IF " Link "Introduction.guide/IF block" 0 } IF block + @{" Block, SELECT " Link "Introduction.guide/SELECT block" 0 } SELECT block + @{" Block, SELECT..OF " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" Books, further reading " Link "Appendices.guide/Further Reading" 0 } Further Reading + @{" Bounding a value " Link "BuiltIns.guide/Maths and logic functions" 55 } Maths and logic functions + @{" Box drawing " Link "BuiltIns.guide/Graphics functions" 30 } Graphics functions + @{" Box, black " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Bracketing expressions " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Branch " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Breaking a string over several lines " Link "Format.guide/Statements" 58 } Statements + @{" Breaking statements over several lines " Link "Format.guide/Statements" 30 } Statements + @{" Bug, finding " Link "Appendices.guide/main" 0 } Common Problems + @{" Built-in constants " Link "BuiltIns.guide/Built-In Constants" 0 } Built-In Constants + @{" Built-in functions " Link "BuiltIns.guide/Built-In Functions" 0 } Built-In Functions + @{" Built-in functions, floating-point " Link "FloatingPoint.guide/Floating-Point Functions" 0 } Floating-Point Functions + @{" Built-in functions, linked list " Link "Types.guide/Linked Lists" 13 } Linked Lists + @{" Built-in functions, list and E-list " Link "Types.guide/List functions" 0 } List functions + @{" Built-in functions, string and E-string " Link "Types.guide/String functions" 0 } String functions + @{" Built-in variables " Link "BuiltIns.guide/Built-In Variables" 0 } Built-In Variables + @{" BUT expression " Link "MoreExpressions.guide/BUT expression" 0 } BUT expression + @{" Button click, left " Link "BuiltIns.guide/Intuition support functions" 273 } Intuition support functions + @{" Button click, left (wait) " Link "BuiltIns.guide/Intuition support functions" 324 } Intuition support functions + @{" Buttons state " Link "BuiltIns.guide/Intuition support functions" 235 } Intuition support functions + @{" Calculating with floating-point numbers " Link "FloatingPoint.guide/Floating-Point Calculations" 0 } Floating-Point Calculations + @{" Calling a method " Link "OOE.guide/Methods in E" 28 } Methods in E + @{" Calling a procedure " Link "Introduction.guide/Procedure Execution" 0 } Procedure Execution + @{" Calling a procedure " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Calling system functions from Assembly " Link "MoreExpressions.guide/Assembly and the E language" 39 } Assembly and the E language + @{" Carriage return " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Case of characters in identifiers " Link "Format.guide/Identifiers" 0 } Identifiers + @{" Case, base " Link "Recursion.guide/Factorial Example" 44 } Factorial Example + @{" Case, recursive " Link "Recursion.guide/Factorial Example" 44 } Factorial Example + @{" Ceiling of a floating-point value " Link "FloatingPoint.guide/Floating-Point Functions" 59 } Floating-Point Functions + @{" Changing stdin " Link "BuiltIns.guide/Input and output functions" 161 } Input and output functions + @{" Changing stdout " Link "BuiltIns.guide/Input and output functions" 170 } Input and output functions + @{" Changing stdrast " Link "BuiltIns.guide/Graphics functions" 58 } Graphics functions + @{" Changing the value of a variable " Link "Introduction.guide/Assignment" 0 } Assignment + @{" Character constant " Link "Constants.guide/Numeric Constants" 11 } Numeric Constants + @{" Character, apostrophe " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, backslash " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, carriage return " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, double quote " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, escape " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, linefeed " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, null " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, printing " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Character, read from a file " Link "BuiltIns.guide/Input and output functions" 109 } Input and output functions + @{" Character, tab " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Character, write to file " Link "BuiltIns.guide/Input and output functions" 99 } Input and output functions + @{" Choice, conditional block " Link "Introduction.guide/Conditional Block" 0 } Conditional Block + @{" Class (OOP) " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Class hierarchy " Link "OOE.guide/Inheritance in E" 173 } Inheritance in E + @{" Class, abstract " Link "OOE.guide/Inheritance in E" 173 } Inheritance in E + @{" Class, base " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" Class, derived " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" Class, super " Link "OOE.guide/Inheritance in E" 161 } Inheritance in E + @{" Classes and modules " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" Clean-up, program termination " Link "BuiltIns.guide/System support functions" 65 } System support functions + @{" Close screen " Link "BuiltIns.guide/Intuition support functions" 178 } Intuition support functions + @{" Close window " Link "BuiltIns.guide/Intuition support functions" 122 } Intuition support functions + @{" Code fragment " Link "Introduction.guide/Conditional Block" 0 } Conditional Block + @{" Code modules " Link "Modules.guide/Code Modules" 0 } Code Modules + @{" code part of Intuition message " Link "BuiltIns.guide/Intuition support functions" 313 } Intuition support functions + @{" Code, reuse " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Code, style " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Colour, setting " Link "BuiltIns.guide/Graphics functions" 49 } Graphics functions + @{" Colour, setting foreground and background pen " Link "BuiltIns.guide/Graphics functions" 35 } Graphics functions + @{" Command line argument parsing " Link "Examples.guide/Argument Parsing" 0 } Argument Parsing + @{" Comment, nested " Link "Format.guide/Comments" 7 } Comments + @{" Comments " Link "Format.guide/Comments" 0 } Comments + @{" Common logarithm " Link "FloatingPoint.guide/Floating-Point Functions" 73 } Floating-Point Functions + @{" Common problems " Link "Appendices.guide/main" 0 } Common Problems + @{" Common use of pointers " Link "Types.guide/Extracting data (dereferencing pointers)" 90 } Extracting data (dereferencing pointers) + @{" Comparison of lists " Link "Types.guide/List functions" 28 } List functions + @{" Comparison of strings " Link "Types.guide/String functions" 40 } String functions + @{" Comparison operators " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Compiler, ec " Link "Introduction.guide/Compilation" 0 } Compilation + @{" Complex memory, deallocate " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Complex memory, free " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Complex types " Link "Types.guide/Complex types" 0 } Complex types + @{" Conditional block " Link "Introduction.guide/Conditional Block" 0 } Conditional Block + @{" Constant " Link "Constants.guide/main" 0 } Constants + @{" Constant string " Link "Types.guide/Normal strings and E-strings" 0 } Normal strings and E-strings + @{" Constant, binary " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Constant, built-in " Link "BuiltIns.guide/Built-In Constants" 0 } Built-In Constants + @{" Constant, character " Link "Constants.guide/Numeric Constants" 11 } Numeric Constants + @{" Constant, decimal " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Constant, enumeration " Link "Constants.guide/Enumerations" 0 } Enumerations + @{" Constant, hexadecimal " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Constant, named " Link "Constants.guide/Named Constants" 0 } Named Constants + @{" Constant, numeric " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Constant, set " Link "Constants.guide/Sets" 0 } Sets + @{" Constant, use in Assembly " Link "MoreExpressions.guide/Assembly and the E language" 15 } Assembly and the E language + @{" Constructor " Link "OOE.guide/Classes and methods" 20 } Classes and methods + @{" Constructor, names " Link "OOE.guide/Methods in E" 78 } Methods in E + @{" Control-C testing " Link "BuiltIns.guide/System support functions" 74 } System support functions + @{" Controlling program flow " Link "Introduction.guide/Program Flow Control" 0 } Program Flow Control + @{" Conversion of floating-point numbers " Link "FloatingPoint.guide/Floating-Point Calculations" 0 } Floating-Point Calculations + @{" Convert an expression to a statement " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" Convert header file to module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Convert include file to module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Convert pragma file to module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Converting floating-point numbers from a string " Link "FloatingPoint.guide/Floating-Point Functions" 10 } Floating-Point Functions + @{" Converting strings to numbers " Link "Types.guide/String functions" 199 } String functions + @{" Copy middle part of a string " Link "Types.guide/String functions" 144 } String functions + @{" Copy right-hand part of an E-string " Link "Types.guide/String functions" 136 } String functions + @{" Copying a list " Link "Types.guide/List functions" 37 } List functions + @{" Copying a string " Link "Types.guide/String functions" 58 } String functions + @{" Copying versus assignment " Link "Types.guide/String functions" 70 } String functions + @{" Cosine function " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Crash, avoiding stack problems " Link "Recursion.guide/Stack (and Crashing)" 21 } Stack (and Crashing) + @{" Crash, running out of stack " Link "Recursion.guide/Stack (and Crashing)" 0 } Stack (and Crashing) + @{" Create gadget " Link "BuiltIns.guide/Intuition support functions" 187 } Intuition support functions + @{" Cure for linefeed problem " Link "Introduction.guide/Strings" 0 } Strings + @{" Data, extracting from a pointer " Link "Types.guide/Extracting data (dereferencing pointers)" 0 } Extracting data (dereferencing pointers) + @{" Data, input " Link "Introduction.guide/The Simple Program" 0 } The Simple Program + @{" Data, manipulation " Link "Introduction.guide/The Simple Program" 0 } The Simple Program + @{" Data, named " Link "Introduction.guide/Variables and Expressions" 0 } Variables and Expressions + @{" Data, output " Link "Introduction.guide/The Simple Program" 0 } The Simple Program + @{" Data, static " Link "Types.guide/Static data" 0 } Static data + @{" Data, storage " Link "Introduction.guide/Variable types" 0 } Variable types + @{" Data-abstraction " Link "OOE.guide/Classes and methods" 29 } Classes and methods + @{" Data-hiding " Link "OOE.guide/Classes and methods" 29 } Classes and methods + @{" Deallocating an object " Link "OOE.guide/Objects in E" 31 } Objects in E + @{" Deallocating complex memory " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Deallocating memory " Link "BuiltIns.guide/System support functions" 39 } System support functions + @{" Deallocation of memory " Link "Memory.guide/Deallocation of Memory" 0 } Deallocation of Memory + @{" Deallocation, potential problems " Link "Memory.guide/Deallocation of Memory" 28 } Deallocation of Memory + @{" Decimal constant " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Decimal number, printing " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Decision, conditional block " Link "Introduction.guide/Conditional Block" 0 } Conditional Block + @{" Declaration, array and array pointer " Link "Types.guide/Array pointers" 46 } Array pointers + @{" Declaration, illegal " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Declaration, initialised " Link "MoreExpressions.guide/Initialised Declarations" 0 } Initialised Declarations + @{" Declaration, variable type " Link "Types.guide/Default type" 15 } Default type + @{" Declaring a variable " Link "Introduction.guide/Variable declaration" 0 } Variable declaration + @{" Decrementing a variable " Link "MoreExpressions.guide/INC and DEC statements" 0 } INC and DEC statements + @{" Decrementing array pointer " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Default arguments " Link "Procedures.guide/Default Arguments" 0 } Default Arguments + @{" Default type " Link "Types.guide/Default type" 0 } Default type + @{" Definition of a procedure with parameters " Link "Introduction.guide/Global and local variables" 62 } Global and local variables + @{" Dereferencing a pointer " Link "Types.guide/Extracting data (dereferencing pointers)" 0 } Extracting data (dereferencing pointers) + @{" Derivation (OOP) " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" Derived class " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" Descoping a global variable " Link "Introduction.guide/Global and local variables" 57 } Global and local variables + @{" Destructor " Link "OOE.guide/Classes and methods" 20 } Classes and methods + @{" Destructor, end " Link "OOE.guide/Methods in E" 118 } Methods in E + @{" Direct type " Link "Types.guide/Indirect types" 21 } Indirect types + @{" Division " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Division, 32-bit " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" Double quote " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Doubly linked list " Link "Types.guide/Linked Lists" 64 } Linked Lists + @{" Dragon curve " Link "Examples.guide/Recursion Example" 0 } Recursion Example + @{" Drawing, box " Link "BuiltIns.guide/Graphics functions" 30 } Graphics functions + @{" Drawing, line " Link "BuiltIns.guide/Graphics functions" 27 } Graphics functions + @{" Drawing, text " Link "BuiltIns.guide/Graphics functions" 42 } Graphics functions + @{" Dynamic (typed) memory allocation " Link "Memory.guide/NEW and END Operators" 0 } NEW and END Operators + @{" Dynamic E-list allocation " Link "Types.guide/List functions" 12 } List functions + @{" Dynamic E-string allocation " Link "Types.guide/String functions" 14 } String functions + @{" Dynamic memory allocation " Link "Memory.guide/Dynamic Allocation" 0 } Dynamic Allocation + @{" Dynamic type " Link "OOE.guide/Inheritance in E" 147 } Inheritance in E + @{" E author " Link "Appendices.guide/Amiga E Author" 0 } Amiga E Author + @{" E-list " Link "Types.guide/Lists and E-lists" 0 } Lists and E-lists + @{" E-list functions " Link "Types.guide/List functions" 0 } List functions + @{" E-list, append " Link "Types.guide/List functions" 47 } List functions + @{" E-list, comparison " Link "Types.guide/List functions" 28 } List functions + @{" E-list, copying " Link "Types.guide/List functions" 37 } List functions + @{" E-list, dynamic allocation " Link "Types.guide/List functions" 12 } List functions + @{" E-list, length " Link "Types.guide/List functions" 55 } List functions + @{" E-list, maximum length " Link "Types.guide/List functions" 59 } List functions + @{" E-list, setting the length " Link "Types.guide/List functions" 62 } List functions + @{" E-string " Link "Types.guide/Normal strings and E-strings" 39 } Normal strings and E-strings + @{" E-string functions " Link "Types.guide/String functions" 0 } String functions + @{" E-string handling example " Link "Examples.guide/String Handling and I-O" 0 } String Handling and I-O + @{" E-string, append " Link "Types.guide/String functions" 99 } String functions + @{" E-string, comparison " Link "Types.guide/String functions" 40 } String functions + @{" E-string, copying " Link "Types.guide/String functions" 58 } String functions + @{" E-string, dynamic allocation " Link "Types.guide/String functions" 14 } String functions + @{" E-string, format text to " Link "BuiltIns.guide/Input and output functions" 90 } Input and output functions + @{" E-string, length " Link "Types.guide/String functions" 125 } String functions + @{" E-string, lowercase " Link "Types.guide/String functions" 169 } String functions + @{" E-string, maximum length " Link "Types.guide/String functions" 131 } String functions + @{" E-string, middle copy " Link "Types.guide/String functions" 144 } String functions + @{" E-string, reading from a file " Link "BuiltIns.guide/Input and output functions" 114 } Input and output functions + @{" E-string, right-hand copy " Link "Types.guide/String functions" 136 } String functions + @{" E-string, set length " Link "Types.guide/String functions" 178 } String functions + @{" E-string, trim leading whitespace " Link "Types.guide/String functions" 161 } String functions + @{" E-string, uppercase " Link "Types.guide/String functions" 174 } String functions + @{" Early termination of a function " Link "Procedures.guide/Functions" 32 } Functions + @{" ec compiler " Link "Introduction.guide/Compilation" 0 } Compilation + @{" Element selection " Link "Types.guide/Element selection and element types" 0 } Element selection and element types + @{" Element types " Link "Types.guide/Element selection and element types" 13 } Element selection and element types + @{" Elements of a linked list " Link "Types.guide/Linked Lists" 13 } Linked Lists + @{" Elements of an array " Link "Types.guide/Accessing array data" 0 } Accessing array data + @{" Elements of an object " Link "Types.guide/OBJECT Type" 0 } OBJECT Type + @{" Emodules: assignment " Link "Modules.guide/Using Modules" 0 } Using Modules + @{" end destructor " Link "OOE.guide/Methods in E" 118 } Methods in E + @{" End of file " Link "BuiltIns.guide/Input and output functions" 109 } Input and output functions + @{" Enumeration " Link "Constants.guide/Enumerations" 0 } Enumerations + @{" EOF " Link "BuiltIns.guide/Input and output functions" 109 } Input and output functions + @{" Error handling " Link "Exceptions.guide/main" 0 } Exception Handling + @{" Escape character " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Evaluation of quoted expressions " Link "MoreExpressions.guide/Evaluation" 0 } Evaluation + @{" Even number " Link "BuiltIns.guide/Maths and logic functions" 41 } Maths and logic functions + @{" Example module use " Link "Modules.guide/Example Module Use" 0 } Example Module Use + @{" Examples, altering " Link "Introduction.guide/Tinkering with the example" 0 } Tinkering with the example + @{" Examples, tinkering " Link "Introduction.guide/Tinkering with the example" 0 } Tinkering with the example + @{" Exception " Link "Exceptions.guide/main" 0 } Exception Handling + @{" Exception handler in a procedure " Link "Exceptions.guide/Procedures with Exception Handlers" 0 } Procedures with Exception Handlers + @{" Exception handling " Link "Exceptions.guide/main" 0 } Exception Handling + @{" Exception, automatic " Link "Exceptions.guide/Automatic Exceptions" 0 } Automatic Exceptions + @{" Exception, raising " Link "Exceptions.guide/Raising an Exception" 0 } Raising an Exception + @{" Exception, raising from a handler " Link "Exceptions.guide/Raise within an Exception Handler" 0 } Raise within an Exception Handler + @{" Exception, recursive handling " Link "Recursion.guide/Stack and Exceptions" 9 } Stack and Exceptions + @{" Exception, throwing " Link "Exceptions.guide/Raising an Exception" 0 } Raising an Exception + @{" Exception, use of stack " Link "Recursion.guide/Stack and Exceptions" 0 } Stack and Exceptions + @{" Exception, zero " Link "Exceptions.guide/Raising an Exception" 73 } Raising an Exception + @{" Exceptions and initialisation " Link "Exceptions.guide/Raise within an Exception Handler" 54 } Raise within an Exception Handler + @{" Exclusive or " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" Executing a procedure " Link "Introduction.guide/Procedure Execution" 0 } Procedure Execution + @{" Execution " Link "Introduction.guide/Execution" 0 } Execution + @{" Execution, jumping to a label " Link "MoreExpressions.guide/Labelling and the JUMP statement" 0 } Labelling and the JUMP statement + @{" Exists a list element " Link "MoreExpressions.guide/Lists and quoted expressions" 46 } Lists and quoted expressions + @{" EXIT statement " Link "MoreExpressions.guide/EXIT statement" 0 } EXIT statement + @{" Exiting a loop " Link "MoreExpressions.guide/EXIT statement" 0 } EXIT statement + @{" Exponentiation " Link "FloatingPoint.guide/Floating-Point Functions" 66 } Floating-Point Functions + @{" Expression " Link "Introduction.guide/Expressions" 0 } Expressions + @{" Expression " Link "Introduction.guide/Variables and Expressions" 0 } Variables and Expressions + @{" Expression in parentheses " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Expression, assignment " Link "MoreExpressions.guide/Assignments" 0 } Assignments + @{" Expression, bad grouping " Link "Introduction.guide/Precedence and grouping" 25 } Precedence and grouping + @{" Expression, bracketing " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Expression, BUT " Link "MoreExpressions.guide/BUT expression" 0 } BUT expression + @{" Expression, conversion to a statement " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" Expression, grouping " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Expression, IF " Link "Introduction.guide/IF expression" 0 } IF expression + @{" Expression, quotable " Link "MoreExpressions.guide/Quotable expressions" 0 } Quotable expressions + @{" Expression, quoted " Link "MoreExpressions.guide/Quoted Expressions" 0 } Quoted Expressions + @{" Expression, sequence " Link "MoreExpressions.guide/BUT expression" 0 } BUT expression + @{" Expression, side-effects " Link "MoreExpressions.guide/Side-effects" 0 } Side-effects + @{" Expression, timing example " Link "Examples.guide/Timing Expressions" 0 } Timing Expressions + @{" Expression, voiding " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" Extracting data from a pointer " Link "Types.guide/Extracting data (dereferencing pointers)" 0 } Extracting data (dereferencing pointers) + @{" Extracting floating-point numbers from a string " Link "FloatingPoint.guide/Floating-Point Functions" 10 } Floating-Point Functions + @{" Extracting numbers from a string " Link "Types.guide/String functions" 199 } String functions + @{" Factorial function " Link "Recursion.guide/Factorial Example" 0 } Factorial Example + @{" Field formatting " Link "BuiltIns.guide/Input and output functions" 37 } Input and output functions + @{" Field size " Link "BuiltIns.guide/Input and output functions" 37 } Input and output functions + @{" Field, left-justify " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Field, right-justify " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Field, zero fill " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" File length " Link "BuiltIns.guide/Input and output functions" 154 } Input and output functions + @{" Filtering a list " Link "MoreExpressions.guide/Lists and quoted expressions" 62 } Lists and quoted expressions + @{" Find sub-string in a string " Link "Types.guide/String functions" 156 } String functions + @{" Finding addresses " Link "Types.guide/Finding addresses (making pointers)" 0 } Finding addresses (making pointers) + @{" Finding bugs " Link "Appendices.guide/main" 0 } Common Problems + @{" First element of an array " Link "Types.guide/Accessing array data" 55 } Accessing array data + @{" Flag, AND-ing " Link "Constants.guide/Sets" 19 } Sets + @{" Flag, IDCMP " Link "BuiltIns.guide/Intuition support functions" 70 } Intuition support functions + @{" Flag, mouse button " Link "BuiltIns.guide/Intuition support functions" 244 } Intuition support functions + @{" Flag, OR-ing " Link "Constants.guide/Sets" 19 } Sets + @{" Flag, screen resolution " Link "BuiltIns.guide/Intuition support functions" 171 } Intuition support functions + @{" Flag, set constant " Link "Constants.guide/Sets" 0 } Sets + @{" Flag, window " Link "BuiltIns.guide/Intuition support functions" 89 } Intuition support functions + @{" Floating-point conversion operator " Link "FloatingPoint.guide/Floating-Point Calculations" 0 } Floating-Point Calculations + @{" Floating-point functions " Link "FloatingPoint.guide/Floating-Point Functions" 0 } Floating-Point Functions + @{" Floating-point number " Link "FloatingPoint.guide/main" 0 } Floating-Point Numbers + @{" Floating-point number, extracting from a string " Link "FloatingPoint.guide/Floating-Point Functions" 10 } Floating-Point Functions + @{" Floor of a floating-point value " Link "FloatingPoint.guide/Floating-Point Functions" 59 } Floating-Point Functions + @{" Flow control " Link "Introduction.guide/Program Flow Control" 0 } Program Flow Control + @{" Following elements in a linked list " Link "Types.guide/Linked Lists" 56 } Linked Lists + @{" Font, setting Topaz " Link "BuiltIns.guide/Graphics functions" 67 } Graphics functions + @{" For all list elements " Link "MoreExpressions.guide/Lists and quoted expressions" 29 } Lists and quoted expressions + @{" FOR loop " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" Foreground pen, setting colour " Link "BuiltIns.guide/Graphics functions" 35 } Graphics functions + @{" Format rules " Link "Format.guide/main" 0 } Format and Layout + @{" Format text to an E-string " Link "BuiltIns.guide/Input and output functions" 90 } Input and output functions + @{" Forward through a linked list " Link "Types.guide/Linked Lists" 56 } Linked Lists + @{" Fragment, code " Link "Introduction.guide/Conditional Block" 0 } Conditional Block + @{" Free stack space " Link "BuiltIns.guide/System support functions" 79 } System support functions + @{" Freeing complex memory " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Freeing memory " Link "BuiltIns.guide/System support functions" 39 } System support functions + @{" Function " Link "Procedures.guide/main" 0 } Procedures and Functions + @{" Function, built-in " Link "BuiltIns.guide/Built-In Functions" 0 } Built-In Functions + @{" Function, early termination " Link "Procedures.guide/Functions" 32 } Functions + @{" Function, factorial " Link "Recursion.guide/Factorial Example" 0 } Factorial Example + @{" Function, graphics " Link "BuiltIns.guide/Graphics functions" 0 } Graphics functions + @{" Function, input " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Function, Intuition support " Link "BuiltIns.guide/Intuition support functions" 0 } Intuition support functions + @{" Function, logic " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" Function, maths " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" Function, one-line " Link "Procedures.guide/One-Line Functions" 0 } One-Line Functions + @{" Function, output " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Function, recursive " Link "Recursion.guide/main" 0 } Recursion + @{" Function, return value " Link "Procedures.guide/Functions" 0 } Functions + @{" Function, system support " Link "BuiltIns.guide/System support functions" 0 } System support functions + @{" Functions, floating-point " Link "FloatingPoint.guide/Floating-Point Functions" 0 } Floating-Point Functions + @{" Functions, linked list " Link "Types.guide/Linked Lists" 13 } Linked Lists + @{" Functions, list and E-list " Link "Types.guide/List functions" 0 } List functions + @{" Functions, string and E-string " Link "Types.guide/String functions" 0 } String functions + @{" Further reading " Link "Appendices.guide/Further Reading" 0 } Further Reading + @{" Gadget and IDCMP example " Link "Examples.guide/IDCMP Messages" 0 } IDCMP Messages + @{" Gadget, create " Link "BuiltIns.guide/Intuition support functions" 187 } Intuition support functions + @{" Gadgets example " Link "Examples.guide/Gadgets" 0 } Gadgets + @{" General loop " Link "MoreExpressions.guide/LOOP block" 0 } LOOP block + @{" Global variable " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Global variable, descoping " Link "Introduction.guide/Global and local variables" 57 } Global and local variables + @{" Graphics example " Link "Examples.guide/Graphics" 0 } Graphics + @{" Graphics functions " Link "BuiltIns.guide/Graphics functions" 0 } Graphics functions + @{" Grouping expressions " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Grouping, bad " Link "Introduction.guide/Precedence and grouping" 25 } Precedence and grouping + @{" Guide author " Link "Appendices.guide/Guide Author" 0 } Guide Author + @{" Handler in a procedure " Link "Exceptions.guide/Procedures with Exception Handlers" 0 } Procedures with Exception Handlers + @{" Handler raising an exception " Link "Exceptions.guide/Raise within an Exception Handler" 0 } Raise within an Exception Handler + @{" Handler, recursive " Link "Recursion.guide/Stack and Exceptions" 9 } Stack and Exceptions + @{" Handling exceptions " Link "Exceptions.guide/main" 0 } Exception Handling + @{" Head of a linked list " Link "Types.guide/Linked Lists" 23 } Linked Lists + @{" Header file, convert to module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Hexadecimal constant " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Hexadecimal number, printing " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Hierarchy, class " Link "OOE.guide/Inheritance in E" 173 } Inheritance in E + @{" Horizontal FOR loop " Link "Introduction.guide/FOR loop" 55 } FOR loop + @{" Horizontal function definition " Link "Procedures.guide/One-Line Functions" 0 } One-Line Functions + @{" Horizontal IF block " Link "Introduction.guide/IF block" 29 } IF block + @{" Horizontal WHILE loop " Link "Introduction.guide/WHILE loop" 57 } WHILE loop + @{" I/O example " Link "Examples.guide/String Handling and I-O" 0 } String Handling and I-O + @{" I/O example, with handler " Link "Examples.guide/String Handling and I-O" 307 } String Handling and I-O + @{" iaddr part of Intuition message " Link "BuiltIns.guide/Intuition support functions" 316 } Intuition support functions + @{" IDCMP and gadget example " Link "Examples.guide/IDCMP Messages" 0 } IDCMP Messages + @{" IDCMP flags " Link "BuiltIns.guide/Intuition support functions" 70 } Intuition support functions + @{" IDCMP message, code part " Link "BuiltIns.guide/Intuition support functions" 313 } Intuition support functions + @{" IDCMP message, iaddr part " Link "BuiltIns.guide/Intuition support functions" 316 } Intuition support functions + @{" IDCMP message, qual part " Link "BuiltIns.guide/Intuition support functions" 321 } Intuition support functions + @{" IDCMP message, waiting for " Link "BuiltIns.guide/Intuition support functions" 282 } Intuition support functions + @{" Identifier " Link "Format.guide/Identifiers" 0 } Identifiers + @{" Identifier, case of characters " Link "Format.guide/Identifiers" 0 } Identifiers + @{" IF block " Link "Introduction.guide/IF block" 0 } IF block + @{" IF block, nested " Link "Introduction.guide/IF block" 74 } IF block + @{" IF block, overlapping conditions " Link "Introduction.guide/IF block" 80 } IF block + @{" IF expression " Link "Introduction.guide/IF expression" 0 } IF expression + @{" Illegal declaration " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Include file, convert to module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Incrementing a variable " Link "MoreExpressions.guide/INC and DEC statements" 0 } INC and DEC statements + @{" Incrementing array pointer " Link "Types.guide/Point to other elements" 0 } Point to other elements + @{" Indentation " Link "Format.guide/Spacing and Separators" 0 } Spacing and Separators + @{" Indirect type " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Inheritance (OOP) " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" Inheritance, OBJECT..OF " Link "OOE.guide/Inheritance in E" 0 } Inheritance in E + @{" Initialisation " Link "Introduction.guide/Global and local variables" 109 } Global and local variables + @{" Initialisation and automatic exceptions " Link "Exceptions.guide/Raise within an Exception Handler" 54 } Raise within an Exception Handler + @{" Initialisation, general " Link "MoreExpressions.guide/Initialised Declarations" 28 } Initialised Declarations + @{" Initialised array " Link "Types.guide/Typed lists" 0 } Typed lists + @{" Initialised declaration " Link "MoreExpressions.guide/Initialised Declarations" 0 } Initialised Declarations + @{" Inlining procedures " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Input a character " Link "BuiltIns.guide/Input and output functions" 109 } Input and output functions + @{" Input a string " Link "BuiltIns.guide/Input and output functions" 114 } Input and output functions + @{" Input functions " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Input/output example " Link "Examples.guide/String Handling and I-O" 0 } String Handling and I-O + @{" Input/output example, with handler " Link "Examples.guide/String Handling and I-O" 307 } String Handling and I-O + @{" Interface " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Intuition message flags " Link "BuiltIns.guide/Intuition support functions" 70 } Intuition support functions + @{" Intuition message, code part " Link "BuiltIns.guide/Intuition support functions" 313 } Intuition support functions + @{" Intuition message, iaddr part " Link "BuiltIns.guide/Intuition support functions" 316 } Intuition support functions + @{" Intuition message, qual part " Link "BuiltIns.guide/Intuition support functions" 321 } Intuition support functions + @{" Intuition message, waiting for " Link "BuiltIns.guide/Intuition support functions" 282 } Intuition support functions + @{" Intuition support functions " Link "BuiltIns.guide/Intuition support functions" 0 } Intuition support functions + @{" Iteration " Link "Introduction.guide/Loops" 0 } Loops + @{" Jumping out of a loop " Link "MoreExpressions.guide/Labelling and the JUMP statement" 29 } Labelling and the JUMP statement + @{" Jumping to a label " Link "MoreExpressions.guide/Labelling and the JUMP statement" 0 } Labelling and the JUMP statement + @{" Kickstart version " Link "BuiltIns.guide/System support functions" 84 } System support functions + @{" Label " Link "MoreExpressions.guide/Labelling and the JUMP statement" 0 } Labelling and the JUMP statement + @{" Label, use in Assembly " Link "MoreExpressions.guide/Assembly and the E language" 28 } Assembly and the E language + @{" Languages " Link "Introduction.guide/main" 0 } Introduction to Amiga E + @{" Layout rules " Link "Format.guide/main" 0 } Format and Layout + @{" Leaf " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Left mouse button click " Link "BuiltIns.guide/Intuition support functions" 273 } Intuition support functions + @{" Left mouse button click (wait) " Link "BuiltIns.guide/Intuition support functions" 324 } Intuition support functions + @{" Left shift " Link "BuiltIns.guide/Maths and logic functions" 100 } Maths and logic functions + @{" Left-hand side of an assignment, allowable " Link "MoreExpressions.guide/Assignments" 33 } Assignments + @{" Left-justify field " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Length (maximum) of an E-list " Link "Types.guide/List functions" 59 } List functions + @{" Length (maximum) of an E-string " Link "Types.guide/String functions" 131 } String functions + @{" Length of a file " Link "BuiltIns.guide/Input and output functions" 154 } Input and output functions + @{" Length of a list " Link "Types.guide/List functions" 55 } List functions + @{" Length of a string " Link "Types.guide/String functions" 108 } String functions + @{" Length of an E-list, setting " Link "Types.guide/List functions" 62 } List functions + @{" Length of an E-string " Link "Types.guide/String functions" 125 } String functions + @{" Length of an E-string, setting " Link "Types.guide/String functions" 178 } String functions + @{" Line drawing " Link "BuiltIns.guide/Graphics functions" 27 } Graphics functions + @{" Linefeed " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Linefeed problem " Link "Introduction.guide/Execution" 20 } Execution + @{" Linefeed problem, cure " Link "Introduction.guide/Strings" 0 } Strings + @{" Linefeed, \n " Link "Introduction.guide/Strings" 0 } Strings + @{" Linked list " Link "Types.guide/Linked Lists" 0 } Linked Lists + @{" Linked list, doubly " Link "Types.guide/Linked Lists" 64 } Linked Lists + @{" Linked list, elements " Link "Types.guide/Linked Lists" 13 } Linked Lists + @{" Linked list, following elements " Link "Types.guide/Linked Lists" 56 } Linked Lists + @{" Linked list, functions " Link "Types.guide/Linked Lists" 13 } Linked Lists + @{" Linked list, head " Link "Types.guide/Linked Lists" 23 } Linked Lists + @{" Linked list, linking " Link "Types.guide/Linked Lists" 23 } Linked Lists + @{" Linked list, next element " Link "Types.guide/Linked Lists" 38 } Linked Lists + @{" Linked list, singly " Link "Types.guide/Linked Lists" 64 } Linked Lists + @{" Linking a linked list " Link "Types.guide/Linked Lists" 23 } Linked Lists + @{" List " Link "Types.guide/Lists and E-lists" 0 } Lists and E-lists + @{" List functions " Link "Types.guide/List functions" 0 } List functions + @{" List, append " Link "Types.guide/List functions" 47 } List functions + @{" List, comparison " Link "Types.guide/List functions" 28 } List functions + @{" List, copying " Link "Types.guide/List functions" 37 } List functions + @{" List, filtering " Link "MoreExpressions.guide/Lists and quoted expressions" 62 } Lists and quoted expressions + @{" List, for all elements " Link "MoreExpressions.guide/Lists and quoted expressions" 29 } Lists and quoted expressions + @{" List, length " Link "Types.guide/List functions" 55 } List functions + @{" List, linked " Link "Types.guide/Linked Lists" 0 } Linked Lists + @{" List, mapping a quoted expression " Link "MoreExpressions.guide/Lists and quoted expressions" 8 } Lists and quoted expressions + @{" List, normal " Link "Types.guide/Lists and E-lists" 0 } Lists and E-lists + @{" List, selecting an element " Link "Types.guide/List functions" 65 } List functions + @{" List, tag " Link "Types.guide/Lists and E-lists" 42 } Lists and E-lists + @{" List, there exists an element " Link "MoreExpressions.guide/Lists and quoted expressions" 46 } Lists and quoted expressions + @{" List, typed " Link "Types.guide/Typed lists" 0 } Typed lists + @{" Lists and quoted expressions " Link "MoreExpressions.guide/Lists and quoted expressions" 0 } Lists and quoted expressions + @{" Local variable " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Local variable, initialisation " Link "Introduction.guide/Global and local variables" 109 } Global and local variables + @{" Local variable, same names " Link "Introduction.guide/Global and local variables" 32 } Global and local variables + @{" Local variable, self " Link "OOE.guide/Methods in E" 67 } Methods in E + @{" Local variables in a quoted expression " Link "MoreExpressions.guide/Quotable expressions" 0 } Quotable expressions + @{" Locate sub-string in a string " Link "Types.guide/String functions" 156 } String functions + @{" Location, memory " Link "Types.guide/Memory addresses" 0 } Memory addresses + @{" Location, memory " Link "Types.guide/Addresses" 0 } Addresses + @{" Logarithm, common " Link "FloatingPoint.guide/Floating-Point Functions" 73 } Floating-Point Functions + @{" Logarithm, natural " Link "FloatingPoint.guide/Floating-Point Functions" 73 } Floating-Point Functions + @{" Logic " Link "Introduction.guide/Logic and comparison" 0 } Logic and comparison + @{" Logic functions " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" Logic operators " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Logic, and " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" Logic, exclusive or " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" Logic, not " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" Logic, or " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" LONG type " Link "Types.guide/LONG Type" 0 } LONG Type + @{" LONG type, definition " Link "Types.guide/Indirect types" 21 } Indirect types + @{" Loop " Link "Introduction.guide/Loops" 0 } Loops + @{" LOOP block " Link "MoreExpressions.guide/LOOP block" 0 } LOOP block + @{" Loop check, REPEAT..UNTIL " Link "Introduction.guide/REPEAT..UNTIL loop" 18 } REPEAT..UNTIL loop + @{" Loop check, WHILE " Link "Introduction.guide/WHILE loop" 22 } WHILE loop + @{" Loop termination " Link "Introduction.guide/WHILE loop" 61 } WHILE loop + @{" Loop, EXIT " Link "MoreExpressions.guide/EXIT statement" 0 } EXIT statement + @{" Loop, exiting " Link "MoreExpressions.guide/EXIT statement" 0 } EXIT statement + @{" Loop, FOR " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" Loop, general " Link "MoreExpressions.guide/LOOP block" 0 } LOOP block + @{" Loop, LOOP " Link "MoreExpressions.guide/LOOP block" 0 } LOOP block + @{" Loop, REPEAT..UNTIL " Link "Introduction.guide/REPEAT..UNTIL loop" 0 } REPEAT..UNTIL loop + @{" Loop, terminate by jumping to a label " Link "MoreExpressions.guide/Labelling and the JUMP statement" 29 } Labelling and the JUMP statement + @{" Loop, WHILE " Link "Introduction.guide/WHILE loop" 0 } WHILE loop + @{" Lowercase a string " Link "Types.guide/String functions" 169 } String functions + @{" main procedure " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Making pointers " Link "Types.guide/Finding addresses (making pointers)" 0 } Finding addresses (making pointers) + @{" Manipulation, safe " Link "Types.guide/LIST and STRING Types" 0 } LIST and STRING Types + @{" Mapping a quoted expression over a list " Link "MoreExpressions.guide/Lists and quoted expressions" 8 } Lists and quoted expressions + @{" Matching patterns " Link "MoreExpressions.guide/Unification" 0 } Unification + @{" Mathematical operators " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Maths functions " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" Maximum " Link "BuiltIns.guide/Maths and logic functions" 49 } Maths and logic functions + @{" Maximum length of an E-list " Link "Types.guide/List functions" 59 } List functions + @{" Maximum length of an E-string " Link "Types.guide/String functions" 131 } String functions + @{" Memory address " Link "Types.guide/Memory addresses" 0 } Memory addresses + @{" Memory address " Link "Types.guide/Addresses" 0 } Addresses + @{" Memory, allocating " Link "BuiltIns.guide/System support functions" 0 } System support functions + @{" Memory, allocation " Link "Memory.guide/main" 0 } Memory Allocation + @{" Memory, deallocate " Link "BuiltIns.guide/System support functions" 39 } System support functions + @{" Memory, deallocate complex " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Memory, deallocation " Link "Memory.guide/Deallocation of Memory" 0 } Deallocation of Memory + @{" Memory, dynamic (typed) allocation " Link "Memory.guide/NEW and END Operators" 0 } NEW and END Operators + @{" Memory, dynamic allocation " Link "Memory.guide/Dynamic Allocation" 0 } Dynamic Allocation + @{" Memory, free " Link "BuiltIns.guide/System support functions" 39 } System support functions + @{" Memory, free complex " Link "BuiltIns.guide/System support functions" 44 } System support functions + @{" Memory, reading " Link "BuiltIns.guide/Maths and logic functions" 116 } Maths and logic functions + @{" Memory, sharing " Link "Appendices.guide/Assignment and Copying" 41 } Assignment and Copying + @{" Memory, static allocation " Link "Memory.guide/Static Allocation" 0 } Static Allocation + @{" Memory, writing " Link "BuiltIns.guide/Maths and logic functions" 123 } Maths and logic functions + @{" Method (OOP) " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Method, abstract " Link "OOE.guide/Inheritance in E" 275 } Inheritance in E + @{" Method, calling " Link "OOE.guide/Methods in E" 28 } Methods in E + @{" Method, constructor " Link "OOE.guide/Classes and methods" 20 } Classes and methods + @{" Method, destructor " Link "OOE.guide/Classes and methods" 20 } Classes and methods + @{" Method, end " Link "OOE.guide/Methods in E" 118 } Methods in E + @{" Method, overriding " Link "OOE.guide/Inheritance in E" 96 } Inheritance in E + @{" Method, PROC..OF " Link "OOE.guide/Methods in E" 0 } Methods in E + @{" Method, self local variable " Link "OOE.guide/Methods in E" 67 } Methods in E + @{" Middle copy of a string " Link "Types.guide/String functions" 144 } String functions + @{" Minimum " Link "BuiltIns.guide/Maths and logic functions" 52 } Maths and logic functions + @{" Mnemonics, Assembly " Link "MoreExpressions.guide/Assembly Statements" 0 } Assembly Statements + @{" Module " Link "Modules.guide/main" 0 } Modules + @{" Module, Amiga system " Link "Modules.guide/Amiga System Modules" 0 } Amiga System Modules + @{" Module, code " Link "Modules.guide/Code Modules" 0 } Code Modules + @{" Module, convert from include, header or pragma file " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Module, example use " Link "Modules.guide/Example Module Use" 0 } Example Module Use + @{" Module, non-standard " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Module, using " Link "Modules.guide/Using Modules" 0 } Using Modules + @{" Module, view contents " Link "Modules.guide/Using Modules" 19 } Using Modules + @{" Modules and classes " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" Modulus " Link "BuiltIns.guide/Maths and logic functions" 70 } Maths and logic functions + @{" Mouse button flags " Link "BuiltIns.guide/Intuition support functions" 244 } Intuition support functions + @{" Mouse buttons state " Link "BuiltIns.guide/Intuition support functions" 235 } Intuition support functions + @{" Mouse click, left button " Link "BuiltIns.guide/Intuition support functions" 273 } Intuition support functions + @{" Mouse click, left button (wait) " Link "BuiltIns.guide/Intuition support functions" 324 } Intuition support functions + @{" Mouse x-coordinate " Link "BuiltIns.guide/Intuition support functions" 259 } Intuition support functions + @{" Mouse y-coordinate " Link "BuiltIns.guide/Intuition support functions" 266 } Intuition support functions + @{" Multiple return values " Link "Procedures.guide/Multiple Return Values" 0 } Multiple Return Values + @{" Multiple-assignment " Link "Procedures.guide/Multiple Return Values" 12 } Multiple Return Values + @{" Multiplication " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Multiplication, 32-bit " Link "BuiltIns.guide/Maths and logic functions" 0 } Maths and logic functions + @{" Mutual recursion " Link "Recursion.guide/Mutual Recursion" 0 } Mutual Recursion + @{" Named constant " Link "Constants.guide/Named Constants" 0 } Named Constants + @{" Named data " Link "Introduction.guide/Variables and Expressions" 0 } Variables and Expressions + @{" Named elements " Link "Types.guide/OBJECT Type" 0 } OBJECT Type + @{" Names of constructors " Link "OOE.guide/Methods in E" 78 } Methods in E + @{" Names of local variables " Link "Introduction.guide/Global and local variables" 32 } Global and local variables + @{" Natural logarithm " Link "FloatingPoint.guide/Floating-Point Functions" 73 } Floating-Point Functions + @{" Nested comment " Link "Format.guide/Comments" 7 } Comments + @{" Nested IF blocks " Link "Introduction.guide/IF block" 74 } IF block + @{" Next element of a linked list " Link "Types.guide/Linked Lists" 38 } Linked Lists + @{" Node " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Non-standard module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Normal list " Link "Types.guide/Lists and E-lists" 0 } Lists and E-lists + @{" Normal list, selecting an element " Link "Types.guide/List functions" 65 } List functions + @{" Normal string " Link "Types.guide/Normal strings and E-strings" 0 } Normal strings and E-strings + @{" Not " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" Null character " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Number, even " Link "BuiltIns.guide/Maths and logic functions" 41 } Maths and logic functions + @{" Number, extracting from a string " Link "Types.guide/String functions" 199 } String functions + @{" Number, floating-point " Link "FloatingPoint.guide/main" 0 } Floating-Point Numbers + @{" Number, odd " Link "BuiltIns.guide/Maths and logic functions" 45 } Maths and logic functions + @{" Number, printing " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Number, printing (simple) " Link "Introduction.guide/Changing the example" 18 } Changing the example + @{" Number, quick random " Link "BuiltIns.guide/Maths and logic functions" 93 } Maths and logic functions + @{" Number, random " Link "BuiltIns.guide/Maths and logic functions" 84 } Maths and logic functions + @{" Number, real " Link "FloatingPoint.guide/main" 0 } Floating-Point Numbers + @{" Number, signed or unsigned " Link "Appendices.guide/Signed and Unsigned Values" 0 } Signed and Unsigned Values + @{" Numbered elements of an array " Link "Types.guide/Accessing array data" 0 } Accessing array data + @{" Numeric constant " Link "Constants.guide/Numeric Constants" 0 } Numeric Constants + @{" Object " Link "Types.guide/OBJECT Type" 0 } OBJECT Type + @{" Object (OOP) " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Object element types " Link "Types.guide/Element selection and element types" 13 } Element selection and element types + @{" Object elements, private " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" Object elements, public " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" Object pointer " Link "Types.guide/Element selection and element types" 8 } Element selection and element types + @{" Object selection, use of ++ and - " Link "Types.guide/Element selection and element types" 44 } Element selection and element types + @{" Object, allocation " Link "OOE.guide/Objects in E" 17 } Objects in E + @{" Object, Amiga system " Link "Types.guide/Amiga system objects" 0 } Amiga system objects + @{" Object, deallocation " Link "OOE.guide/Objects in E" 31 } Objects in E + @{" Object, element selection " Link "Types.guide/Element selection and element types" 0 } Element selection and element types + @{" Object, named elements " Link "Types.guide/OBJECT Type" 0 } OBJECT Type + @{" Object, size " Link "MoreExpressions.guide/SIZEOF expression" 0 } SIZEOF expression + @{" OBJECT..OF, inheritance " Link "OOE.guide/Inheritance in E" 0 } Inheritance in E + @{" Odd number " Link "BuiltIns.guide/Maths and logic functions" 45 } Maths and logic functions + @{" One-line function " Link "Procedures.guide/One-Line Functions" 0 } One-Line Functions + @{" OOP, class " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" OOP, derivation " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" OOP, inheritance " Link "OOE.guide/Inheritance" 0 } Inheritance + @{" OOP, method " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" OOP, object " Link "OOE.guide/Classes and methods" 0 } Classes and methods + @{" Open screen " Link "BuiltIns.guide/Intuition support functions" 129 } Intuition support functions + @{" Open window " Link "BuiltIns.guide/Intuition support functions" 16 } Intuition support functions + @{" Operator precedence " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Operator, SUPER " Link "OOE.guide/Inheritance in E" 110 } Inheritance in E + @{" Operators, comparison " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Operators, logic " Link "Introduction.guide/Logic and comparison" 11 } Logic and comparison + @{" Operators, mathematical " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Option, set constant " Link "Constants.guide/Sets" 0 } Sets + @{" Optional return values " Link "Procedures.guide/Multiple Return Values" 32 } Multiple Return Values + @{" Or " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" OR, bit-wise " Link "MoreExpressions.guide/Bitwise AND and OR" 0 } Bitwise AND and OR + @{" Or, exclusive " Link "BuiltIns.guide/Maths and logic functions" 14 } Maths and logic functions + @{" OR-ing flags " Link "Constants.guide/Sets" 19 } Sets + @{" Output a character " Link "BuiltIns.guide/Input and output functions" 99 } Input and output functions + @{" Output functions " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Output text " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Output window " Link "BuiltIns.guide/Built-In Variables" 34 } Built-In Variables + @{" Overlapping conditions " Link "Introduction.guide/IF block" 80 } IF block + @{" Overriding methods " Link "OOE.guide/Inheritance in E" 96 } Inheritance in E + @{" Pad byte " Link "MoreExpressions.guide/SIZEOF expression" 17 } SIZEOF expression + @{" Parameter " Link "Introduction.guide/Parameters" 0 } Parameters + @{" Parameter variable " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Parameter, default " Link "Procedures.guide/Default Arguments" 0 } Default Arguments + @{" Parameter, procedure local variables " Link "Introduction.guide/Global and local variables" 62 } Global and local variables + @{" Parentheses and expressions " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Parsing command line arguments " Link "Examples.guide/Argument Parsing" 0 } Argument Parsing + @{" Pattern matching " Link "MoreExpressions.guide/Unification" 0 } Unification + @{" Peeking memory " Link "BuiltIns.guide/Maths and logic functions" 116 } Maths and logic functions + @{" Pen colour, setting " Link "BuiltIns.guide/Graphics functions" 49 } Graphics functions + @{" Pen, setting foreground and background colour " Link "BuiltIns.guide/Graphics functions" 35 } Graphics functions + @{" Place-holder, decimal \d " Link "Introduction.guide/Changing the example" 18 } Changing the example + @{" Place-holder, field formatting " Link "BuiltIns.guide/Input and output functions" 37 } Input and output functions + @{" Place-holder, field size " Link "BuiltIns.guide/Input and output functions" 37 } Input and output functions + @{" Place-holders " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Plot a point " Link "BuiltIns.guide/Graphics functions" 16 } Graphics functions + @{" Point, plot " Link "BuiltIns.guide/Graphics functions" 16 } Graphics functions + @{" Pointer " Link "Types.guide/PTR Type" 0 } PTR Type + @{" Pointer (array) and array declaration " Link "Types.guide/Array pointers" 46 } Array pointers + @{" Pointer analogy " Link "Types.guide/Addresses" 10 } Addresses + @{" Pointer diagram " Link "Types.guide/Addresses" 37 } Addresses + @{" Pointer type " Link "Types.guide/PTR Type" 0 } PTR Type + @{" Pointer, array " Link "Types.guide/Array pointers" 0 } Array pointers + @{" Pointer, common use " Link "Types.guide/Extracting data (dereferencing pointers)" 90 } Extracting data (dereferencing pointers) + @{" Pointer, dereference " Link "Types.guide/Extracting data (dereferencing pointers)" 0 } Extracting data (dereferencing pointers) + @{" Pointer, making " Link "Types.guide/Finding addresses (making pointers)" 0 } Finding addresses (making pointers) + @{" Pointer, object " Link "Types.guide/Element selection and element types" 8 } Element selection and element types + @{" Pointer, sharing memory " Link "Appendices.guide/Assignment and Copying" 41 } Assignment and Copying + @{" Poking memory " Link "BuiltIns.guide/Maths and logic functions" 123 } Maths and logic functions + @{" Polymorphism " Link "OOE.guide/Inheritance in E" 147 } Inheritance in E + @{" Potential problems using Assembly " Link "MoreExpressions.guide/Things to watch out for" 0 } Things to watch out for + @{" Pragma file, convert to module " Link "Modules.guide/Non-Standard Modules" 0 } Non-Standard Modules + @{" Precedence, operators " Link "Introduction.guide/Precedence and grouping" 0 } Precedence and grouping + @{" Printing characters " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Printing decimal numbers " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Printing hexadecimal numbers " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Printing numbers " Link "Introduction.guide/Changing the example" 18 } Changing the example + @{" Printing strings " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Printing text " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" Printing to an E-string " Link "BuiltIns.guide/Input and output functions" 90 } Input and output functions + @{" Private, object elements " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" Problems, common " Link "Appendices.guide/main" 0 } Common Problems + @{" PROC..OF, method " Link "OOE.guide/Methods in E" 0 } Methods in E + @{" Procedure " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Procedure argument " Link "Introduction.guide/Parameters" 0 } Parameters + @{" Procedure parameter " Link "Introduction.guide/Parameters" 0 } Parameters + @{" Procedure parameter local variables " Link "Introduction.guide/Global and local variables" 62 } Global and local variables + @{" Procedure parameter types " Link "Types.guide/Procedure parameters" 0 } Procedure parameters + @{" Procedure parameter variable " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Procedure parameter, array " Link "Types.guide/Array procedure parameters" 0 } Array procedure parameters + @{" Procedure parameter, default " Link "Procedures.guide/Default Arguments" 0 } Default Arguments + @{" Procedure with parameters, definition " Link "Introduction.guide/Global and local variables" 62 } Global and local variables + @{" Procedure, calling " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Procedure, calling " Link "Introduction.guide/Procedure Execution" 0 } Procedure Execution + @{" Procedure, definition " Link "Introduction.guide/Procedure Definition" 0 } Procedure Definition + @{" Procedure, early termination " Link "Procedures.guide/Functions" 32 } Functions + @{" Procedure, exception handler " Link "Exceptions.guide/Procedures with Exception Handlers" 0 } Procedures with Exception Handlers + @{" Procedure, execution " Link "Introduction.guide/Procedure Execution" 0 } Procedure Execution + @{" Procedure, inlining " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Procedure, recent " Link "Exceptions.guide/Raising an Exception" 87 } Raising an Exception + @{" Procedure, return value " Link "Procedures.guide/Functions" 0 } Functions + @{" Procedure, reuse " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Procedure, running " Link "Introduction.guide/Procedure Execution" 0 } Procedure Execution + @{" Procedure, running " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Procedure, style " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Procedure, use in Assembly " Link "MoreExpressions.guide/Assembly and the E language" 28 } Assembly and the E language + @{" Program flow control " Link "Introduction.guide/Program Flow Control" 0 } Program Flow Control + @{" Program termination " Link "BuiltIns.guide/System support functions" 65 } System support functions + @{" Program, finish " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Program, running " Link "Introduction.guide/Execution" 0 } Execution + @{" Program, start " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Pseudo-random number " Link "BuiltIns.guide/Maths and logic functions" 84 } Maths and logic functions + @{" Public, object elements " Link "OOE.guide/Data-Hiding in E" 0 } Data-Hiding in E + @{" qual part of Intuition message " Link "BuiltIns.guide/Intuition support functions" 321 } Intuition support functions + @{" Quick random number " Link "BuiltIns.guide/Maths and logic functions" 93 } Maths and logic functions + @{" Quotable expressions " Link "MoreExpressions.guide/Quotable expressions" 0 } Quotable expressions + @{" Quoted expression " Link "MoreExpressions.guide/Quoted Expressions" 0 } Quoted Expressions + @{" Quoted expression, evaluation " Link "MoreExpressions.guide/Evaluation" 0 } Evaluation + @{" Quoted expression, for all list elements " Link "MoreExpressions.guide/Lists and quoted expressions" 29 } Lists and quoted expressions + @{" Quoted expression, local variables " Link "MoreExpressions.guide/Quotable expressions" 0 } Quotable expressions + @{" Quoted expression, mapping over a list " Link "MoreExpressions.guide/Lists and quoted expressions" 8 } Lists and quoted expressions + @{" Quoted expression, there exists a list element " Link "MoreExpressions.guide/Lists and quoted expressions" 46 } Lists and quoted expressions + @{" Quoted expressions and lists " Link "MoreExpressions.guide/Lists and quoted expressions" 0 } Lists and quoted expressions + @{" Raising an exception " Link "Exceptions.guide/Raising an Exception" 0 } Raising an Exception + @{" Raising an exception from a handler " Link "Exceptions.guide/Raise within an Exception Handler" 0 } Raise within an Exception Handler + @{" Raising to a power " Link "FloatingPoint.guide/Floating-Point Functions" 66 } Floating-Point Functions + @{" Random number " Link "BuiltIns.guide/Maths and logic functions" 84 } Maths and logic functions + @{" Random number, quick " Link "BuiltIns.guide/Maths and logic functions" 93 } Maths and logic functions + @{" Range of floating-point numbers " Link "FloatingPoint.guide/Accuracy and Range" 0 } Accuracy and Range + @{" ReadArgs, using " Link "Examples.guide/AmigaDOS 2.0 (and above)" 0 } AmigaDOS 2.0 (and above) + @{" Reading a character from a file " Link "BuiltIns.guide/Input and output functions" 109 } Input and output functions + @{" Reading a string from a file " Link "BuiltIns.guide/Input and output functions" 114 } Input and output functions + @{" Reading from memory " Link "BuiltIns.guide/Maths and logic functions" 116 } Maths and logic functions + @{" Reading, further " Link "Appendices.guide/Further Reading" 0 } Further Reading + @{" Real number " Link "FloatingPoint.guide/main" 0 } Floating-Point Numbers + @{" Recent procedure " Link "Exceptions.guide/Raising an Exception" 87 } Raising an Exception + @{" Recursion " Link "Recursion.guide/main" 0 } Recursion + @{" Recursion example " Link "Examples.guide/Recursion Example" 0 } Recursion Example + @{" Recursion, mutual " Link "Recursion.guide/Mutual Recursion" 0 } Mutual Recursion + @{" Recursive case " Link "Recursion.guide/Factorial Example" 44 } Factorial Example + @{" Recursive exception handling " Link "Recursion.guide/Stack and Exceptions" 9 } Stack and Exceptions + @{" Recursive function " Link "Recursion.guide/main" 0 } Recursion + @{" Recursive type " Link "Recursion.guide/main" 0 } Recursion + @{" Registers, A4 and A5 " Link "MoreExpressions.guide/Things to watch out for" 11 } Things to watch out for + @{" Regular return value " Link "Procedures.guide/Multiple Return Values" 32 } Multiple Return Values + @{" Remainder " Link "BuiltIns.guide/Maths and logic functions" 70 } Maths and logic functions + @{" REPEAT..UNTIL loop " Link "Introduction.guide/REPEAT..UNTIL loop" 0 } REPEAT..UNTIL loop + @{" REPEAT..UNTIL loop check " Link "Introduction.guide/REPEAT..UNTIL loop" 18 } REPEAT..UNTIL loop + @{" REPEAT..UNTIL loop version of a FOR loop " Link "Introduction.guide/REPEAT..UNTIL loop" 17 } REPEAT..UNTIL loop + @{" Repeated execution " Link "Introduction.guide/Loops" 0 } Loops + @{" Resolution flags " Link "BuiltIns.guide/Intuition support functions" 171 } Intuition support functions + @{" Return value of a function " Link "Procedures.guide/Functions" 0 } Functions + @{" Return value, optional " Link "Procedures.guide/Multiple Return Values" 32 } Multiple Return Values + @{" Return value, regular " Link "Procedures.guide/Multiple Return Values" 32 } Multiple Return Values + @{" Return values, multiple " Link "Procedures.guide/Multiple Return Values" 0 } Multiple Return Values + @{" Reusing code " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Reusing procedures " Link "Introduction.guide/Style Reuse and Readability" 0 } Style Reuse and Readability + @{" Revision, Kickstart " Link "BuiltIns.guide/System support functions" 84 } System support functions + @{" Rewriting a FOR loop as a REPEAT..UNTIL loop " Link "Introduction.guide/REPEAT..UNTIL loop" 17 } REPEAT..UNTIL loop + @{" Rewriting a FOR loop as a WHILE loop " Link "Introduction.guide/WHILE loop" 17 } WHILE loop + @{" Rewriting SELECT block as IF block " Link "Introduction.guide/SELECT block" 23 } SELECT block + @{" Rewriting SELECT..OF block as IF block " Link "Introduction.guide/SELECT..OF block" 71 } SELECT..OF block + @{" Right shift " Link "BuiltIns.guide/Maths and logic functions" 108 } Maths and logic functions + @{" Right-hand copy of an E-string " Link "Types.guide/String functions" 136 } String functions + @{" Right-justify field " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + @{" Root " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Rounding a floating-point value " Link "FloatingPoint.guide/Floating-Point Functions" 59 } Floating-Point Functions + @{" Rules, format and layout " Link "Format.guide/main" 0 } Format and Layout + @{" Running a method " Link "OOE.guide/Methods in E" 28 } Methods in E + @{" Running a procedure " Link "Introduction.guide/Procedures" 0 } Procedures + @{" Running a program " Link "Introduction.guide/Execution" 0 } Execution + @{" Safe manipulation " Link "Types.guide/LIST and STRING Types" 0 } LIST and STRING Types + @{" Same names of local variables " Link "Introduction.guide/Global and local variables" 32 } Global and local variables + @{" Screen example, with handler " Link "Examples.guide/Screens" 71 } Screens + @{" Screen example, without handler " Link "Examples.guide/Screens" 0 } Screens + @{" Screen resolution flags " Link "BuiltIns.guide/Intuition support functions" 171 } Intuition support functions + @{" Screen, close " Link "BuiltIns.guide/Intuition support functions" 178 } Intuition support functions + @{" Screen, open " Link "BuiltIns.guide/Intuition support functions" 129 } Intuition support functions + @{" Seed of a random sequence " Link "BuiltIns.guide/Maths and logic functions" 93 } Maths and logic functions + @{" SELECT block " Link "Introduction.guide/SELECT block" 0 } SELECT block + @{" SELECT block, rewriting as IF block " Link "Introduction.guide/SELECT block" 23 } SELECT block + @{" SELECT..OF block " Link "Introduction.guide/SELECT..OF block" 0 } SELECT..OF block + @{" SELECT..OF block, rewriting as IF block " Link "Introduction.guide/SELECT..OF block" 71 } SELECT..OF block + @{" SELECT..OF block, speed versus size " Link "Introduction.guide/SELECT..OF block" 90 } SELECT..OF block + @{" Selecting an element of a normal list " Link "Types.guide/List functions" 65 } List functions + @{" Selecting an element of an object " Link "Types.guide/Element selection and element types" 0 } Element selection and element types + @{" Selection, use of ++ and - " Link "Types.guide/Element selection and element types" 44 } Element selection and element types + @{" self, method local variable " Link "OOE.guide/Methods in E" 67 } Methods in E + @{" Separators " Link "Format.guide/Spacing and Separators" 0 } Spacing and Separators + @{" Sequencing expressions " Link "MoreExpressions.guide/BUT expression" 0 } BUT expression + @{" Sequential composition " Link "Format.guide/Statements" 18 } Statements + @{" Set " Link "Constants.guide/Sets" 0 } Sets + @{" Set length of an E-string " Link "Types.guide/String functions" 178 } String functions + @{" Setting foreground and background pen colours " Link "BuiltIns.guide/Graphics functions" 35 } Graphics functions + @{" Setting pen colours " Link "BuiltIns.guide/Graphics functions" 49 } Graphics functions + @{" Setting stdin " Link "BuiltIns.guide/Input and output functions" 161 } Input and output functions + @{" Setting stdout " Link "BuiltIns.guide/Input and output functions" 170 } Input and output functions + @{" Setting stdrast " Link "BuiltIns.guide/Graphics functions" 58 } Graphics functions + @{" Setting the length of an E-list " Link "Types.guide/List functions" 62 } List functions + @{" Setting Topaz font " Link "BuiltIns.guide/Graphics functions" 67 } Graphics functions + @{" Sharing memory " Link "Appendices.guide/Assignment and Copying" 41 } Assignment and Copying + @{" Shift left " Link "BuiltIns.guide/Maths and logic functions" 100 } Maths and logic functions + @{" Shift right " Link "BuiltIns.guide/Maths and logic functions" 108 } Maths and logic functions + @{" Short-hand for first element of an array " Link "Types.guide/Accessing array data" 55 } Accessing array data + @{" Show module contents " Link "Modules.guide/Using Modules" 19 } Using Modules + @{" Side-effects " Link "MoreExpressions.guide/Side-effects" 0 } Side-effects + @{" Sign of a number " Link "BuiltIns.guide/Maths and logic functions" 36 } Maths and logic functions + @{" Signed and unsigned values " Link "Appendices.guide/Signed and Unsigned Values" 0 } Signed and Unsigned Values + @{" Sine function " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Singly linked list " Link "Types.guide/Linked Lists" 64 } Linked Lists + @{" Size of an array " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Size of an object " Link "MoreExpressions.guide/SIZEOF expression" 0 } SIZEOF expression + @{" Size versus speed, SELECT..OF block " Link "Introduction.guide/SELECT..OF block" 90 } SELECT..OF block + @{" Spacing " Link "Format.guide/Spacing and Separators" 0 } Spacing and Separators + @{" Special character sequences " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Speed versus size, SELECT..OF block " Link "Introduction.guide/SELECT..OF block" 90 } SELECT..OF block + @{" Splitting a string over several lines " Link "Format.guide/Statements" 58 } Statements + @{" Splitting statements over several lines " Link "Format.guide/Statements" 30 } Statements + @{" Square root " Link "FloatingPoint.guide/Floating-Point Functions" 63 } Floating-Point Functions + @{" Stack and crashing " Link "Recursion.guide/Stack (and Crashing)" 0 } Stack (and Crashing) + @{" Stack and exceptions " Link "Recursion.guide/Stack and Exceptions" 0 } Stack and Exceptions + @{" Stack space, free " Link "BuiltIns.guide/System support functions" 79 } System support functions + @{" Stack, avoiding crashes " Link "Recursion.guide/Stack (and Crashing)" 21 } Stack (and Crashing) + @{" State of mouse buttons " Link "BuiltIns.guide/Intuition support functions" 235 } Intuition support functions + @{" Statement " Link "Format.guide/Statements" 0 } Statements + @{" Statement, Assembly " Link "MoreExpressions.guide/Assembly Statements" 0 } Assembly Statements + @{" Statement, breaking " Link "Format.guide/Statements" 30 } Statements + @{" Statement, conversion from an expression " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" Statement, several on one line " Link "Format.guide/Statements" 18 } Statements + @{" Statement, splitting " Link "Format.guide/Statements" 30 } Statements + @{" Static data " Link "Types.guide/Static data" 0 } Static data + @{" Static data, potential problems " Link "Types.guide/Static data" 22 } Static data + @{" Static memory allocation " Link "Memory.guide/Static Allocation" 0 } Static Allocation + @{" Static memory, use in Assembly " Link "MoreExpressions.guide/Static memory" 0 } Static memory + @{" stdin, setting " Link "BuiltIns.guide/Input and output functions" 161 } Input and output functions + @{" stdout, setting " Link "BuiltIns.guide/Input and output functions" 170 } Input and output functions + @{" stdrast, setting " Link "BuiltIns.guide/Graphics functions" 58 } Graphics functions + @{" String " Link "Introduction.guide/Strings" 0 } Strings + @{" String " Link "Types.guide/Normal strings and E-strings" 0 } Normal strings and E-strings + @{" String diagram " Link "Types.guide/Normal strings and E-strings" 38 } Normal strings and E-strings + @{" String functions " Link "Types.guide/String functions" 0 } String functions + @{" String handling example " Link "Examples.guide/String Handling and I-O" 0 } String Handling and I-O + @{" String handling example, with handler " Link "Examples.guide/String Handling and I-O" 307 } String Handling and I-O + @{" STRING type " Link "Types.guide/Normal strings and E-strings" 49 } Normal strings and E-strings + @{" String, append " Link "Types.guide/String functions" 99 } String functions + @{" String, breaking " Link "Format.guide/Statements" 58 } Statements + @{" String, comparison " Link "Types.guide/String functions" 40 } String functions + @{" String, constant " Link "Types.guide/Normal strings and E-strings" 0 } Normal strings and E-strings + @{" String, converting to floating-point number " Link "FloatingPoint.guide/Floating-Point Functions" 10 } Floating-Point Functions + @{" String, converting to numbers " Link "Types.guide/String functions" 199 } String functions + @{" String, copying " Link "Types.guide/String functions" 58 } String functions + @{" String, find sub-string " Link "Types.guide/String functions" 156 } String functions + @{" String, length " Link "Types.guide/String functions" 108 } String functions + @{" String, lowercase " Link "Types.guide/String functions" 169 } String functions + @{" String, middle copy " Link "Types.guide/String functions" 144 } String functions + @{" String, printing " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" String, right-hand copy " Link "Types.guide/String functions" 136 } String functions + @{" String, special character sequence " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" String, splitting " Link "Format.guide/Statements" 58 } Statements + @{" String, trim leading whitespace " Link "Types.guide/String functions" 161 } String functions + @{" String, uppercase " Link "Types.guide/String functions" 174 } String functions + @{" Structure " Link "Types.guide/OBJECT Type" 0 } OBJECT Type + @{" Sub-string location in a string " Link "Types.guide/String functions" 156 } String functions + @{" Subtraction " Link "Introduction.guide/Mathematics" 0 } Mathematics + @{" Successful, zero exception " Link "Exceptions.guide/Raising an Exception" 73 } Raising an Exception + @{" Summary of Part One " Link "Introduction.guide/Summary" 0 } Summary + @{" Super class " Link "OOE.guide/Inheritance in E" 161 } Inheritance in E + @{" SUPER, operator " Link "OOE.guide/Inheritance in E" 110 } Inheritance in E + @{" System function, calling from Assembly " Link "MoreExpressions.guide/Assembly and the E language" 39 } Assembly and the E language + @{" System module " Link "Modules.guide/Amiga System Modules" 0 } Amiga System Modules + @{" System objects " Link "Types.guide/Amiga system objects" 0 } Amiga system objects + @{" System support functions " Link "BuiltIns.guide/System support functions" 0 } System support functions + @{" System variables " Link "BuiltIns.guide/Built-In Variables" 0 } Built-In Variables + @{" Tab character " Link "Constants.guide/String Constants Special Character Sequences" 0 } String Constants Special Character Sequences + @{" Table of data " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Tag list " Link "Types.guide/Lists and E-lists" 42 } Lists and E-lists + @{" Tail of a linked list " Link "Types.guide/Linked Lists" 23 } Linked Lists + @{" Tangent function " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Terminating loops " Link "Introduction.guide/WHILE loop" 61 } WHILE loop + @{" Termination, program " Link "BuiltIns.guide/System support functions" 65 } System support functions + @{" Test for control-C " Link "BuiltIns.guide/System support functions" 74 } System support functions + @{" Test for even number " Link "BuiltIns.guide/Maths and logic functions" 41 } Maths and logic functions + @{" Test for odd number " Link "BuiltIns.guide/Maths and logic functions" 45 } Maths and logic functions + @{" Text drawing " Link "BuiltIns.guide/Graphics functions" 42 } Graphics functions + @{" Text, printing " Link "BuiltIns.guide/Input and output functions" 0 } Input and output functions + @{" There exists a list element " Link "MoreExpressions.guide/Lists and quoted expressions" 46 } Lists and quoted expressions + @{" Throwing an exception " Link "Exceptions.guide/Raising an Exception" 0 } Raising an Exception + @{" Timing expressions example " Link "Examples.guide/Timing Expressions" 0 } Timing Expressions + @{" Tinkering " Link "Introduction.guide/Tinkering with the example" 0 } Tinkering with the example + @{" Topaz, setting font " Link "BuiltIns.guide/Graphics functions" 67 } Graphics functions + @{" Tree, binary " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Tree, branch " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Tree, leaf " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Tree, node " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Tree, root " Link "Recursion.guide/Binary Trees" 0 } Binary Trees + @{" Trigonometry functions " Link "FloatingPoint.guide/Floating-Point Functions" 51 } Floating-Point Functions + @{" Trim leading whitespace from a string " Link "Types.guide/String functions" 161 } String functions + @{" Trouble-shooting " Link "Appendices.guide/main" 0 } Common Problems + @{" Truth values as numbers " Link "Introduction.guide/Logic and comparison" 36 } Logic and comparison + @{" Turn an expression into a statement " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" Type " Link "Types.guide/main" 0 } Types + @{" Type of a variable " Link "Introduction.guide/Variable types" 0 } Variable types + @{" Type, 16-bit " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Type, 32-bit " Link "Types.guide/Default type" 0 } Default type + @{" Type, 8-bit " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Type, address " Link "Types.guide/Addresses" 0 } Addresses + @{" Type, array " Link "Types.guide/Tables of data" 0 } Tables of data + @{" Type, complex " Link "Types.guide/Complex types" 0 } Complex types + @{" Type, default " Link "Types.guide/Default type" 0 } Default type + @{" Type, direct " Link "Types.guide/Indirect types" 21 } Indirect types + @{" Type, dynamic " Link "OOE.guide/Inheritance in E" 147 } Inheritance in E + @{" Type, E-list " Link "Types.guide/Lists and E-lists" 0 } Lists and E-lists + @{" Type, indirect " Link "Types.guide/Indirect types" 0 } Indirect types + @{" Type, list " Link "Types.guide/Lists and E-lists" 0 } Lists and E-lists + @{" Type, LONG " Link "Types.guide/LONG Type" 0 } LONG Type + @{" Type, LONG (definition) " Link "Types.guide/Indirect types" 21 } Indirect types + @{" Type, object " Link "Types.guide/OBJECT Type" 0 } OBJECT Type + @{" Type, object elements " Link "Types.guide/Element selection and element types" 13 } Element selection and element types + @{" Type, pointer " Link "Types.guide/PTR Type" 0 } PTR Type + @{" Type, procedure parameters " Link "Types.guide/Procedure parameters" 0 } Procedure parameters + @{" Type, recursive " Link "Recursion.guide/main" 0 } Recursion + @{" Type, STRING " Link "Types.guide/Normal strings and E-strings" 49 } Normal strings and E-strings + @{" Type, variable declaration " Link "Types.guide/Default type" 15 } Default type + @{" Typed list " Link "Types.guide/Typed lists" 0 } Typed lists + @{" Unification " Link "MoreExpressions.guide/Unification" 0 } Unification + @{" Unsigned and signed values " Link "Appendices.guide/Signed and Unsigned Values" 0 } Signed and Unsigned Values + @{" Uppercase a string " Link "Types.guide/String functions" 174 } String functions + @{" Using a module " Link "Modules.guide/Using Modules" 0 } Using Modules + @{" Using arg " Link "Examples.guide/Any AmigaDOS" 0 } Any AmigaDOS + @{" Using modules, example " Link "Modules.guide/Example Module Use" 0 } Example Module Use + @{" Using ReadArgs " Link "Examples.guide/AmigaDOS 2.0 (and above)" 0 } AmigaDOS 2.0 (and above) + @{" Using wbmessage " Link "Examples.guide/Any AmigaDOS" 0 } Any AmigaDOS + @{" van Oortmerssen, Wouter " Link "Appendices.guide/Amiga E Author" 0 } Amiga E Author + @{" Variable " Link "Introduction.guide/Variables and Expressions" 0 } Variables and Expressions + @{" Variable initialisation and automatic exceptions " Link "Exceptions.guide/Raise within an Exception Handler" 54 } Raise within an Exception Handler + @{" Variable type " Link "Types.guide/Default type" 15 } Default type + @{" Variable, built-in " Link "BuiltIns.guide/Built-In Variables" 0 } Built-In Variables + @{" Variable, changing value " Link "Introduction.guide/Assignment" 0 } Assignment + @{" Variable, declaration " Link "Introduction.guide/Variable declaration" 0 } Variable declaration + @{" Variable, decrement " Link "MoreExpressions.guide/INC and DEC statements" 0 } INC and DEC statements + @{" Variable, global " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Variable, increment " Link "MoreExpressions.guide/INC and DEC statements" 0 } INC and DEC statements + @{" Variable, initialisation " Link "Introduction.guide/Global and local variables" 109 } Global and local variables + @{" Variable, local " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Variable, procedure parameter " Link "Introduction.guide/Global and local variables" 0 } Global and local variables + @{" Variable, same global and local names " Link "Introduction.guide/Global and local variables" 57 } Global and local variables + @{" Variable, same local names " Link "Introduction.guide/Global and local variables" 32 } Global and local variables + @{" Variable, system " Link "BuiltIns.guide/Built-In Variables" 0 } Built-In Variables + @{" Variable, type " Link "Introduction.guide/Variable types" 0 } Variable types + @{" Variable, use in Assembly statements " Link "MoreExpressions.guide/Assembly and the E language" 0 } Assembly and the E language + @{" Version, Kickstart " Link "BuiltIns.guide/System support functions" 84 } System support functions + @{" Vertical FOR loop " Link "Introduction.guide/FOR loop" 0 } FOR loop + @{" Vertical IF block " Link "Introduction.guide/IF block" 0 } IF block + @{" Vertical WHILE loop " Link "Introduction.guide/WHILE loop" 0 } WHILE loop + @{" View module contents " Link "Modules.guide/Using Modules" 19 } Using Modules + @{" Voiding an expression " Link "MoreExpressions.guide/Turning an Expression into a Statement" 0 } Turning an Expression into a Statement + @{" Voiding, automatic " Link "MoreExpressions.guide/Turning an Expression into a Statement" 20 } Turning an Expression into a Statement + @{" Wait for left mouse button click " Link "BuiltIns.guide/Intuition support functions" 324 } Intuition support functions + @{" Waiting for Intuition messages " Link "BuiltIns.guide/Intuition support functions" 282 } Intuition support functions + @{" wbmessage, using " Link "Examples.guide/Any AmigaDOS" 0 } Any AmigaDOS + @{" WHILE loop " Link "Introduction.guide/WHILE loop" 0 } WHILE loop + @{" WHILE loop check " Link "Introduction.guide/WHILE loop" 22 } WHILE loop + @{" WHILE loop version of a FOR loop " Link "Introduction.guide/WHILE loop" 17 } WHILE loop + @{" Whitespace " Link "Format.guide/Spacing and Separators" 0 } Spacing and Separators + @{" Whitespace, trim from a string " Link "Types.guide/String functions" 161 } String functions + @{" Window flags " Link "BuiltIns.guide/Intuition support functions" 89 } Intuition support functions + @{" Window, close " Link "BuiltIns.guide/Intuition support functions" 122 } Intuition support functions + @{" Window, open " Link "BuiltIns.guide/Intuition support functions" 16 } Intuition support functions + @{" Window, output " Link "BuiltIns.guide/Built-In Variables" 34 } Built-In Variables + @{" Wouter van Oortmerssen " Link "Appendices.guide/Amiga E Author" 0 } Amiga E Author + @{" Writing a character to file " Link "BuiltIns.guide/Input and output functions" 99 } Input and output functions + @{" Writing to memory " Link "BuiltIns.guide/Maths and logic functions" 123 } Maths and logic functions + @{" X-coordinate, mouse " Link "BuiltIns.guide/Intuition support functions" 259 } Intuition support functions + @{" Y-coordinate, mouse " Link "BuiltIns.guide/Intuition support functions" 266 } Intuition support functions + @{" Zero exception (success) " Link "Exceptions.guide/Raising an Exception" 73 } Raising an Exception + @{" Zero fill field " Link "BuiltIns.guide/Input and output functions" 54 } Input and output functions + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Index.guide.info b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Index.guide.info new file mode 100644 index 0000000..1e5b05b Binary files /dev/null and b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Index.guide.info differ diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Introduction.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Introduction.guide new file mode 100644 index 0000000..e3f61e4 --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Introduction.guide @@ -0,0 +1,1681 @@ +@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" "Introduction to Amiga E" +@Next "Understanding a Simple Program" +@Prev "Contents.guide/main" +@Toc "Contents.guide/main" + +Introduction to Amiga E +*********************** + + To interact with your Amiga you need to speak a language it understands. +Luckily, there is a wide choice of such languages, each of which fits a +particular need. For instance, BASIC (in most of its flavours) is simple +and easy to learn, and so is ideal for beginners. Assembly, on the other +hand, requires a lot of effort and is quite tedious, but can produce the +fastest programs so is generally used by commercial programmers. These +are two extremes and most businesses and colleges use C or +Pascal/Modula-2, which try to strike a balance between simplicity and +speed. + + E programs look very much like Pascal or Modula-2 programs, but E is +based more closely on C. Anyone familiar with these languages will easily +learn E, only really needing to get to grips with E's unique features and +those borrowed from other languages. This guide is aimed at people who +haven't done much programming and may be too trivial for competent +programmers, who should find the `E Reference Manual' more than adequate +(although some of the later sections offer different explanations to the +`Reference Manual', which may prove useful). + + Part One (this part) goes through some of the basics of the E language +and programming in general. Part Two delves deeper into E, covering the +more complex topics and the unique features of E. Part Three goes through +a few example programs, which are a bit longer than the examples in the +other Parts. Finally, Part Four contains the Appendices, which is where +you'll find some other, miscellaneous information. + + + @{" A Simple Program " Link "A Simple Program" } + + +@ENDNODE + +@NODE "A Simple Program" "A Simple Program" +@Toc "main" + +A Simple Program +================ + + If you're still reading you're probably desperate to do some +programming in E but you don't know how to start. We'll therefore jump +straight in the deep end with a small example. You'll need to know two +things before we start: how to use a text editor and the Shell/CLI. + + + @{" The code " Link "The code" } + @{" Compilation " Link "Compilation" } + @{" Execution " Link "Execution" } + + +@ENDNODE + +@NODE "The code" "The code" +@Next "Compilation" +@Toc "A Simple Program" + +The code +-------- + + Enter the following lines of code into a text editor and save it as the +file @{b }simple.e@{ub } (taking care to copy each line accurately). (Just type the +characters shown, and at the end of each line press the RETURN or ENTER +key.) + + PROC main() + WriteF('My first program') + ENDPROC + +Don't try to do anything different to the code, yet: the case of the +letters in each word is significant and the funny characters are important. +If you're a real beginner you might have difficulty finding the ' +character. On my GB keyboard it's on the big key in the top left-hand +corner directly below the ESC key. On a US and most European keyboards +it's two to the right of the L key, next to the ; key. (If you don't have +your keyboard set up properly then you find that keys don't produce the +same characters that are printed on them--especially when use use the +shift key. In this case it will probably behave like a US keyboard, +although you should really fix this and set it up properly--see the +manuals that came with your Amiga.) + + +@ENDNODE + +@NODE "Compilation" "Compilation" +@Next "Execution" +@Prev "The code" +@Toc "A Simple Program" + +Compilation +----------- + + Once the file is saved (preferably in the RAM disk, since it's only a +small program), you can use the E compiler to turn it into an executable +program. All you need is the file @{b }ec@{ub } in your @{b }C:@{ub } directory or somewhere +else on your search path (advanced users note: we don't need the @{b }Emodules:@{ub } +assignment because we aren't using any modules). Assuming you have this +and you have a Shell/CLI running, enter the following at the prompt after +changing directory to where you saved your new file: + + ec simple + +If all's well you should be greeted, briefly, by the E compiler. If +anything went wrong then double-check the contents of the file @{b }simple.e@{ub }, +that your CLI is in the same directory as this file, and that the program +@{b }ec@{ub } is in your @{b }C:@{ub } directory (or on your search path). + + +@ENDNODE + +@NODE "Execution" "Execution" +@Prev "Compilation" +@Toc "A Simple Program" + +Execution +--------- + + Once everything is working you can run your first program by entering +the following at the CLI prompt: + + simple + + As a help here's the complete transcript of the whole compilation and +execution process (the CLI prompt, below, is the bit of text beginning +with @{b }1.@{ub } and ending in @{b }>@{ub }): + + 1.System3.0:> cd ram: + 1.Ram Disk:> ec simple + Amiga E Compiler/Assembler/Linker/PP v3.2e registered (c) '91-95 Wouter + lexical analysing ... + parsing and compiling ... + no errors + 1.Ram Disk:> simple + My first program1.Ram Disk:> + +Your display should be something similar if it's all worked. Notice how +the output from the program runs into the prompt (the last line). We'll +fix this soon. + + +@ENDNODE + +@NODE "Understanding a Simple Program" "Understanding a Simple Program" +@Next "Variables and Expressions" +@Prev "main" +@Toc "Contents.guide/main" + +Understanding a Simple Program +****************************** + + To understand the example program we need to understand quite a few +things. The observant amongst you will have noticed that all it does is +print out a message, and that message was part of a line we wrote in the +program. The first thing to do is see how to change this message. + + + @{" Changing the Message " Link "Changing the Message" } + @{" Procedures " Link "Procedures" } + @{" Parameters " Link "Parameters" } + @{" Strings " Link "Strings" } + @{" Style Reuse and Readability " Link "Style Reuse and Readability" } + @{" The Simple Program " Link "The Simple Program" } + + +@ENDNODE + +@NODE "Changing the Message" "Changing the Message" +@Next "Procedures" +@Toc "Understanding a Simple Program" + +Changing the Message +==================== + + Edit the file so that line contains a different message between the two +' characters and compile it again using the same procedure as before. +Don't use any ' characters except those around the message. If all went +well, when you run the program again it should produce a different message. +If something went wrong, compare the contents of your file with the +original and make sure the only difference is the message between the ' +characters. + + + @{" Tinkering with the example " Link "Tinkering with the example" } + @{" Brief overview " Link "Brief overview" } + + +@ENDNODE + +@NODE "Tinkering with the example" "Tinkering with the example" +@Next "Brief overview" +@Toc "Changing the Message" + +Tinkering with the example +-------------------------- + + Simple tinkering is a good way to learn for yourself so it is +encouraged on these simple examples. Don't stray too far, though, and if +you start getting confused return to the proper example pretty sharpish! + + +@ENDNODE + +@NODE "Brief overview" "Brief overview" +@Prev "Tinkering with the example" +@Toc "Changing the Message" + +Brief overview +-------------- + + We'll look in detail at the important parts of the program in the +following sections, but we need first to get a glimpse of the whole +picture. Here's a brief description of some fundamental concepts: + + @{b }*@{ub } @{i }Procedures:@{ui } We defined a procedure called @{b }main@{ub } and used the + (built-in) procedure @{b }WriteF@{ub }. A procedure can be thought of as a + small program with a name. + + @{b }*@{ub } @{i }Parameters:@{ui } The message in parentheses after @{b }WriteF@{ub } in our + program is the parameter to @{b }WriteF@{ub }. This is the data which the + procedure should use. + + @{b }*@{ub } @{i }Strings:@{ui } The message we passed to @{b }WriteF@{ub } was a series of + characters enclosed in ' characters. This is known as a @{fg shine }string@{fg text }. + + +@ENDNODE + +@NODE "Procedures" "Procedures" +@Next "Parameters" +@Prev "Changing the Message" +@Toc "Understanding a Simple Program" + +Procedures +========== + + As mentioned above, a procedure can be thought of as a small program +with a name. In fact, when an E program is run the procedure called @{b }main@{ub } +is executed. Therefore, if your E program is going to do anything you +must define a @{b }main@{ub } procedure. Other (built-in or user-defined) procedures +may be run (or @{fg shine }called@{fg text }) from this procedure (as we did @{b }WriteF@{ub } in the +example). For instance, if the procedure @{b }fred@{ub } calls the procedure @{b }barney@{ub } +the code (or mini-program) associated with @{b }barney@{ub } is executed. This may +involve calls to other procedures, and when the execution of this code is +complete the next piece of code in the procedure @{b }fred@{ub } is executed (and +this is generally the next line of the procedure). When the end of the +procedure @{b }main@{ub } has been reached the program has finished. However, lots +can happen between the beginning and end of a procedure, and sometimes the +program may never get to finish. Alternatively, the program may @{fg shine }crash@{fg text }, +causing strange things to happen to your computer. + + + @{" Procedure Definition " Link "Procedure Definition" } + @{" Procedure Execution " Link "Procedure Execution" } + @{" Extending the example " Link "Extending the example" } + + +@ENDNODE + +@NODE "Procedure Definition" "Procedure Definition" +@Next "Procedure Execution" +@Toc "Procedures" + +Procedure Definition +-------------------- + + Procedures are defined using the keyword @{b }PROC@{ub }, followed by the new +procedure's name (starting with a lowercase letter), a description of the +parameters it takes (in parentheses), a series of lines forming the code +of the procedure and then the keyword @{b }ENDPROC@{ub }. Look at the example +program again to identify the various parts. See @{"The code" Link "The code" }. + + +@ENDNODE + +@NODE "Procedure Execution" "Procedure Execution" +@Next "Extending the example" +@Prev "Procedure Definition" +@Toc "Procedures" + +Procedure Execution +------------------- + + Procedures can be called (or executed) from within the code part of +another procedure. You do this by giving its name, followed by some data +in parentheses. Look at the call to @{b }WriteF@{ub } in the example program. See +@{"The code" Link "The code" }. + + +@ENDNODE + +@NODE "Extending the example" "Extending the example" +@Prev "Procedure Execution" +@Toc "Procedures" + +Extending the example +--------------------- + + Here's how we could change the example program to define another +procedure: + + PROC main() + WriteF('My first program') + fred() + ENDPROC + + PROC fred() + WriteF('...slightly improved') + ENDPROC + +This may seem complicated, but in fact it's very simple. All we've done +is define a second procedure called @{b }fred@{ub } which is just like the original +program--it outputs a message. We've @{fg shine }called@{fg text } this procedure in the @{b }main@{ub } +procedure just after the line which outputs the original message. +Therefore, the message in @{b }fred@{ub } is output after this message. Compile the +program as before and run it so you don't have to take my word for it. + + +@ENDNODE + +@NODE "Parameters" "Parameters" +@Next "Strings" +@Prev "Procedures" +@Toc "Understanding a Simple Program" + +Parameters +========== + + Generally we want procedures to work with particular data. In our +example we wanted the @{b }WriteF@{ub } procedure to work on a particular message. +We passed the message as a @{fg shine }parameter@{fg text } (or @{fg shine }argument@{fg text }) to @{b }WriteF@{ub } by +putting it between the parentheses (the @{b }(@{ub } and @{b })@{ub } characters) that follow +the procedure name. When we called the @{b }fred@{ub } procedure, however, we did +not require it to use any data so the parentheses were left empty. + + When defining a procedure we define how much and what type of data we +want it to work on, and when calling a procedure we give the specific data +it should use. Notice that the procedure @{b }fred@{ub } (like the procedure @{b }main@{ub }) +has empty parentheses in its definition. This means that the procedure +cannot be given any data as parameters when it is called. Before we can +define our own procedure that takes parameters we must learn about +variables. We'll do this in the next chapter. See +@{"Global and local variables" Link "Global and local variables" }. + + +@ENDNODE + +@NODE "Strings" "Strings" +@Next "Style Reuse and Readability" +@Prev "Parameters" +@Toc "Understanding a Simple Program" + +Strings +======= + + A series of characters between two ' characters is known as a string. +Almost any character can be used in a string, although the \\ and ' +characters have a special meaning. For instance, a linefeed is denoted by +the two characters @{b }\\n@{ub }. We now know how to stop the message running into +the prompt. Change the program to be: + + PROC main() + WriteF('My first program\\n') + fred() + ENDPROC + + PROC fred() + WriteF('...slightly improved\\n') + ENDPROC + +Compile it as before, and run it. You should notice that the messages now +appear on lines by themselves, and the second message is separated from +the prompt which follows it. We have therefore cured the linefeed problem +we spotted earlier (see @{"Execution" Link "Execution" }). + + +@ENDNODE + +@NODE "Style Reuse and Readability" "Style Reuse and Readability" +@Next "The Simple Program" +@Prev "Strings" +@Toc "Understanding a Simple Program" + +Style, Reuse and Readability +============================ + + The example has grown into two procedures, one called @{b }main@{ub } and one +called @{b }fred@{ub }. However, we could get by with only one procedure: + + PROC main() + WriteF('My first program\\n') + WriteF('...slightly improved\\n') + ENDPROC + + What we've done is replace the call to the procedure @{b }fred@{ub } with the code +it represents (this is called @{fg shine }inlining@{fg text } the procedure). In fact, almost +all programs can be easily re-written to eliminate all but the @{b }main@{ub } +procedure. However, splitting a program up using procedures normally +results in more readable code. It is also helpful to name your procedures +so that their function is apparent, so our procedure @{b }fred@{ub } should probably +have been named @{b }message@{ub } or something similar. A well-written program in +this style can read just like English (or any other spoken language). + + Another reason for having procedures is to reuse code, rather than +having to write it out every time you use it. Imagine you wanted to print +the same, long message fairly often in your program--you'd either have to +write it all out every time, or you could write it once in a procedure and +call this procedure when you wanted the message printed. Using a +procedure also has the benefit of having only one copy of the message to +change, should it ever need changing. + + +@ENDNODE + +@NODE "The Simple Program" "The Simple Program" +@Prev "Style Reuse and Readability" +@Toc "Understanding a Simple Program" + +The Simple Program +================== + + The simple program should now (hopefully) seem simple. The only bit +that hasn't been explained is the built-in procedure @{b }WriteF@{ub }. E has many +built-in procedures and later we'll meet some of them in detail. The +first thing we need to do, though, is manipulate data. This is really +what a computer does all the time--it accepts data from some source +(possibly the user), manipulates it in some way (possibly storing it +somewhere, too) and outputs new data (usually to a screen or printer). +The simple example program did all this, except the first two stages were +rather trivial. You told the computer to execute the compiled program +(this was some user input) and the real data (the message to be printed) +was retrieved from the program. This data was manipulated by passing it +as a parameter to @{b }WriteF@{ub }, which then did some clever stuff to print it on +the screen. To do our own manipulation of data we need to learn about +variables and expressions. + + +@ENDNODE + +@NODE "Variables and Expressions" "Variables and Expressions" +@Next "Program Flow Control" +@Prev "Understanding a Simple Program" +@Toc "Contents.guide/main" + +Variables and Expressions +************************* + + Anybody who's done any school algebra will probably know what a +variable is--it's just a named piece of data. In algebra the data is +usually a number, but in E it can be all sorts of things (e.g., a string). +The manipulation of data like the addition of two numbers is known as an +@{fg shine }expression@{fg text }. The result of an expression can be used to build bigger +expressions. For instance, @{b }1+2@{ub } is an expression, and so is @{b }6-(1+2)@{ub }. The +good thing is you can use variables in place of data in expressions, so if +@{b }x@{ub } represents the number 1 and @{b }y@{ub } represents 5, then the expression @{b }y-x@{ub } +represents the number 4. In the next two sections we'll look at what kind +of variables you can define and what the different sorts of expressions +are. + + + @{" Variables " Link "Variables" } + @{" Expressions " Link "Expressions" } + + +@ENDNODE + +@NODE "Variables" "Variables" +@Next "Expressions" +@Toc "Variables and Expressions" + +Variables +========= + + Variables in E can hold many different kinds of data (called @{fg shine }types@{fg text }). +However, before a variable can be used it must be defined, and this is +known as @{fg shine }declaring@{fg text } the variable. A variable declaration also decides +whether the variable is available for the whole program or just during the +code of a procedure (i.e., whether the variable is @{fg shine }global@{fg text } or @{fg shine }local@{fg text }). +Finally, the data stored in a variable can be changed using @{fg shine }assignments@{fg text }. +The following sections discuss these topics in slightly more detail. + + + @{" Variable types " Link "Variable types" } + @{" Variable declaration " Link "Variable declaration" } + @{" Assignment " Link "Assignment" } + @{" Global and local variables " Link "Global and local variables" } + @{" Changing the example " Link "Changing the example" } + + +@ENDNODE + +@NODE "Variable types" "Variable types" +@Next "Variable declaration" +@Toc "Variables" + +Variable types +-------------- + + In E a variable is a storage place for data (and this storage is part +of the Amiga's RAM). Different kinds of data may require different +amounts of storage. However, data can be grouped together in @{fg shine }types@{fg text }, and +two pieces of data from the same type require the same amount of storage. +Every variable has an associated type and this dictates the maximum amount +of storage it uses. Most commonly, variables in E store data from the +type @{b }LONG@{ub }. This type contains the integers from -2,147,483,648 to +2,147,483,647, so is normally more than sufficient. There are other +types, such as @{b }INT@{ub } and @{b }LIST@{ub }, and more complex things to do with types, but +for now knowing about @{b }LONG@{ub } is enough. + + +@ENDNODE + +@NODE "Variable declaration" "Variable declaration" +@Next "Assignment" +@Prev "Variable types" +@Toc "Variables" + +Variable declaration +-------------------- + + Variables must be declared before they can be used. They are declared +using the @{b }DEF@{ub } keyword followed by a (comma-separated) list of the names of +the variables to be declared. These variables will all have type @{b }LONG@{ub } +(later we will see how to declare variables with other types). Some +examples will hopefully make things clearer: + + DEF x + + DEF a, b, c + +The first line declares the single variable @{b }x@{ub }, whilst the second declares +the variables @{b }a@{ub }, @{b }b@{ub } and @{b }c@{ub } all in one go. + + +@ENDNODE + +@NODE "Assignment" "Assignment" +@Next "Global and local variables" +@Prev "Variable declaration" +@Toc "Variables" + +Assignment +---------- + + The data stored by variables can be changed and this is normally done +using @{fg shine }assignments@{fg text }. An assignment is formed using the variable's name +and an expression denoting the new data it is to store. The symbol @{b }:=@{ub } +separates the variable from the expression. For example, the following +code stores the number two in the variable @{b }x@{ub }. The left-hand side of the +@{b }:=@{ub } is the name of the variable to be affected (@{b }x@{ub } in this case) and the +right-hand side is an expression denoting the new value (simply the number +two in this case). + + x := 2 + +The following, more complex example uses the value stored in the variable +before the assignment as part of the expression for the new data. The +value of the expression on the right-hand side of the @{b }:=@{ub } is the value +stored in the variable @{b }x@{ub } plus one. This value is then stored in @{b }x@{ub }, +over-writing the previous data. (So, the overall effect is that @{b }x@{ub } is +incremented.) + + x := x + 1 + +This may be clearer in the next example which does not change the data +stored in @{b }x@{ub }. In fact, this piece of code is just a waste of CPU time, +since all it does is look up the value stored in @{b }x@{ub } and store it back there! + + x := x + + +@ENDNODE + +@NODE "Global and local variables" "Global and local variables" +@Next "Changing the example" +@Prev "Assignment" +@Toc "Variables" + +Global and local variables (and procedure parameters) +----------------------------------------------------- + + There are two kinds of variable: @{fg shine }global@{fg text } and @{fg shine }local@{fg text }. Data stored by +global variables can be read and changed by all procedures, but data +stored by local variables can only be accessed by the procedure to which +they are local. Global variables must be declared before the first +procedure definition. Local variables are declared within the procedure +to which they are local (i.e., between the @{b }PROC@{ub } and @{b }ENDPROC@{ub }). For +example, the following code declares a global variable @{b }w@{ub } and local +variables @{b }x@{ub } and @{b }y@{ub }. + + DEF w + + PROC main() + DEF x + x:=2 + w:=1 + fred() + ENDPROC + + PROC fred() + DEF y + y:=3 + w:=2 + ENDPROC + +The variable @{b }x@{ub } is local to the procedure @{b }main@{ub }, and @{b }y@{ub } is local to @{b }fred@{ub }. +The procedures @{b }main@{ub } and @{b }fred@{ub } can read and alter the value of the global +variable @{b }w@{ub }, but @{b }fred@{ub } cannot read or alter the value of @{b }x@{ub } (since that +variable is local to @{b }main@{ub }). Similarly, @{b }main@{ub } cannot read or alter @{b }y@{ub }. + + The local variables of one procedure are, therefore, completely +different to the local variables of another procedure. For this reason +they can share the same names without confusion. So, in the above +example, the local variable @{b }y@{ub } in @{b }fred@{ub } could have been called @{b }x@{ub } and the +program would have done exactly the same thing. + + DEF w + + PROC main() + DEF x + x:=2 + w:=1 + fred() + ENDPROC + + PROC fred() + DEF x + x:=3 + w:=2 + ENDPROC + +This works because the @{b }x@{ub } in the assignment in @{b }fred@{ub } can refer only to the +local variable @{b }x@{ub } of @{b }fred@{ub } (the @{b }x@{ub } in @{b }main@{ub } is local to @{b }main@{ub } so cannot be +accessed from @{b }fred@{ub }). + + If a local variable for a procedure has the same name as a global +variable then in the rest of the procedure the name refers only to the +local variable. Therefore, the global variable cannot be accessed in the +procedure, and this is called @{fg shine }descoping@{fg text } the global variable. + + The parameters of a procedure are local variables for that procedure. +We've seen how to pass values as parameters when a procedure is called +(the use of @{b }WriteF@{ub } in the example), but until now we haven't been able to +define a procedure which takes parameters. Now we know a bit about +variables we can have a go: + + DEF y + + PROC onemore(x) + y:=x+1 + ENDPROC + +This isn't a complete program so don't try to compile it. Basically, +we've declared a variable @{b }y@{ub } (which will be of type @{b }LONG@{ub }) and a procedure +@{b }onemore@{ub }. The procedure is defined with a parameter @{b }x@{ub }, and this is just +like a (local) variable declaration. When @{b }onemore@{ub } is called a parameter +must be supplied, and this value is stored in the (local) variable @{b }x@{ub } +before execution of @{b }onemore@{ub }'s code. The code stores the value of @{b }x@{ub } plus +one in the (global) variable @{b }y@{ub }. The following are some examples of +calling @{b }onemore@{ub }: + + onemore(120) + onemore(52+34) + onemore(y) + + A procedure can be defined to take any number of parameters. Below, +the procedure @{b }addthem@{ub } is defined to take two parameters, @{b }a@{ub } and @{b }b@{ub }, so it +must therefore be called with two parameters. Notice that values stored +by the parameter variables (@{b }a@{ub } and @{b }b@{ub }) can be changed within the code of the +procedure, since they are just like local variables for the procedure. +(The only real difference between local and parameter variables is that +parameter variables are initialised with the values supplied as parameters +when the procedure is called.) + + DEF y + + PROC addthem(a, b) + a:=a+2 + y:=a*b + ENDPROC + +The following are some examples of calling @{b }addthem@{ub }: + + addthem(120,-20) + addthem(52,34) + addthem(y,y) + + Global variables are, by default, initialised to zero. Parameter +variables are, of course, initialised by the actual values passed as +parameters when a procedure is called. However, local variables are not +initialised. This means that a local variable will contain a fairly +random value when the code of a procedure is first executed. It is the +responsibility of the programmer to ensure no assumptions are made about +the value of local variables before they have been initialised. The +obvious way to initialise a local variable is using an assignment, but +there is also a way of giving an initialisation value as part of the +declaration (see @{"Initialised Declarations" Link "MoreExpressions.guide/Initialised Declarations" }). Initialisation of variables +is often very important, and is a common reason why programs go wrong. + + +@ENDNODE + +@NODE "Changing the example" "Changing the example" +@Prev "Global and local variables" +@Toc "Variables" + +Changing the example +-------------------- + + Before we change the example we must learn something about @{b }WriteF@{ub }. We +already know that the characters @{b }\\n@{ub } in a string mean a linefeed. +However, there are several other important combinations of characters in a +string, and some are special to procedures like @{b }WriteF@{ub }. One such +combination is @{b }\\d@{ub }, which is easier to describe after we've seen the +changed example. + + PROC main() + WriteF('My first program\\n') + fred() + ENDPROC + + PROC fred() + WriteF('...brought to you by the number \\d\\n', 236) + ENDPROC + +You might be able to guess what happens, but compile it and try it out +anyway. If everything's worked you should see that the second message +prints out the number that was passed as the second parameter to @{b }WriteF@{ub }. +That's what the @{b }\\d@{ub } combination does--it marks the place in the string +where the number should be printed. Here's the output the example should +generate: + + My first program + ...brought to you by the number 236 + +Try this next change: + + PROC main() + WriteF('My first program\\n') + fred() + ENDPROC + + PROC fred() + WriteF('...the number \\d is quite nice\\n', 16) + ENDPROC + +This is very similar, and just shows that the @{b }\\d@{ub } really does mark the +place where the number is printed. Again, here's the output it should +generate: + + My first program + ...the number 16 is quite nice + +We'll now try printing two numbers. + + PROC main() + WriteF('My first program\\n') + fred() + ENDPROC + + PROC fred() + WriteF('...brought to you by the numbers \\d and \\d\\n', 16, 236) + ENDPROC + +Because we're printing two numbers we need two lots of @{b }\\d@{ub }, and we need to +supply two numbers as parameters in the order in which we want them to be +printed. The number 16 will therefore be printed before the word `and' +and before the number 236. Here's the output: + + My first program + ...brought to you by the numbers 16 and 236 + + We can now make a big step forward and pass the numbers as parameters +to the procedure @{b }fred@{ub }. Just look at the differences between this next +example and the previous one. + + PROC main() + WriteF('My first program\\n') + fred(16, 236) + ENDPROC + + PROC fred(a,b) + WriteF('...brought to you by the numbers \\d and \\d\\n', a,b) + ENDPROC + +This time we pass the (local) variables @{b }a@{ub } and @{b }b@{ub } to @{b }WriteF@{ub }. This is +exactly the same as passing the values they store (which is what the +previous example did), and so the output will be the same. In the next +section we'll manipulate the variables by doing some arithmetic with @{b }a@{ub } and +@{b }b@{ub }, and get @{b }WriteF@{ub } to print the results. + + +@ENDNODE + +@NODE "Expressions" "Expressions" +@Prev "Variables" +@Toc "Variables and Expressions" + +Expressions +=========== + + The E language includes the normal mathematical and logical operators. +These operators are combined with values (usually in variables) to give +@{fg shine }expressions@{fg text } which yield new values. The following sections discuss this +topic in more detail. + + + @{" Mathematics " Link "Mathematics" } + @{" Logic and comparison " Link "Logic and comparison" } + @{" Precedence and grouping " Link "Precedence and grouping" } + + +@ENDNODE + +@NODE "Mathematics" "Mathematics" +@Next "Logic and comparison" +@Toc "Expressions" + +Mathematics +----------- + + All the standard mathematical operators are supported in E. You can do +addition, subtraction, multiplication and division. Other functions such +as sine, modulus and square-root can also be used as they are part of the +Amiga system libraries, but we only need to know about simple mathematics +at the moment. The @{b }+@{ub } character is used for addition, @{b }-@{ub } for subtraction, @{b }*@{ub } +for multiplication (it's the closest you can get to a multiplication sign +on a keyboard without using the letter @{b }x@{ub }), and @{b }/@{ub } for division (be careful +not to confuse the @{b }\\@{ub} used in strings with @{b }/@{ub } used for division). The +following are examples of expressions: + + 1+2+3+4 + 15-5 + 5*2 + 330/33 + -10+20 + 3*3+1 + +Each of these expressions yields ten as its result. The last example is +very carefully written to get the precedence correct (see +@{"Precedence and grouping" Link "Precedence and grouping" }). + + All the above expressions use integer operators, so they manipulate +integers, giving integers as results. @{fg shine }Floating-point@{fg text } numbers are also +supported by E, but using them is quite complicated (see +@{"Floating-Point Numbers" Link "FloatingPoint.guide/main" }). (Floating-point numbers can represent both very +small fractions and very large integers, but they have a limited accuracy, +i.e., a limited number of @{i }significant@{ui } digits.) + + +@ENDNODE + +@NODE "Logic and comparison" "Logic and comparison" +@Next "Precedence and grouping" +@Prev "Mathematics" +@Toc "Expressions" + +Logic and comparison +-------------------- + + Logic lies at the very heart of a computer. They rarely guess what to +do next; instead they rely on hard facts and precise reasoning. Consider +the password protection on most games. The computer must decide whether +you entered the correct number or word before it lets you play the game. +When you play the game it's constantly making decisions: did your laser +hit the alien?, have you got any lives left?, etc. Logic controls the +operation of a program. + + In E, the constants @{b }TRUE@{ub } and @{b }FALSE@{ub } represent the truth values true and +false (respectively), and the operators @{b }AND@{ub } and @{b }OR@{ub } are the standard logic +operators. The comparison operators are @{b }=@{ub } (equal to), @{b }>@{ub } (greater than), @{b }<@{ub } +(less than), @{b }>=@{ub } (greater than or equal to), @{b }<=@{ub } (less than or equal to) and +@{b }<>@{ub } (not equal to). All the following expressions are true: + + TRUE + TRUE AND TRUE + TRUE OR FALSE + 1=1 + 2>1 + 3<>0 + +And these are all false: + + FALSE + TRUE AND FALSE + FALSE OR FALSE + 0=2 + 2<1 + (2<1) AND (-1=0) + +The last example must use parentheses. We'll see why in the next section +(it's to do with precedence, again). + + The truth values @{b }TRUE@{ub } and @{b }FALSE@{ub } are actually numbers. This is how the +logic system works in E. @{b }TRUE@{ub } is the number -1 and @{b }FALSE@{ub } is zero. The +logic operators @{b }AND@{ub } and @{b }OR@{ub } expect such numbers as their parameters. In +fact, the @{b }AND@{ub } and @{b }OR@{ub } operators are really bit-wise operators (see +@{"Bitwise AND and OR" Link "MoreExpressions.guide/Bitwise AND and OR" }), so most of the time any non-zero number is taken to +be @{b }TRUE@{ub }. It can sometimes be convenient to rely on this knowledge, +although most of the time it is preferable (and more readable) to use a +slightly more explicit form. Also, these facts can cause a few subtle +problems as we shall see in the next section. + + +@ENDNODE + +@NODE "Precedence and grouping" "Precedence and grouping" +@Prev "Logic and comparison" +@Toc "Expressions" + +Precedence and grouping +----------------------- + + At school most of us are taught that multiplications must be done +before additions in a sum. In E it's different--there is no operator +precedence, and the normal order in which the operations are performed is +left-to-right, just like the expression is written. This means that +expressions like @{b }1+3*3@{ub } do not give the results a mathematician might +expect. In fact, @{b }1+3*3@{ub } represents the number 12 in E. This is because the +addition, @{b }1+3@{ub }, is done before the multiplication, since it occurs before +the multiplication. If the multiplication were written before the +addition it would be done first (like we would normally expect). +Therefore, @{b }3*3+1@{ub } represents the number 10 in E and in school mathematics. + + To overcome this difference we can use parentheses to group the +expression. If we'd written @{b }1+(3*3)@{ub } the result would be 10. This is +because we've forced E to do the multiplication first. Although this may +seem troublesome to begin with, it's actually a lot better than learning a +lot of rules for deciding which operator is done first (in C this can be a +real pain, and you usually end up writing the brackets in just to be +sure!). + + The logic examples above contained the expression: + + (2<1) AND (-1=0) + +This expression was false. If we'd left the parentheses out, it would +have been: + + 2<1 AND -1=0 + +This is actually interpreted the same as: + + ((2<1) AND -1) = 0 + +Now the number -1 shouldn't really be used to represent a truth value with +@{b }AND@{ub }, but we do know that @{b }TRUE@{ub } is the number -1, so E will make sense of +this and the E compiler won't complain. We will soon see how @{b }AND@{ub } and @{b }OR@{ub } +really work (see @{"Bitwise AND and OR" Link "MoreExpressions.guide/Bitwise AND and OR" }), but for now we'll just work out what +E would calculate for this expression: + + 1. Two is not less than one so @{b }2<1@{ub } can be replaced by @{b }FALSE@{ub }. + + (FALSE AND -1) = 0 + + 2. @{b }TRUE@{ub } is -1 so we can replace -1 by @{b }TRUE@{ub }. + + (FALSE AND TRUE) = 0 + + 3. @{b }FALSE AND TRUE@{ub } is @{b }FALSE@{ub }. + + (FALSE) = 0 + + 4. @{b }FALSE@{ub } is really the number zero, so we can replace it with zero. + + 0 = 0 + + 5. Zero is equal to zero, so the expression is @{b }TRUE@{ub }. + + TRUE + +So E calculates the expression to be true. But the original expression +(with parentheses) was false. Bracketing is therefore very important! It +is also very easy to do correctly. + + +@ENDNODE + +@NODE "Program Flow Control" "Program Flow Control" +@Next "Summary" +@Prev "Variables and Expressions" +@Toc "Contents.guide/main" + +Program Flow Control +******************** + + A computer program often needs to repeatedly execute a series of +statements or execute different statements according to the result of some +decision. For example, a program to print all the numbers between one and +a thousand would be very long and tedious to write if each print statement +had to be given individually--it would be much better to use a variable +and repeatedly print its value and increment it. + + Another aspect of flow control is choosing between different pieces of +code to execute. For instance, if something goes wrong a program may need +to decide whether to continue or print an error message and stop--this +part of a program is a typical example of a conditional block. + + + @{" Conditional Block " Link "Conditional Block" } + @{" Loops " Link "Loops" } + + +@ENDNODE + +@NODE "Conditional Block" "Conditional Block" +@Next "Loops" +@Toc "Program Flow Control" + +Conditional Block +================= + + There are two kinds of conditional block: @{b }IF@{ub } and @{b }SELECT@{ub }. Examples of +these blocks are given below as fragments of E code (i.e., the examples +are not complete E programs). + + IF x>0 + x:=x+1 + WriteF('Increment: x is now \\d\\n', x) + ELSEIF x<0 + x:=x-1 + WriteF('Decrement: x is now \\d\\n', x) + ELSE + WriteF('Zero: x is 0\\n') + ENDIF + +In the above @{b }IF@{ub } block, the first part checks if the value of @{b }x@{ub } is greater +than zero, and, if it is, @{b }x@{ub } is incremented and the new value is printed +(with a message saying it was incremented). The program will then skip +the rest of the block, and will execute the statements which follow the +@{b }ENDIF@{ub }. If, however, @{b }x@{ub } it is not greater than zero the @{b }ELSEIF@{ub } part is +checked, so if @{b }x@{ub } is less than zero it will be decremented and printed, and +the rest of the block is skipped. If @{b }x@{ub } is not greater than zero and not +less than zero the statements in the @{b }ELSE@{ub } part are executed, so a message +saying @{b }x@{ub } is zero is printed. The @{b }IF@{ub } conditional is described in more +detail below. + + + @{" IF block " Link "IF block" } + @{" IF expression " Link "IF expression" } + + SELECT x + CASE 0 + WriteF('x is zero\\n') + CASE 10 + WriteF('x is ten\\n') + CASE -2 + WriteF('x is -2\\n') + DEFAULT + WriteF('x is not zero, ten or -2\\n') + ENDSELECT + +The @{b }SELECT@{ub } block is similar to the @{b }IF@{ub } block--it does different things +depending on the value of @{b }x@{ub }. However, @{b }x@{ub } is only checked against specific +values, given in the series of @{b }CASE@{ub } statements. If it is not any of these +values the @{b }DEFAULT@{ub } part is executed. + + There's also a variation on the @{b }SELECT@{ub } block (known as the @{b }SELECT..OF@{ub } +block) which matches ranges of values and is quite fast. The two kinds of +@{b }SELECT@{ub } block are described in more detail below. + + + @{" SELECT block " Link "SELECT block" } + @{" SELECT..OF block " Link "SELECT..OF block" } + + +@ENDNODE + +@NODE "IF block" "IF block" +@Next "IF expression" +@Toc "Conditional Block" + +@{b }IF@{ub } block +-------- + + The @{b }IF@{ub } block has the following form (the bits like @{fg shine }expression@{fg text } are +descriptions of the kinds of E code which is allowed at that point--they +are not proper E code): + + IF @{fg shine }expressionA@{fg text } + @{fg shine }statementsA@{fg text } + ELSEIF @{fg shine }expressionB@{fg text } + @{fg shine }statementsB@{fg text } + ELSE + @{fg shine }statementsC@{fg text } + ENDIF + +This block means: + + @{b }*@{ub } If @{fg shine }expressionA@{fg text } is true (i.e., represents @{b }TRUE@{ub } or any non-zero + number) the code denoted by @{fg shine }statementsA@{fg text } is executed. + + @{b }*@{ub } If @{fg shine }expressionA@{fg text } is false (i.e., represents @{b }FALSE@{ub } or zero) and + @{fg shine }expressionB@{fg text } is true the @{fg shine }statementsB@{fg text } part is executed. + + @{b }*@{ub } If both @{fg shine }expressionA@{fg text } and @{fg shine }expressionB@{fg text } are false the @{fg shine }statementsC@{fg text } + part is executed. + +There does not need to be an @{b }ELSE@{ub } part but if one is present it must be +the last part (immediately before the @{b }ENDIF@{ub }). Also, there can be any +number of @{b }ELSEIF@{ub } parts between the @{b }IF@{ub } and @{b }ELSE@{ub } parts. + + An alternative to this vertical form (where each part is on a separate +line) is the horizontal form: + + IF @{fg shine }expression@{fg text } THEN @{fg shine }statementA@{fg text } ELSE @{fg shine }statementB@{fg text } + +This has the disadvantage of no @{b }ELSEIF@{ub } parts and having to cram everything +onto a single line. Notice the presence of the @{b }THEN@{ub } keyword to separate the +@{fg shine }expression@{fg text } and @{fg shine }statementA@{fg text }. This horizontal form is closely related to +the @{b }IF@{ub } expression, which is described below (see @{"IF expression" Link "IF expression" }). + + To help make things clearer here are a number of E code fragments which +illustrate the allowable @{b }IF@{ub } blocks: + + IF x>0 THEN x:=x+1 ELSE x:=0 + + IF x>0 + x:=x+1 + ELSE + x:=0 + ENDIF + + IF x=0 THEN WriteF('x is zero\\n') + + IF x=0 + WriteF('x is zero\\n') + ENDIF + + IF x<0 + Write('Negative x\\n') + ELSEIF x>2000 + Write('Too big x\\n') + ELSEIF (x=2000) OR (x=0) + Write('Worrying x\\n') + ENDIF + + IF x>0 + IF x>2000 + WriteF('Big x\\n') + ELSE + WriteF('OK x\\n') + ENDIF + ELSE + IF x<-800 THEN WriteF('Small x\\n') ELSE Write('Negative OK x') + ENDIF + +In the last example there are @{fg shine }nested@{fg text } @{b }IF@{ub } blocks (i.e., an @{b }IF@{ub } block within +an @{b }IF@{ub } block). There is no ambiguity in which @{b }ELSE@{ub } or @{b }ELSEIF@{ub } parts belong +to which @{b }IF@{ub } block because the beginning and end of the @{b }IF@{ub } blocks are +clearly marked. For instance, the first @{b }ELSE@{ub } line can be interpreted only +as being part of the innermost @{b }IF@{ub } block. + + As a matter of style the conditions on the @{b }IF@{ub } and @{b }ELSEIF@{ub } parts should +not @{fg shine }overlap@{fg text } (i.e., at most one of the conditions should be true). If +they do, however, the first one will take precedence. Therefore, the +following two fragments of E code do the same thing: + + IF x>0 + WriteF('x is bigger than zero\\n') + ELSEIF x>200 + WriteF('x is bigger than 200\\n') + ELSE + WriteF('x is too small\\n') + ENDIF + + IF x>0 + WriteF('x is bigger than zero\\n') + ELSE + WriteF('x is too small\\n') + ENDIF + +The @{b }ELSEIF@{ub } part of the first fragment checks whether @{b }x@{ub } is greater than 200. +But, if it is, the check in the @{b }IF@{ub } part would have been true (@{b }x@{ub } is +certainly greater than zero if it's greater than 200), and so only the +code in the @{b }IF@{ub } part is executed. The whole @{b }IF@{ub } block behaves as if the +@{b }ELSEIF@{ub } was not there. + + +@ENDNODE + +@NODE "IF expression" "IF expression" +@Next "SELECT block" +@Prev "IF block" +@Toc "Conditional Block" + +@{b }IF@{ub } expression +------------- + + @{b }IF@{ub } is such a commonly used construction that there is also an @{b }IF@{ub } +expression. The @{b }IF@{ub } block is a statement and it controls which lines of +code are executed, whereas the @{b }IF@{ub } expression is an expression and it +controls its own value. For example, the following @{b }IF@{ub } block: + + IF x>0 + y:=x+1 + ELSE + y:=0 + ENDIF + +can be written more succinctly using an @{b }IF@{ub } expression: + + y:=(IF x>0 THEN x+1 ELSE 0) + +The parentheses are unnecessary but they help to make the example more +readable. Since the @{b }IF@{ub } block is just choosing between two assignments to +@{b }y@{ub } it isn't really the lines of code that are different (they are both +assignments), rather it is the values that are assigned to @{b }y@{ub } that are +different. The @{b }IF@{ub } expression makes this similarity very clear. It +chooses the @{i }value@{ui } to be assigned in just the same way that the @{b }IF@{ub } block +choose the @{i }assignment@{ui }. + + The @{b }IF@{ub } expression has the following form: + + IF @{fg shine }exp@{fg text } THEN @{fg shine }expA@{fg text } ELSE @{fg shine }expB@{fg text } + +As you can see, @{b }IF@{ub } expressions are written like the horizontal form of the +@{b }IF@{ub } block. However, there must be an @{b }ELSE@{ub } part and there can be no @{b }ELSEIF@{ub } +parts. This means that the expression will always have a value (either +@{fg shine }expA@{fg text } or @{fg shine }expB@{fg text }, depending on the value of @{fg shine }exp@{fg text }), and it isn't cluttered +with lots of cases. + + Don't worry too much about @{b }IF@{ub } expressions, since there are only useful +in a handful of cases and can always be rewritten as a more wordy @{b }IF@{ub } block. +Having said that they are very elegant and a lot more readable than the +equivalent @{b }IF@{ub } block. + + +@ENDNODE + +@NODE "SELECT block" "SELECT block" +@Next "SELECT..OF block" +@Prev "IF expression" +@Toc "Conditional Block" + +@{b }SELECT@{ub } block +------------ + + The @{b }SELECT@{ub } block has the following form: + + SELECT @{fg shine }variable@{fg text } + CASE @{fg shine }expressionA@{fg text } + @{fg shine }statementsA@{fg text } + CASE @{fg shine }expressionB@{fg text } + @{fg shine }statementsB@{fg text } + DEFAULT + @{fg shine }statementsC@{fg text } + ENDSELECT + +The value of the selection variable (denoted by @{fg shine }variable@{fg text } in the @{b }SELECT@{ub } +part) is compared with the value of the expression in each of the @{b }CASE@{ub } +parts in turn. If there's a match, the statements in the (first) matching +@{b }CASE@{ub } part are executed. There can be any number of @{b }CASE@{ub } parts between the +@{b }SELECT@{ub } and @{b }DEFAULT@{ub } parts. If there is no match, the statements in the +@{b }DEFAULT@{ub } part are executed. There does not need to be a @{b }DEFAULT@{ub } part but +if one is present it must be the last part (immediately before the +@{b }ENDSELECT@{ub }). + + It should be clear that @{b }SELECT@{ub } blocks can be rewritten as @{b }IF@{ub } blocks, +with the checks on the @{b }IF@{ub } and @{b }ELSEIF@{ub } parts being equality checks on the +selection variable. For example, the following code fragments are +equivalent: + + SELECT x + CASE 22 + WriteF('x is 22\\n') + CASE (y+z)/2 + WriteF('x is (y+x)/2\\n') + DEFAULT + WriteF('x isn't anything significant\\n') + ENDSELECT + + IF x=22 + WriteF('x is 22\\n') + ELSEIF x=(y+z)/2 + WriteF('x is (y+x)/2\\n') + ELSE + WriteF('x isn't anything significant\\n') + ENDIF + +Notice that the @{b }IF@{ub } and @{b }ELSEIF@{ub } parts come from the @{b }CASE@{ub } parts, the @{b }ELSE@{ub } +part comes from the @{b }DEFAULT@{ub } part, and the order of the parts is preserved. +The advantage of the @{b }SELECT@{ub } block is that it's much easier to see that the +value of @{b }x@{ub } is being tested all the time, and also we don't have to keep +writing @{b }x=@{ub } in the checks. + + +@ENDNODE + +@NODE "SELECT..OF block" "SELECT..OF block" +@Prev "SELECT block" +@Toc "Conditional Block" + +@{b }SELECT..OF@{ub } block +---------------- + + The @{b }SELECT..OF@{ub } block is a bit more complicated than the normal @{b }SELECT@{ub } +block, but can be very useful. It has the following form: + + SELECT @{fg shine }maxrange@{fg text } OF @{fg shine }expression@{fg text } + CASE @{fg shine }constA@{fg text } + @{fg shine }statementsA@{fg text } + CASE @{fg shine }constB1@{fg text } TO @{fg shine }constB2@{fg text } + @{fg shine }statementsB@{fg text } + CASE @{fg shine }range1@{fg text }, @{fg shine }range2@{fg text } + @{fg shine }statementsC@{fg text } + DEFAULT + @{fg shine }statementsD@{fg text } + ENDSELECT + + The value to be matched is @{fg shine }expression@{fg text }, which can be any expression, +not just a variable like in the normal @{b }SELECT@{ub } block. However, the +@{fg shine }maxrange@{fg text }, @{fg shine }constA@{fg text }, @{fg shine }constB1@{fg text } and @{fg shine }constB2@{fg text } must all be explicit numbers, +i.e., constants (see @{"Constants" Link "Constants.guide/main" }). @{fg shine }maxrange@{fg text } must be a positive constant +and the other constants must all be between zero and @{fg shine }maxrange@{fg text } (including +zero but excluding @{fg shine }maxrange@{fg text }). + + The @{b }CASE@{ub } values to be matched are specified using @{fg shine }ranges@{fg text }. A simple +range is a single constant (the first @{b }CASE@{ub } above). The more general range +is shown in the second @{b }CASE@{ub }, using the @{b }TO@{ub } keyword (@{fg shine }constB2@{fg text } must be +greater than @{fg shine }constB1@{fg text }). A general @{b }CASE@{ub } in the @{b }SELECT..OF@{ub } block can +specify a number of possible ranges to match against by separating each +range with a comma, as in the third @{b }CASE@{ub } above. For example, the +following @{b }CASE@{ub } lines are equivalent and can be used to match any number +from one to five (inclusive): + + CASE 1 TO 5 + + CASE 1, 2, 3, 4, 5 + + CASE 1 TO 3, 3 TO 5 + + CASE 1, 2 TO 3, 4, 5 + + CASE 1, 5, 2, 4, 3 + + CASE 2 TO 3, 5, 1, 4 + + If the value of the @{fg shine }expression@{fg text } is less than zero, greater than or +equal to @{fg shine }maxrange@{fg text }, or it does not match any of the constants in the @{b }CASE@{ub } +ranges, then the statements in the @{b }DEFAULT@{ub } part are executed. Otherwise +the statements in the first matching @{b }CASE@{ub } part are executed. As in the +normal @{b }SELECT@{ub } block, there does not need to be a @{b }DEFAULT@{ub } part. + + The following @{b }SELECT..OF@{ub } block prints the (numeric) day of the month +nicely: + + SELECT 32 OF day + CASE 1, 21, 31 + WriteF('The \\dst day of the month\\n', day) + CASE 2, 22 + WriteF('The \\dnd day of the month\\n', day) + CASE 3, 23 + WriteF('The \\drd day of the month\\n', day) + CASE 4 TO 20, 24 TO 30 + WriteF('The \\dth day of the month\\n', day) + DEFAULT + WriteF('Error: invalid day=\\d\\n', day) + ENDSELECT + +The @{fg shine }maxrange@{fg text } for this block is 32, since 31 is the maximum of the values +used in the @{b }CASE@{ub } parts. If the value of @{b }day@{ub } was 100, for instance, then +the statements in the @{b }DEFAULT@{ub } part would be executed, signalling an +invalid day. + + This example can be rewritten as an @{b }IF@{ub } block: + + IF (day=1) OR (day=21) OR (day=31) + WriteF('The \\dst day of the month\\n', day) + ELSEIF (day=2) OR (day=22) + WriteF('The \\dnd day of the month\\n', day) + ELSEIF (day=3) OR (day=23) + WriteF('The \\drd day of the month\\n', day) + ELSEIF ((4<=day) AND (day<=20)) OR ((24<=day) AND (day<=30)) + WriteF('The \\dth day of the month\\n', day) + ELSE + WriteF('Error: invalid day=\\d\\n', day) + ENDIF + +The comma separating two ranges in the @{b }CASE@{ub } part has been replaced by an +@{b }OR@{ub } of two comparison expressions, and the @{b }TO@{ub } range has been replaced +by an @{b }AND@{ub } of two comparisons. (It is worth noticing the careful +bracketing of the resulting expressions.) + + Clearly, the @{b }SELECT..OF@{ub } block is much more readable than the equivalent +@{b }IF@{ub } block. It is also a lot faster, mainly because none of the comparisons +present in @{b }IF@{ub } block have to be done in the @{b }SELECT..OF@{ub } version. Instead +the value to be matched is used to immediately locate the correct @{b }CASE@{ub } +part. However, it's not all good news: the @{fg shine }maxrange@{fg text } value directly +affects the size of compiled executable, so it is recommended that +@{b }SELECT..OF@{ub } blocks be used only with small @{fg shine }maxrange@{fg text } values. See the +`Reference Manual' for more details. + + +@ENDNODE + +@NODE "Loops" "Loops" +@Prev "Conditional Block" +@Toc "Program Flow Control" + +Loops +===== + + Loops are all about making a program execute a series of statements +over and over again. Probably the simplest loop to understand is the @{b }FOR@{ub } +loop. There are other kinds of loops, but they are easier to understand +once we know how to use a @{b }FOR@{ub } loop. + + + @{" FOR loop " Link "FOR loop" } + @{" WHILE loop " Link "WHILE loop" } + @{" REPEAT..UNTIL loop " Link "REPEAT..UNTIL loop" } + + +@ENDNODE + +@NODE "FOR loop" "FOR loop" +@Next "WHILE loop" +@Toc "Loops" + +@{b }FOR@{ub } loop +-------- + + If you want to write a program to print the numbers one to 100 you can +either type each number and wear out your fingers, or you can use a single +variable and a small @{b }FOR@{ub } loop. Try compiling this E program (the space +after the @{b }\\d@{ub } in the string is needed to separate the printed numbers): + + PROC main() + DEF x + FOR x:=1 TO 100 + WriteF('\\d ', x) + ENDFOR + WriteF('\\n') + ENDPROC + +When you run this you'll get all the numbers from one to 100 printed, just +like we wanted. It works by using the (local) variable @{b }x@{ub } to hold the +number to be printed. The @{b }FOR@{ub } loop starts off by setting the value of @{b }x@{ub } +to one (the bit that looks like an assignment). Then the statements +between the @{b }FOR@{ub } and @{b }ENDFOR@{ub } lines are executed (so the value of @{b }x@{ub } gets +printed). When the program reaches the @{b }ENDFOR@{ub } it increments @{b }x@{ub } and checks +to see if it is bigger than 100 (the limit we set with the @{b }TO@{ub } part). If +it is, the loop is finished and the statements after the @{b }ENDFOR@{ub } are +executed. If, however, it wasn't bigger than 100, the statements between +the @{b }FOR@{ub } and @{b }ENDFOR@{ub } lines are executed all over again, and this time @{b }x@{ub } is +one bigger since it has been incremented. In fact, this program does +exactly the same as the following program (the @{b }...@{ub } is not E code--it +stands for the 97 other @{b }WriteF@{ub } statements): + + PROC main() + WriteF('\\d ', 1) + WriteF('\\d ', 2) + ... + WriteF('\\d ', 100) + WriteF('\\n') + ENDPROC + + The general form of the @{b }FOR@{ub } loop is as follows: + + FOR @{fg shine }var@{fg text } := @{fg shine }expressionA@{fg text } TO @{fg shine }expressionB@{fg text } STEP @{fg shine }number@{fg text } + @{fg shine }statements@{fg text } + ENDFOR + +The @{fg shine }var@{fg text } bit stands for the loop variable (in the example above this was +@{b }x@{ub }). The @{fg shine }expressionA@{fg text } bit gives the start value for the loop variable +and the @{fg shine }expressionB@{fg text } bit gives the last allowable value for it. The @{b }STEP@{ub } +part allows you to specify the value (given by @{fg shine }number@{fg text }) which is added to +the loop variable on each loop. Unlike the values given for the start and +end (which can be arbitrary expressions), the @{b }STEP@{ub } value must be a +constant (see @{"Constants" Link "Constants.guide/main" }). The @{b }STEP@{ub } value defaults to one if the @{b }STEP@{ub } part +is omitted (as in our example). Negative @{b }STEP@{ub } values are allowed, but in +this case the check used at the end of each loop is whether the loop +variable is @{i }less than@{ui } the value in the @{b }TO@{ub } part. Zero is not allowed as +the @{b }STEP@{ub } value. + + As with the @{b }IF@{ub } block there is a horizontal form of a @{b }FOR@{ub } loop: + + FOR @{fg shine }var@{fg text } := @{fg shine }expA@{fg text } TO @{fg shine }expB@{fg text } STEP @{fg shine }expC@{fg text } DO @{fg shine }statement@{fg text } + + +@ENDNODE + +@NODE "WHILE loop" "WHILE loop" +@Next "REPEAT..UNTIL loop" +@Prev "FOR loop" +@Toc "Loops" + +@{b }WHILE@{ub } loop +---------- + + The @{b }FOR@{ub } loop used a loop variable and checked whether that variable had +gone past its limit. A @{b }WHILE@{ub } loop allows you to specify your own loop +check. For instance, this program does the same as the program in the +previous section: + + PROC main() + DEF x + x:=1 + WHILE x<=100 + WriteF('\\d ', x) + x:=x+1 + ENDWHILE + WriteF('\\n') + ENDPROC + +We've replaced the @{b }FOR@{ub } loop with an initialisation of @{b }x@{ub } and a @{b }WHILE@{ub } loop +with an extra statement to increment @{b }x@{ub }. We can now see the inner workings +of the @{b }FOR@{ub } loop and, in fact, this is exactly how the @{b }FOR@{ub } loop works. + + It is important to know that our check, @{b }x<=100@{ub }, is done before the loop +statements are executed. This means that the loop statements might not +even be executed once. For instance, if we'd made the check @{b }x>=100@{ub } it +would be false at the beginning of the loop (since @{b }x@{ub } is initialised to one +in the assignment before the loop). Therefore, the loop would have +terminated immediately and execution would pass straight to the statements +after the @{b }ENDWHILE@{ub }. + + Here's a more complicated example: + + PROC main() + DEF x,y + x:=1 + y:=2 + WHILE (x<10) AND (y<10) + WriteF('x is \\d and y is \\d\\n', x, y) + x:=x+2 + y:=y+2 + ENDWHILE + ENDPROC + +We've used two (local) variables this time. As soon as one of them is ten +or more the loop is terminated. A bit of inspection of the code reveals +that @{b }x@{ub } is initialised to one, and keeps having two added to it. It will, +therefore, always be an odd number. Similarly, @{b }y@{ub } will always be even. +The @{b }WHILE@{ub } check shows that it won't print any numbers which are greater +than or equal to ten. From this and the fact that @{b }x@{ub } starts at one and @{b }y@{ub } +at two we can decide that the last pair of numbers will be seven and eight. +Run the program to confirm this. It should produce the following output: + + x is 1 and y is 2 + x is 3 and y is 4 + x is 5 and y is 6 + x is 7 and y is 8 + + Like the @{b }FOR@{ub } loop, there is a horizontal form of the @{b }WHILE@{ub } loop: + + WHILE @{fg shine }expression@{fg text } DO @{fg shine }statement@{fg text } + + Loop termination is always a big problem. @{b }FOR@{ub } loops are guaranteed to +eventually reach their limit (if you don't mess with the loop variable, +that is). However, @{b }WHILE@{ub } loops (and all other loops) may go on forever +and never terminate. For example, if the loop check were @{b }1<2@{ub } it would +always be true and nothing the loop could do would prevent it being true! +You must therefore take care that your loops terminate in some way if you +want to program to finish. There is a sneaky way of terminating loops +using the @{b }JUMP@{ub } statement, but we'll ignore that for now. + + +@ENDNODE + +@NODE "REPEAT..UNTIL loop" "REPEAT..UNTIL loop" +@Prev "WHILE loop" +@Toc "Loops" + +@{b }REPEAT..UNTIL@{ub } loop +------------------ + + A @{b }REPEAT..UNTIL@{ub } loop is very similar to a @{b }WHILE@{ub } loop. The only +difference is where you specify the loop check, and when and how the check +is performed. To illustrate this, here's the program from the previous +two sections rewritten using a @{b }REPEAT..UNTIL@{ub } loop (try to spot the subtle +differences): + + PROC main() + DEF x + x:=1 + REPEAT + WriteF('\\d ', x) + x:=x+1 + UNTIL x>100 + WriteF('\\n') + ENDPROC + +Just as in the @{b }WHILE@{ub } loop version we've got an initialisation of @{b }x@{ub } and an +extra statement in the loop to increment @{b }x@{ub }. However, this time the loop +check is specified at the end of the loop (in the @{b }UNTIL@{ub } part), and the +check is only performed at the end of each loop. This difference means +that the code in a @{b }REPEAT..UNTIL@{ub } loop will be executed at least once, +whereas the code in a @{b }WHILE@{ub } loop may never be executed. Also, the logical +sense of the check follows the English: a @{b }REPEAT..UNTIL@{ub } loop executes +@{i }until@{ui } the check is true, whereas the @{b }WHILE@{ub } loop executes @{i }while@{ui } the +check is true. Therefore, the @{b }REPEAT..UNTIL@{ub } loop executes while the check +is false! This may seem confusing at first, but just remember to read the +code as if it were English and you'll get the correct interpretation. + + +@ENDNODE + +@NODE "Summary" "Summary" +@Next "Format.guide/main" +@Prev "Program Flow Control" +@Toc "Contents.guide/main" + +Summary +******* + + This is the end of Part One, which was hopefully enough to get you +started. If you've grasped the main concepts you are good position to +attack Part Two, which covers the E language in more detail. + + This is probably a good time to look at the different parts of one of +the examples from the previous sections, since we've now used quite a bit +of E. The following examination uses the @{b }WHILE@{ub } loop example. Just to make +things easier to follow, each line has been numbered (don't try to compile +it with the line numbers on!). + + 1. PROC main() + 2. DEF x,y + 3. x:=1 + 4. y:=2 + 5. WHILE (x<10) AND (y<10) + 6. WriteF('x is \\d and y is \\d\\n', x, y) + 7. x:=x+2 + 8. y:=y+2 + 9. ENDWHILE + 10. ENDPROC + +Hopefully, you should be able to recognise all the features listed in the +table below. If you don't then you might need to go back over the +previous chapters, or find a much better programming guide than this! + + @{i }Line(s)@{ui } @{i }Observation@{ui } + --------------------------------------------------------- + 1-10 The procedure definition. + + 1 The declaration of the procedure @{b }main@{ub }, with no + parameters. + + 2 The declaration of local variables @{b }x@{ub } and @{b }y@{ub }. + + 3, 4 Initialisation of @{b }x@{ub } and @{b }y@{ub } using assignment + statements. + + 5-9 The @{b }WHILE@{ub } loop. + + 5 The loop check for the @{b }WHILE@{ub } loop using the + logical operator @{b }AND@{ub }, the comparison operator + @{b }<@{ub }, and parentheses to group the expression. + + 6 The call to the (built-in) procedure @{b }WriteF@{ub } + using parameters. Notice the string, the place + holders for numbers, @{b }\\d@{ub }, and the linefeed, + @{b }\\n@{ub }. + + 7, 8 Assignments to @{b }x@{ub } and @{b }y@{ub }, adding two to + their values. + + 9 The marker for the end of the @{b }WHILE@{ub } loop. + + 10 The marker for the end of the procedure. + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Memory.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Memory.guide new file mode 100644 index 0000000..38616b5 --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Memory.guide @@ -0,0 +1,557 @@ +@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" "Memory Allocation" +@Next "FloatingPoint.guide/main" +@Prev "Exceptions.guide/main" +@Toc "Contents.guide/main" + +Memory Allocation +***************** + + When a program is running memory is being used in various different +ways. In order to use any memory it must first be @{fg shine }allocated@{fg text }, which is +simply a way of marking memory as being `in use'. This is to prevent the +same piece of memory being used for different data storage (e.g., by +different programs), and so helps prevent corruption of the data stored +there. There are two general ways in which memory can be allocated: +dynamically and statically. + + + @{" Static Allocation " Link "Static Allocation" } + @{" Deallocation of Memory " Link "Deallocation of Memory" } + @{" Dynamic Allocation " Link "Dynamic Allocation" } + @{" NEW and END Operators " Link "NEW and END Operators" } + + +@ENDNODE + +@NODE "Static Allocation" "Static Allocation" +@Next "Deallocation of Memory" +@Toc "main" + +Static Allocation +================= + + @{fg shine }Statically@{fg text } allocated memory is memory allocated by the program for +variables and static data like string constants, lists and typed lists +(see @{"Static data" Link "Types.guide/Static data" }). Every variable in a program requires some memory in +which to store its value. Variables declared to be of type @{b }ARRAY@{ub }, @{b }LIST@{ub }, +@{b }STRING@{ub } or any object require two lots of memory: one to hold the value of +the pointer and one to hold the large amount of data (e.g., the elements +in an @{b }ARRAY@{ub }). In fact, such declarations are merely @{b }PTR TO @{ub }@{fg shine }type@{fg text }@{b }@{ub } +declarations together with an initialisation of the pointer to the address +of some (statically) allocated memory to hold the data. The following +example shows very similar declarations, with the difference being that in +the second case (using @{b }PTR@{ub }) only memory to hold the pointer values is +allocated. The first case also allocates memory to hold the appropriate +size of array, object and E-string. + + DEF a[20]:ARRAY, m:myobj, s[10]:STRING + + DEF a:PTR TO CHAR, m:PTR TO myobj, s:PTR TO CHAR + + The pointers in the second case are not initialised by the declaration +and, therefore, they are not valid pointers. This means that they should +not be dereferenced in any way, until they have been initialised to the +address of some allocated memory. This usually involves dynamic +allocation of memory (see @{"Dynamic Allocation" Link "Dynamic Allocation" }). + + +@ENDNODE + +@NODE "Deallocation of Memory" "Deallocation of Memory" +@Next "Dynamic Allocation" +@Prev "Static Allocation" +@Toc "main" + +Deallocation of Memory +====================== + + When memory is allocated it is, conceptually, marked as being `in use'. +This means that this piece of memory cannot be allocated again, so a +different piece will be allocated (if any is available) when the program +wants to allocate some more. In this way, variables are allocated +different pieces of memory, and so their values can be distinct. But +there is only a certain amount of memory available, and if it could not be +marked as `not in use' again it would soon run out (and the program would +come to a nasty end). This is what @{fg shine }deallocation@{fg text } does: it marks +previously allocated memory as being `not in use' and so makes it +available for allocation again. However, memory should be deallocated +only when it is actually no longer in use, and this is where things get a +bit complicated. + + Memory is such a vital resource in every computer that it is important +to use as little of it as necessary and to deallocate it whenever possible. +This is why a programming language like E handles most of the memory +allocation for variables. The memory allocated for variables can be +automatically deallocated when it is no longer possible for the program to +use that variable. However, this automatic deallocation is not useful for +global variables, since they can be used from any procedure and so can be +deallocated only when the program terminates. A procedure's local +variables, on the other hand, are allocated when the procedure is called +but cannot be used after the procedure returns. They can, therefore, be +deallocated when the procedure returns. + + Pointers, as always, can cause big problems. The following example +shows why you need to be careful when using pointers as the return value +of a procedure. + + /* This is an example of what *NOT* to do */ + PROC fullname(first, last) + DEF full[40]:STRING + StrCopy(full, first) + StrAdd(full, ' ') + StrAdd(full, last) + ENDPROC full + + PROC main() + WriteF('Name is \\s\\n', fullname('Fred', 'Flintstone')) + ENDPROC + +On first sight this seems fine, and, in fact, it may even work correctly +if you run it once or twice (but be careful: it could crash your machine). +The problem is that the procedure @{b }fullname@{ub } returns the value of the local +variable @{b }full@{ub }, which is a pointer to some statically allocated memory for +the E-string and this memory will be deallocated when the procedure +returns. This means that the return value of any call to @{b }fullname@{ub } is the +address of recently deallocated memory, so it is invalid to dereference it. +But the call to @{b }WriteF@{ub } does just that: it dereferences the result of +@{b }fullname@{ub } in order to print the E-string it points to. This is a very +common problem, because it is such an easy thing to do. The fact that it +may, on many occasions, appear to work makes it much harder to find, too. +The solution, in this case, is to use dynamic allocation (see +@{"Dynamic Allocation" Link "Dynamic Allocation" }). + + If you're still a bit sceptical that this really is a problem, try the +above @{b }fullname@{ub } procedure definition with either of these replacement @{b }main@{ub } +procedures, but be aware, again, that each one has the potential to crash +your machine. + + /* This might not print the correct string */ + PROC main() + DEF f + f:=fullname('Fred', 'Flintstone') + WriteF('Name is \\s\\n', f) + ENDPROC + + /* This will definitely print g instead of f */ + PROC main() + DEF f, g + f:=fullname('Fred', 'Flintstone') + g:=fullname('Barney', 'Rubble') + WriteF('Name is \\s\\n', f) + ENDPROC + +(The reason why things go wrong is outlined above, but the reasons why +each prints what it does is beyond the scope of this Guide.) + + +@ENDNODE + +@NODE "Dynamic Allocation" "Dynamic Allocation" +@Next "NEW and END Operators" +@Prev "Deallocation of Memory" +@Toc "main" + +Dynamic Allocation +================== + + @{fg shine }Dynamically@{fg text } allocated memory is any memory that is not statically +allocated. To allocate memory dynamically you can use the @{b }List@{ub } and @{b }String@{ub } +functions, all flavours of @{b }New@{ub }, and the versatile @{b }NEW@{ub } operator. But +because the memory is dynamically allocated it must be explicitly +deallocated when no longer needed. In all the above cases, though, any +memory that is still allocated when the program terminates will be +deallocated automatically. + + Another way to allocate memory dynamically is to use the Amiga system +functions based on @{b }AllocMem@{ub }. However, these functions require that the +memory allocated using them be deallocated (using functions like @{b }FreeMem@{ub }) +before the program terminates, or else it will never be deallocated (not +until your machine is rebooted, anyway). It is safer, therefore, to try +to use the E functions for dynamic allocation whenever possible. + + There are many reasons why you might want to use dynamic allocation, +and most of them involve initialisation of pointers. For example, the +declarations in the section about static allocation can be extended to +give initialisations for the pointers declared in the second @{b }DEF@{ub } line (see +@{"Static Allocation" Link "Static Allocation" }). + + DEF a[20]:ARRAY, m:myobj, s[10]:STRING + + DEF a:PTR TO CHAR, m:PTR TO myobj, s:PTR TO CHAR + a:=New(20) + m:=New(SIZEOF myobj) + s:=String(20) + +These are initialisations to dynamically allocated memory, whereas the +first line of declarations initialise similar pointers to statically +allocated memory. If these sections of code were part of a procedure +then, since they would now be local variables, there would be one other, +significant difference: the dynamically allocated memory would not +automatically be deallocated when the procedure returns, whereas the +statically allocated memory would. This means that we can solve the +deallocation problem (see @{"Deallocation of Memory" Link "Deallocation of Memory" }). + + /* This is the correct way of doing it */ + PROC fullname(first, last) + DEF full + full:=String(40) + StrCopy(full, first) + StrAdd(full, ' ') + StrAdd(full, last) + ENDPROC full + + PROC main() + DEF f, g + WriteF('Name is \\s\\n', fullname('Fred', 'Flintstone')) + f:=fullname('Fred', 'Flintstone') + g:=fullname('Barney', 'Rubble') + WriteF('Name is \\s\\n', f) + ENDPROC + + The memory for the E-string pointed to by @{b }full@{ub } is now allocated +dynamically, using @{b }String@{ub }, and is not deallocated until the end of the +program. This means that it is quite valid to pass the value of @{b }full@{ub } as +the result of the procedure @{b }fullname@{ub }, and it is quite valid to dereference +the result by printing it using @{b }WriteF@{ub }. However, this has caused one last +problem: the memory is not deallocated until the end of the program, so is +potentially wasted since it could be used, for example, to hold the +results of subsequent calls. Of course, the memory can be deallocated +only when the data it stores is no longer required. The following +replacement @{b }main@{ub } procedure shows when you might want to deallocate the +E-string (using @{b }DisposeLink@{ub }). + + PROC main() + DEF f, g + f:=fullname('Fred', 'Flintstone') + WriteF('Name is \\s, f points to $\\h\\n', f, f) + /* Try this with and without the next DisposeLink line */ + DisposeLink(f) + g:=fullname('Barney', 'Rubble') + WriteF('Name is \\s, g points to $\\h\\n', g, g) + DisposeLink(g) + ENDPROC + + If you run this with the @{b }DisposeLink(f)@{ub } line you'll probably find that +@{b }g@{ub } will be a pointer to the same memory as @{b }f@{ub }. This is because the call +to @{b }DisposeLink@{ub } has deallocated the memory pointed to by @{b }f@{ub }, so it can be +reused to store the E-string pointed to by @{b }g@{ub }. If you comment out (or +delete) the @{b }DisposeLink@{ub } line, then you will find that @{b }f@{ub } and @{b }g@{ub } always point +to different memory. + + In some ways it is best to never do any deallocation, because of the +problems you can get into if you deallocate memory too early (i.e., before +you've finished with the data it contains). Of course, it is safe (but +temporarily wasteful) to do this with the E dynamic allocation functions, +but it is very wasteful (and wrong) to do this with the Amiga system +functions like @{b }AllocMem@{ub }. + + Another benefit of using dynamic allocation is that the size of the +arrays, E-lists and E-strings that can be created can be the result of any +expression, so is not restricted to constant values. (Remember that the +size given on @{b }ARRAY@{ub }, @{b }LIST@{ub } and @{b }STRING@{ub } declarations must be a constant.) +This means that the @{b }fullname@{ub } procedure can be made more efficient and +allocate only the amount of memory it needs for the E-string it creates. + + PROC fullname(first, last) + DEF full + /* The extra +1 is for the added space */ + full:=String(StrLen(first)+StrLen(last)+1) + StrCopy(full, first) + StrAdd(full, ' ') + StrAdd(full, last) + ENDPROC full + +However, it may be very complicated or inefficient to calculate the +correct size. In these cases, a quick, constant estimate might be better, +overall. + + The various functions for allocating memory dynamically have +corresponding functions for deallocating that memory. The following table +shows some of the more common pairings. + + Allocation Deallocation + ------------------------------ + New Dispose + NewR Dispose + List DisposeLink + String DisposeLink + NEW END + FastNew FastDispose + AllocMem FreeMem + AllocVec FreeVec + AllocDosObject FreeDosObject + +@{b }NEW@{ub } and @{b }END@{ub } are versatile and powerful operators, discussed in the +following section. The functions beginning with @{b }Alloc-@{ub } are Amiga system +functions and are paired with similarly suffixed functions with a @{b }Free-@{ub } +prefix. See the `Rom Kernel Reference Manual' for more details. + + +@ENDNODE + +@NODE "NEW and END Operators" "NEW and END Operators" +@Prev "Dynamic Allocation" +@Toc "main" + +@{b }NEW@{ub } and @{b }END@{ub } Operators +===================== + + To help deal with dynamic allocation and deallocation of memory there +are two, powerful operators, @{b }NEW@{ub } and @{b }END@{ub }. The @{b }NEW@{ub } operator is very +versatile, and similar in operation to the @{b }New@{ub } family of built-in +functions (see @{"System support functions" Link "BuiltIns.guide/System support functions" }). The @{b }END@{ub } operator is the +deallocating complement of @{b }NEW@{ub } (so it is similar to the @{b }Dispose@{ub } family of +built-in functions). The major difference between @{b }NEW@{ub } and the various +flavours of @{b }New@{ub } is that @{b }NEW@{ub } allocates memory based on the types of its +arguments. + + + @{" Object and simple typed allocation " Link "Object and simple typed allocation" } + @{" Array allocation " Link "Array allocation" } + @{" List and typed list allocation " Link "List and typed list allocation" } + @{" OOP object allocation " Link "OOP object allocation" } + + +@ENDNODE + +@NODE "Object and simple typed allocation" "Object and simple typed allocation" +@Next "Array allocation" +@Toc "NEW and END Operators" + +Object and simple typed allocation +---------------------------------- + + The following sections of code are roughly equivalent and serve to show +the function of @{b }NEW@{ub }, and how it is closely related to @{b }NewR@{ub }. (The @{fg shine }type@{fg text } +can be any object or simple type.) + + DEF p:PTR TO @{fg shine }type@{fg text } + NEW p + + DEF p:PTR TO @{fg shine }type@{fg text } + p:=NewR(SIZEOF @{fg shine }type@{fg text }) + +Notice that the use of @{b }NEW@{ub } is not like a function call, as there are no +parentheses around the parameter @{b }p@{ub }. This is because @{b }NEW@{ub } is an operator +rather than a function. It works differently from a function, since it +also needs to know the types of its arguments. This means that the +declaration of @{b }p@{ub } is very important, since it governs how much memory is +allocated by @{b }NEW@{ub }. The version using @{b }NewR@{ub } explicitly gives the amount of +memory to be allocated (using the @{b }SIZEOF@{ub } operator), so in this case the +declared type of @{b }p@{ub } is not so important for correct allocation. + + The next example shows how @{b }NEW@{ub } can be used to initialise several +pointers at once. The second section of code is roughly equivalent, but +uses @{b }NewR@{ub }. (Remember that the default type of a variable is @{b }LONG@{ub }, which +is actually @{b }PTR TO CHAR@{ub }.) + + DEF p:PTR TO LONG, q:PTR TO myobj, r + NEW p, q, r + + DEF p:PTR TO LONG, q:PTR TO myobj, r + p:=NewR(SIZEOF LONG) + q:=NewR(SIZEOF myobj) + r:=NewR(SIZEOF CHAR) + + These first two examples have shown the statement form of @{b }NEW@{ub }. There +is also an expression form, which has one parameter and returns the +address of the newly allocated memory as well as initialising the argument +pointer to this address. + + DEF p:PTR TO myobj, q:PTR TO myobj + q:=NEW p + + DEF p:PTR TO myobj, q:PTR TO myobj + q:=(p:=NewR(SIZEOF @{fg shine }type@{fg text })) + +This may not seem desperately useful, but it's also the way that @{b }NEW@{ub } is +used to allocate copies of lists and typed lists (see +@{"List and typed list allocation" Link "List and typed list allocation" }). + + To deallocate memory allocated using @{b }NEW@{ub } you use the @{b }END@{ub } statement with +the pointers that you want to deallocate. To work properly, @{b }END@{ub } requires +that the type of each pointer matches the type used when it was allocated +with @{b }NEW@{ub }. Failure to do this will result in an incorrect amount of memory +being deallocated, and this can cause many subtle problems in a program. +You must also be careful not to deallocate the same memory twice, and to +this end the pointers given to @{b }END@{ub } are re-initialised to @{b }NIL@{ub } after the +memory they point to is deallocated (it is quite safe to use @{b }END@{ub } with a +pointer which is @{b }NIL@{ub }). This does not catch all problems, however, since +more than one pointer can point to the same piece of memory, as shown in +the example below. + + DEF p:PTR TO LONG, q:PTR TO LONG + q:=NEW p + p[]:=-24 + q[]:=613 + END p + /* p is now NIL, but q is now invalid but not NIL */ + + The first assignment initialises @{b }q@{ub } to be the same as @{b }p@{ub } (which is +initialised by @{b }NEW@{ub }). @{i }Both@{ui } the next two assignments change the value +pointed to by @{i }both@{ui } @{b }p@{ub } and @{b }q@{ub }. The memory allocated to store this value is +then deallocated, using @{b }END@{ub }, and this also sets @{b }p@{ub } to @{b }NIL@{ub }. However, the +address stored in @{b }q@{ub } is not altered, and still points to the memory that +has just been deallocated. This means that @{b }q@{ub } now has a plausible, but +invalid, pointer value. The only thing that can safely be done with @{b }q@{ub } is +re-initialise it. One of the @{i }worst@{ui } things that could be done is to use it +with @{b }END@{ub }, which would deallocate the same memory again, and potentially +crash your machine. So, in summary, don't deallocate the same pointer +value more than once, and keep track of which variables point to the same +memory as others. + + Just as a use of @{b }NEW@{ub } has a simple (but rough) equivalent using @{b }NewR@{ub }, +@{b }END@{ub } has an equivalent using @{b }Dispose@{ub }, as shown by the following +sections of code. + + END p + + IF p + Dispose(p) + p:=NIL + ENDIF + +In fact, it's a tiny bit more complicated than that, since OOP objects are +allocated and deallocated using @{b }NEW@{ub } and @{b }END@{ub } (see @{"Object Oriented E" Link "OOE.guide/main" }). + + +@ENDNODE + +@NODE "Array allocation" "Array allocation" +@Next "List and typed list allocation" +@Prev "Object and simple typed allocation" +@Toc "NEW and END Operators" + +Array allocation +---------------- + + Arrays can also be allocated using @{b }NEW@{ub }, and this works in a very +similar way to that outlined in the previous section. The difference is +that the size of the array must also be supplied, in both the use of @{b }NEW@{ub } +and @{b }END@{ub }. Of course, the size supplied to @{b }END@{ub } must be the same as the size +supplied to the appropriate use of @{b }NEW@{ub }. All this extra effort also gains +you the ability to create an array of a size which is not a constant +(unlike variables of type @{b }ARRAY@{ub }). This means that the size supplied to +@{b }NEW@{ub } and @{b }END@{ub } can be the result of an arbitrary expression. + + DEF a:PTR TO LONG, b:PTR TO myobj, s + NEW a[10] /* A dynamic array of LONG */ + s:=my_random(20) + NEW b[s] /* A dynamic array of myobj */ + /* ...some other code... */ + END a[10], b[s] + +The @{b }my_random@{ub } function stands for some arbitrary calculation, to show that +@{b }s@{ub } does not have to be a constant. This form of @{b }NEW@{ub } can also be used as an +expression, as before. + + +@ENDNODE + +@NODE "List and typed list allocation" "List and typed list allocation" +@Next "OOP object allocation" +@Prev "Array allocation" +@Toc "NEW and END Operators" + +List and typed list allocation +------------------------------ + + Lists and typed lists are usually static data, but @{b }NEW@{ub } can be used to +create dynamically allocated versions. This form of @{b }NEW@{ub } can be used only +as an expression, and it takes the list (or typed list) as its argument +and returns the address of the dynamically allocated copy of the list. +Deallocation of the memory allocated in this way is a bit more complicated +than before, but you can, of course, let it be deallocated automatically +at the end of the program. + + The following example shows how simple it is to use @{b }NEW@{ub } to cure the +static data problem described previously (see @{"Static data" Link "Types.guide/Static data" }). The +difference from the original, incorrect program is very subtle. + + PROC main() + DEF i, a[10]:ARRAY OF LONG, p:PTR TO LONG + FOR i:=0 TO 9 + a[i]:=NEW [1, i, i*i] + /* a[i] is now dynamically allocated */ + ENDFOR + FOR i:=0 TO 9 + p:=a[i] + WriteF('a[\\d] is an array at address \\d\\n', i, p) + WriteF(' and the second element is \\d\\n', p[1]) + ENDFOR + ENDPROC + +The minor alteration is to prefix the list with @{b }NEW@{ub }, thereby making the +list dynamic. This means that each @{b }a[i]@{ub } is now a different list, rather +than the same, static list of the original version of the program. + + Typed lists are allocated in a similar way, and the following example +also shows how to deallocate this memory. Basically, you need to know how +long the new array is (i.e., how many elements there are), since a typed +list is really just an initialised array. You can then deallocate it like +a normal array, remembering to use an appropriately typed pointer. +Object-typed lists are restricted (when used with @{b }NEW@{ub }) to an array of at +most one object, so is useful only for allocating an initialised object +(not really an array). Notice how, in the following code, the pointer @{b }q@{ub } +can be treated both as an object and as an array of one object (see +@{"Element selection and element types" Link "Types.guide/Element selection and element types" }). + + OBJECT myobj + x:INT, y:LONG, z:INT + ENDOBJECT + + PROC main() + DEF p:PTR TO INT, q:PTR TO myobj + p:=NEW [1, 9, 3, 7, 6]:INT + q:=NEW [1, 2]:myobj + WriteF('Last element in array p is \\d\\n', p[4]) + WriteF('Object q is x=\\d, y=\\d, z=\\d\\n', + q.x, q.y, q.z) + WriteF('Array q is q[0].x=\\d, q[0].y=\\d, q[0].z=\\d\\n', + q[].x, q[].y, q[].z) + END p[5], q + ENDPROC + +The dynamically allocated version of an object-typed list differs from the +static version in another way: it always has memory allocated for a whole +number of objects, so a partially initialised object is padded with zero +elements. The static version does not allocate this extra padding, so you +must be careful not to access any element beyond those mentioned in the +list. + + The deallocation of @{b }NEW@{ub } copies of normal lists can, as ever, be left to +be done automatically at the end of the program. If you want to +deallocate them before this time you must use the function +@{b }FastDisposeList@{ub }, passing the address of the list as the only argument. +You @{i }must@{ui } not use @{b }END@{ub } or any other method of deallocation. @{b }FastDisposeList@{ub } +is the only safe way of deallocating lists allocated using @{b }NEW@{ub }. + + +@ENDNODE + +@NODE "OOP object allocation" "OOP object allocation" +@Prev "List and typed list allocation" +@Toc "NEW and END Operators" + +OOP object allocation +--------------------- + + Currently, the only way to create OOP objects in E is to use @{b }NEW@{ub } and +the only safe way to destroy them is to use @{b }END@{ub }. This is probably the +most common use of @{b }NEW@{ub } and @{b }END@{ub } and is described in detail later (see +@{"Objects in E" Link "OOE.guide/Objects in E" }). + + +@ENDNODE + diff --git a/amigae33a/E_v3.3a/Docs/BeginnersGuide/Modules.guide b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Modules.guide new file mode 100644 index 0000000..e4021e0 --- /dev/null +++ b/amigae33a/E_v3.3a/Docs/BeginnersGuide/Modules.guide @@ -0,0 +1,260 @@ +@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" "Modules" +@Next "Exceptions.guide/main" +@Prev "BuiltIns.guide/main" +@Toc "Contents.guide/main" + +Modules +******* + + A @{fg shine }module@{fg text } is the E equivalent of a C header file and an Assembly +include file. It can contain various object and constant definitions, and +also library function offsets and library base variables. This information is +necessary for the correct use of a library. + + A @{fg shine }code module@{fg text } is an extension of the module idea. As well as object +and constant definitions, a code module can contain procedures and global +variables. Code modules are like C and Assembly object files. + + + @{" Using Modules " Link "Using Modules" } + @{" Amiga System Modules " Link "Amiga System Modules" } + @{" Non-Standard Modules " Link "Non-Standard Modules" } + @{" Example Module Use " Link "Example Module Use" } + @{" Code Modules " Link "Code Modules" } + + +@ENDNODE + +@NODE "Using Modules" "Using Modules" +@Next "Amiga System Modules" +@Toc "main" + +Using Modules +============= + + To use the definitions in a particular module you use the @{b }MODULE@{ub } +statement at the beginning of your program (before the first procedure +definition). You follow the @{b }MODULE@{ub } keyword by a comma-separated list of +strings, each of which is the filename (with path if necessary) of a +module (without the @{b }.m@{ub } extension--since every module file name must end +with @{b }.m@{ub }). The filenames (and paths) are all relative to the logical +volume @{b }Emodules:@{ub } (which can be set-up using an @{b }assign@{ub } as described in the +`Reference Manual'), unless the first character of the string is @{b }*@{ub }. In +this case the files are relative to the directory of the current source +file. For instance, the statement: + + MODULE 'fred', 'dir/barney', '*mymod' + +will try to load the files @{b }Emodules:fred.m@{ub }, @{b }Emodules:dir/barney.m@{ub } and +@{b }mymod.m@{ub }. If it can't find these files or they aren't proper modules the E +compiler will complain. + + All the definitions in the modules included in this way are available +to every procedure in the program. To see what a module contains you can +use the @{b }showmodule@{ub } program that comes with the Amiga E distribution. + + +@ENDNODE + +@NODE "Amiga System Modules" "Amiga System Modules" +@Next "Non-Standard Modules" +@Prev "Using Modules" +@Toc "main" + +Amiga System Modules +==================== + + Amiga E comes with the standard Amiga system include files as E modules. +The AmigaDOS 2.04 modules are supplied with E version 2.1, and the +AmigaDOS 3.0 modules are supplied with E version 3.0. However, modules +are much more useful in E version 3.0 (see @{"Code Modules" Link "Code Modules" }). If you want to +use any of the standard Amiga libraries properly you will need to +investigate the modules for that library. The top-level @{b }.m@{ub } files in +@{b }Emodules:@{ub } contain the library function offsets, and those in directories +in @{b }Emodules:@{ub } contain constant and object definitions for the appropriate +library. For instance, the module @{b }asl@{ub } (i.e., the file @{b }Emodules:asl.m@{ub }) +contains the ASL library function offsets and @{b }libraries/asl@{ub } contains the +ASL library constants and objects. + + If you are going to use, say, the ASL library then you need to open the +library using the @{b }OpenLibrary@{ub } function (an Amiga system function) before +you can use any of the library functions. You also need to define the +library function offsets by using the @{b }MODULE@{ub } statement. However, the DOS, +Exec, Graphics and Intuition libraries don't need to be opened and their +function offsets are built in to E. That's why you won't find, for +example, a @{b }dos.m@{ub } file in @{b }Emodules:@{ub }. The constants and objects for these +libraries still need to be included via modules (they are not built in to +E). + + +@ENDNODE + +@NODE "Non-Standard Modules" "Non-Standard Modules" +@Next "Example Module Use" +@Prev "Amiga System Modules" +@Toc "main" + +Non-Standard Modules +==================== + + Several non-standard library modules are also supplied with Amiga E. To +make your own modules you need the @{b }pragma2module@{ub } and @{b }iconvert@{ub } programs. +These convert standard format C header files and Assembly include files to +modules. The C header file should contain pragmas for function offsets, +and the Assembly include file should contain constant and structure +definitions (the Assembly structures will be converted to objects). +However, unless you're trying to do really advanced things you probably +don't need to worry about any of this! + + +@ENDNODE + +@NODE "Example Module Use" "Example Module Use" +@Next "Code Modules" +@Prev "Non-Standard Modules" +@Toc "main" + +Example Module Use +================== + + The gadget example program in Part Three shows how to use constants +from the module @{b }intuition/intuition@{ub } (see @{"Gadgets" Link "Examples.guide/Gadgets" }), and the IDCMP example +program shows the object @{b }gadget@{ub } from that module being used (see +@{"IDCMP Messages" Link "Examples.guide/IDCMP Messages" }). The following program uses the modules for the Reqtools +library, which is not a standard Amiga system library but a commonly used +one, and the appropriate modules are supplied with Amiga E. To run this +program, you will, of course, need the @{b }reqtools.library@{ub } in @{b }Libs:@{ub }. + + MODULE 'reqtools' + + PROC main() + DEF col + IF (reqtoolsbase:=OpenLibrary('reqtools.library',37))<>NIL + IF (col:=RtPaletteRequestA('Select a colour', 0,0))<>-1 + RtEZRequestA('You picked colour \\d', + 'I did|I can\\at remember',0,[col],0) + ENDIF + CloseLibrary(reqtoolsbase) + ELSE + WriteF('Could not open reqtools.library, version 37+\\n') + ENDIF + ENDPROC + +The @{b }reqtoolsbase@{ub } variable is the library base variable for the Reqtools +library. This is defined in the module @{b }reqtools@{ub } and you @{i }must@{ui } store the +result of the @{b }OpenLibrary@{ub } call in this variable if you are going to use +any of the functions from the Reqtools library. (You can find out which +variable to use for other libraries by running the @{b }showmodule@{ub } program on +the library module.) The two functions the program uses are +@{b }RtPaletteRequestA@{ub } and @{b }RtEZRequestA@{ub }. Without the inclusion of the @{b }reqtools@{ub } +module and the setting up of the @{b }reqtoolsbase@{ub } variable you would not be +able to use these functions. In fact, if you didn't have the @{b }MODULE@{ub } line +you wouldn't even be able to compile the program because the compiler +wouldn't know where the functions came from and would complain bitterly. + + Notice that the Reqtools library is closed before the program +terminates (if it had been successfully opened). This is always +necessary: if you succeed in opening a library you @{i }must@{ui } close it when +you're finished with it. + + +@ENDNODE + +@NODE "Code Modules" "Code Modules" +@Prev "Example Module Use" +@Toc "main" + +Code Modules +============ + + You can also make modules containing procedure definitions and some +global variables. These are called @{fg shine }code modules@{fg text } and can be extremely +useful. This section briefly outlines their construction and use. For +in-depth details see the `Reference Manual'. + + Code modules can be made by using the E compiler as you would to make +an executable, except you put the statement @{b }OPT MODULE@{ub } at the start of the +code. Also, any definitions that are to be accessed from outside the +module need to be marked with the @{b }EXPORT@{ub } keyword. Alternatively, all +definitions can be exported using @{b }OPT EXPORT@{ub } at the start of the code. +You include the definitions from this module in your program using @{b }MODULE@{ub } +in the normal way. + + The following code is an example of a small module: + + OPT MODULE + + EXPORT CONST MAX_LEN=20 + + EXPORT OBJECT fullname + firstname, surname + ENDOBJECT + + EXPORT PROC printname(p:PTR TO fullname) + IF short(p.surname) + WriteF('Hello, \\s \\s\\n', p.firstname, p.surname) + ELSE + WriteF('Gosh, you have a long name\\n') + ENDIF + ENDPROC + + PROC short(s) + RETURN StrLen(s)