Fixed the shift behaviour by moving it out into functions like the add and subtract operations already were
This commit is contained in:
parent
40bb883497
commit
018951ef40
|
@ -263,15 +263,6 @@ cgetScalarType A.Timer = Just "Time"
|
||||||
cgetScalarType A.Time = Just "Time"
|
cgetScalarType A.Time = Just "Time"
|
||||||
cgetScalarType _ = Nothing
|
cgetScalarType _ = Nothing
|
||||||
|
|
||||||
cgetUnsignedType :: A.Type -> Maybe String
|
|
||||||
cgetUnsignedType t | elem t [A.Byte, A.UInt16, A.UInt32, A.UInt64] = cgetScalarType t
|
|
||||||
cgetUnsignedType A.Int8 = cgetScalarType A.Byte
|
|
||||||
cgetUnsignedType A.Int = cgetScalarType A.UInt32
|
|
||||||
cgetUnsignedType A.Int16 = cgetScalarType A.UInt16
|
|
||||||
cgetUnsignedType A.Int32 = cgetScalarType A.UInt32
|
|
||||||
cgetUnsignedType A.Int64 = cgetScalarType A.UInt64
|
|
||||||
cgetUnsignedType _ = Nothing
|
|
||||||
|
|
||||||
-- | Generate the C type corresponding to a variable being declared.
|
-- | Generate the C type corresponding to a variable being declared.
|
||||||
-- It must be possible to use this in arrays.
|
-- It must be possible to use this in arrays.
|
||||||
cgenType :: A.Type -> CGen ()
|
cgenType :: A.Type -> CGen ()
|
||||||
|
@ -853,19 +844,8 @@ cgenDyadic m A.Rem e f = call genFuncDyadic m "rem" e f
|
||||||
cgenDyadic _ A.Plus e f = call genSimpleDyadic "+" e f
|
cgenDyadic _ A.Plus e f = call genSimpleDyadic "+" e f
|
||||||
cgenDyadic _ A.Minus e f = call genSimpleDyadic "-" e f
|
cgenDyadic _ A.Minus e f = call genSimpleDyadic "-" e f
|
||||||
cgenDyadic _ A.Times e f = call genSimpleDyadic "*" e f
|
cgenDyadic _ A.Times e f = call genSimpleDyadic "*" e f
|
||||||
cgenDyadic _ A.LeftShift e f = call genSimpleDyadic "<<" e f
|
cgenDyadic m A.LeftShift e f = call genFuncDyadic m "lshift" e f
|
||||||
cgenDyadic m A.RightShift e f
|
cgenDyadic m A.RightShift e f = call genFuncDyadic m "rshift" e f
|
||||||
= do t <- typeOfExpression e
|
|
||||||
(normalT, unsignedT) <- case (cgetScalarType t, cgetUnsignedType t) of
|
|
||||||
(Just x, Just y) -> return (x,y)
|
|
||||||
_ -> diePC m $ formatCode "Attempting to shift non-integer type: %" t
|
|
||||||
if (normalT == unsignedT)
|
|
||||||
then call genSimpleDyadic ">>" e f
|
|
||||||
else do tell ["((", normalT, ")(((", unsignedT, ")"]
|
|
||||||
call genExpression e
|
|
||||||
tell [") >> "]
|
|
||||||
call genExpression f
|
|
||||||
tell ["))"]
|
|
||||||
cgenDyadic _ A.BitAnd e f = call genSimpleDyadic "&" e f
|
cgenDyadic _ A.BitAnd e f = call genSimpleDyadic "&" e f
|
||||||
cgenDyadic _ A.BitOr e f = call genSimpleDyadic "|" e f
|
cgenDyadic _ A.BitOr e f = call genSimpleDyadic "|" e f
|
||||||
cgenDyadic _ A.BitXor e f = call genSimpleDyadic "^" e f
|
cgenDyadic _ A.BitXor e f = call genSimpleDyadic "^" e f
|
||||||
|
|
|
@ -180,6 +180,28 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
|
||||||
return a - (i * b); \
|
return a - (i * b); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAKE_SHIFT(type) \
|
||||||
|
static inline type occam_lshift_##type (type, int, const char*) occam_unused; \
|
||||||
|
static inline type occam_lshift_##type (type a, int b, const char* pos) { \
|
||||||
|
if (b < 0 || b > sizeof(type) * CHAR_BIT) { \
|
||||||
|
occam_stop (pos, "left shift by negative value or value (strictly) greater than number of bits in type"); \
|
||||||
|
} else if (b == sizeof(type) * CHAR_BIT) { \
|
||||||
|
return 0; \
|
||||||
|
} else { \
|
||||||
|
return (a << b); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
static inline type occam_rshift_##type (type, int, const char*) occam_unused; \
|
||||||
|
static inline type occam_rshift_##type (type a, int b, const char* pos) { \
|
||||||
|
if (b < 0 || b > sizeof(type) * CHAR_BIT) { \
|
||||||
|
occam_stop (pos, "right shift by negative value or value (strictly) greater than number of bits in type"); \
|
||||||
|
} else if (b == sizeof(type) * CHAR_BIT) { \
|
||||||
|
return 0; \
|
||||||
|
} else { \
|
||||||
|
return (type)(((u##type)a) >> b); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define MAKE_ALL_SIGNED(type,flag) \
|
#define MAKE_ALL_SIGNED(type,flag) \
|
||||||
MAKE_RANGE_CHECK(type,flag) \
|
MAKE_RANGE_CHECK(type,flag) \
|
||||||
MAKE_ADD(type) \
|
MAKE_ADD(type) \
|
||||||
|
@ -187,7 +209,8 @@ static inline int occam_check_retype (int src, int dest, const char *pos) {
|
||||||
MAKE_MUL(type) \
|
MAKE_MUL(type) \
|
||||||
MAKE_DIV(type) \
|
MAKE_DIV(type) \
|
||||||
MAKE_REM(type) \
|
MAKE_REM(type) \
|
||||||
MAKE_NEGATE(type)
|
MAKE_NEGATE(type) \
|
||||||
|
MAKE_SHIFT(type)
|
||||||
|
|
||||||
//{{{ uint8_t
|
//{{{ uint8_t
|
||||||
MAKE_RANGE_CHECK(uint8_t, "%d")
|
MAKE_RANGE_CHECK(uint8_t, "%d")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user