Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
topia opened this issue Apr 4, 2023 · 1 comment
Open

Comments

@topia
Copy link

topia commented Apr 4, 2023

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
    ]
}
@paxcut
Copy link
Contributor

paxcut commented Aug 28, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants