III. Basic components
3.1 Naming convention:
1. Built-in:
A Note on CHARACTER Literals
There are two ways to express character literals.
Any printable character (alphanumeric or symbol) can
be expressed by enclosing it in apos-trophes
(single quotes).
'A' 'a'
'?' '$' '+'
Control characters which are not
printable can be expressed using a format similar to that for decimal integers.
The decimal (i.e. base 10) value of the character is written followed by
the letter C. The C must be in upper-case.
13C => carriage return
7C => bell
27C => escape
A Note on STRING Literals
To use the quotation character inside
a string literal, place two quotation marks wherever a single one is needed
in the string. For instance:
"He said ""Thank you"""
will evaluate as:
He said "Thank you"
A Note on BOOLEAN Literals
There is one format for Boolean
literals. The possible values are TRUE and FALSE.
Incorrect: IF
Status = "TRUE"
Correct: IF
Status = TRUE
TYPE
carType =
(Chrysler, Ford, Nissan, Honda);
colorType = (red, green,
yellow);
VAR
n, j, k
: INTEGER;
x, y, z
: REAL;
filename
: STRING;
car54
: carType;
trafficlight
: colorType;
PROCEDURE variable declarations:
VAR
p:PROCEDURE BOOLEAN;
PROCEDURE IsInrange(IN x : INTEGER) : BOOLEAN;
BEGIN
....
END PROCEDURE
BEGIN
p := IsInRange;
IF CALL P(49)
...
END MODULE
5+(3*(2+2))
Operator precedence:
Type of expressions:
Example:
In the statement:
IF ( x <= 37 ) AND ( Func(k)/SQRT(x) < 21.0)
If x is larger than 37, no further evaluation is conducted.
NEW(player); { Allocate another
playerType record }
player.nextPlayer := team; {
new record refers to second }
team := player;
NEW(player); { Allocate another
playerType record }
player.nextPlayer := team; {new
record refers to third }
team := player;
MODSIM III | C |
IF x < 0
Statement1; ELSE Statement3; END IF; Statement5; IF y > 0 Statement1; Statement2; ELSE Statement3; Statement4; END IF; Statement5; |
if (x < 0)
Statement1; else Statement3; Statement5; if (y > 0) { Statement1; Statement2; } else { Statement3; Statement4; }; Statement5; |
The CASE statement provides a convenient method for branching on various values or ranges of values of a single expression:
CASE month
WHEN 1..3:
quarter := "1st Quarter";
WHEN 4, 5, 6:
{ alternative syntax}
quarter := "2nd Quarter";
WHEN 7..9:
quarter := "3rd Quarter";
OTHERWISE
quarter := "4th Quarter";
END CASE;
CASE month
WHEN 1, 3, 5, 7..8, 10, 12:
days := 31;
WHEN 4, 6, 9, 11:
days := 30;
OTHERWISE
IF leapYear
days := 29;
ELSE
days := 28;
END IF;
END CASE;
The WHILE statement
n := 2;
WHILE n < 5
OUTPUT("n = ", n);
INC(n); { same as n :=
n + 1 }
END WHILE;
The REPEAT Statement:
The REPEAT statement is a loop which is repeated one or more times. The Boolean expres-sion is located at the end of the statement and is not evaluated until the body of the loop has been executed at least once:
REPEAT
OUTPUT("This statement will
print at least once.");
INC(a); { same as a:=
a + 1 }
UNTIL a > 5;
The FOR Statement:
FOR n := 1 TO 5
OUTPUT("The next number is:",
n);
END FOR;
The FOREACH Statement:
The FOREACH statement provides an easy mechanism for iterating over the contents of a group object (defined in the MODSIM library module GrpMod) or any object derived from a group object. The FOREACH statement will iterate over the members of the group even if a group contains the same object more than once.
MyGroupObj = OBJECT
ASK METHOD First : Aobj;
ASK METHOD Next (IN obj : Aobj)
: Aobj;
ASK METHOD Prev (IN obj : Aobj)
: Aobj;
ASK METHOD Last : Aobj;
END OBJECT;
. . .
PROCEDURE iterate (IN grp: MyGroupObj);
VAR
a : Aobj;
BEGIN
FOREACH a IN grp
{Use 'a' }
END FOREACH;
END PROCEDURE;
The EXIT Statement:
The EXIT statement immediately transfers
control to the first statement after a loop con-struct. The EXIT statement
can be used with any loop construct.
The LOOP Statement:
The LOOP statement simply loops forever. The only way to stop this loop is to use the EXIT statement. This loop construct is quite versatile since the EXIT statement(s), and any cor-responding Boolean expression, may be located at the beginning, end, or anywhere within the body of the loop:
LOOP
OUTPUT("bread");
INC(IntVar); { same as
IntVar:= IntVar + 1 }
IF IntVar > 5
EXIT;
END IF;
OUTPUT("cheese and turkey");
END LOOP;
The parameter:
PROCEDURE increment(INOUT n :
INTEGER);
BEGIN
n := n + 1;
END PROCEDURE;
Case 2:
MAIN MODULE Sample5;
VAR
textLine : STRING;
PROCEDURE PrintIt(IN Str: STRING);
BEGIN
OUTPUT(Str);
END PROCEDURE;
BEGIN
textLine := "This is a VERY
simple program.";
PrintIt(textLine); { Call the
procedure defined above }
END MODULE.
Case 3:
PROCEDURE Hyp1(IN a, b : REAL;
OUT c : REAL);
BEGIN
c := SQRT( a*a + b*b );
END PROCEDURE;
PROCEDURE Hyp2(IN a, b : REAL)
: REAL;
BEGIN
RETURN SQRT( a*a + b*b );
END PROCEDURE;
Hyp1(3.0, 4.0, answer);
...
answer := Hyp2(3.0, 4.0);
Note:
Used when a procedure needs to be used before it has been defined:
PROCEDURE Hyp1(IN a, b : REAL;
OUT c : REAL); FORWARD;
Used to import type, data, function etc. from library.
Case 1:
FROM UtilMod IMPORT DateTime,
GetComputerType;
FROM MathMod IMPORT SIN, COS,
pi;
FROM MathMod IMPORT SIN AS sine,
COS AS cosine, pi;
Case 2:
TYPE
FileUseType = ( Input, Output,
InOut, Append, Update );
FROM IOMod IMPORT ALL FileUseType;
FROM IOMod IMPORT FileUseType(
Input, Output );
FROM IOMod IMPORT FileUseType(
Input AS in, Output);
FROM IOMod IMPORT ALL FileUseType(
Input AS in );
MAIN Module:
The MAIN module contains the main routine of the program. It is the only required module.
DEFINITION Module:
DEFINITION MODULE Trig;
CONST
goldenSection = 3.0 / 5.0;
PROCEDURE Hyp1(IN a, b : REAL;
OUT c : REAL);
END MODULE;
IMPLEMENTATION Module:
File Naming Conventions for Modules:
Module Name File Name
MAIN MODULE Alpha
MAlpha.mod
DEFINITION MODULE Beta
DBeta.mod
IMPLEMENTATION MODULE Beta
IBeta.mod
C++ code for Beta
Beta.cpp
Including C or C++ Code in a MODSIM Program:
Case 1:
DEFINITION MODULE Sample6; {
file DSample6.mod }
PROCEDURE foo1(IN x : REAL)
: INTEGER; NONMODSIM;
PROCEDURE foo2(IN x : REAL)
: INTEGER; NONMODSIM "C";
END MODULE;
IMPLEMENTATION MODULE Sample6;
{ file ISample6.mod}
END MODULE;
#include <modsim.h>
/* file Sample6.cpp */
#include <iostream.h>
MS_INTEGER foo1(MS_REAL x)
{
MS_INTEGER n;
cout << "x = " <<
x << << "\n";
return n;
}
#include <modsim.h> /*
file Sample6.c */
#include <stdio.h>
MS_INTEGER foo2(MS_REAL x)
{
MS_INTEGER n;
printf ("x = %f\n", x);
return n;
}
Note: The examples above include
’modsim.h’. This is the preferred way to interface
MODSIM to C++ code as it helps
ensure that C++ code will link without problems, and
will be compatible with future
releases of MODSIM.
Case 2:
DEFININTION MODULE Sample7;
PROCEDURE Proc7(IN x : REAL;
INOUT n : INTEGER) : CHAR; NONMODSIM;
END MODULE.
MS_CHAR Proc7(MS_REAL x, MS_INTEGER*
n)
{
...
}
Note: When passing parameters to a C/C++ routine it is important to note that INOUT and OUT parameters are handled as pointers.
Case 3:
PROCEDURE foo(IN str: STRING);
NONMODSIM; { file Itest.mod }
TYPE
Arr = ARRAY INTEGER OF CHAR;
PROCEDURE Test(IN cstr: Arr);
VAR
str : STRING;
BEGIN
str := CHARTOSTR(cstr); { convert
to MODSIM string }
OUTPUT("C++ string: ", str);
END PROCEDURE;
PROCEDURE TestStrings;
VAR
str: STRING;
BEGIN
str := "a MODSIM string";
foo(str); { pass string to C++
routine foo }
END PROCEDURE;
#include <modsim.h>
/* file test.cpp */
#include <iostream.h>
extern void test_Test(MS_CHAR*
astr);
void foo(MS_STRING str)
{
cout << "MODSIM string:
" << str << "\n";
char* cstr = "a C++ string";
test_Test((MS_CHAR*)cstr); //
calling MODSIM PROCEDURE Test
}