git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
1032 lines
23 KiB
C++
1032 lines
23 KiB
C++
//-------------------------------------------------------------------------
|
|
// Desc: Query evaluation
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 1993-2000,2003-2006 Novell, Inc. All Rights Reserved.
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of version 2 of the GNU General Public
|
|
// License as published by the Free Software Foundation.
|
|
//
|
|
// This program 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 General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, contact Novell, Inc.
|
|
//
|
|
// To contact Novell about this file by physical or electronic mail,
|
|
// you may find current contact information at www.novell.com
|
|
//
|
|
// $Id: fqeval2.cpp 12271 2006-01-19 14:48:13 -0700 (Thu, 19 Jan 2006) dsanders $
|
|
//-------------------------------------------------------------------------
|
|
|
|
#include "flaimsys.h"
|
|
|
|
FSTATIC RCODE OpSyntaxError(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUBitAND(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUBitOR(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUBitXOR(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUSMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSSMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSUMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpURMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRUMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSRMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRSMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRRMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUSDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSSDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSUDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpURDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRUDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSRDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRSDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRRDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUSMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSSMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSUMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUSPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSSPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSUPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpURPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRUPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSRPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRSPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRRPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUUMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpUSMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSSMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSUMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpURMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRUMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpSRMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRSMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
FSTATIC RCODE OpRRMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult);
|
|
|
|
|
|
/****************************************************************************
|
|
Desc: Returns a syntax error on the operation. The combined values are
|
|
not allowed in the operation.
|
|
Ret: FERR_CURSOR_SYNTAX
|
|
****************************************************************************/
|
|
FSTATIC RCODE OpSyntaxError(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
F_UNREFERENCED_PARM( pLhs);
|
|
F_UNREFERENCED_PARM( pRhs);
|
|
F_UNREFERENCED_PARM( pResult );
|
|
return( RC_SET( FERR_CURSOR_SYNTAX));
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs the bit AND operation on signed and unsigned values.
|
|
Used for UtoU, UtoSigned, SignedToU and SignedToSigned.
|
|
Notes: The signed and unsigned values better take up the same location
|
|
in the union. I (Scott) am a little concerned that we are even
|
|
working on signed values. I think that a uniary cast to an
|
|
unsigned in the query would be better.
|
|
****************************************************************************/
|
|
|
|
FSTATIC RCODE OpUUBitAND(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal & pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs the bit OR operation on signed and unsigned values.
|
|
Notes: The signed and unsigned values better take up the same location
|
|
in the union.
|
|
****************************************************************************/
|
|
|
|
FSTATIC RCODE OpUUBitOR(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal | pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs the bit XOR operation on signed and unsigned values.
|
|
Notes: The signed and unsigned values better take up the same location
|
|
in the union.
|
|
****************************************************************************/
|
|
|
|
FSTATIC RCODE OpUUBitXOR(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal ^ pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs the multiply operation on unsigned, signed and real values.
|
|
Notes: Overflow conditions are not checked for. For the most part,
|
|
a signed value is usually a negative value - otherwise it would
|
|
be an unsigned value.
|
|
****************************************************************************/
|
|
|
|
FSTATIC RCODE OpUUMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal * pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpUSMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
|
|
pResult->val.iVal = (FLMINT)pLhs->val.uiVal * pRhs->val.iVal;
|
|
pResult->eType = FLM_INT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSSMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal * pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0) ? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSUMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal * (FLMINT)pRhs->val.uiVal;
|
|
pResult->eType = FLM_INT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpURMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.uiVal * pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
FSTATIC RCODE OpRUMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real * (FLMLREAL) pRhs->val.uiVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpSRMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.iVal * pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
FSTATIC RCODE OpRSMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real * (FLMLREAL) pRhs->val.iVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
FSTATIC RCODE OpRRMult(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real * pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs the divide operation on unsigned, signed and real values.
|
|
Divide on signed and unsigned values will result in a signed or
|
|
unsigned value that is floored down to an integer.
|
|
Notes: Divide by zero is checked for, but the result is 0 unsigned.
|
|
For the most part, a signed value is usually a negative value.
|
|
VISIT: There are problems in casting large unsigned values into a signed
|
|
value. We should be treating INT32_VAL as a negative bit and
|
|
always working with unsigned values. I hate to change too much
|
|
though.
|
|
VISIT: Need to visit the divide/mod by zero cases.
|
|
****************************************************************************/
|
|
|
|
FSTATIC RCODE OpUUDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.uiVal)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal / pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpUSDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.iVal)
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLhs->val.uiVal / pRhs->val.iVal;
|
|
pResult->eType = FLM_INT32_VAL;
|
|
}
|
|
else // Divide by ZERO case - let's try not to crash.
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSSDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.iVal)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal / pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // divide by ZERO case
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSUDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.uiVal)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal / (FLMINT)pRhs->val.uiVal;
|
|
pResult->eType = FLM_INT32_VAL;
|
|
}
|
|
else // Divide by ZERO case - let's try not to crash.
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpURDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
if( pRhs->val.Real)
|
|
{
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.uiVal / pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRUDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
if( pRhs->val.uiVal)
|
|
{
|
|
pResult->val.Real = pLhs->val.Real / (FLMLREAL)pRhs->val.uiVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpSRDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
if( pRhs->val.Real)
|
|
{
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.iVal / pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRSDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
if( pRhs->val.iVal)
|
|
{
|
|
pResult->val.Real = pLhs->val.Real / (FLMLREAL)pRhs->val.iVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRRDiv(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
if( pRhs->val.Real)
|
|
{
|
|
pResult->val.Real = pLhs->val.Real / pRhs->val.Real;
|
|
pLhs->eType = FLM_REAL_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs the modulo operation on unsigned, signed and real values.
|
|
Notes: Mod by zero is checked for, but the result is 0 unsigned.
|
|
For the most part, a signed value is usually a negative value.
|
|
****************************************************************************/
|
|
FSTATIC RCODE OpUUMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.uiVal != 0)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal % pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpUSMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.iVal != 0)
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLhs->val.uiVal / pRhs->val.iVal;
|
|
pResult->eType = FLM_INT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSSMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.iVal != 0)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal % pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSUMod(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.uiVal != 0)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal % ((FLMINT)pRhs->val.uiVal);
|
|
pResult->eType = FLM_INT32_VAL;
|
|
}
|
|
else // Divide by ZERO case - let's try not to crash.
|
|
{
|
|
pResult->val.uiVal = 0;
|
|
pResult->eType = FLM_UNKNOWN;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
Desc: Performs an addition operation on unsigned, signed and real values.
|
|
Notes: Underflow and overflow conditions are not checked. In addition,
|
|
casting unsigned values to signed could lose data. Casting
|
|
ANYTHING to real will always lose some data.
|
|
****************************************************************************/
|
|
|
|
FSTATIC RCODE OpUUPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal + pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpUSPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( ( pRhs->val.iVal >= 0) ||
|
|
( pLhs->val.uiVal > MAX_SIGNED_VAL))
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal + (FLMUINT)pRhs->val.iVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLhs->val.uiVal + pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSSPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal + pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSUPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( ( pLhs->val.iVal >= 0) ||
|
|
( pRhs->val.uiVal > MAX_SIGNED_VAL))
|
|
{
|
|
pResult->val.uiVal = (FLMUINT)pLhs->val.iVal + pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal + (FLMINT)pRhs->val.uiVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpURPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.uiVal + pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRUPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real + (FLMLREAL)pRhs->val.uiVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpSRPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.iVal + pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRSPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real + (FLMLREAL)pRhs->val.iVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRRPlus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real + pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
/****************************************************************************
|
|
Desc: Performs a subtraction operation on unsigned, signed and real values.
|
|
Notes: Underflow and overflow conditions are not checked. In addition,
|
|
casting unsigned values to signed could lose data. Casting
|
|
ANYTHING to real will always lose some data.
|
|
****************************************************************************/
|
|
FSTATIC RCODE OpUUMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pLhs->val.uiVal >= pRhs->val.uiVal)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal - pRhs->val.uiVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = (FLMINT)(pLhs->val.uiVal - pRhs->val.uiVal);
|
|
pResult->eType = FLM_INT32_VAL;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpUSMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
/* VISIT: The original code had...
|
|
if(( pRhs->val.iVal < 0) || ( pRhs->val.uiVal < pLhs->val.uiVal))
|
|
I don't know what the second part means.
|
|
*/
|
|
|
|
if( pRhs->val.iVal < 0)
|
|
{
|
|
pResult->val.uiVal = pLhs->val.uiVal - pRhs->val.iVal;
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLhs->val.uiVal - pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSSMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if(( pLhs->val.iVal > 0) && ( pRhs->val.iVal < 0))
|
|
{
|
|
pResult->val.uiVal = (FLMUINT)( pLhs->val.iVal - pRhs->val.iVal);
|
|
pResult->eType = FLM_UINT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal - pRhs->val.iVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpSUMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
if( pRhs->val.uiVal > MAX_SIGNED_VAL)
|
|
{
|
|
pResult->val.iVal = ( pLhs->val.iVal - MAX_SIGNED_VAL)
|
|
- (FLMINT)(pRhs->val.uiVal - MAX_SIGNED_VAL);
|
|
pResult->eType = FLM_INT32_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = pLhs->val.iVal - (FLMINT)pRhs->val.uiVal;
|
|
pResult->eType = (pResult->val.iVal < 0)
|
|
? FLM_INT32_VAL : FLM_UINT32_VAL;
|
|
}
|
|
return( FERR_OK);
|
|
}
|
|
|
|
FSTATIC RCODE OpURMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.uiVal - pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRUMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real - (FLMLREAL)pRhs->val.uiVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpSRMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = (FLMLREAL)pLhs->val.iVal - pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRSMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real - (FLMLREAL)pRhs->val.iVal;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FSTATIC RCODE OpRRMinus(
|
|
FQATOM_p pLhs,
|
|
FQATOM_p pRhs,
|
|
FQATOM_p pResult)
|
|
{
|
|
#ifndef FLM_REAL
|
|
return( OpSyntaxError( pLhs, pRhs, pResult));
|
|
#else
|
|
pResult->val.Real = pLhs->val.Real - pRhs->val.Real;
|
|
pResult->eType = FLM_REAL_VAL;
|
|
return( FERR_OK);
|
|
#endif
|
|
}
|
|
|
|
FQ_OPERATION * FQ_DoOperation [
|
|
((LAST_ARITH_OP - FIRST_ARITH_OP) + 1) * 9 ] =
|
|
{
|
|
/* U = Unsigned S = Signed R = Real
|
|
U + U U + S U + R
|
|
S + U S + S S + R
|
|
R + U R + S R + R */
|
|
/* BITAND */ OpUUBitAND, OpUUBitAND, OpSyntaxError,
|
|
OpUUBitAND, OpUUBitAND, OpSyntaxError,
|
|
OpSyntaxError, OpSyntaxError, OpSyntaxError,
|
|
/* BITOR */ OpUUBitOR, OpUUBitOR, OpSyntaxError,
|
|
OpUUBitOR, OpUUBitOR, OpSyntaxError,
|
|
OpSyntaxError, OpSyntaxError, OpSyntaxError,
|
|
/* BITXOR */ OpUUBitXOR, OpUUBitXOR, OpSyntaxError,
|
|
OpUUBitXOR, OpUUBitXOR, OpSyntaxError,
|
|
OpSyntaxError, OpSyntaxError, OpSyntaxError,
|
|
/* MULT */ OpUUMult, OpUSMult, OpURMult,
|
|
OpSUMult, OpSSMult, OpSRMult,
|
|
OpRUMult, OpRSMult, OpRRMult,
|
|
/* DIV */ OpUUDiv, OpUSDiv, OpURDiv,
|
|
OpSUDiv, OpSSDiv, OpSRDiv,
|
|
OpRUDiv, OpRSDiv, OpRRDiv,
|
|
/* MOD */ OpUUMod, OpUSMod, OpSyntaxError,
|
|
OpSUMod, OpSSMod, OpSyntaxError,
|
|
OpSyntaxError, OpSyntaxError, OpSyntaxError,
|
|
/* PLUS */ OpUUPlus, OpUSPlus, OpURPlus,
|
|
OpSUPlus, OpSSPlus, OpSRPlus,
|
|
OpRUPlus, OpRSPlus, OpRRPlus,
|
|
/* MINUS */ OpUUMinus, OpUSMinus, OpURMinus,
|
|
OpSUMinus, OpSSMinus, OpSRMinus,
|
|
OpRUMinus, OpRSMinus, OpRRMinus
|
|
};
|