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 <osl/diagnose.h>
32 AstExpression::AstExpression(ExprComb c
, AstExpression
*pExpr1
, AstExpression
*pExpr2
)
39 AstExpression::AstExpression(sal_Int32 l
)
40 : m_combOperator(ExprComb::NONE
)
42 m_exprValue
.reset( new AstExprValue
);
43 m_exprValue
->et
= ET_long
;
44 m_exprValue
->u
.lval
= l
;
47 AstExpression::AstExpression(sal_Int32 l
, ExprType et
)
48 : m_combOperator(ExprComb::NONE
)
50 m_exprValue
.reset( new AstExprValue
);
52 m_exprValue
->u
.lval
= l
;
55 AstExpression::AstExpression(sal_Int64 h
)
56 : m_combOperator(ExprComb::NONE
)
58 m_exprValue
.reset( new AstExprValue
);
59 m_exprValue
->et
= ET_hyper
;
60 m_exprValue
->u
.hval
= h
;
63 AstExpression::AstExpression(sal_uInt64 uh
)
64 : m_combOperator(ExprComb::NONE
)
66 m_exprValue
.reset( new AstExprValue
);
67 m_exprValue
->et
= ET_uhyper
;
68 m_exprValue
->u
.uhval
= uh
;
71 AstExpression::AstExpression(double d
)
72 : m_combOperator(ExprComb::NONE
)
74 m_exprValue
.reset( new AstExprValue
);
75 m_exprValue
->et
= ET_double
;
76 m_exprValue
->u
.dval
= d
;
79 AstExpression::AstExpression(OString
* scopedName
)
80 : m_combOperator(ExprComb::Symbol
)
83 m_xSymbolicName
= *scopedName
;
86 AstExpression::~AstExpression()
91 * Perform the coercion from the given AstExprValue to the requested
92 * ExprType. Return an AstExprValue if successful, NULL if failed.
93 * must be done for hyper, uhyper
96 coerce_value(AstExprValue
*ev
, ExprType t
)
109 if (ev
->u
.usval
> SAL_MAX_INT16
)
111 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.usval
);
115 if (ev
->u
.lval
< SAL_MIN_INT16
|| ev
->u
.lval
> SAL_MAX_INT16
)
117 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.lval
);
121 if (ev
->u
.ulval
> SAL_MAX_INT16
)
123 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.ulval
);
127 if (ev
->u
.hval
< SAL_MIN_INT16
|| ev
->u
.hval
> SAL_MAX_INT16
)
129 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.hval
);
133 if (ev
->u
.uhval
> SAL_MAX_INT16
)
135 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.uhval
);
139 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.bval
);
143 if (ev
->u
.fval
< SAL_MIN_INT16
|| ev
->u
.fval
> SAL_MAX_INT16
)
145 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.fval
);
149 if (ev
->u
.dval
< SAL_MIN_INT16
|| ev
->u
.dval
> SAL_MAX_INT16
)
151 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.dval
);
155 ev
->u
.sval
= static_cast<sal_Int16
>(ev
->u
.byval
);
168 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.sval
);
174 if (ev
->u
.lval
< 0 || ev
->u
.lval
> SAL_MAX_UINT16
)
176 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.lval
);
180 if (ev
->u
.ulval
> SAL_MAX_UINT16
)
182 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.ulval
);
186 if (ev
->u
.hval
< 0 || ev
->u
.hval
> SAL_MAX_UINT16
)
188 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.hval
);
192 if (ev
->u
.uhval
> SAL_MAX_UINT16
)
194 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.uhval
);
198 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.bval
);
202 if (ev
->u
.fval
< 0.0 || ev
->u
.fval
> SAL_MAX_UINT16
)
204 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.fval
);
208 if (ev
->u
.dval
< 0.0 || ev
->u
.dval
> SAL_MAX_UINT16
)
210 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.dval
);
214 ev
->u
.usval
= static_cast<sal_uInt16
>(ev
->u
.byval
);
225 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.sval
);
229 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.usval
);
235 if (ev
->u
.ulval
> SAL_MAX_INT32
)
237 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.ulval
);
241 if (ev
->u
.hval
< SAL_MIN_INT32
|| ev
->u
.hval
> SAL_MAX_INT32
)
243 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.hval
);
247 if (ev
->u
.uhval
> SAL_MAX_INT32
)
249 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.uhval
);
253 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.bval
);
257 if (ev
->u
.fval
< SAL_MIN_INT32
|| ev
->u
.fval
> SAL_MAX_INT32
)
259 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.fval
);
263 if (ev
->u
.dval
< SAL_MIN_INT32
|| ev
->u
.dval
> SAL_MAX_INT32
)
265 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.dval
);
269 ev
->u
.lval
= static_cast<sal_Int32
>(ev
->u
.byval
);
282 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.sval
);
286 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.usval
);
292 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.lval
);
298 if (ev
->u
.hval
< 0 || ev
->u
.hval
> SAL_MAX_UINT32
)
300 ev
->u
.lval
= static_cast<sal_uInt32
>(ev
->u
.hval
);
304 if (ev
->u
.uhval
> SAL_MAX_UINT32
)
306 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.uhval
);
310 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.bval
);
314 if (ev
->u
.fval
< 0.0 || ev
->u
.fval
> SAL_MAX_UINT32
)
316 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.fval
);
320 if (ev
->u
.dval
< 0.0 || ev
->u
.dval
> SAL_MAX_UINT32
)
322 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.dval
);
326 ev
->u
.ulval
= static_cast<sal_uInt32
>(ev
->u
.byval
);
337 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.sval
);
341 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.usval
);
345 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.lval
);
349 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.ulval
);
355 if (ev
->u
.uhval
> SAL_MAX_INT64
)
357 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.uhval
);
361 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.bval
);
365 if (ev
->u
.fval
< SAL_MIN_INT64
|| ev
->u
.fval
> SAL_MAX_INT64
)
367 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.fval
);
371 if (ev
->u
.dval
< SAL_MIN_INT64
|| ev
->u
.dval
> SAL_MAX_INT64
)
373 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.dval
);
377 ev
->u
.hval
= static_cast<sal_Int64
>(ev
->u
.byval
);
390 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.sval
);
394 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.usval
);
400 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.lval
);
404 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.ulval
);
410 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.hval
);
416 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.bval
);
420 if (ev
->u
.fval
< 0.0 || ev
->u
.fval
> SAL_MAX_UINT64
)
422 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.fval
);
426 if (ev
->u
.dval
< 0.0 || ev
->u
.dval
> SAL_MAX_UINT64
)
428 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.dval
);
432 ev
->u
.uhval
= static_cast<sal_uInt64
>(ev
->u
.byval
);
443 ev
->u
.bval
= ev
->u
.sval
!= 0;
447 ev
->u
.bval
= ev
->u
.usval
!= 0;
451 ev
->u
.bval
= ev
->u
.lval
!= 0;
455 ev
->u
.bval
= ev
->u
.ulval
!= 0;
459 ev
->u
.bval
= ev
->u
.hval
!= 0;
463 ev
->u
.bval
= ev
->u
.uhval
!= 0;
469 ev
->u
.bval
= ev
->u
.fval
!= 0.0;
473 ev
->u
.bval
= ev
->u
.dval
!= 0.0;
477 ev
->u
.bval
= ev
->u
.byval
!= 0;
488 ev
->u
.fval
= static_cast<float>(ev
->u
.sval
);
492 ev
->u
.fval
= static_cast<float>(ev
->u
.usval
);
496 ev
->u
.fval
= static_cast<float>(ev
->u
.lval
);
500 ev
->u
.fval
= static_cast<float>(ev
->u
.ulval
);
504 ev
->u
.fval
= static_cast<float>(ev
->u
.hval
);
508 if (static_cast<float>(ev
->u
.ulval
) > FLT_MAX
)
510 ev
->u
.fval
= static_cast<float>(ev
->u
.ulval
);
514 ev
->u
.fval
= ev
->u
.bval
? 1.0f
: 0.0f
;
520 if (static_cast<float>(ev
->u
.dval
) > FLT_MAX
|| static_cast<float>(ev
->u
.dval
) < -FLT_MAX
)
522 ev
->u
.fval
= static_cast<float>(ev
->u
.dval
);
526 ev
->u
.fval
= static_cast<float>(ev
->u
.byval
);
537 ev
->u
.dval
= static_cast<double>(ev
->u
.sval
);
541 ev
->u
.dval
= static_cast<double>(ev
->u
.usval
);
545 ev
->u
.dval
= static_cast<double>(ev
->u
.lval
);
549 ev
->u
.dval
= static_cast<double>(ev
->u
.ulval
);
553 ev
->u
.dval
= static_cast<double>(ev
->u
.hval
);
557 if (ev
->u
.dval
> FLT_MAX
|| ev
->u
.dval
< -FLT_MAX
)
559 ev
->u
.dval
= static_cast<double>(ev
->u
.ulval
);
563 ev
->u
.dval
= ev
->u
.bval
? 1.0 : 0.0;
567 ev
->u
.dval
= static_cast<double>(ev
->u
.fval
);
573 ev
->u
.dval
= static_cast<double>(ev
->u
.byval
);
584 if (ev
->u
.sval
< SAL_MIN_INT8
|| ev
->u
.sval
> SAL_MAX_UINT8
)
586 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.sval
);
590 if (ev
->u
.usval
> SAL_MAX_UINT8
)
592 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.usval
);
596 if (ev
->u
.lval
< SAL_MIN_INT8
|| ev
->u
.lval
> SAL_MAX_UINT8
)
598 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.lval
);
602 if (ev
->u
.ulval
> SAL_MAX_UINT8
)
604 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.ulval
);
608 if (ev
->u
.hval
< SAL_MIN_INT8
|| ev
->u
.hval
> SAL_MAX_UINT8
)
610 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.hval
);
614 if (ev
->u
.uhval
> SAL_MAX_UINT8
)
616 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.uhval
);
620 ev
->u
.byval
= ev
->u
.bval
? 1 : 0;
624 if (ev
->u
.fval
< SAL_MIN_INT8
|| ev
->u
.fval
> SAL_MAX_UINT8
)
626 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.fval
);
630 if (ev
->u
.dval
< SAL_MIN_INT8
|| ev
->u
.dval
> SAL_MAX_UINT8
)
632 ev
->u
.byval
= static_cast<unsigned char>(ev
->u
.dval
);
647 bool AstExpression::coerce(ExprType t
)
650 * Is it already of the right type?
652 if (m_exprValue
!= nullptr && m_exprValue
->et
== t
)
657 * First, evaluate it, then try to coerce result type
658 * If already evaluated, return the result
661 if (m_exprValue
== nullptr)
664 if (!coerce_value(m_exprValue
.get(), t
))
667 return m_exprValue
!= nullptr;
670 bool AstExpression::compareLong(AstExpression
*pExpr
)
673 if (m_combOperator
!= pExpr
->m_combOperator
)
677 if (m_exprValue
== nullptr || pExpr
->getExprValue() == nullptr)
679 if (m_exprValue
->et
!= pExpr
->getExprValue()->et
)
681 switch (m_exprValue
->et
)
684 bRet
= m_exprValue
->u
.lval
== pExpr
->getExprValue()->u
.lval
;
694 void AstExpression::evaluate()
699 if ( m_exprValue
!= nullptr )
702 * OK, must evaluate operator
704 switch (m_combOperator
)
707 case ExprComb::Minus
:
711 m_exprValue
= eval_bin_op();
717 case ExprComb::Right
:
718 m_exprValue
= eval_bit_op();
720 case ExprComb::UPlus
:
721 case ExprComb::UMinus
:
722 m_exprValue
= eval_un_op();
724 case ExprComb::Symbol
:
725 m_exprValue
= eval_symbol();
732 std::unique_ptr
<AstExprValue
> AstExpression::eval_bin_op()
734 ExprType eType
= ET_double
;
736 if ( m_combOperator
== ExprComb::Mod
)
739 if (m_subExpr1
== nullptr || m_subExpr2
== nullptr)
741 m_subExpr1
->evaluate();
742 if (m_subExpr1
->getExprValue() == nullptr)
744 if (!m_subExpr1
->coerce(eType
))
746 m_subExpr2
->evaluate();
747 if (m_subExpr2
->getExprValue() == nullptr)
749 if (!m_subExpr2
->coerce(eType
))
752 std::unique_ptr
< AstExprValue
> retval(new AstExprValue
);
755 switch (m_combOperator
)
758 if (m_subExpr2
->getExprValue()->u
.hval
== 0)
760 retval
->u
.hval
= m_subExpr1
->getExprValue()->u
.hval
% m_subExpr2
->getExprValue()->u
.hval
;
763 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
+ m_subExpr2
->getExprValue()->u
.dval
;
765 case ExprComb::Minus
:
766 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
- m_subExpr2
->getExprValue()->u
.dval
;
769 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
* m_subExpr2
->getExprValue()->u
.dval
;
772 if (m_subExpr2
->getExprValue()->u
.dval
== 0.0)
774 retval
->u
.dval
= m_subExpr1
->getExprValue()->u
.dval
/ m_subExpr2
->getExprValue()->u
.dval
;
783 std::unique_ptr
<AstExprValue
> AstExpression::eval_bit_op()
785 if (m_subExpr1
== nullptr || m_subExpr2
== nullptr)
787 m_subExpr1
->evaluate();
788 if (m_subExpr1
->getExprValue() == nullptr)
790 if (!m_subExpr1
->coerce(ET_long
))
792 m_subExpr2
->evaluate();
793 if (m_subExpr2
->getExprValue() == nullptr)
795 if (!m_subExpr2
->coerce(ET_long
))
798 std::unique_ptr
< AstExprValue
> retval(new AstExprValue
);
799 retval
->et
= ET_long
;
801 switch (m_combOperator
)
804 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
| m_subExpr2
->getExprValue()->u
.lval
;
807 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
^ m_subExpr2
->getExprValue()->u
.lval
;
810 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
& m_subExpr2
->getExprValue()->u
.lval
;
813 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
<< m_subExpr2
->getExprValue()->u
.lval
;
815 case ExprComb::Right
:
816 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
>> m_subExpr2
->getExprValue()->u
.lval
;
825 std::unique_ptr
<AstExprValue
> AstExpression::eval_un_op()
827 if (m_subExpr1
== nullptr)
829 m_subExpr1
->evaluate();
830 if (m_subExpr1
->getExprValue() == nullptr)
832 if (!m_subExpr1
->coerce(ET_double
))
835 std::unique_ptr
< AstExprValue
> retval(new AstExprValue
);
836 retval
->et
= ET_double
;
838 switch (m_combOperator
)
840 case ExprComb::UPlus
:
841 retval
->u
.lval
= m_subExpr1
->getExprValue()->u
.lval
;
843 case ExprComb::UMinus
:
844 retval
->u
.lval
= -(m_subExpr1
->getExprValue()->u
.lval
);
853 std::unique_ptr
<AstExprValue
> AstExpression::eval_symbol()
855 AstScope
*pScope
= nullptr;
856 AstDeclaration
*pDecl
;
860 * Is there a symbol stored?
862 if (!m_xSymbolicName
)
864 ErrorHandler::evalError(this);
868 * Get current scope for lookup
870 if (idlc()->scopes()->depth() > 0)
871 pScope
= idlc()->scopes()->topNonNull();
874 ErrorHandler::lookupError(*m_xSymbolicName
);
880 pDecl
= pScope
->lookupByName(*m_xSymbolicName
);
881 if (pDecl
== nullptr)
883 ErrorHandler::lookupError(*m_xSymbolicName
);
889 if (pDecl
->getNodeType() != NT_const
&&
890 pDecl
->getNodeType() != NT_enum_val
)
892 ErrorHandler::constantExpected(pDecl
, *m_xSymbolicName
);
895 if (!ErrorHandler::checkPublished(pDecl
))
900 * OK, now evaluate the constant we just got, to produce its value
902 pConst
= static_cast< AstConstant
* >(pDecl
);
903 pConst
->getConstValue()->evaluate();
904 auto const val
= pConst
->getConstValue()->getExprValue();
905 return val
== nullptr ? nullptr : std::make_unique
<AstExprValue
>(*val
);
908 OString
AstExpression::toString()
911 if ( m_combOperator
== ExprComb::Symbol
)
912 return m_xSymbolicName
? *m_xSymbolicName
: OString("<Undefined Name>");
916 switch (m_exprValue
->et
)
919 return OString::number(m_exprValue
->u
.sval
);
921 return OString::number(m_exprValue
->u
.usval
);
923 return OString::number(m_exprValue
->u
.lval
);
925 return OString::number(m_exprValue
->u
.ulval
);
927 return OString::number(m_exprValue
->u
.hval
);
929 return OString::number(m_exprValue
->u
.uhval
);
931 return OString::number(m_exprValue
->u
.fval
);
933 return OString::number(m_exprValue
->u
.dval
);
935 return OString::number(m_exprValue
->u
.byval
);
937 if ( m_exprValue
->u
.lval
== 0)
938 return OString("FALSE");
940 return OString("TRUE");
947 switch (m_combOperator
)
949 case ExprComb::UPlus
:
952 case ExprComb::UMinus
:
959 exprStr
+= m_subExpr1
->toString();
960 switch (m_combOperator
)
965 case ExprComb::Minus
:
989 case ExprComb::Right
:
997 exprStr
+= m_subExpr2
->toString();
1002 // Convert the type of an AST_Expression to a char *
1003 const sal_Char
* exprTypeToString(ExprType t
)
1010 return "unsigned short";
1014 return "unsigned long";
1018 return "unsigned hyper";
1044 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */