| |
A number of common mistakes can be made when writing OVM code. Some of these reflect weak areas in the OVM / Wozterm / Ozterm language, while others reflect weak areas in the OVM compiler. In future versions of OVM changes may be made to the language, and to the OVM compiler to remove these weaknesses. Some of the more common problems are described here with an example of each.
Perhaps the easiest mistake to make is to forget the @ at the start of an OVM command line. Since OVM attempts to be backwards compatible with Ozterm, and Ozterm sends non @ lines to the currently connected host the OVM compiler will not always generate an error message when you forget the @. In some cases the compiler can detect the error but it other cases it will assume the line was meant to be a host command. You can tell the OVM compiler to display (via your application) an error or a warning about every implicit host command. You should always turn the error option on if you do not intend to use implicit host commands in your program
comment("Hello World") ! Oops - this may get sent to an exchange instead
The OVM compiler will always pick you up on this one provided that no variable of the same name exists in an outer scope.
@for i = 1 to 10 ! oops - we didn't define i
@begin
@comment("i = ",i)
@end
@goto START ! Jump to label START
@integer fred = 33 ! Oops - this line won't be reached at runtime
@label START
@comment("fred = ",fred) ! Display fred's value
Although the OVM compiler knows the variable fred exists it does not assign the value 33 to fred until the line @integer fred = 33 is reached at runtime. This is because the above code is a shorthand for :
@goto START ! Jump to label START
@integer fred ! This line is used at compile time
@set fred = 33 ! Oops - this line won't be reached at runtime
@label START
@comment("fred = ",fred) ! Display fred's value
To explicity assign a deafult value to a variable the defaultvalue keyword.
@integer fred defaultvalue = 33 ! Variable given 33 as default value
When using strings containing escape sequences remember that you must use backquotes to contain the string. Escape sequences only work within backquotes to maintain backwards compatability with Ozterm which supports neither backquotes or escape sequences.
@string ansiclearscreen = "\e[2J" ! wont work @string ansiclearscreen = `\e[2J` ! will work
When using string literals (eg "Hello World") remember to use the same quote character to end the string as you used to start the string.
@string fred = "Hello world" ! everything ok here @string mary = "Hi Fred’ ! oops - wrong closing quote
Remember that on most systems an OVM integer will be internally represented by 32 bits organised as a 2’s complement number. This means the range of an integer is limited to -2147483648 to 2147483647 (-$80000000 to $7FFFFFFF hex). If you try to assign a larger or smaller value than this to an integer the result will be undefined (Ie not the answer you were expecting). Currently the OVM compiler does not detect integer literals that are too large or small but it may do so in future versions. In some cases it is better to use a string, or an array of integers such as when storing 10 digit telephone numbers.
@integer fred 9999999999 ! Oops - this number is just too big !
A string variable can hold a maximum of 255 characters. Attempting to exceed this limit will result in either a compile time, or run time error.
! Setting fred as below will cause a compile time error @string fred = \ "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" ! Concatenating mary and jane will cause a runtime error @string mary = \ "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ @string jane = \ "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ + "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"\ @string oops = mary + jane ! runtime error
Programmers who are used to the C / C++ programming language may find themselves forgetting to including the "then" keyword after an if statement. The OVM compiler will always pick this error for you.
@integer a = random(100) ! pick a number
@if a > 50 ! oops - forgot the then
@comment("a is bigger than 50")
The following function is meant to remember how many times it has been called but it has a logic error which keeps reseting the crictical variable. This error can be corrected by using the defaultvalue keyword.
@procedure TheCount() ! I display how many times I have been called (or do I?)
@begin
@integer count = 0 ! Oops - I should have used the defaultvalue keyword
@inc(count) ! Add 1 to count
@comment("I am the count and I love to count. Ha ha ha ha.")
@comment("I am counting the number of times you have called me.")
@comment("You have called me ",count," times. Ha ha ha ha.")
@end
@for integer i = 1 to 10 ! We will call TheCount 10 times
@begin
@TheCount() ! Call TheCount
@end
In DOS Ozterm a FOR loop has a similar syntax to the BASIC programming language where the end of the loop was determined by encountering a NEXT statement. The OVM compiler will pick up this up as an error as the Ozterm keyword NEXT is not supported in OVM (see NEXTLOOP). In OVM a FOR loop has a syntax similar to Pascal where the loop condition is followed by either a single command, or by a begin - end block. Ozterm’s ENDFOR command has been replaced with the generic ENDLOOP command which also works with WHILE and REPEAT loops.Ozterm’s NEXT command has been replaced with the generic NEXTLOOP command which also works with WHILE and REPEAT loops.
! This was the old Ozterm way
@for fred = 1 to 10
! code to loop goes here
! and here
! and here etc
@next fred
! The new OVM / Wozterm / Wozix way for a single command
@for integer mary = 1 to 10
@comment("One command on its own")
! The new OVM / Wozterm / Wozix way for a block of commands
@for integer jane = 1 to 10
@begin
! code to loop goes here
! and here
! and here
! note - you can use an endloop to exit early
! note - you can use a nextloop to loop early
@end
Remember that when you want a FOR loop to count down to a value you need to use "downto" instead of "to". The OVM compiler will not pick you up on this even if you use literals / constants for the loop bounderies as in the examples above.
@for fred = 1 to 10 ! Display 1 up to 10
@comment("fred = ",fred)
@for mary = 10 to 1 ! Oops - Won't count down
@comment("mary = ",fred)
@for jane = 10 downto 1
@comment("jane = ",jane) ! Display 10 down to 1
In DOS Ozterm a label that has been defined with the @label command could be called by a variety of commands but most commonly by @goto, and @gosub. In OVM the new keyword @subroutine has been added to prevent accidentally goto’ing a subroutine, or gosub’ing a label. The OVM compiler will detect this error for you.
@label ABCD ! define label called ABCD
@goto ABCD ! works
@gosub ABCD ! not allowed
@subroutine EFGH ! define a subroutine called EFGH
@begin
! Subroutine code goes here
@end
@gosub EFGH ! works
@goto EFGH ! not allowed
To group blocks of commands you must use @BEGIN and @END. Forgetting to do so may result either in compile time errors or in unexpected results at runtime.
! The @else will cause a compile time error because
! the 2 comment lines were not enclosed within a begin-end block
@integer a = random(100)
@if a > 50 then
@comment("a is greater than 50")
@comment("but less than 101") ! oops - should have used a begin end block
@else
@comment("a is less than or equal to 50")
! The @for loop below will produce the incorrect result at runtime
! because the @comment line will not be executed by the @for loop
@for integer i = 1 to 10
@display("The value of i = ")
@comment(i) ! oops - should have used a begin end block
| |
| This publication has been prepared and written by Telstra Corporation Limited (ACN 051 775 556), and is copyright. Other than for the purposes of and subject to the conditions prescribed under the Copyright Act, no part of it may in any form or by any means (electronic, mechanical, microcopying, photocopying, recording or otherwise) be reproduced, stored in a retrieval system or transmitted without prior written permission from the document controller. Product or company names are trademarks or registered trademarks of their respective holders. Note for non-Telstra readers: The contents of this publication are subject to change without notice. All efforts have been made to ensure the accuracy of this publication. Notwithstanding, Telstra Corporation Limited does not assume responsibility for any errors nor for any consequences arising from any errors in this publication. |