ndsev / zserio

zero sugar, zero fat, zero serialization overhead
https://zserio.org/
BSD 3-Clause "New" or "Revised" License
108 stars 26 forks source link

Cross language portability for expressions #86

Open Mi-La opened 5 years ago

Mi-La commented 5 years ago

Value evaluation doesn't work with data types and generated code can behave differently in each generator (e.g. how works data type overflow in C++, Java and Python).

ExpressionIntegerValue shall know about data type. We have to define how to evaluate expressions with various data types (e.g. uint8 + uint8 = uint8 or uint16???). It has to work consistently across all generators (C++, Java, Python, ...).

It is important to ensure that conditions for optional fields are evaluated same in all generators and that functions returns same values, etc...

Mi-La commented 5 years ago

Related to #84

mikir commented 5 years ago

Example1:

struct ExpressionTest
{
    uint32   value1 = 2147483648;  // 2^31
    uint32   value2 = 2147483648;  // 2^31

    function uint32 getSum()
    {
        return value1 + value2;
    }
};

Java: getSum() = 4294967296 C++: getSum() = 0 Python: getSum() = 4294967296

Example2:

struct ExpressionTest
{
    int8   value1 = 127;
    int8   value2 = 1;

    function int8 getSum()
    {
        return value1 + value2;
    }
};

Java: getSum() = -128 C++: getSum() = -128 Python: getSum() = 128

Mi-La commented 5 years ago

Also note that generated expressions may be uncompilable in some languages - e.g. in Java due to BigInteger.

enum uint64 TestEnum
{
    ONE, TWO, THREE
};

struct Test
{
    uint64 field1;
    uint32 field2 : field2 < field1;
    uint8 field3 : field3 < valueof(TestEnum.ONE);
};
Mi-La commented 4 years ago

ZserioType should be defined for each expression (even for literals!). See implementation of bitwise operators for bitmask type.

mikir commented 2 years ago

Please note, that division and modulo operator differs in Python. See #152.