PatternLanguage icon indicating copy to clipboard operation
PatternLanguage copied to clipboard

Enum with negative number (with signed integer) not work as expected

Open topia opened this issue 2 years ago • 1 comments

When I tried the following pattern language on web:

enum temp : s8 {
    unknown = -1,
    fe = 0xfe,
    one = 1,
    two = 2,
    zero = 0,
};

temp foo[5] @ 0x0;
s8 raw[5] @ 0x0;

with the following hex:

ff fe 00 01 02 03

I expected the first "ff" recognized as unknown, but recognized as ???.

actual

{
    "foo": [
        "temp::???",
        "temp::fe",
        "temp::zero",
        "temp::one",
        "temp::two"
    ],
    "raw": [
        -1,
        -2,
        0,
        1,
        2
    ]
}

expected

{
    "foo": [
        "temp::unknown",
        "temp::fe",  # or "temp:???"
        "temp::zero",
        "temp::one",
        "temp::two"
    ],
    "raw": [
        -1,
        -2,
        0,
        1,
        2
    ]
}

topia avatar Apr 04 '23 12:04 topia

If you expect temp::unknown for -1 then you should also expect temp::fe for -2 based on definition

enum temp : s8 {
    unknown = -1,
    fe = 0xfe, //0xf2 is -2
    one = 1,
    two = 2,
    zero = 0,
};

At any rate the error is not with the enums per se but in the way the literals are being handled combined with the fact that all enums are promoted to 128 bit integers automatically. In the following example I use both signed and unsigned examples of enums that are 128 and 64 bit integers. The error only occurs when the literals are expressed as signed numbers and only if the type is not 128 bit integer.

#pragma example 67 45 75 75 87 88 68 08 65 64 63 65 47 54 77 55 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 84 36 36 37 63 64 46 45 23 64 63 34 63 63 46 45 45 24 64 36 75 46 74 83 00 00 00 00 00 00 00 00 56 45 67 56 76 57 57 75 47 55 75 75 57 55 75 77 45 54 75 47 67 88 86 86 75 44 36 46 57 75 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 36 53 46 44 64 54 53 45 64 36 36 43 64 63 34

#include "std/limits.pat"
#include "std/string.pat"

enum U128 : u128 {
    ERROR = 0x80000000000000000000000000000000 ... 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
    NO_ERROR = 0,
    VALID = 1 ... 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
};

//std::print("{}",std::limits::s128_min());
//std::print("{}",std::limits::s128_max());
enum S128 : s128 {
    ERROR = -170141183460469231731687303715884105728 ... -1,
    NO_ERROR = 0,
    VALID = 1 ... 170141183460469231731687303715884105727
};

enum U64 : u64 {
    ERROR = 0x8000000000000000 ... 0xFFFFFFFFFFFFFFFF,
    NO_ERROR = 0,
    VALID = 1 ... 0x7FFFFFFFFFFFFFFF
};

//std::print("{}",std::limits::s64_min());
//std::print("{}",std::limits::s64_max());

enum S64 : s64 {
    ERROR = -9223372036854775808 ... -1,
    NO_ERROR = 0,
    VALID = 1 ... 9223372036854775807
};


U128 testu128[8] @ 0;
S128 tests128[8] @ 0;
U64 testu64[8] @ 0;
S64 tests64[8] @ 0;

std::print("{}",testu128);
std::print("{}",tests128);
std::print("{}",testu64);
std::print("{}",tests64);

yields

I: [ U128::VALID, U128::ERROR, U128::VALID, U128::VALID, U128::VALID, U128::ERROR, U128::NO_ERROR, U128::VALID ]
I: [ S128::VALID, S128::ERROR, S128::VALID, S128::VALID, S128::VALID, S128::ERROR, S128::NO_ERROR, S128::VALID ]
I: [ U64::VALID, U64::VALID, U64::ERROR, U64::ERROR, U64::VALID, U64::VALID, U64::ERROR, U64::NO_ERROR ]
I: [ S64::VALID, S64::VALID, S64::???, S64::???, S64::VALID, S64::VALID, S64::???, S64::NO_ERROR ]
I: Pattern exited with code: 0
I: Evaluation took 0.0981599s

paxcut avatar Aug 28 '23 07:08 paxcut