Re: IN function with SETs
Posted: Sat Jun 06, 2015 8:13 am
Thanks Luowy,
I will add you prefered version to the next CPC edition
Helmut
I will add you prefered version to the next CPC edition
Helmut
I wonder why they made that change in the transition from Oberon to Component Pascal? The Oberon / Oberon-2 / Oberon-07 Language Reports are all less restrictive:Robert wrote:The language report saysx IN s stands for "x is an element of s". x must be an integer in the range 0..MAX(SET), and s of type SET.
When using Oberon I sometimes find it convenient to write code like this:x IN s stands for "x is an element of s". x must be of type INTEGER, and s of type SET.
Code: Select all
IF i IN {0..9} THEN ...
Code: Select all
IF (i >= 0) and (i <= 9) THEN ...
Code: Select all
IF k IN {0..9} THEN ...
IF (k >= 0) and (k <= 9) THEN ...
None. They are not backward-compatible. The programmer no longer has the ability to skip the runtime checks if that is preferred.luowy wrote:which one is better?
Hi Robert,Robert wrote:Does your second suggested change implement this for VARiable k? Does it implement this for CONSTant k?
Does your suggested change make the run-time code slower?
Code: Select all
0F A3 45 F8 BT [EBP-8], EAX
0F 92 C0 SETB AL
Code: Select all
83 F8 20 CMP EAX, 32 ;<<<
73 04 JNB 4 ;<<<
0F A3 45 F8 BT [EBP-8], EAX
0F 92 C0 SETB AL
hi Chris,please check the "BT" code desc(in the intel manual part2) carefully:cfbsoftware wrote:None. They are not backward-compatible. The programmer no longer has the ability to skip the runtime checks if that is preferred.
Code: Select all
BT [EBP-8], EAX
SETB AL
Code: Select all
PROCEDURE Set*();
VAR k: INTEGER;
VAR s: ARRAY 2 OF SET;
VAR b: BOOLEAN;
BEGIN
k := 32;
s[0] := {0..31};
s[1] := {0..31};
Log.Bool(k IN s[0]); Log.Ln;
s[1] := {1..31};
Log.Bool(k IN s[0]); Log.Ln;
END Set;
luowy wrote:If you do a check: ... you will understand why we need this fixup.luowy
Code: Select all
k := 32;
s[0] := {0..31};
s[1] := {0..31};
f.BoolLn (k IN s[0]);
s[1] := {1..31};
f.BoolLn (k IN s[0]);
new symbol file 116 4
TRUE
FALSE
Dear Robert,
It may be that for argument >= 32 the result of such operation will be
undefined. I'm surprised too. But if you rewrite the code at this manner:
BEGIN
RETURN 33 IN {1}
You will have error "set element greater than MAX(SET) or less than 0".
So BlackBox validates arguments at compile time, but does not at
runtilme. I think, teason of it is improvement of the performance.
Btw, Ofront gives the same error at compile time and the same result of
work in runtime:
static INTEGER Test_k;
static BOOLEAN Test_Fn (void)
{
Test_k = 33;
return __IN(Test_k, 0x02);
}
where macros __IN defined as:
#define __IN(x, s) (((s)>>(x))&1)
So result = (2>>33)&1 = NOT ZERO = TRUE ( Why? )
Tested in MINGW and TCC. As I understand, (2>>33)&1 must be = 0 in 32
bit depth range, but maybe this expression calculated also in
compile-time with bigger bit depth?
Who can say how works BlackBox's IN operation at low-level?