1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <astexpression.hxx>
22 #include <astconstant.hxx>
23 #include <astscope.hxx>
24 #include <errorhandler.hxx>
26 #include <o3tl/float_int_conversion.hxx>
27 #include <osl/diagnose.h>
33 AstExpression::AstExpression(ExprComb c
, AstExpression
*pExpr1
, AstExpression
*pExpr2
)
40 AstExpression::AstExpression(sal_Int32 l
)
41 : m_combOperator(ExprComb::NONE
)
43 m_exprValue
.reset( new AstExprValue
);
44 m_exprValue
->et
= ET_long
;
45 m_exprValue
->u
.lval
= l
;
48 AstExpression::AstExpression(sal_Int32 l
, ExprType et
)
49 : m_combOperator(ExprComb::NONE
)
51 m_exprValue
.reset( new AstExprValue
);
53 m_exprValue
->u
.lval
= l
;
56 AstExpression::AstExpression(sal_Int64 h
)
57 : m_combOperator(ExprComb::NONE
)
59 m_exprValue
.reset( new AstExprValue
);
60 m_exprValue
->et
= ET_hyper
;
61 m_exprValue
->u
.hval
= h
;
64 AstExpression::AstExpression(sal_uInt64 uh
)
65 : m_combOperator(ExprComb::NONE
)
67 m_exprValue
.reset( new AstExprValue
);
68 m_exprValue
->et
= ET_uhyper
;
69 m_exprValue
->u
.uhval
= uh
;
72 AstExpression::AstExpression(double d
)
73 : m_combOperator(ExprComb::NONE
)
75 m_exprValue
.reset( new AstExprValue
);
76 m_exprValue
->et
= ET_double
;
77 m_exprValue
->u
.dval
= d
;
80 AstExpression::AstExpression(OString
* scopedName
)
81 : m_combOperator(ExprComb::Symbol
)
84 m_xSymbolicName
= *scopedName
;
87 AstExpression::~AstExpression()
92 * Perform the coercion from the given AstExprValue to the requested
93 * ExprType. Return an AstExprValue if successful, NULL if failed.
94 * must be done for hyper, uhyper
97 coerce_value(AstExprValue
*ev
, ExprType t
)
111 if (ev
->u
.usval
> SAL_MAX_INT16
)
113 auto tmp
= static_cast<sal_Int16
>(ev
->u
.usval
);
120 if (ev
->u
.lval
< SAL_MIN_INT16
|| ev
->u
.lval
> SAL_MAX_INT16
)
122 auto tmp
= static_cast<sal_Int16
>(ev
->u
.lval
);
129 if (ev
->u
.ulval
> SAL_MAX_INT16
)
131 auto tmp
= static_cast<sal_Int16
>(ev
->u
.ulval
);
138 if (ev
->u
.hval
< SAL_MIN_INT16
|| ev
->u
.hval
> SAL_MAX_INT16
)
140 auto tmp
= static_cast<sal_Int16
>(ev
->u
.hval
);
147 if (ev
->u
.uhval
> SAL_MAX_INT16
)
149 auto tmp
= static_cast<sal_Int16
>(ev
->u
.uhval
);
156 auto tmp
= static_cast<sal_Int16
>(ev
->u
.bval
);
163 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.fval
), SAL_MIN_INT16
)
164 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_INT16
)))
168 auto tmp
= static_cast<sal_Int16
>(ev
->u
.fval
);
175 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.dval
), SAL_MIN_INT16
)
176 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_INT16
)))
180 auto tmp
= static_cast<sal_Int16
>(ev
->u
.dval
);
187 auto tmp
= static_cast<sal_Int16
>(ev
->u
.byval
);
203 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.sval
);
212 if (ev
->u
.lval
< 0 || ev
->u
.lval
> SAL_MAX_UINT16
)
214 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.lval
);
221 if (ev
->u
.ulval
> SAL_MAX_UINT16
)
223 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.ulval
);
230 if (ev
->u
.hval
< 0 || ev
->u
.hval
> SAL_MAX_UINT16
)
232 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.hval
);
239 if (ev
->u
.uhval
> SAL_MAX_UINT16
)
241 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.uhval
);
248 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.bval
);
256 || !o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_UINT16
))
260 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.fval
);
268 || !o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_UINT16
))
272 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.dval
);
279 auto tmp
= static_cast<sal_uInt16
>(ev
->u
.byval
);
293 auto tmp
= static_cast<sal_Int32
>(ev
->u
.sval
);
300 auto tmp
= static_cast<sal_Int32
>(ev
->u
.usval
);
309 if (ev
->u
.ulval
> SAL_MAX_INT32
)
311 auto tmp
= static_cast<sal_Int32
>(ev
->u
.ulval
);
318 if (ev
->u
.hval
< SAL_MIN_INT32
|| ev
->u
.hval
> SAL_MAX_INT32
)
320 auto tmp
= static_cast<sal_Int32
>(ev
->u
.hval
);
327 if (ev
->u
.uhval
> SAL_MAX_INT32
)
329 auto tmp
= static_cast<sal_Int32
>(ev
->u
.uhval
);
336 auto tmp
= static_cast<sal_Int32
>(ev
->u
.bval
);
343 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.fval
), SAL_MIN_INT32
)
344 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_INT32
)))
348 auto tmp
= static_cast<sal_Int32
>(ev
->u
.fval
);
355 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.dval
), SAL_MIN_INT32
)
356 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_INT32
)))
360 auto tmp
= static_cast<sal_Int32
>(ev
->u
.dval
);
367 auto tmp
= static_cast<sal_Int32
>(ev
->u
.byval
);
383 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.sval
);
390 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.usval
);
399 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.lval
);
408 if (ev
->u
.hval
< 0 || ev
->u
.hval
> SAL_MAX_UINT32
)
410 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.hval
);
417 if (ev
->u
.uhval
> SAL_MAX_UINT32
)
419 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.uhval
);
426 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.bval
);
434 || !o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_UINT32
))
438 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.fval
);
446 || !o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_UINT32
))
450 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.dval
);
457 auto tmp
= static_cast<sal_uInt32
>(ev
->u
.byval
);
471 auto tmp
= static_cast<sal_Int64
>(ev
->u
.sval
);
478 auto tmp
= static_cast<sal_Int64
>(ev
->u
.usval
);
485 auto tmp
= static_cast<sal_Int64
>(ev
->u
.lval
);
492 auto tmp
= static_cast<sal_Int64
>(ev
->u
.ulval
);
501 if (ev
->u
.uhval
> SAL_MAX_INT64
)
503 auto tmp
= static_cast<sal_Int64
>(ev
->u
.uhval
);
510 auto tmp
= static_cast<sal_Int64
>(ev
->u
.bval
);
517 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.fval
), SAL_MIN_INT64
)
518 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_INT64
)))
522 auto tmp
= static_cast<sal_Int64
>(ev
->u
.fval
);
529 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.dval
), SAL_MIN_INT64
)
530 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_INT64
)))
534 auto tmp
= static_cast<sal_Int64
>(ev
->u
.dval
);
541 auto tmp
= static_cast<sal_Int64
>(ev
->u
.byval
);
557 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.sval
);
564 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.usval
);
573 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.lval
);
580 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.ulval
);
589 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.hval
);
598 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.bval
);
606 || !o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_UINT64
))
610 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.fval
);
618 || !o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_UINT64
))
622 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.dval
);
629 auto tmp
= static_cast<sal_uInt64
>(ev
->u
.byval
);
642 ev
->u
.bval
= ev
->u
.sval
!= 0;
646 ev
->u
.bval
= ev
->u
.usval
!= 0;
650 ev
->u
.bval
= ev
->u
.lval
!= 0;
654 ev
->u
.bval
= ev
->u
.ulval
!= 0;
658 ev
->u
.bval
= ev
->u
.hval
!= 0;
662 ev
->u
.bval
= ev
->u
.uhval
!= 0;
668 ev
->u
.bval
= ev
->u
.fval
!= 0.0;
672 ev
->u
.bval
= ev
->u
.dval
!= 0.0;
676 ev
->u
.bval
= ev
->u
.byval
!= 0;
688 auto tmp
= static_cast<float>(ev
->u
.sval
);
695 auto tmp
= static_cast<float>(ev
->u
.usval
);
702 auto tmp
= static_cast<float>(ev
->u
.lval
);
709 auto tmp
= static_cast<float>(ev
->u
.ulval
);
716 auto tmp
= static_cast<float>(ev
->u
.hval
);
723 if (static_cast<float>(ev
->u
.ulval
) > FLT_MAX
)
725 auto tmp
= static_cast<float>(ev
->u
.ulval
);
731 ev
->u
.fval
= ev
->u
.bval
? 1.0f
: 0.0f
;
738 if (static_cast<float>(ev
->u
.dval
) > FLT_MAX
|| static_cast<float>(ev
->u
.dval
) < -FLT_MAX
)
740 auto tmp
= static_cast<float>(ev
->u
.dval
);
747 auto tmp
= static_cast<float>(ev
->u
.byval
);
761 auto tmp
= static_cast<double>(ev
->u
.sval
);
768 auto tmp
= static_cast<double>(ev
->u
.usval
);
775 auto tmp
= static_cast<double>(ev
->u
.lval
);
782 auto tmp
= static_cast<double>(ev
->u
.ulval
);
789 auto tmp
= static_cast<double>(ev
->u
.hval
);
796 if (ev
->u
.dval
> FLT_MAX
|| ev
->u
.dval
< -FLT_MAX
)
798 auto tmp
= static_cast<double>(ev
->u
.ulval
);
804 ev
->u
.dval
= ev
->u
.bval
? 1.0 : 0.0;
809 auto tmp
= static_cast<double>(ev
->u
.fval
);
818 auto tmp
= static_cast<double>(ev
->u
.byval
);
832 if (ev
->u
.sval
< SAL_MIN_INT8
|| ev
->u
.sval
> SAL_MAX_UINT8
)
834 auto tmp
= static_cast<unsigned char>(ev
->u
.sval
);
841 if (ev
->u
.usval
> SAL_MAX_UINT8
)
843 auto tmp
= static_cast<unsigned char>(ev
->u
.usval
);
850 if (ev
->u
.lval
< SAL_MIN_INT8
|| ev
->u
.lval
> SAL_MAX_UINT8
)
852 auto tmp
= static_cast<unsigned char>(ev
->u
.lval
);
859 if (ev
->u
.ulval
> SAL_MAX_UINT8
)
861 auto tmp
= static_cast<unsigned char>(ev
->u
.ulval
);
868 if (ev
->u
.hval
< SAL_MIN_INT8
|| ev
->u
.hval
> SAL_MAX_UINT8
)
870 auto tmp
= static_cast<unsigned char>(ev
->u
.hval
);
877 if (ev
->u
.uhval
> SAL_MAX_UINT8
)
879 auto tmp
= static_cast<unsigned char>(ev
->u
.uhval
);
885 ev
->u
.byval
= ev
->u
.bval
? 1 : 0;
890 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.fval
), SAL_MIN_INT8
)
891 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.fval
), SAL_MAX_UINT8
)))
895 auto tmp
= static_cast<unsigned char>(static_cast<sal_Int32
>(ev
->u
.fval
));
902 if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev
->u
.dval
), SAL_MIN_INT8
)
903 && o3tl::convertsToAtMost(o3tl::roundAway(ev
->u
.dval
), SAL_MAX_UINT8
)))
907 auto tmp
= static_cast<unsigned char>(static_cast<sal_Int32
>(ev
->u
.dval
));
924 bool AstExpression::coerce(ExprType t
)
927 * Is it already of the right type?
929 if (m_exprValue
!= nullptr && m_exprValue
->et
== t
)
934 * First, evaluate it, then try to coerce result type
935 * If already evaluated, return the result
938 if (m_exprValue
== nullptr)
941 if (!coerce_value(m_exprValue
.get(), t
))
944 return m_exprValue
!= nullptr;
947 bool AstExpression::compareLong(AstExpression
*pExpr
)
950 if (m_combOperator
!= pExpr
->m_combOperator
)
954 if (m_exprValue
== nullptr || pExpr
->getExprValue() == nullptr)
956 if (m_exprValue
->et
!= pExpr
->getExprValue()->et
)
958 switch (m_exprValue
->et
)
961 bRet
= m_exprValue
->u
.lval
== pExpr
->getExprValue()->u
.lval
;
971 void AstExpression::evaluate()
976 if ( m_exprValue
!= nullptr )
979 * OK, must evaluate operator
981 switch (m_combOperator
)
984 case ExprComb::Minus
:
988 m_exprValue
= eval_bin_op();
994 case ExprComb::Right
:
995 m_exprValue
= eval_bit_op();
997 case ExprComb::UPlus
:
998 case ExprComb::UMinus
:
999 m_exprValue
= eval_un_op();
1001 case ExprComb::Symbol
:
1002 m_exprValue
= eval_symbol();
1004 case ExprComb::NONE
:
1009 std::unique_ptr
<AstExprValue
> AstExpression::eval_bin_op()
1011 ExprType eType
= ET_double
;
1013 if ( m_combOperator
== ExprComb::Mod
)
1016 if (m_subExpr1
== nullptr || m_subExpr2
== nullptr)
1018 m_subExpr1
->evaluate();
1019 if (m_subExpr1
->getExprValue() == nullptr)
1021 if (!m_subExpr1
->coerce(eType
))
1023 m_subExpr2
->evaluate();
1024 if (m_subExpr2
->getExprValue() == nullptr)
1026 if (!m_subExpr2
->coerce(eType
))
1029 std::unique_ptr
< AstExprValue
> retval(new AstExprValue
);
1032 switch (m_combOperator
)
1035 if (m_subExpr2
->getExprValue()->u
.hval
== 0)
1037 retval
->u
.hval
= m_subExpr1
->getExprValue()->u
.hval
% m_subExpr2
->getExprValue()->u
.hval
;
1040 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
+ m_subExpr2
->getExprValue()->u
.dval
;
1042 case ExprComb::Minus
:
1043 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
- m_subExpr2
->getExprValue()->u
.dval
;
1046 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
* m_subExpr2
->getExprValue()->u
.dval
;
1049 if (m_subExpr2
->getExprValue()->u
.dval
== 0.0)
1051 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
/ m_subExpr2
->getExprValue()->u
.dval
;
1060 std::unique_ptr
<AstExprValue
> AstExpression::eval_bit_op()
1062 if (m_subExpr1
== nullptr || m_subExpr2
== nullptr)
1064 m_subExpr1
->evaluate();
1065 if (m_subExpr1
->getExprValue() == nullptr)
1067 if (!m_subExpr1
->coerce(ET_long
))
1069 m_subExpr2
->evaluate();
1070 if (m_subExpr2
->getExprValue() == nullptr)
1072 if (!m_subExpr2
->coerce(ET_long
))
1075 std::unique_ptr
< AstExprValue
> retval(new AstExprValue
);
1076 retval
->et
= ET_long
;
1078 switch (m_combOperator
)
1081 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
| m_subExpr2
->getExprValue()->u
.lval
;
1084 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
^ m_subExpr2
->getExprValue()->u
.lval
;
1087 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
& m_subExpr2
->getExprValue()->u
.lval
;
1089 case ExprComb::Left
:
1090 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
<< m_subExpr2
->getExprValue()->u
.lval
;
1092 case ExprComb::Right
:
1093 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
>> m_subExpr2
->getExprValue()->u
.lval
;
1102 std::unique_ptr
<AstExprValue
> AstExpression::eval_un_op()
1104 if (m_subExpr1
== nullptr)
1106 m_subExpr1
->evaluate();
1107 if (m_subExpr1
->getExprValue() == nullptr)
1109 if (!m_subExpr1
->coerce(ET_double
))
1112 std::unique_ptr
< AstExprValue
> retval(new AstExprValue
);
1113 retval
->et
= ET_double
;
1115 switch (m_combOperator
)
1117 case ExprComb::UPlus
:
1118 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
;
1120 case ExprComb::UMinus
:
1121 retval
->u
.lval
= -(m_subExpr1
->getExprValue()->u
.lval
);
1130 std::unique_ptr
<AstExprValue
> AstExpression::eval_symbol()
1132 AstScope
*pScope
= nullptr;
1133 AstDeclaration
*pDecl
;
1134 AstConstant
*pConst
;
1137 * Is there a symbol stored?
1139 if (!m_xSymbolicName
)
1141 ErrorHandler::evalError(this);
1145 * Get current scope for lookup
1147 if (idlc()->scopes()->depth() > 0)
1148 pScope
= idlc()->scopes()->topNonNull();
1151 ErrorHandler::lookupError(*m_xSymbolicName
);
1157 pDecl
= pScope
->lookupByName(*m_xSymbolicName
);
1158 if (pDecl
== nullptr)
1160 ErrorHandler::lookupError(*m_xSymbolicName
);
1166 if (pDecl
->getNodeType() != NT_const
&&
1167 pDecl
->getNodeType() != NT_enum_val
)
1169 ErrorHandler::constantExpected(pDecl
, *m_xSymbolicName
);
1172 if (!ErrorHandler::checkPublished(pDecl
))
1177 * OK, now evaluate the constant we just got, to produce its value
1179 pConst
= static_cast< AstConstant
* >(pDecl
);
1180 pConst
->getConstValue()->evaluate();
1181 auto const val
= pConst
->getConstValue()->getExprValue();
1182 return val
== nullptr ? nullptr : std::make_unique
<AstExprValue
>(*val
);
1185 OString
AstExpression::toString()
1188 if ( m_combOperator
== ExprComb::Symbol
)
1189 return m_xSymbolicName
? *m_xSymbolicName
: OString("<Undefined Name>");
1193 switch (m_exprValue
->et
)
1196 return OString::number(m_exprValue
->u
.sval
);
1198 return OString::number(m_exprValue
->u
.usval
);
1200 return OString::number(m_exprValue
->u
.lval
);
1202 return OString::number(m_exprValue
->u
.ulval
);
1204 return OString::number(m_exprValue
->u
.hval
);
1206 return OString::number(m_exprValue
->u
.uhval
);
1208 return OString::number(m_exprValue
->u
.fval
);
1210 return OString::number(m_exprValue
->u
.dval
);
1212 return OString::number(m_exprValue
->u
.byval
);
1214 if ( m_exprValue
->u
.lval
== 0)
1224 switch (m_combOperator
)
1226 case ExprComb::UPlus
:
1229 case ExprComb::UMinus
:
1236 exprStr
+= m_subExpr1
->toString();
1237 switch (m_combOperator
)
1242 case ExprComb::Minus
:
1263 case ExprComb::Left
:
1266 case ExprComb::Right
:
1274 exprStr
+= m_subExpr2
->toString();
1279 // Convert the type of an AST_Expression to a char *
1280 const sal_Char
* exprTypeToString(ExprType t
)
1287 return "unsigned short";
1291 return "unsigned long";
1295 return "unsigned hyper";
1321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */