Common code for MIN and MAX of integer types.

This commit is contained in:
David Brown 2016-08-13 18:39:26 +01:00
parent b2263d933e
commit d424697aa1
5 changed files with 97 additions and 6 deletions

View file

@ -940,6 +940,19 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
*)
END CheckLeaf;
PROCEDURE SignedMaximum(bytecount: LONGINT): LONGINT;
VAR result: LONGINT;
BEGIN
result := 1;
result := SYSTEM.LSH(result, bytecount*8-1);
RETURN result - 1;
END SignedMaximum;
PROCEDURE SignedMinimum(bytecount: LONGINT): LONGINT;
BEGIN RETURN -SignedMaximum(bytecount) - 1
END SignedMinimum;
PROCEDURE StPar0*(VAR par0: OPT.Node; fctno: INTEGER); (* par0: first param of standard proc *)
VAR f: INTEGER; typ: OPT.Struct; x: OPT.Node;
BEGIN x := par0; f := x^.typ^.form;
@ -991,9 +1004,9 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
CASE f OF
OPM.Bool: x := NewBoolConst(FALSE)
| OPM.Char: x := NewIntConst(0); x^.typ := OPT.chartyp
| OPM.SInt: x := NewIntConst(OPM.MinSInt)
| OPM.Int: x := NewIntConst(OPM.MinInt)
| OPM.LInt: x := NewIntConst(OPM.MinLInt)
| OPM.SInt,
OPM.Int,
OPM.LInt: x := NewIntConst(SignedMinimum(x.typ.size))
| OPM.Set: x := NewIntConst(0); x^.typ := OPT.inttyp
| OPM.Real: x := NewRealConst(OPM.MinReal, OPT.realtyp)
| OPM.LReal: x := NewRealConst(OPM.MinLReal, OPT.lrltyp)
@ -1006,9 +1019,9 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
CASE f OF
OPM.Bool: x := NewBoolConst(TRUE)
| OPM.Char: x := NewIntConst(0FFH); x^.typ := OPT.chartyp
| OPM.SInt: x := NewIntConst(OPM.MaxSInt)
| OPM.Int: x := NewIntConst(OPM.MaxInt)
| OPM.LInt: x := NewIntConst(OPM.MaxLInt)
| OPM.SInt,
OPM.Int,
OPM.LInt: x := NewIntConst(SignedMaximum(x.typ.size))
| OPM.Set: x := NewIntConst(OPM.MaxSet); x^.typ := OPT.inttyp
| OPM.Real: x := NewRealConst(OPM.MaxReal, OPT.realtyp)
| OPM.LReal: x := NewRealConst(OPM.MaxLReal, OPT.lrltyp)

View file

@ -0,0 +1,18 @@
MODULE IntSyntax;
(* Test for error messages generated by incompatible integer types *)
VAR s: SHORTINT; i: INTEGER; l: LONGINT;
BEGIN
l := l; (* Good, same types *)
l := i; (* Good, LONGINT longer than INTEGER *)
l := s; (* Good, LONGINT longer than SHORTINT *)
i := s; (* Good, INTEGER longer then SHORTINT *)
i := l; (* Bad, INTEGER shorter than LONGINT *)
s := l; (* Bad, SHORTINT shorter than LONGINT *)
i := l; (* Bad, SHORTINT shorter than INTEGER *)
END IntSyntax.

View file

@ -0,0 +1,15 @@
IntSyntax.mod compiling IntSyntax.
14: i := l; (* Bad, INTEGER shorter than LONGINT *)
^
pos 341 err 113 incompatible assignment
15: s := l; (* Bad, SHORTINT shorter than LONGINT *)
^
pos 393 err 113 incompatible assignment
16: i := l; (* Bad, SHORTINT shorter than INTEGER *)
^
pos 446 err 113 incompatible assignment
Module compilation failed.

View file

@ -0,0 +1,5 @@
#!/bin/sh
. ../testenv.sh
# Generate mixed source and assembly code listing
voc IntSyntax.mod -m >result
. ../testresult.sh

View file

@ -95,7 +95,47 @@ BEGIN
END Shift;
PROCEDURE TestValue(v,e: LONGINT; name: ARRAY OF CHAR);
BEGIN
IF v # e THEN
Console.String(name);
Console.String(" = ");
Console.Int(v,1);
Console.String(", expected ");
Console.Int(e,1);
Console.Ln;
END
END TestValue;
PROCEDURE IntSize;
VAR l: LONGINT;
BEGIN
TestValue(MIN(SHORTINT), -80H, "MIN(SHORTINT)");
TestValue(MAX(SHORTINT), 7FH, "MAX(SHORTINT)");
IF SIZE(INTEGER) = 2 THEN (* 32 bit machine *)
TestValue(MIN(INTEGER), -7FFFH - 1, "MIN(INTEGER)");
TestValue(MAX(INTEGER), 7FFFH, "MAX(INTEGER)");
TestValue(MIN(LONGINT), -7FFFFFFFH - 1, "MIN(LONGINT)");
TestValue(MAX(LONGINT), 7FFFFFFFH, "MAX(LONGINT)");
ELSIF SIZE(INTEGER) = 4 THEN (* 64 bit machine *)
TestValue(MIN(INTEGER), -7FFFFFFFH - 1, "MIN(INTEGER)");
TestValue(MAX(INTEGER), 7FFFFFFFH, "MAX(INTEGER)");
(* Since we need to be compilable on 32 bit machines we cannot use
a 64 bit constant, so use arithmetic. *)
l := 1; l := SYSTEM.LSH(l, 63); l := l-1; (* Generate l = 7FFFFFFFFFFFFFFFH *)
TestValue(MIN(LONGINT), -l - 1, "MIN(LONGINT)");
TestValue(MAX(LONGINT), l, "MAX(LONGINT)");
ELSE
Console.String("SIZE(INTEGER) = ");
Console.Int(SIZE(INTEGER),1);
Console.String(", expected 2 or 4.");
Console.Ln;
END;
END IntSize;
BEGIN
Shift;
IntSize;
Console.String("Language tests successful."); Console.Ln;
END TestLanguage.