diff options
Diffstat (limited to 'idlc/source/astexpression.cxx')
-rw-r--r-- | idlc/source/astexpression.cxx | 1269 |
1 files changed, 1269 insertions, 0 deletions
diff --git a/idlc/source/astexpression.cxx b/idlc/source/astexpression.cxx new file mode 100644 index 000000000000..c687d3104785 --- /dev/null +++ b/idlc/source/astexpression.cxx @@ -0,0 +1,1269 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: astexpression.cxx,v $ + * $Revision: 1.13 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_idlc.hxx" +#include <idlc/astexpression.hxx> +#include <idlc/astconstant.hxx> +#include <idlc/astscope.hxx> +#include <idlc/errorhandler.hxx> + +#include <limits.h> +#include <float.h> + +#undef MAXCHAR +#define MAXCHAR 127 +#undef MINCHAR +#define MINCHAR -128 + +using namespace ::rtl; + +AstExpression::AstExpression(ExprComb c, AstExpression *pExpr1, AstExpression *pExpr2) + : m_combOperator(c) + , m_subExpr1(pExpr1) + , m_subExpr2(pExpr2) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + +} + +AstExpression::AstExpression(sal_Int32 l) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_long; + m_exprValue->u.lval = l; +} + +AstExpression::AstExpression(sal_Int32 l, ExprType et) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = et; + m_exprValue->u.lval = l; +} + +AstExpression::AstExpression(sal_Int64 h) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_hyper; + m_exprValue->u.hval = h; +} + +AstExpression::AstExpression(sal_uInt64 uh) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_uhyper; + m_exprValue->u.uhval = uh; +} + +AstExpression::AstExpression(double d) + : m_combOperator(EC_none) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(NULL) +{ + fillDefinitionDetails(); + + m_exprValue = new AstExprValue(); + m_exprValue->et = ET_double; + m_exprValue->u.dval = d; +} + +AstExpression::AstExpression(::rtl::OString* scopedName) + : m_combOperator(EC_symbol) + , m_subExpr1(NULL) + , m_subExpr2(NULL) + , m_exprValue(NULL) + , m_pSymbolicName(scopedName) +{ + fillDefinitionDetails(); +} + +AstExpression::~AstExpression() +{ + if ( m_exprValue ) + delete m_exprValue; + if ( m_subExpr1 ) + delete m_subExpr1; + if ( m_subExpr2 ) + delete m_subExpr2; + if ( m_pSymbolicName ) + delete m_pSymbolicName; +} + +/* + * Perform the coercion from the given AstExprValue to the requested + * ExprType. Return an AstExprValue if successful, NULL if failed. + * must be done for hyper, uhyper + */ +static AstExprValue * +coerce_value(AstExprValue *ev, ExprType t) +{ + if (ev == NULL) + return NULL; + + switch (t) + { + case ET_short: + switch (ev->et) + { + case ET_short: + return ev; + case ET_ushort: + if (ev->u.usval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.usval; + ev->et = ET_short; + return ev; + case ET_long: + if (ev->u.lval < SAL_MIN_INT16 || ev->u.lval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.lval; + ev->et = ET_short; + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.ulval; + ev->et = ET_short; + return ev; + case ET_hyper: + if (ev->u.hval < SAL_MIN_INT16 || ev->u.hval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.hval; + ev->et = ET_short; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.uhval; + ev->et = ET_short; + return ev; + case ET_boolean: + ev->u.sval = (sal_Int16)ev->u.bval; + ev->et = ET_short; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT16 || ev->u.fval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.fval; + ev->et = ET_short; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT16 || ev->u.dval > SAL_MAX_INT16) + return NULL; + ev->u.sval = (sal_Int16)ev->u.dval; + ev->et = ET_short; + return ev; + case ET_byte: + ev->u.sval = (sal_Int16)ev->u.byval; + ev->et = ET_short; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_ushort: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < 0) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.sval; + ev->et = ET_ushort; + return ev; + case ET_ushort: + return ev; + case ET_long: + if (ev->u.lval < 0 || ev->u.lval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.lval; + ev->et = ET_ushort; + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.ulval; + ev->et = ET_ushort; + return ev; + case ET_hyper: + if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.hval; + ev->et = ET_ushort; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.uhval; + ev->et = ET_ushort; + return ev; + case ET_boolean: + ev->u.usval = (sal_uInt16)ev->u.bval; + ev->et = ET_short; + return ev; + case ET_float: + if (ev->u.fval < 0.0 || ev->u.fval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.fval; + ev->et = ET_short; + return ev; + case ET_double: + if (ev->u.dval < 0.0 || ev->u.dval > SAL_MAX_UINT16) + return NULL; + ev->u.usval = (sal_uInt16)ev->u.dval; + ev->et = ET_short; + return ev; + case ET_byte: + ev->u.usval = (sal_uInt16)ev->u.byval; + ev->et = ET_ushort; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_long: + switch (ev->et) + { + case ET_short: + ev->u.lval = (sal_Int32)ev->u.sval; + ev->et = ET_long; + return ev; + case ET_ushort: + ev->u.lval = (sal_Int32)ev->u.usval; + ev->et = ET_long; + return ev; + case ET_long: + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.ulval; + ev->et = ET_long; + return ev; + case ET_hyper: + if (ev->u.hval < SAL_MIN_INT32 || ev->u.hval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.hval; + ev->et = ET_long; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.uhval; + ev->et = ET_long; + return ev; + case ET_boolean: + ev->u.lval = (sal_Int32)ev->u.bval; + ev->et = ET_long; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT32 || ev->u.fval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.fval; + ev->et = ET_long; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT32 || ev->u.dval > SAL_MAX_INT32) + return NULL; + ev->u.lval = (sal_Int32)ev->u.dval; + ev->et = ET_long; + return ev; + case ET_byte: + ev->u.lval = (sal_Int32) ev->u.byval; + ev->et = ET_long; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_ulong: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < 0) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.sval; + ev->et = ET_ulong; + return ev; + case ET_ushort: + ev->u.ulval = (sal_uInt32)ev->u.usval; + ev->et = ET_ulong; + return ev; + case ET_long: + if (ev->u.lval < 0) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.lval; + ev->et = ET_ulong; + return ev; + case ET_ulong: + return ev; + case ET_hyper: + if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT32) + return NULL; + ev->u.lval = (sal_uInt32)ev->u.hval; + ev->et = ET_ulong; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_UINT32) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.uhval; + ev->et = ET_ulong; + return ev; + case ET_boolean: + ev->u.ulval = (sal_uInt32)ev->u.bval; + ev->et = ET_ulong; + return ev; + case ET_float: + if (ev->u.fval < 0.0 || ev->u.fval > SAL_MAX_UINT32) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.fval; + ev->et = ET_ulong; + return ev; + case ET_double: + if (ev->u.dval < 0.0 || ev->u.dval > SAL_MAX_UINT32) + return NULL; + ev->u.ulval = (sal_uInt32)ev->u.dval; + ev->et = ET_ulong; + return ev; + case ET_byte: + ev->u.ulval = (sal_uInt32)ev->u.byval; + ev->et = ET_ulong; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_hyper: + switch (ev->et) + { + case ET_short: + ev->u.hval = (sal_Int64)ev->u.sval; + ev->et = ET_hyper; + return ev; + case ET_ushort: + ev->u.hval = (sal_Int64)ev->u.usval; + ev->et = ET_hyper; + return ev; + case ET_long: + ev->u.hval = (sal_Int64)ev->u.lval; + ev->et = ET_hyper; + return ev; + case ET_ulong: + ev->u.hval = (sal_Int64)ev->u.ulval; + ev->et = ET_hyper; + return ev; + case ET_hyper: + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_INT64) + return NULL; + ev->u.hval = (sal_Int64)ev->u.uhval; + ev->et = ET_long; + return ev; + case ET_boolean: + ev->u.hval = (sal_Int64)ev->u.bval; + ev->et = ET_hyper; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT64 || ev->u.fval > SAL_MAX_INT64) + return NULL; + ev->u.hval = (sal_Int64)ev->u.fval; + ev->et = ET_hyper; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT64 || ev->u.dval > SAL_MAX_INT64) + return NULL; + ev->u.hval = (sal_Int64)ev->u.dval; + ev->et = ET_hyper; + return ev; + case ET_byte: + ev->u.hval = (sal_Int64)ev->u.byval; + ev->et = ET_hyper; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_uhyper: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < 0) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.sval; + ev->et = ET_uhyper; + return ev; + case ET_ushort: + ev->u.uhval = (sal_uInt64)ev->u.usval; + ev->et = ET_uhyper; + return ev; + case ET_long: + if (ev->u.lval < 0) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.lval; + ev->et = ET_uhyper; + return ev; + case ET_ulong: + ev->u.uhval = (sal_uInt64)ev->u.ulval; + ev->et = ET_uhyper; + return ev; + case ET_hyper: + if (ev->u.hval < 0) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.hval; + ev->et = ET_uhyper; + return ev; + case ET_uhyper: + return ev; + case ET_boolean: + ev->u.uhval = (sal_uInt64)ev->u.bval; + ev->et = ET_uhyper; + return ev; + case ET_float: + if (ev->u.fval < 0.0 || ev->u.fval > SAL_MAX_UINT64) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.fval; + ev->et = ET_uhyper; + return ev; + case ET_double: + if (ev->u.dval < 0.0 || ev->u.dval > SAL_MAX_UINT64) + return NULL; + ev->u.uhval = (sal_uInt64)ev->u.dval; + ev->et = ET_uhyper; + return ev; + case ET_byte: + ev->u.uhval = (sal_uInt64)ev->u.byval; + ev->et = ET_uhyper; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_boolean: + switch (ev->et) + { + case ET_short: + ev->u.bval = (ev->u.sval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_ushort: + ev->u.bval = (ev->u.usval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_long: + ev->u.bval = (ev->u.lval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_ulong: + ev->u.bval = (ev->u.ulval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_hyper: + ev->u.bval = (ev->u.hval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_uhyper: + ev->u.bval = (ev->u.uhval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_boolean: + return ev; + case ET_float: + ev->u.bval = (ev->u.fval == 0.0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_double: + ev->u.bval = (ev->u.dval == 0.0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + case ET_byte: + ev->u.bval = (ev->u.byval == 0) ? sal_False : sal_True; + ev->et = ET_boolean; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_float: + switch (ev->et) + { + case ET_short: + ev->u.fval = (float)ev->u.sval; + ev->et = ET_float; + return ev; + case ET_ushort: + ev->u.fval = (float)ev->u.usval; + ev->et = ET_float; + return ev; + case ET_long: + ev->u.fval = (float)ev->u.lval; + ev->et = ET_float; + return ev; + case ET_ulong: + ev->u.fval = (float)ev->u.ulval; + ev->et = ET_float; + return ev; + case ET_hyper: + ev->u.fval = (float)ev->u.hval; + ev->et = ET_float; + return ev; + case ET_uhyper: + if ((float)ev->u.ulval > FLT_MAX) + return NULL; + ev->u.fval = (float)ev->u.ulval; + ev->et = ET_float; + return ev; + case ET_boolean: + ev->u.fval = (ev->u.bval == sal_True) ? 1.0f : 0.0f; + ev->et = ET_float; + return ev; + case ET_float: + return ev; + case ET_double: + if ((float)ev->u.dval > FLT_MAX || (float)ev->u.dval < -FLT_MAX) + return NULL; + ev->u.fval = (float)ev->u.dval; + ev->et = ET_float; + return ev; + case ET_byte: + ev->u.fval = (float)ev->u.byval; + ev->et = ET_float; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_double: + switch (ev->et) + { + case ET_short: + ev->u.dval = (double)ev->u.sval; + ev->et = ET_double; + return ev; + case ET_ushort: + ev->u.dval = (double)ev->u.usval; + ev->et = ET_double; + return ev; + case ET_long: + ev->u.dval = (double)ev->u.lval; + ev->et = ET_double; + return ev; + case ET_ulong: + ev->u.dval = (double)ev->u.ulval; + ev->et = ET_double; + return ev; + case ET_hyper: + ev->u.dval = (double)ev->u.hval; + ev->et = ET_double; + return ev; + case ET_uhyper: + if ((double)ev->u.dval > FLT_MAX || (double)ev->u.dval < -FLT_MAX) + return NULL; + ev->u.dval = (double)ev->u.ulval; + ev->et = ET_double; + return ev; + case ET_boolean: + ev->u.dval = (ev->u.bval == sal_True) ? 1.0 : 0.0; + ev->et = ET_double; + return ev; + case ET_float: + ev->u.dval = (double)ev->u.fval; + ev->et = ET_double; + return ev; + case ET_double: + return ev; + case ET_byte: + ev->u.dval = (double)ev->u.byval; + ev->et = ET_double; + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + case ET_byte: + switch (ev->et) + { + case ET_short: + if (ev->u.sval < SAL_MIN_INT8 || ev->u.sval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar)ev->u.sval; + ev->et = ET_byte; + return ev; + case ET_ushort: + if (ev->u.usval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar)ev->u.usval; + ev->et = ET_byte; + return ev; + case ET_long: + if (ev->u.lval < SAL_MIN_INT8 || ev->u.lval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.lval; + ev->et = ET_byte; + return ev; + case ET_ulong: + if (ev->u.ulval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.ulval; + ev->et = ET_byte; + return ev; + case ET_hyper: + if (ev->u.hval < SAL_MIN_INT8 || ev->u.hval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.hval; + ev->et = ET_byte; + return ev; + case ET_uhyper: + if (ev->u.uhval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.uhval; + ev->et = ET_byte; + return ev; + case ET_boolean: + ev->u.byval = (ev->u.bval == sal_False) ? 1 : 0; + ev->et = ET_byte; + return ev; + case ET_float: + if (ev->u.fval < SAL_MIN_INT8 || ev->u.fval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.fval; + ev->et = ET_byte; + return ev; + case ET_double: + if (ev->u.dval < SAL_MIN_INT8 || ev->u.dval > SAL_MAX_UINT8) + return NULL; + ev->u.byval = (sal_uChar) ev->u.dval; + ev->et = ET_byte; + return ev; + case ET_byte: + return ev; + default: + OSL_ASSERT(false); + return NULL; + } + default: + OSL_ASSERT(false); + return NULL; + } +} + +/* + * Evaluate the expression with the evaluation kind requested. Supported + * evaluation kinds are + * - EK_const: The expression must evaluate to a constant + * - EK_positive_int: The expression must further evaluate to a + * positive integer + */ +static AstExprValue * +eval_kind(AstExprValue *ev, EvalKind ek) +{ + if (ek == EK_const) + return ev; + if (ek == EK_positive_int) + return coerce_value(ev, ET_ulong); + + return NULL; +} + +AstExprValue* AstExpression::coerce(ExprType t, sal_Bool bAssign) +{ + AstExprValue *copy; + + /* + * Is it already of the right type? + */ + if (m_exprValue != NULL && m_exprValue->et == t) + return m_exprValue; + /* + * OK, must coerce + * + * First, evaluate it, then try to coerce result type + * If already evaluated, return the result + */ + m_exprValue = eval_internal(EK_const); + if (m_exprValue == NULL) + return NULL; + + /* + * Create a copy to contain coercion result + */ + copy = new AstExprValue; + + copy->et = m_exprValue->et; + switch (m_exprValue->et) + { + case ET_short: + copy->u.sval = m_exprValue->u.sval; + break; + case ET_ushort: + copy->u.usval = m_exprValue->u.usval; + break; + case ET_long: + copy->u.lval = m_exprValue->u.lval; + break; + case ET_ulong: + copy->u.ulval = m_exprValue->u.ulval; + break; + case ET_hyper: + copy->u.hval = m_exprValue->u.hval; + break; + case ET_uhyper: + copy->u.uhval = m_exprValue->u.uhval; + break; + case ET_boolean: + copy->u.bval = m_exprValue->u.bval; + break; + case ET_float: + copy->u.fval = m_exprValue->u.fval; + break; + case ET_double: + copy->u.dval = m_exprValue->u.dval; + break; + case ET_byte: + copy->u.byval = m_exprValue->u.byval; + break; + default: + OSL_ASSERT(false); + break; + } + + if (bAssign) + { + m_exprValue = coerce_value(copy, t); + return m_exprValue; + } + + return coerce_value(copy, t); +} + +void AstExpression::evaluate(EvalKind ek) +{ + m_exprValue = eval_internal(ek); + m_exprValue = eval_kind(m_exprValue, ek); +} + +sal_Bool AstExpression::operator==(AstExpression *pExpr) +{ + if (m_combOperator != pExpr->getCombOperator()) + return sal_False; + evaluate(EK_const); + pExpr->evaluate(EK_const); + if (m_exprValue == NULL || pExpr->getExprValue() == NULL) + return sal_False; + if (m_exprValue->et != pExpr->getExprValue()->et) + return sal_False; + switch (m_exprValue->et) + { + case ET_short: + return (m_exprValue->u.sval == pExpr->getExprValue()->u.sval) ? sal_True : sal_False; + case ET_ushort: + return (m_exprValue->u.usval == pExpr->getExprValue()->u.usval) ? sal_True : sal_False; + case ET_long: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + case ET_ulong: + return (m_exprValue->u.ulval == pExpr->getExprValue()->u.ulval) ? sal_True : sal_False; + case ET_hyper: + return (m_exprValue->u.hval == pExpr->getExprValue()->u.hval) ? sal_True : sal_False; + case ET_uhyper: + return (m_exprValue->u.uhval == pExpr->getExprValue()->u.uhval) ? sal_True : sal_False; + case ET_float: + return (m_exprValue->u.fval == pExpr->getExprValue()->u.fval) ? sal_True : sal_False; + case ET_double: + return (m_exprValue->u.dval == pExpr->getExprValue()->u.dval) ? sal_True : sal_False; + case ET_byte: + return (m_exprValue->u.byval == pExpr->getExprValue()->u.byval) ? sal_True : sal_False; + case ET_boolean: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + default: + OSL_ASSERT(false); + return sal_False; + } + + return sal_False; +} + +sal_Bool AstExpression::compare(AstExpression *pExpr) +{ + if (m_combOperator != pExpr->getCombOperator()) + return sal_False; + evaluate(EK_const); + pExpr->evaluate(EK_const); + if (m_exprValue == NULL || pExpr->getExprValue() == NULL) + return sal_False; + if (m_exprValue->et != pExpr->getExprValue()->et) + return sal_False; + switch (m_exprValue->et) + { + case ET_short: + return (m_exprValue->u.sval == pExpr->getExprValue()->u.sval) ? sal_True : sal_False; + case ET_ushort: + return (m_exprValue->u.usval == pExpr->getExprValue()->u.usval) ? sal_True : sal_False; + case ET_long: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + case ET_ulong: + return (m_exprValue->u.ulval == pExpr->getExprValue()->u.ulval) ? sal_True : sal_False; + case ET_hyper: + return (m_exprValue->u.hval == pExpr->getExprValue()->u.hval) ? sal_True : sal_False; + case ET_uhyper: + return (m_exprValue->u.uhval == pExpr->getExprValue()->u.uhval) ? sal_True : sal_False; + case ET_float: + return (m_exprValue->u.fval == pExpr->getExprValue()->u.fval) ? sal_True : sal_False; + case ET_double: + return (m_exprValue->u.dval == pExpr->getExprValue()->u.dval) ? sal_True : sal_False; + case ET_byte: + return (m_exprValue->u.byval == pExpr->getExprValue()->u.byval) ? sal_True : sal_False; + case ET_boolean: + return (m_exprValue->u.lval == pExpr->getExprValue()->u.lval) ? sal_True : sal_False; + default: + OSL_ASSERT(false); + return sal_False; + } + + return sal_False; +} + +void AstExpression::fillDefinitionDetails() +{ + m_pScope = idlc()->scopes()->depth() > 0 ? idlc()->scopes()->top() : NULL; + m_lineNo = idlc()->getLineNumber(); + m_fileName = idlc()->getFileName(); +} + +AstExprValue* AstExpression::eval_internal(EvalKind ek) +{ + /* + * Already evaluated? + */ + if ( m_exprValue != NULL ) + return eval_kind(m_exprValue, ek); + /* + * OK, must evaluate operator + */ + switch (m_combOperator) + { + case EC_add: + case EC_minus: + case EC_mul: + case EC_div: + case EC_mod: + m_exprValue = eval_bin_op(ek); + return eval_kind(m_exprValue, ek); + case EC_or: + case EC_xor: + case EC_and: + case EC_left: + case EC_right: + m_exprValue = eval_bit_op(ek); + return eval_kind(m_exprValue, ek); + case EC_u_plus: + case EC_u_minus: + case EC_bit_neg: + m_exprValue = eval_un_op(ek); + return eval_kind(m_exprValue, ek); + case EC_symbol: + m_exprValue = eval_symbol(ek); + return eval_kind(m_exprValue, ek); + case EC_none: + return NULL; + } + + return NULL; +} + +AstExprValue* AstExpression::eval_bin_op(EvalKind ek) +{ + AstExprValue *retval = NULL; + ExprType eType = ET_double; + + if ( m_combOperator == EC_mod ) + eType = ET_hyper; + + if (ek != EK_const && ek != EK_positive_int) + return NULL; + if (m_subExpr1 == NULL || m_subExpr2 == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->eval_internal(ek)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->coerce(eType)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->eval_internal(ek)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->coerce(eType)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + + retval = new AstExprValue(); + retval->et = eType; + + switch (m_combOperator) + { + case EC_mod: + if (m_subExpr2->getExprValue()->u.hval == 0) + return NULL; + retval->u.hval = m_subExpr1->getExprValue()->u.hval % m_subExpr2->getExprValue()->u.hval; + break; + case EC_add: + retval->u.dval = m_subExpr1->getExprValue()->u.dval + m_subExpr2->getExprValue()->u.dval; + break; + case EC_minus: + retval->u.dval = m_subExpr1->getExprValue()->u.dval - m_subExpr2->getExprValue()->u.dval; + break; + case EC_mul: + retval->u.dval = m_subExpr1->getExprValue()->u.dval * m_subExpr2->getExprValue()->u.dval; + break; + case EC_div: + if (m_subExpr2->getExprValue()->u.dval == 0.0) + return NULL; + retval->u.dval = m_subExpr1->getExprValue()->u.dval / m_subExpr2->getExprValue()->u.dval; + break; + default: + return NULL; + } + + return retval; +} + +AstExprValue* AstExpression::eval_bit_op(EvalKind ek) +{ + AstExprValue *retval = NULL; + + if (ek != EK_const && ek != EK_positive_int) + return NULL; + if (m_subExpr1 == NULL || m_subExpr2 == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->eval_internal(ek)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->coerce(ET_long)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->eval_internal(ek)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + m_subExpr2->setExprValue(m_subExpr2->coerce(ET_long)); + if (m_subExpr2->getExprValue() == NULL) + return NULL; + + retval = new AstExprValue; + retval->et = ET_long; + + switch (m_combOperator) + { + case EC_or: + retval->u.lval = m_subExpr1->getExprValue()->u.lval | m_subExpr2->getExprValue()->u.lval; + break; + case EC_xor: + retval->u.lval = m_subExpr1->getExprValue()->u.lval ^ m_subExpr2->getExprValue()->u.lval; + break; + case EC_and: + retval->u.lval = m_subExpr1->getExprValue()->u.lval & m_subExpr2->getExprValue()->u.lval; + break; + case EC_left: + retval->u.lval = m_subExpr1->getExprValue()->u.lval << m_subExpr2->getExprValue()->u.lval; + break; + case EC_right: + retval->u.lval = m_subExpr1->getExprValue()->u.lval >> m_subExpr2->getExprValue()->u.lval; + break; + default: + return NULL; + } + + return retval; +} + +AstExprValue* AstExpression::eval_un_op(EvalKind ek) +{ + AstExprValue *retval = NULL; + + if (m_exprValue != NULL) + return m_exprValue; + + if (ek != EK_const && ek != EK_positive_int) + return NULL; + if (m_subExpr1 == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->eval_internal(ek)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + m_subExpr1->setExprValue(m_subExpr1->coerce(ET_double)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + + retval = new AstExprValue(); + retval->et = ET_double; + + switch (m_combOperator) + { + case EC_u_plus: + retval->u.lval = m_subExpr1->getExprValue()->u.lval; + break; + case EC_u_minus: + retval->u.lval = -(m_subExpr1->getExprValue()->u.lval); + break; + case EC_bit_neg: + m_subExpr1->setExprValue(m_subExpr1->coerce(ET_long)); + if (m_subExpr1->getExprValue() == NULL) + return NULL; + retval->u.lval = ~m_subExpr1->getExprValue()->u.lval; + break; + default: + return NULL; + } + + return retval; +} + +AstExprValue* AstExpression::eval_symbol(EvalKind ek) +{ + AstScope *pScope = 0; + AstDeclaration *pDecl; + AstConstant *pConst; + + /* + * Is there a symbol stored? + */ + if (m_pSymbolicName == NULL) + { + idlc()->error()->evalError(this); + return NULL; + } + /* + * Get current scope for lookup + */ + if (idlc()->scopes()->depth() > 0) + pScope = idlc()->scopes()->topNonNull(); + if ( !pScope ) + { + idlc()->error()->lookupError(*m_pSymbolicName); + return NULL; + } + /* + * Do lookup + */ + pDecl = pScope->lookupByName(*m_pSymbolicName); + if (pDecl == NULL) + { + idlc()->error()->lookupError(*m_pSymbolicName); + return NULL; + } + /* + * Is it a constant? + */ + if (pDecl->getNodeType() != NT_const && + pDecl->getNodeType() != NT_enum_val) + { + idlc()->error()->constantExpected(pDecl, *m_pSymbolicName); + return NULL; + } + if (!idlc()->error()->checkPublished(pDecl)) + { + return NULL; + } + /* + * OK, now evaluate the constant we just got, to produce its value + */ + pConst = static_cast< AstConstant* >(pDecl); + if (pConst == NULL) + return NULL; + return pConst->getConstValue()->eval_internal(ek); +} + +OString AstExpression::toString() +{ + OString exprStr; + if ( m_combOperator == EC_symbol ) + return *m_pSymbolicName; + + if ( m_exprValue ) + { + switch (m_exprValue->et) + { + case ET_short: + return OString::valueOf((sal_Int32)m_exprValue->u.sval); + case ET_ushort: + return OString::valueOf((sal_Int32)m_exprValue->u.usval); + case ET_long: + return OString::valueOf(m_exprValue->u.lval); + case ET_ulong: + return OString::valueOf((sal_Int32)m_exprValue->u.ulval); + case ET_hyper: + return OString::valueOf(m_exprValue->u.hval); + case ET_uhyper: + return OString::valueOf((sal_Int64)m_exprValue->u.uhval); + case ET_float: + return OString::valueOf(m_exprValue->u.fval); + case ET_double: + return OString::valueOf(m_exprValue->u.dval); + case ET_byte: + return OString::valueOf((sal_Int32)m_exprValue->u.byval); + case ET_boolean: + if ( m_exprValue->u.lval == 0) + return OString("FALSE"); + else + return OString("TRUE"); + default: + OSL_ASSERT(false); + return OString(); + } + } + + switch (m_combOperator) + { + case EC_u_plus: + exprStr += OString("+"); + break; + case EC_u_minus: + exprStr += OString("-"); + break; + case EC_bit_neg: + exprStr += OString("~"); + break; + default: + break; + } + if ( m_subExpr1 ) + exprStr += m_subExpr1->toString(); + switch (m_combOperator) + { + case EC_add: + exprStr += OString(" + "); + break; + case EC_minus: + exprStr += OString(" - "); + break; + case EC_mul: + exprStr += OString(" * "); + break; + case EC_div: + exprStr += OString(" / "); + break; + case EC_mod: + exprStr += OString(" % "); + break; + case EC_or: + exprStr += OString(" | "); + break; + case EC_xor: + exprStr += OString(" ^ "); + break; + case EC_and: + exprStr += OString(" & "); + break; + case EC_left: + exprStr += OString(" << "); + break; + case EC_right: + exprStr += OString(" >> "); + break; + default: + break; + } + + if ( m_subExpr2 ) + exprStr += m_subExpr2->toString(); + + return exprStr; +} + +// Convert the type of an AST_Expression to a char * +const sal_Char* SAL_CALL exprTypeToString(ExprType t) +{ + switch (t) + { + case ET_short: + return "short"; + case ET_ushort: + return "unsigned short"; + case ET_long: + return "long"; + case ET_ulong: + return "unsigned long"; + case ET_hyper: + return "hyper"; + case ET_uhyper: + return "unsigned hyper"; + case ET_float: + return "float"; + case ET_double: + return "double"; + case ET_char: + return "char"; + case ET_byte: + return "byte"; + case ET_boolean: + return "boolean"; + case ET_string: + return "string"; + case ET_any: + return "any"; + case ET_type: + return "type"; + case ET_void: + return "void"; + case ET_none: + return "none"; + } + + return ("unkown"); +} |