In this chapter we suggest a few guidelines about how a Proteus program should be
formatted to increase readability, comprehensibility and portability. Obviously, you are
free to follow or not these suggestions: however, if you follow them it will be easier for
people that have read this manual to understand your programs.
Formatting rules:
- the body of WHILE, REPEAT and FOR
should be indented by at least two characters until the corresponding LOOP, UNTIL
or NEXT, that should be aligned with the
corresponding starting method:
WHILE test
method
..
LOOP
|
REPEAT
method
..
UNTIL test
|
FOR id = v1 TO v2
method
..
NEXT
|
- the body of IF should be indented by at
least two characters until ELSE (if
present) or FI; ELSE and FI
should be aligned with the corresponding IF, while the body of the ELSE
branch should be indented as already mentioned:
IF test
method
..
ELSE
method
..
FI
|
!ifdef MS_DOS
!include "dosspec.prt"
!else
!include "unxspec.prt"
!endif
|
- the body of SWITCH should be indented
by at least two characters until the corresponding OFF;
the body of each case ON or OTHER should be indented by another two
characters:
SWITCH exp [func]
ON v1[, v2..]
method
..
ONC v3[, v4..]
method
..
OTHER
method
..
OFF
|
- the body of every UDF should be indented by
at least two characters after the FUNCTION
declaration and should be separated from it by a single blank line; the last RETURN should be aligned with FUNCTION:
FUNCTION FuncName(par..)
method
..
RETURN exp
|
- if the value returned is always ignored (the function is actually a procedure), omit the
expression following RETURN; for example, this is especially true for the
predefined functions ONSTART and ONEND;
- all reserved words (methods, library
functions, predefined identifiers),
constants and labels should be written in UPPERCASE; the names of local identifiers should be written in lowercase,
just like the names of the directives; UDF
names and public identifiers should be Capitalized;
by using these rules it is easy, for example, to detect a common mistake which consists in
accessing a public identifier in a UDF without using PSET or PUB.
Identifiers consisting in more than one word should be written with every initial letter
converted to uppercase (e.g. MyVar) or using an underscore (e.g. MY_VAR); this is true
even for UDF names; e.g.:
!ifdef ITALIANO
CONST DEF_DAYS = "Dom Lun Mar Mer Gio Ven Sab"
CONST DEF_MONTHS = "Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic"
CONST TODAY_IS = "Oggi è: "
!else
CONST DEF_DAYS = "Sun Mon Tue Wed Thu Fri Sat"
CONST DEF_MONTHS = "Jan Feb Mar Apr May Jun Jul Ago Sep Oct Nov Dec"
CONST TODAY_IS = "Today is: "
!endif
FUNCTION DayMonthYear(date)
RETURN CDOW(date) " " DAY(date) CMONTH(date) " " YEAR(date)
Today = DATE()
DAYS = DEF_DAYS
MONTHS = DEF_MONTHS
CONSOLELN TODAY_IS DayMonthYear(Today)
|
- if a line of code exceeds 80 columns, use the end of line character ('\') to break
it down to shorter lines; in this way, the script can be read without horizontally
scrolling the text;
- use !ifdef MS_DOS (or UNIX
or WINDOWS) to isolate
system-dependant parts of the script;
- use FUNC only when strictly needed, to
speed up execution time and keep the control over the number of parameters specified in a
function call;
- insert the command line parameter -k (e.g. in the line #!) when relative paths appear in the script and you want to
use it both under Dos and under Unix; avoid, in this case, specifying drive letters;
- use constants as much as possible, avoiding to repeat the same
values over and over again (constants are easier to maintain and let you avoid errors
introduced by manually inserting the same value in several places of the script);
- try to limit access and modification of public variables
in UDF; pass the required variables as parameters and use the explicit reference operator (@) to underline
that the variable can be modified by the function;
- keep your UDFs short; adopt divide
and conquer extensively, to avoid copying large pieces of code;
- avoid using variables, if their value is used only once; if possible, re-use the
variables (but do not mix types, to avoid confusion) and nest the calls to completely
avoid unneeded SETs;
- insert all the constants used at the beginning of the script;
- write a lot of remarks; use the directives !bdoc/!edoc to insert multi-line remarks;
- if the Proteus script must be run directly using the line #!,
always specify the character '#' as the start of remark.
The example protform.prt can be used to correctly
format any Proteus program according to the rules above.
Naming conventions
Whenever distinguishing the type of each variable becomes crucial, it is reccomended to
start the name of the variable with a letter identifying its type, according to the
following table: