From d424697aa1813a4e8fa0cd9ba83070429fed3f71 Mon Sep 17 00:00:00 2001 From: David Brown Date: Sat, 13 Aug 2016 18:39:26 +0100 Subject: [PATCH] Common code for MIN and MAX of integer types. --- src/compiler/OPB.Mod | 25 +++++++++--- src/test/confidence/intsyntax/IntSyntax.mod | 18 +++++++++ src/test/confidence/intsyntax/expected | 15 +++++++ src/test/confidence/intsyntax/test.sh | 5 +++ src/test/confidence/language/TestLanguage.mod | 40 +++++++++++++++++++ 5 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 src/test/confidence/intsyntax/IntSyntax.mod create mode 100644 src/test/confidence/intsyntax/expected create mode 100644 src/test/confidence/intsyntax/test.sh diff --git a/src/compiler/OPB.Mod b/src/compiler/OPB.Mod index 57ac4ded..5bdacb73 100644 --- a/src/compiler/OPB.Mod +++ b/src/compiler/OPB.Mod @@ -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) diff --git a/src/test/confidence/intsyntax/IntSyntax.mod b/src/test/confidence/intsyntax/IntSyntax.mod new file mode 100644 index 00000000..c5ac799c --- /dev/null +++ b/src/test/confidence/intsyntax/IntSyntax.mod @@ -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. \ No newline at end of file diff --git a/src/test/confidence/intsyntax/expected b/src/test/confidence/intsyntax/expected new file mode 100644 index 00000000..82813b89 --- /dev/null +++ b/src/test/confidence/intsyntax/expected @@ -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. diff --git a/src/test/confidence/intsyntax/test.sh b/src/test/confidence/intsyntax/test.sh new file mode 100644 index 00000000..5702749a --- /dev/null +++ b/src/test/confidence/intsyntax/test.sh @@ -0,0 +1,5 @@ +#!/bin/sh +. ../testenv.sh +# Generate mixed source and assembly code listing +voc IntSyntax.mod -m >result +. ../testresult.sh diff --git a/src/test/confidence/language/TestLanguage.mod b/src/test/confidence/language/TestLanguage.mod index 11aa3f5d..cf160311 100644 --- a/src/test/confidence/language/TestLanguage.mod +++ b/src/test/confidence/language/TestLanguage.mod @@ -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.