home *** CD-ROM | disk | FTP | other *** search
- *------------------------*
- * Tutorial : expressions * Sun Sep 1 14:42:42 1991
- *------------------------*
-
-
- ===================== Commands used in this tutorial =========================
-
- disp Display integer
- exec Go to the ExecBase list
- help Ask for help
- list Show a list (tasks, libraries, message ports, ...)
- loadfd Load a fd file
- memory List memory
- print Print a string
- remvar Remove a variable
- scan Ask input
- task Go to the task list
- void Evaluate the arguments given
-
- ===================== Functions used in this tutorial ========================
-
- alloc Allocate memory
- cols Ask the number of columns in logical window
- eval Evaluate string
- free Free memory
- if Conditional evaluation
- lines Ask the number of rows in logical window
-
- ============================== Introduction ==================================
-
- PowerVisor has a very powerful expression evaluator. Before you continue
- reading this file make sure you have mastered the basic features of
- PowerVisor (read the file 'GettingStarted' first).
-
- First start PowerVisor (if it is not already in memory).
-
- PowerVisor has two basic types: ¹strings and ¹integers. Sometimes these two
- types collide a bit. In this tutor file I will make you more comfortable
- with all the features PowerVisor has in this regard.
-
- All commands and functions in PowerVisor expect integers and/or strings
- as their arguments. You can use expressions everywhere.
-
- ============================= Simple integers ================================
-
- First we have ²decimal integers :
-
- < disp 5 <enter>
- > 00000005 , 5
-
- < disp 1236 <enter>
- > 000004D4 , 1236
-
- < disp -100 <enter>
- > FFFFFF9C , -100
-
- But not (can you see why ?) :
-
- < disp 01236 <enter>
- > 00001236 , 4662
-
- This last notation is used for ²²hexadecimal numbers :
-
- < disp 01A <enter>
- > 0000001A , 26
-
- < disp $1a <enter>
- > 0000001A , 26
-
- You can see that PowerVisor has two ways to notate a hexadecimal number.
- PowerVisor interpretes '0<number>' as a hexadecimal number because this is
- very convenient if you 'snap' a hex number from the PowerVisor screen. Such
- a number almost always contains some leading zeroes.
-
- Note that in the current version of PowerVisor the following command :
-
- < disp 1A <enter>
-
- does not give an error :
-
- > 00000001 , 1
-
- This is in fact a bug and it will be solved in a later version of PowerVisor.
-
- =============================== Expressions ==================================
-
- You can use more complex ¹expressions :
-
- < disp 5+5 <enter>
- > 0000000A , 10
-
- < disp 1+(5*9)-(3&5) <enter>
- > 0000002D , 45
-
- Note that you cannot use spaces in expressions.
-
- You can use the following binary operators. The list is from high to
- low priority :
-
- * / % ¹¹multiply, ²²integer divide, ¹¹remainder
- + - ¹¹add, ¹¹subtract
- << >> ²²left shift, ²²right shift
- > < >= <= ²²integer comparisons
- != == ³³not equal to, ²²equal to
- & ²²bitwise and
- ^ ²²bitwise xor
- | ²²bitwise or
- && ²²logical and
- || ²²logical or
-
- There are also some ²²unary operators :
- - ¹¹negation
- ! ²²logical not
- ~ ²²bitwise not
- * ²²contents operator
- & ²²address operator (explained later)
-
- You can also use brackets.
- Some examples :
-
- < disp 5+(9-(7*(5/(3+~1 <enter>
- > FFFFFFEB , -21
-
- Note that you need not close all brackets.
-
- The contents operator needs some more examples :
-
- < disp *4 <enter>
- > 07E007E4 , 132122596
-
- (This is the pointer to execbase)
-
- < disp *4.b <enter>
- > 00000007 , 7
-
- < disp *4.w <enter>
- > 000007E0 , 2016
-
- < disp *(2+2).l <enter>
- > 07E007E4 , 132122596
-
- The syntax of the * operator is:
- '*'<expression>['.' ('b' | 'w' | 'l') ]
- 'b', 'w' and 'l' are the size indicators (b = byte, w = word, l = long).
- If you do not specify '.', PowerVisor assumes long mode. This operator checks
- for illegal addresses :
-
- < disp *5 <enter>
- > Odd address error !
-
- On the ¹68000 processor you cannot read a long at an ²odd address.
- PowerVisor will always give this error even if you have a ¹68020/68030
- processor.
-
- ============================= String pointers ================================
-
- A ²²string pointer is NOT a string, it is an integer. When you use a string
- pointer, PowerVisor will allocate a temporary space for this string and
- give you the address. Example :
-
- < disp "Hello" <enter>
- > 07E50E52 , 132451922
-
- < memory 07E50E52 10 <enter>
- > 07E50E52: 68656C6C 6F0007E2 1010 Hello.....
-
- PowerVisor remembers the last 10 strings and string pointers (all in one
- pool) before it frees them. This means that you can only use 10 string
- pointers in one command at the same time.
- If you want a permanent string pointer you can use the 'alloc' function.
-
-
- The next example illustrates the use of the ²contents operator (*) and
- a string pointer :
-
- < disp *("Hello"+1).b <enter>
- > 00000065 , 101
-
- (101 is the ascii value for 'e').
-
- Look at the following example :
-
- < memory "Left\41\42\43Right" 16 <enter>
- > 07EC98A2: 4C656674 41424352 69676874 000007EC LeftABCRight....
-
- The '\' notation is useful for ²unprintable characters (and untypable).
- After the '\' follow two hexadecimal digits. If the first character following
- the '\' is not a hexadecimal digit the first '\' is ignored :
-
- < memory "Left\\Right" 10 <enter>
- > 07E5C0BA: 4C656674 5C526967 6874 Left\Right
-
- < memory "Left\"Right" 10 <enter>
- > 07E5C0BA: 4C656674 22526967 6874 Left"Right
-
-
- There is one extra feature that you have with quoting. Consider the
- following example :
-
- < memory "Left\(4+5)Right" 16 <enter>
- > 07E31A72: 4C656674 39526967 68740000 00000000 Left9Right......
-
- The expression between the two brackets can be as complex as you wish.
- You can use variables, functions, ...
- You can use an optional ²format string directly after the expression (include
- some white space of course). Use standard ¹C-formatting conventions :
-
- < memory "Left(4+5,%02ld)Right" 16 <enter>
- > 07E31A72: 4C656674 30395269 67687400 00000000 Left09Right.....
-
- < memory "Left(65,%lc)Right" 16 <enter>
- > 07E31A72: 4C656674 41526967 68740000 00000000 LeftARight......
-
-
- ================================== Names =====================================
-
- ¹¹Names are probably the most difficult things in the PowerVisor parsing
- language. They can be almost everything. I think examples are the best
- way to illustrate their purpose :
-
- < task <enter>
- < list <enter>
-
- > Task node name : Node Pri StackPtr StackS Stat Command Acc
- > ---------------------------------------------------------------------------
- > RAM : 07E25260 00 07E2554E 1200 Rdy PROC -
- > Background Process : 07E26BA8 00 07E2CBD8 4000 Wait iprefs (02) -
- > RexxMaster : 07E39BA8 04 07E3A3EA 2048 Wait (00) -
- > SYS:System/CLI : 07E529C0 00 07E538CA 4096 Wait (00) -
- > ramlib : 07E1F680 00 07E1FE80 2048 Wait PROC -
- > CON : 07E56A20 05 07E57522 3200 Wait PROC -
- > Background CLI : 07E65518 00 07E65F66 3200 Wait (01) -
- > console.device : 07E0E1A2 00 07E0F1A4 4096 Wait TASK -
- > PowerSnap 1.0 by Nic: 07E48450 05 07E48C9A 2000 Wait PROC -
- > WB_2.x : 07E11488 0A 07E11E4E 2400 Wait PROC -
- > DF0 : 07E17208 0A 07E17BCE 2400 Wait PROC -
- > Workbench : 07E54930 01 07E56956 8192 Wait (05) -
- > PowerVisor1.0.task : 07E7CBE0 00 07E7D096 1024 Wait TASK -
- > SCSI bus handler : 07E0AFD0 0C 07E0B3B6 1000 Wait TASK -
- > scsi.device : 07E0A3F8 0B 07E0A396 1000 Wait TASK -
- > trackdisk.device : 07E0F988 05 07E0FB96 512 Wait TASK -
- > Work : 07E19940 0A 07E1A306 2400 Wait PROC -
- > Background Process : 07E3B4A0 00 07E52354 4000 Wait clock (03) -
- > input.device : 07E08AF2 14 07E09AF8 4096 Wait TASK -
- > Background Process : 07E7B418 04 07E8E386 4000 Run pv (04) -
-
- < disp powervisor <enter>
- > 07E7CBE0 , 132631520
-
- In this case we used a name ('powervisor') as an ¹abbreviation for an element
- in the ²current list. We could also have written :
-
- < disp POWERvi <enter>
-
- or
-
- < disp 'Powervisor1' <enter>
-
- or
-
- < disp power <enter>
-
- The last command is correct but it is ambiguous in this case since there are
- two names in the current list beginning with 'power'. When this is the case
- the first match is used (PowerSnap 1.0 in this case).
-
- Important to remember is that when we use names for this purpose the
- following rules apply :
-
- - you may use quotes (if you want to include spaces for example)
- - the searching is case insensitive
- - you can use abbreviations, i.e. you need not give the full name
-
- Consider the following example :
-
- < powervisor=5 <enter>
-
- < disp powervisor <enter>
- > 00000005 , 5
-
- < disp 'powervisor' <enter>
- > 07E7CBE0 , 132631520
-
- < disp powerviso <enter>
- > 07E7CBE0 , 132631520
-
- < disp powervisor1 <enter>
- > 07E7CBE0 , 132631520
-
- We have created a ¹¹variable 'powervisor' with value 5. The name 'powervisor'
- has now lost it's meaning as an abbreviation for an element in the current
- list. Note that we can still use 'powerviso' and 'powervisor1' for the
- element in the current list.
- So we see that the following rules apply for variables :
-
- - you can't use quotes for variable names (if you do it is interpreted
- as an element in the current list)
- - variable names can't be abbreviated
- - variable names are case insensitive
-
- When you use quotes you ²force interpretation of the ²current list. There
- is a shorter and better way to do this (also see the 'List operator'
- section) :
-
- < disp :powervisor <enter>
- > 07E7CBE0 , 132631520
-
- Now we remove the created variable :
-
- < remvar powervisor <enter>
-
- There is still a third way to interprete names. But it is at this moment
- not appropriate to give examples. A name can also be a ¹symbol
- for the ³current debug task (see debugging). The rules for symbol names
- are :
-
- - you can use quotes
- - symbol names are case sensitive
- - no abbreviations are possible
-
- In case of ambiguity observe the following order of checking :
-
- - PowerVisor will first check if it is a variable
- - If it is not a variable it could be a symbol for the current debug task
- - If it is not a symbol PowerVisor will search the current list
-
- If you use quotes for the name, PowerVisor will skip the variable testing
- and only test if it is a symbol or a list element. If you use the ':'
- operator (see above) PowerVisor will only search the current list.
-
-
- ================================ Functions ===================================
-
- ¹¹Functions are a special form of ¹variables. Internally they are almost the
- same. Type :
-
- < help functions <enter>
-
- > General functions
- > -----------------
- > ALLOC : allocate memory LASTMEM : give last memory
- > FREE : free memory LASTFOUND : last search address
- > REALLOC : reallocate memory PEEK : peek value in structure
- > GETSIZE : give size of memoryblock APEEK : peek address
- > ISALLOC : is memory a pv-block ? STSIZE : get structure size
- > KEY : returns pressed key RFCMD : refresh command
- > QUAL : qualifier for last key RFRATE : refresh rate
- > GETCOL : get logical col width GETLWIN : current logical window
- > GETROW : get logical row height GETERROR : get error of routine
- > TOPPC : get debug win top pc TAGLIST : get current tag list
- > BOTPC : get debug win bottom pc EVAL : evaluate argument string
- > ISBREAK : check if breakpoint IF : conditional evaluation
- > GETDEBUG : get current debug ptr CURLIST : current list
- > GETX : get the current x coord COLS : get max nr of cols
- > GETY : get y coord LINES : get max nr lines
- > GETCHAR : get the current char BASE : get first listelem
-
- Since functions are so much like variables the same evaluation rules apply
- to them (see the previous section: 'names'). You must use the full name
- (no abbreviations). The only exception is that you must use brackets after
- the function name even if there are no arguments.
-
- Some examples :
-
- < disp lines(main)
- > 00000035 , 53
-
- This means that I have 53 lines on my PowerVisor screen.
- (See the 'screen' manual for more complete information about this function).
- 'main' is the argument for the function.
-
- The following is incorrect (There is a space between 'lines' and '(main)') :
-
- < disp lines (main)
- > You must use brackets with functions !
-
- The following is correct (You need not close the brackets) :
-
- < disp cols(main
- > 00000056 , 86
-
- ============================ Library functions ===============================
-
- PowerVisor has the very powerful capability to execute ²library functions.
- You only need to load the corresponding ¹fd-file (in the fd2.0 or fd1.3
- subdirectory) :
-
- < loadfd exec :fd2.0/exec_lib.fd <enter>
-
- or
-
- < loadfd libs:exec :fd2.0/exec_lib.fd <enter>
-
- > New functions: 0000007E,126
-
- PowerVisor will then know how to call all functions from the exec library.
-
- You can now use all the exec library functions as if they were normal
- PowerVisor functions :
-
- < disp typeofmem(100000) <enter>
- > 00000303 , 771
-
- < disp openlibrary("exec.library",0) <enter>
- > 07E007E4 , 132122596
-
- The following rules for ²²library functions apply :
-
- - you MUST use brackets even if there are no arguments (like functions)
- - you MUST close the brackets for the library function arguments. This
- means that if you use an expression as an argument you must close the
- brackets for this expression as well
- - you cannot use abbreviations for library functions
- - library function names are case insensitive
- - you cannot use quotes
-
- ============================ The list operator ===============================
-
- Example :
-
- < exec <enter>
- < list <enter>
-
- > SoftVer : 00CF | LowMemChkSum : 0000 | ChkBase : F81FF81B
- > ColdCapture : 00000000 | CoolCapture : 00000000 | WarmCapture : 00000000
- > SysStkUpper : 07E02248 | SysStkLower : 07E00A48 | MaxLocMem : 00200000
- > DebugEntry : 00F82E28 | DebugData : 00000000 | AlertData : 00000000
- > MaxExtMem : 00000000 | ChkSum : A366 | ThisTask : 07E7B418
- > IdleCount : 000CC6E6 | DispCount : 0005444A | Quantum : 0004
- > Elapsed : 0004 | SysFlags : 0000 | IDNestCnt : FF
- > TDNestCnt : F4 | AttnFlags : 0017 | AttnResched : 0000
- > ResModules : 07E00428 | TaskTrapCode : 07E80AE6 | TaskExceptCod: 00F83A9C
- > TaskExitCode : 00F823D0 | TaskSigAlloc : 0000FFFF | TaskTrapAlloc: 8000
- > VBlankFreq : 32 | PowerSupplyFr: 32 | KickTagPtr : 00000000
- > KickCheckSum : 00000000 | RamLibPrivate: 07E1F470 | EClockFreq : 000AD303
- > CacheCtrl : 00002919 | TaskID : 00000001 | PuddleSize : 00000000
- > MMULock : 00000000 |
-
- We are now in the execbase ²structure list.
-
- < disp quantum <enter>
- > 00000004 , 4
-
- The same rules apply as for normal list element searching (see the 'Names'
- section).
-
- If there are possible ambiguities you can use the ':' operator.
-
- < disp :quantum <enter>
- > 00000004 , 4
-
- If you want to change the quantum variable you can use the '&' operator
- (This operator is only supported for lists of this type (exec, graf, intb,
- ...)) :
-
- < disp &exec:quantum <enter>
- > 07E00904 , 132122884
-
- This operator returns the address of the quantum variable in the exec base
- list.
-
- You can now use this address to change the variable (also see the 'Assignment'
- section) :
-
- < *&exec:quantum.w=16 <enter>
-
- You can also use the list name before the operator (useful if you are in
- another current list) :
-
- < d exec:quantum <enter>
- > 00000004 , 4
-
- =============================== Assignment ===================================
-
- We have already used ¹¹assignment a few times. We used it to assign a value
- to a ¹variable, and we used it (in the previous section) to assign a value
- to a memory location. Here are some more examples :
-
- < a=4 <enter>
- < b=5 <enter>
- < disp a+b <enter>
- > 00000009 , 9
-
- < var100=100 <enter>
- < var100=var100+var100 <enter>
- < disp var100+var100 <enter>
- > 00000190 , 400
-
- In this form we use assignment to assign a value to a variable.
-
- Do not put spaces arround the '=' operator. Otherwise PowerVisor will
- try to execute the variable as a command and the '=' as an argument.
-
- One more example :
-
- < mem=alloc(n,100) <enter>
- < *mem=$11111111 <enter>
- < *(mem+4).w=$2222 <enter>
- < *(mem+6).b=$33 <enter>
-
- < memory mem 16 <enter>
- > 07E7761A: 11111111 22223300 00000000 00000000 ....""3.........
-
- < void free(mem) <enter>
-
- With the 'alloc' function we allocated 100 bytes of memory. (The 'n' argument
- means the next argument is a number (see the 'alloc' function for more
- details). Then we fill this memory with some values. With the 'memory'
- command we display them.
- After that we use the 'free' function to free our ²allocated memory. Note
- that PowerVisor will automatically ²free memory allocated with 'alloc' when
- PowerVisor quits.
-
- =========================== The group operator ===============================
-
- Sometimes it is conveniant to ³group several commands together. You can do
- just this with the ²²group operator. You can use the group operator in two
- different ways. As a command or as a function. Here are some examples :
-
- Using the group operator as a command :
-
- < {disp 3;disp 5;disp 7} <enter>
- > 00000003 , 3
- > 00000005 , 5
- > 00000007 , 7
-
- < {{disp 1;{{disp 2};disp 3};disp 4};disp 5} <enter>
- > 00000001 , 1
- > 00000002 , 2
- > 00000003 , 3
- > 00000004 , 4
- > 00000005 , 5
-
- < {a=2;b=3;disp a*b} <enter>
- > 00000006 , 6
-
- You can see that the sole purpose of this operator is to allow you to
- give more than one command on the commandline. This can be very useful
- when some command expects another command as an argument (see the
- 'refresh' command).
-
- You can also use the group operator as a function :
-
- < disp {a=4}*2 <enter>
- > 00000008 , 8
-
- This command will first assign 4 to 'a' and then execute 'disp 4*2'.
-
- < disp {a=4;temp=a*7;void temp+temp*(temp/4)} <enter>
- > 000000E0 , 224
-
- The 'void' command simply evaluates all it's arguments. It does not
- display anything.
-
- < disp {disp 1}+2 <enter>
- > 00000001 , 1
- > 00000003 , 3
-
- When the group operator is used as a function, it is the last executed
- command in this group that determines the ²return value. The return value
- is different for each command. Look at the command reference for more
- details.
-
- ================================= Strings ====================================
-
- All previous sections covered integers. PowerVisor also uses ¹¹strings. A
- string is very easy. When a command expects a string, almost everything
- is correct. Some examples :
-
- < print Hello <enter>
- > Hello
-
- < print Hello\0a <enter>
- > Hello
-
- Notice the difference between these two commands. If you do not explicitely
- ask for a <enter> at the end of the line you will not get one. '\0a' is the
- linefeed character.
-
- < print 'Hello\0a' <enter>
- > Hello
-
- < print 5+6 <enter>
- > 5+6
-
- < print Complete rubbish <enter>
- > Complete
-
- < print 'Complete rubbish' <enter>
- > Complete rubbish
-
- < print 'Complete rubbish <enter>
- > Complete rubbish
-
- < print "Complete rubbish" <enter>
- > Complete rubbish
-
- < print 'a\0ab\0ac\0ad\0a' <enter>
- > a
- > b
- > c
- > d
-
- < print Hello\ you <enter>
- > Hello you
-
- < print 'Hello you' <enter>
- > Hello you
-
- Strings are very versatile. Even the notation for ²string pointers (double
- quotes) is accepted.
-
- There is one exception :
-
- < a="Hello there\0a" <enter>
- < print a <enter>
- > a
-
- < print #a <enter>
- > Hello there
-
- You can use the ²# operator to interprete a string pointer in a variable
- as a string. You can't simply use the variable because PowerVisor will parse
- this as if it was a string. You must preceed the variable with a '#'.
- The expression after the '#' operator is not limited to variables only, you
- can use complex expressions.
-
- Strings (like string pointers) also support the special integer quoting
- feature :
-
- < a=1 <enter>
- < print 'Testing \(a) \(2,%03ld) \(11+11+11,%04lx) \(65,%lc) !\0a' <enter>
- > Testing 1 002 0021 A !
-
- < print 'First string : \("Second string",%6.6s).\0a' <enter>
- > First string : Second.
-
-
- ========================== Some useful functions =============================
-
- You can make ²²conditional expressions using the 'if' function. Here is an
- example :
-
- < a=2 <enter>
- < disp if(a==2,1000+5,2000) <enter>
- > 000003ED , 1005
-
- A very complex example :
-
- < disp if(a==3,{disp 3*3;void 1},if(a==2,{disp 2*2;void 1},0))
- > 00000004 , 4
- > 00000001 , 1
-
- This completely useless command computes the square of the variable 'a',
- but only if 'a' is equal to 2 or to 3. It also prints the value 1 if 'a'
- is equal to 2 or to 3, and 0 if it isn't.
-
- I think some detailed explanation can be useful here :-)
-
- The 'disp' command takes it's first argument and prints it.
- This argument is equal to :
-
- if(a==3,{disp 3*3;void 1},if(a==2,{disp 2*2;void 1},0))
-
- The first thing that is evaluated is the 'if' function. The 'if' function
- has three arguments :
-
- one number :
- a==3
-
- and two other expressions :
- {disp 3*3;void 1}
- if(a==2,{disp 2*2;void 1},0)
-
- If 'a' is equal to 3 the first string is taken and evaluated.
-
- This results in evaluation of the following expression :
-
- {disp 3*3;void 1}
-
- This is a ²group expression (see the ²group operator). The group operator
- executes all the commands in it and returns as a result the result
- from the last executed command. This results in the execution of :
-
- disp 3*3
-
- and
-
- void 1
-
- So 9 is printed on the screen and 1 is returned as a result from
- the group operator (the 'void' command simply evaluates all it's
- arguments).
-
- So the result of the first 'if' function is 1 (but 9 is already
- printed). This result is printed. So you have 9 and 1 as output.
-
- ! End evaluation !
-
- If 'a' is not equal to 3 the second string is taken and evaluated.
-
- This results in evaluation of the following string :
-
- if(a==2,{disp 2*2;void 1},0)
-
- This is again an 'if' expression and is evaluated analogous.
-
- If you happen to have an ¹expression in a string (this could be a string typed
- in by the user) you can evaluate it using the 'eval' function :
-
- Ask for input ('scan' returns a pointer to a string. We store the pointer in
- variable 'a') :
-
- < a={scan} <enter>
-
- Type an expression :
-
- < 10+5 <enter>
-
- See if the string is really correct :
-
- < print #a <enter>
- > 10+5
-
- Evaluate it :
-
- < disp eval(#a) <enter>
- > 0000000F , 15
-
- or you can of course type :
-
- < disp eval('10+5') <enter>
- > 0000000F , 15
-