2011-05-01 02:50:00 -04:00
/* picoc expression evaluator - a stack-based expression evaluation system
* which handles operator precedence */
2011-02-17 02:11:20 -05:00
# include "interpreter.h"
2009-03-08 03:56:28 -04:00
2009-03-11 22:21:12 -04:00
/* whether evaluation is left to right for a given precedence level */
2010-07-04 15:52:52 -04:00
# define IS_LEFT_TO_RIGHT(p) ((p) != 2 && (p) != 14)
2009-03-28 07:10:34 -04:00
# define BRACKET_PRECEDENCE 20
2009-11-07 15:22:11 -05:00
# define IS_TYPE_TOKEN(t) ((t) >= TokenIntType && (t) <= TokenUnsignedType)
2009-03-11 22:21:12 -04:00
2011-02-15 19:13:11 -05:00
# define DEEP_PRECEDENCE (BRACKET_PRECEDENCE*1000)
2009-04-13 02:57:32 -04:00
# ifdef DEBUG_EXPRESSIONS
# define debugf printf
# else
void debugf ( char * Format , . . . )
{
}
# endif
2009-03-11 22:21:12 -04:00
2009-04-04 22:24:00 -04:00
/* local prototypes */
2009-03-11 22:21:12 -04:00
enum OperatorOrder
{
2009-03-29 07:08:03 -04:00
OrderNone ,
2009-03-11 22:21:12 -04:00
OrderPrefix ,
OrderInfix ,
OrderPostfix
} ;
/* a stack of expressions we use in evaluation */
struct ExpressionStack
{
2009-04-13 02:57:32 -04:00
struct ExpressionStack * Next ; /* the next lower item on the stack */
2009-10-04 12:22:19 -04:00
struct Value * Val ; /* the value for this stack node */
enum LexToken Op ; /* the operator */
2009-04-13 02:57:32 -04:00
short unsigned int Precedence ; /* the operator precedence of this node */
unsigned char Order ; /* the evaluation order of this operator */
2009-03-11 22:21:12 -04:00
} ;
2009-03-08 03:56:28 -04:00
/* operator precedence definitions */
struct OpPrecedence
{
2009-06-02 03:50:46 -04:00
unsigned int PrefixPrecedence : 4 ;
unsigned int PostfixPrecedence : 4 ;
unsigned int InfixPrecedence : 4 ;
2009-04-13 02:57:32 -04:00
char * Name ;
2009-03-08 03:56:28 -04:00
} ;
2009-10-11 07:09:07 -04:00
/* NOTE: the order of this array must correspond exactly to the order of these tokens in enum LexToken */
2009-03-08 03:56:28 -04:00
static struct OpPrecedence OperatorPrecedence [ ] =
{
2009-04-13 02:57:32 -04:00
/* TokenNone, */ { 0 , 0 , 0 , " none " } ,
/* TokenComma, */ { 0 , 0 , 0 , " , " } ,
/* TokenAssign, */ { 0 , 0 , 2 , " = " } , /* TokenAddAssign, */ { 0 , 0 , 2 , " += " } , /* TokenSubtractAssign, */ { 0 , 0 , 2 , " -= " } ,
/* TokenMultiplyAssign, */ { 0 , 0 , 2 , " *= " } , /* TokenDivideAssign, */ { 0 , 0 , 2 , " /= " } , /* TokenModulusAssign, */ { 0 , 0 , 2 , " %= " } ,
/* TokenShiftLeftAssign, */ { 0 , 0 , 2 , " <<= " } , /* TokenShiftRightAssign, */ { 0 , 0 , 2 , " >>= " } , /* TokenArithmeticAndAssign, */ { 0 , 0 , 2 , " &= " } ,
/* TokenArithmeticOrAssign, */ { 0 , 0 , 2 , " |= " } , /* TokenArithmeticExorAssign, */ { 0 , 0 , 2 , " ^= " } ,
/* TokenQuestionMark, */ { 0 , 0 , 3 , " ? " } , /* TokenColon, */ { 0 , 0 , 3 , " : " } ,
/* TokenLogicalOr, */ { 0 , 0 , 4 , " || " } ,
/* TokenLogicalAnd, */ { 0 , 0 , 5 , " && " } ,
/* TokenArithmeticOr, */ { 0 , 0 , 6 , " | " } ,
/* TokenArithmeticExor, */ { 0 , 0 , 7 , " ^ " } ,
/* TokenAmpersand, */ { 14 , 0 , 8 , " & " } ,
/* TokenEqual, */ { 0 , 0 , 9 , " == " } , /* TokenNotEqual, */ { 0 , 0 , 9 , " != " } ,
/* TokenLessThan, */ { 0 , 0 , 10 , " < " } , /* TokenGreaterThan, */ { 0 , 0 , 10 , " > " } , /* TokenLessEqual, */ { 0 , 0 , 10 , " <= " } , /* TokenGreaterEqual, */ { 0 , 0 , 10 , " >= " } ,
/* TokenShiftLeft, */ { 0 , 0 , 11 , " << " } , /* TokenShiftRight, */ { 0 , 0 , 11 , " >> " } ,
/* TokenPlus, */ { 14 , 0 , 12 , " + " } , /* TokenMinus, */ { 14 , 0 , 12 , " - " } ,
/* TokenAsterisk, */ { 14 , 0 , 13 , " * " } , /* TokenSlash, */ { 0 , 0 , 13 , " / " } , /* TokenModulus, */ { 0 , 0 , 13 , " % " } ,
2009-10-04 12:22:19 -04:00
/* TokenIncrement, */ { 14 , 15 , 0 , " ++ " } , /* TokenDecrement, */ { 14 , 15 , 0 , " -- " } , /* TokenUnaryNot, */ { 14 , 0 , 0 , " ! " } , /* TokenUnaryExor, */ { 14 , 0 , 0 , " ~ " } , /* TokenSizeof, */ { 14 , 0 , 0 , " sizeof " } , /* TokenCast, */ { 14 , 0 , 0 , " cast " } ,
2009-04-14 02:55:00 -04:00
/* TokenLeftSquareBracket, */ { 0 , 0 , 15 , " [ " } , /* TokenRightSquareBracket, */ { 0 , 15 , 0 , " ] " } , /* TokenDot, */ { 0 , 0 , 15 , " . " } , /* TokenArrow, */ { 0 , 0 , 15 , " -> " } ,
2009-04-13 02:57:32 -04:00
/* TokenOpenBracket, */ { 15 , 0 , 0 , " ( " } , /* TokenCloseBracket, */ { 0 , 15 , 0 , " ) " }
2009-03-08 03:56:28 -04:00
} ;
2011-02-15 19:13:11 -05:00
void ExpressionParseFunctionCall ( struct ParseState * Parser , struct ExpressionStack * * StackTop , const char * FuncName , int RunIt ) ;
2009-04-04 22:24:00 -04:00
2009-04-13 02:57:32 -04:00
# ifdef DEBUG_EXPRESSIONS
/* show the contents of the expression stack */
void ExpressionStackShow ( struct ExpressionStack * StackTop )
{
2009-04-15 06:47:51 -04:00
printf ( " Expression stack [0x%lx,0x%lx]: " , ( long ) HeapStackTop , ( long ) StackTop ) ;
2009-04-13 02:57:32 -04:00
while ( StackTop ! = NULL )
{
if ( StackTop - > Order = = OrderNone )
2009-04-14 02:55:00 -04:00
{
/* it's a value */
2009-10-04 12:22:19 -04:00
if ( StackTop - > Val - > IsLValue )
2009-04-13 02:57:32 -04:00
printf ( " lvalue= " ) ;
else
printf ( " value= " ) ;
2009-10-04 12:22:19 -04:00
switch ( StackTop - > Val - > Typ - > Base )
2009-04-13 02:57:32 -04:00
{
2009-04-13 23:18:40 -04:00
case TypeVoid : printf ( " void " ) ; break ;
2009-10-04 12:22:19 -04:00
case TypeInt : printf ( " %d:int " , StackTop - > Val - > Val - > Integer ) ; break ;
2009-10-11 07:09:07 -04:00
case TypeShort : printf ( " %d:short " , StackTop - > Val - > Val - > ShortInteger ) ; break ;
2009-10-04 12:22:19 -04:00
case TypeChar : printf ( " %d:char " , StackTop - > Val - > Val - > Character ) ; break ;
2009-11-07 16:05:15 -05:00
case TypeLong : printf ( " %d:long " , StackTop - > Val - > Val - > LongInteger ) ; break ;
case TypeUnsignedShort : printf ( " %d:unsigned short " , StackTop - > Val - > Val - > UnsignedShortInteger ) ; break ;
case TypeUnsignedInt : printf ( " %d:unsigned int " , StackTop - > Val - > Val - > UnsignedInteger ) ; break ;
case TypeUnsignedLong : printf ( " %d:unsigned long " , StackTop - > Val - > Val - > UnsignedLongInteger ) ; break ;
2009-10-04 12:22:19 -04:00
case TypeFP : printf ( " %f:fp " , StackTop - > Val - > Val - > FP ) ; break ;
case TypeFunction : printf ( " %s:function " , StackTop - > Val - > Val - > Identifier ) ; break ;
case TypeMacro : printf ( " %s:macro " , StackTop - > Val - > Val - > Identifier ) ; break ;
2009-04-13 02:57:32 -04:00
case TypePointer :
2010-06-13 10:41:03 -04:00
if ( StackTop - > Val - > Val - > Pointer = = NULL )
2009-06-03 20:18:28 -04:00
printf ( " ptr(NULL) " ) ;
2009-10-04 12:22:19 -04:00
else if ( StackTop - > Val - > Typ - > FromType - > Base = = TypeChar )
2010-06-13 10:41:03 -04:00
printf ( " \" %s \" :string " , ( char * ) StackTop - > Val - > Val - > Pointer ) ;
2009-04-13 02:57:32 -04:00
else
2010-06-13 10:41:03 -04:00
printf ( " ptr(0x%lx) " , ( long ) StackTop - > Val - > Val - > Pointer ) ;
2009-04-13 02:57:32 -04:00
break ;
case TypeArray : printf ( " array " ) ; break ;
2009-10-04 12:22:19 -04:00
case TypeStruct : printf ( " %s:struct " , StackTop - > Val - > Val - > Identifier ) ; break ;
case TypeUnion : printf ( " %s:union " , StackTop - > Val - > Val - > Identifier ) ; break ;
case TypeEnum : printf ( " %s:enum " , StackTop - > Val - > Val - > Identifier ) ; break ;
2011-01-06 23:06:33 -05:00
case Type_Type : PrintType ( StackTop - > Val - > Val - > Typ , CStdOut ) ; printf ( " :type " ) ; break ;
2009-04-13 02:57:32 -04:00
default : printf ( " unknown " ) ; break ;
}
2009-10-04 12:22:19 -04:00
printf ( " [0x%lx,0x%lx] " , ( long ) StackTop , ( long ) StackTop - > Val ) ;
2009-04-13 02:57:32 -04:00
}
else
2009-10-25 16:50:56 -04:00
{
/* it's an operator */
2009-10-04 12:22:19 -04:00
printf ( " op='%s' %s %d " , OperatorPrecedence [ ( int ) StackTop - > Op ] . Name ,
2009-04-13 02:57:32 -04:00
( StackTop - > Order = = OrderPrefix ) ? " prefix " : ( ( StackTop - > Order = = OrderPostfix ) ? " postfix " : " infix " ) ,
StackTop - > Precedence ) ;
2009-04-15 06:47:51 -04:00
printf ( " [0x%lx] " , ( long ) StackTop ) ;
2009-04-13 02:57:32 -04:00
}
StackTop = StackTop - > Next ;
if ( StackTop ! = NULL )
printf ( " , " ) ;
}
printf ( " \n " ) ;
}
# endif
2009-03-28 07:10:34 -04:00
2009-11-07 16:05:15 -05:00
long ExpressionCoerceInteger ( struct Value * Val )
2009-10-25 07:54:34 -04:00
{
switch ( Val - > Typ - > Base )
{
2009-11-07 16:05:15 -05:00
case TypeInt : return ( long ) Val - > Val - > Integer ;
case TypeChar : return ( long ) Val - > Val - > Character ;
case TypeShort : return ( long ) Val - > Val - > ShortInteger ;
case TypeLong : return ( long ) Val - > Val - > LongInteger ;
case TypeUnsignedInt : return ( long ) Val - > Val - > UnsignedInteger ;
case TypeUnsignedShort : return ( long ) Val - > Val - > UnsignedShortInteger ;
case TypeUnsignedLong : return ( long ) Val - > Val - > UnsignedLongInteger ;
2010-06-13 10:41:03 -04:00
case TypePointer : return ( long ) Val - > Val - > Pointer ;
2009-10-25 07:54:34 -04:00
# ifndef NO_FP
2009-11-07 16:05:15 -05:00
case TypeFP : return ( long ) Val - > Val - > FP ;
2009-10-25 07:54:34 -04:00
# endif
default : return 0 ;
}
}
2009-11-07 16:05:15 -05:00
unsigned long ExpressionCoerceUnsignedInteger ( struct Value * Val )
2009-10-25 07:54:34 -04:00
{
switch ( Val - > Typ - > Base )
{
2009-11-07 16:05:15 -05:00
case TypeInt : return ( unsigned long ) Val - > Val - > Integer ;
case TypeChar : return ( unsigned long ) Val - > Val - > Character ;
case TypeShort : return ( unsigned long ) Val - > Val - > ShortInteger ;
case TypeLong : return ( unsigned long ) Val - > Val - > LongInteger ;
case TypeUnsignedInt : return ( unsigned long ) Val - > Val - > UnsignedInteger ;
case TypeUnsignedShort : return ( unsigned long ) Val - > Val - > UnsignedShortInteger ;
case TypeUnsignedLong : return ( unsigned long ) Val - > Val - > UnsignedLongInteger ;
2010-06-13 10:41:03 -04:00
case TypePointer : return ( unsigned long ) Val - > Val - > Pointer ;
2009-10-25 07:54:34 -04:00
# ifndef NO_FP
2009-11-07 16:05:15 -05:00
case TypeFP : return ( unsigned long ) Val - > Val - > FP ;
2009-10-25 07:54:34 -04:00
# endif
default : return 0 ;
}
}
2009-11-08 14:23:50 -05:00
# ifndef NO_FP
2009-10-25 07:54:34 -04:00
double ExpressionCoerceFP ( struct Value * Val )
{
2009-11-08 14:23:50 -05:00
# ifndef BROKEN_FLOAT_CASTS
int IntVal ;
unsigned UnsignedVal ;
switch ( Val - > Typ - > Base )
{
case TypeInt : IntVal = Val - > Val - > Integer ; return ( double ) IntVal ;
case TypeChar : IntVal = Val - > Val - > Character ; return ( double ) IntVal ;
case TypeShort : IntVal = Val - > Val - > ShortInteger ; return ( double ) IntVal ;
case TypeLong : IntVal = Val - > Val - > LongInteger ; return ( double ) IntVal ;
case TypeUnsignedInt : UnsignedVal = Val - > Val - > UnsignedInteger ; return ( double ) UnsignedVal ;
case TypeUnsignedShort : UnsignedVal = Val - > Val - > UnsignedShortInteger ; return ( double ) UnsignedVal ;
case TypeUnsignedLong : UnsignedVal = Val - > Val - > UnsignedLongInteger ; return ( double ) UnsignedVal ;
case TypeFP : return Val - > Val - > FP ;
default : return 0.0 ;
}
# else
2009-10-25 07:54:34 -04:00
switch ( Val - > Typ - > Base )
{
case TypeInt : return ( double ) Val - > Val - > Integer ;
case TypeChar : return ( double ) Val - > Val - > Character ;
case TypeShort : return ( double ) Val - > Val - > ShortInteger ;
2009-11-07 16:05:15 -05:00
case TypeLong : return ( double ) Val - > Val - > LongInteger ;
2009-10-25 07:54:34 -04:00
case TypeUnsignedInt : return ( double ) Val - > Val - > UnsignedInteger ;
case TypeUnsignedShort : return ( double ) Val - > Val - > UnsignedShortInteger ;
2009-11-07 16:05:15 -05:00
case TypeUnsignedLong : return ( double ) Val - > Val - > UnsignedLongInteger ;
2009-10-25 07:54:34 -04:00
case TypeFP : return ( double ) Val - > Val - > FP ;
2009-11-08 14:23:50 -05:00
default : return 0.0 ;
2009-10-25 07:54:34 -04:00
}
2009-11-08 14:23:50 -05:00
# endif
2009-10-25 07:54:34 -04:00
}
2009-11-08 14:23:50 -05:00
# endif
2009-10-25 07:54:34 -04:00
2009-04-22 08:06:58 -04:00
/* assign an integer value */
2009-11-07 16:05:15 -05:00
long ExpressionAssignInt ( struct ParseState * Parser , struct Value * DestValue , long FromInt , int After )
2009-04-22 08:06:58 -04:00
{
2009-11-07 16:05:15 -05:00
long Result ;
2009-04-22 08:06:58 -04:00
if ( ! DestValue - > IsLValue )
ProgramFail ( Parser , " can't assign to this " ) ;
if ( After )
2009-11-03 15:40:35 -05:00
Result = ExpressionCoerceInteger ( DestValue ) ;
2009-04-22 08:06:58 -04:00
else
Result = FromInt ;
2009-11-03 15:40:35 -05:00
switch ( DestValue - > Typ - > Base )
{
case TypeInt : DestValue - > Val - > Integer = FromInt ; break ;
case TypeShort : DestValue - > Val - > ShortInteger = ( short ) FromInt ; break ;
case TypeChar : DestValue - > Val - > Character = ( unsigned char ) FromInt ; break ;
2009-11-07 16:05:15 -05:00
case TypeLong : DestValue - > Val - > LongInteger = ( long ) FromInt ; break ;
2009-11-03 15:40:35 -05:00
case TypeUnsignedInt : DestValue - > Val - > UnsignedInteger = ( unsigned int ) FromInt ; break ;
case TypeUnsignedShort : DestValue - > Val - > UnsignedShortInteger = ( unsigned short ) FromInt ; break ;
2010-07-27 04:53:06 -04:00
case TypeUnsignedLong : DestValue - > Val - > UnsignedLongInteger = ( unsigned long ) FromInt ; break ;
2009-11-03 15:40:35 -05:00
default : break ;
}
2009-04-22 08:06:58 -04:00
return Result ;
}
2009-04-22 18:28:30 -04:00
# ifndef NO_FP
/* assign a floating point value */
2009-05-26 20:05:31 -04:00
double ExpressionAssignFP ( struct ParseState * Parser , struct Value * DestValue , double FromFP )
2009-04-22 08:06:58 -04:00
{
if ( ! DestValue - > IsLValue )
ProgramFail ( Parser , " can't assign to this " ) ;
DestValue - > Val - > FP = FromFP ;
return FromFP ;
}
2009-04-22 18:28:30 -04:00
# endif
2009-04-22 08:06:58 -04:00
2009-03-28 07:10:34 -04:00
/* push a node on to the expression stack */
void ExpressionStackPushValueNode ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct Value * ValueLoc )
{
struct ExpressionStack * StackNode = VariableAlloc ( Parser , sizeof ( struct ExpressionStack ) , FALSE ) ;
StackNode - > Next = * StackTop ;
2009-10-04 12:22:19 -04:00
StackNode - > Val = ValueLoc ;
2009-03-28 07:10:34 -04:00
* StackTop = StackNode ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_MESSAGES
StackNode - > Line = Parser - > Line ;
StackNode - > CharacterPos = Parser - > CharacterPos ;
# endif
2009-04-13 02:57:32 -04:00
# ifdef DEBUG_EXPRESSIONS
ExpressionStackShow ( * StackTop ) ;
# endif
2009-03-28 07:10:34 -04:00
}
2009-04-04 22:24:00 -04:00
/* push a blank value on to the expression stack by type */
2009-04-19 07:49:01 -04:00
struct Value * ExpressionStackPushValueByType ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct ValueType * PushType )
2009-04-04 22:24:00 -04:00
{
2009-06-02 01:51:51 -04:00
struct Value * ValueLoc = VariableAllocValueFromType ( Parser , PushType , FALSE , NULL , FALSE ) ;
2009-04-04 22:24:00 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , ValueLoc ) ;
2009-04-19 07:49:01 -04:00
return ValueLoc ;
2009-04-04 22:24:00 -04:00
}
2009-03-28 07:10:34 -04:00
/* push a value on to the expression stack */
void ExpressionStackPushValue ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct Value * PushValue )
{
2009-04-15 06:47:51 -04:00
struct Value * ValueLoc = VariableAllocValueAndCopy ( Parser , PushValue , FALSE ) ;
2009-04-13 02:57:32 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , ValueLoc ) ;
}
2009-04-22 03:23:26 -04:00
void ExpressionStackPushLValue ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct Value * PushValue , int Offset )
2009-04-13 02:57:32 -04:00
{
2009-04-15 06:47:51 -04:00
struct Value * ValueLoc = VariableAllocValueShared ( Parser , PushValue ) ;
2009-06-02 03:50:46 -04:00
ValueLoc - > Val = ( void * ) ( ( char * ) ValueLoc - > Val + Offset ) ;
2009-03-28 07:10:34 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , ValueLoc ) ;
}
2009-04-25 23:26:04 -04:00
void ExpressionStackPushDereference ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct Value * DereferenceValue )
{
struct Value * DerefVal ;
2009-11-06 17:16:12 -05:00
struct Value * ValueLoc ;
2009-04-25 23:26:04 -04:00
int Offset ;
struct ValueType * DerefType ;
2009-06-04 20:55:54 -04:00
int DerefIsLValue ;
void * DerefDataLoc = VariableDereferencePointer ( Parser , DereferenceValue , & DerefVal , & Offset , & DerefType , & DerefIsLValue ) ;
2009-11-06 17:16:12 -05:00
if ( DerefDataLoc = = NULL )
ProgramFail ( Parser , " NULL pointer dereference " ) ;
ValueLoc = VariableAllocValueFromExistingData ( Parser , DerefType , ( union AnyValue * ) DerefDataLoc , DerefIsLValue , DerefVal ) ;
2009-04-25 23:26:04 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , ValueLoc ) ;
}
2009-11-07 16:05:15 -05:00
void ExpressionPushInt ( struct ParseState * Parser , struct ExpressionStack * * StackTop , long IntValue )
2009-03-28 07:10:34 -04:00
{
2009-06-02 01:51:51 -04:00
struct Value * ValueLoc = VariableAllocValueFromType ( Parser , & IntType , FALSE , NULL , FALSE ) ;
2009-03-28 07:10:34 -04:00
ValueLoc - > Val - > Integer = IntValue ;
ExpressionStackPushValueNode ( Parser , StackTop , ValueLoc ) ;
}
2009-04-18 21:15:01 -04:00
# ifndef NO_FP
2009-03-28 07:10:34 -04:00
void ExpressionPushFP ( struct ParseState * Parser , struct ExpressionStack * * StackTop , double FPValue )
{
2009-06-02 01:51:51 -04:00
struct Value * ValueLoc = VariableAllocValueFromType ( Parser , & FPType , FALSE , NULL , FALSE ) ;
2009-03-28 07:10:34 -04:00
ValueLoc - > Val - > FP = FPValue ;
ExpressionStackPushValueNode ( Parser , StackTop , ValueLoc ) ;
}
2009-04-18 21:15:01 -04:00
# endif
2009-03-28 07:10:34 -04:00
2009-10-10 13:59:55 -04:00
/* assign to a pointer */
void ExpressionAssignToPointer ( struct ParseState * Parser , struct Value * ToValue , struct Value * FromValue , const char * FuncName , int ParamNo , int AllowPointerCoercion )
2009-04-27 08:19:36 -04:00
{
struct ValueType * PointedToType = ToValue - > Typ - > FromType ;
2009-11-03 21:02:37 -05:00
if ( FromValue - > Typ = = ToValue - > Typ | | FromValue - > Typ = = VoidPtrType | | ( ToValue - > Typ = = VoidPtrType & & FromValue - > Typ - > Base = = TypePointer ) )
2010-06-13 10:41:03 -04:00
ToValue - > Val - > Pointer = FromValue - > Val - > Pointer ; /* plain old pointer assignment */
2009-04-27 08:19:36 -04:00
2009-11-03 21:02:37 -05:00
else if ( FromValue - > Typ - > Base = = TypeArray & & ( PointedToType = = FromValue - > Typ - > FromType | | ToValue - > Typ = = VoidPtrType ) )
2009-04-27 08:19:36 -04:00
{
/* the form is: blah *x = array of blah */
2010-06-13 10:41:03 -04:00
ToValue - > Val - > Pointer = ( void * ) & FromValue - > Val - > ArrayMem [ 0 ] ;
2009-04-27 08:19:36 -04:00
}
2009-11-03 21:02:37 -05:00
else if ( FromValue - > Typ - > Base = = TypePointer & & FromValue - > Typ - > FromType - > Base = = TypeArray & &
( PointedToType = = FromValue - > Typ - > FromType - > FromType | | ToValue - > Typ = = VoidPtrType ) )
2009-04-27 08:19:36 -04:00
{
/* the form is: blah *x = pointer to array of blah */
2010-06-13 10:41:03 -04:00
ToValue - > Val - > Pointer = VariableDereferencePointer ( Parser , FromValue , NULL , NULL , NULL , NULL ) ;
2009-04-27 08:19:36 -04:00
}
2009-10-25 07:54:34 -04:00
else if ( IS_NUMERIC_COERCIBLE ( FromValue ) & & ExpressionCoerceInteger ( FromValue ) = = 0 )
2009-04-27 08:19:36 -04:00
{
2009-06-02 01:51:51 -04:00
/* null pointer assignment */
2010-06-13 10:41:03 -04:00
ToValue - > Val - > Pointer = NULL ;
2009-04-27 08:19:36 -04:00
}
2009-10-10 13:59:55 -04:00
else if ( AllowPointerCoercion & & IS_NUMERIC_COERCIBLE ( FromValue ) )
{
/* assign integer to native pointer */
2010-06-13 10:41:03 -04:00
ToValue - > Val - > Pointer = ( void * ) ( unsigned long ) ExpressionCoerceUnsignedInteger ( FromValue ) ;
2009-10-10 13:59:55 -04:00
}
2011-02-20 19:57:06 -05:00
else if ( AllowPointerCoercion & & FromValue - > Typ - > Base = = TypePointer )
{
/* assign a pointer to a pointer to a different type */
ToValue - > Val - > Pointer = FromValue - > Val - > Pointer ;
}
2009-06-02 01:51:51 -04:00
else
2009-06-02 20:26:14 -04:00
AssignFail ( Parser , " %t from %t " , ToValue - > Typ , FromValue - > Typ , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
}
/* assign any kind of value */
2009-10-10 13:59:55 -04:00
void ExpressionAssign ( struct ParseState * Parser , struct Value * DestValue , struct Value * SourceValue , int Force , const char * FuncName , int ParamNo , int AllowPointerCoercion )
2009-06-02 01:51:51 -04:00
{
if ( ! DestValue - > IsLValue & & ! Force )
2009-06-02 20:26:14 -04:00
AssignFail ( Parser , " not an lvalue " , NULL , NULL , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
2009-10-25 07:54:34 -04:00
if ( IS_NUMERIC_COERCIBLE ( DestValue ) & & ! IS_NUMERIC_COERCIBLE_PLUS_POINTERS ( SourceValue , AllowPointerCoercion ) )
AssignFail ( Parser , " %t from %t " , DestValue - > Typ , SourceValue - > Typ , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
switch ( DestValue - > Typ - > Base )
{
2009-10-25 07:54:34 -04:00
case TypeInt : DestValue - > Val - > Integer = ExpressionCoerceInteger ( SourceValue ) ; break ;
2011-10-05 06:57:24 -04:00
case TypeShort : DestValue - > Val - > ShortInteger = ( short ) ExpressionCoerceInteger ( SourceValue ) ; break ;
case TypeChar : DestValue - > Val - > Character = ( unsigned char ) ExpressionCoerceUnsignedInteger ( SourceValue ) ; break ;
2009-11-07 16:05:15 -05:00
case TypeLong : DestValue - > Val - > LongInteger = ExpressionCoerceInteger ( SourceValue ) ; break ;
2009-10-25 07:54:34 -04:00
case TypeUnsignedInt : DestValue - > Val - > UnsignedInteger = ExpressionCoerceUnsignedInteger ( SourceValue ) ; break ;
2011-10-05 06:57:24 -04:00
case TypeUnsignedShort : DestValue - > Val - > UnsignedShortInteger = ( unsigned short ) ExpressionCoerceUnsignedInteger ( SourceValue ) ; break ;
2009-11-07 16:05:15 -05:00
case TypeUnsignedLong : DestValue - > Val - > UnsignedLongInteger = ExpressionCoerceUnsignedInteger ( SourceValue ) ; break ;
2009-10-11 07:09:07 -04:00
2009-06-02 01:51:51 -04:00
# ifndef NO_FP
case TypeFP :
2009-10-10 13:59:55 -04:00
if ( ! IS_NUMERIC_COERCIBLE_PLUS_POINTERS ( SourceValue , AllowPointerCoercion ) )
2009-06-02 20:26:14 -04:00
AssignFail ( Parser , " %t from %t " , DestValue - > Typ , SourceValue - > Typ , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
2009-10-25 07:54:34 -04:00
DestValue - > Val - > FP = ExpressionCoerceFP ( SourceValue ) ;
2009-06-02 01:51:51 -04:00
break ;
# endif
case TypePointer :
2009-10-10 13:59:55 -04:00
ExpressionAssignToPointer ( Parser , DestValue , SourceValue , FuncName , ParamNo , AllowPointerCoercion ) ;
2009-06-02 01:51:51 -04:00
break ;
case TypeArray :
2012-09-03 06:14:06 -04:00
if ( SourceValue - > Typ - > Base = = TypeArray & & DestValue - > Typ - > FromType = = DestValue - > Typ - > FromType & & DestValue - > Typ - > ArraySize = = 0 )
{
/* destination array is unsized - need to resize the destination array to the same size as the source array */
DestValue - > Typ = SourceValue - > Typ ;
VariableRealloc ( Parser , DestValue , TypeSizeValue ( DestValue , FALSE ) ) ;
if ( DestValue - > LValueFrom ! = NULL )
{
/* copy the resized value back to the LValue */
DestValue - > LValueFrom - > Val = DestValue - > Val ;
DestValue - > LValueFrom - > AnyValOnHeap = DestValue - > AnyValOnHeap ;
}
}
2009-06-02 01:51:51 -04:00
if ( DestValue - > Typ ! = SourceValue - > Typ )
2009-06-02 20:26:14 -04:00
AssignFail ( Parser , " %t from %t " , DestValue - > Typ , SourceValue - > Typ , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
2009-10-23 15:01:32 -04:00
if ( DestValue - > Typ - > ArraySize ! = SourceValue - > Typ - > ArraySize )
AssignFail ( Parser , " from an array of size %d to one of size %d " , NULL , NULL , DestValue - > Typ - > ArraySize , SourceValue - > Typ - > ArraySize , FuncName , ParamNo ) ;
2011-02-14 23:25:09 -05:00
memcpy ( ( void * ) DestValue - > Val , ( void * ) SourceValue - > Val , TypeSizeValue ( DestValue , FALSE ) ) ;
2009-06-02 01:51:51 -04:00
break ;
case TypeStruct :
case TypeUnion :
if ( DestValue - > Typ ! = SourceValue - > Typ )
2009-06-02 20:26:14 -04:00
AssignFail ( Parser , " %t from %t " , DestValue - > Typ , SourceValue - > Typ , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
2011-02-14 23:25:09 -05:00
memcpy ( ( void * ) DestValue - > Val , ( void * ) SourceValue - > Val , TypeSizeValue ( SourceValue , FALSE ) ) ;
2009-06-02 01:51:51 -04:00
break ;
default :
2009-06-02 20:26:14 -04:00
AssignFail ( Parser , " %t " , DestValue - > Typ , NULL , 0 , 0 , FuncName , ParamNo ) ;
2009-06-02 01:51:51 -04:00
break ;
}
2009-04-27 08:19:36 -04:00
}
2010-07-04 15:52:52 -04:00
/* evaluate the first half of a ternary operator x ? y : z */
void ExpressionQuestionMarkOperator ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct Value * BottomValue , struct Value * TopValue )
{
if ( ! IS_NUMERIC_COERCIBLE ( TopValue ) )
ProgramFail ( Parser , " first argument to '?' should be a number " ) ;
if ( ExpressionCoerceInteger ( TopValue ) )
{
/* the condition's true, return the BottomValue */
ExpressionStackPushValue ( Parser , StackTop , BottomValue ) ;
}
else
{
/* the condition's false, return void */
ExpressionStackPushValueByType ( Parser , StackTop , & VoidType ) ;
}
}
/* evaluate the second half of a ternary operator x ? y : z */
void ExpressionColonOperator ( struct ParseState * Parser , struct ExpressionStack * * StackTop , struct Value * BottomValue , struct Value * TopValue )
{
if ( TopValue - > Typ - > Base = = TypeVoid )
{
/* invoke the "else" part - return the BottomValue */
ExpressionStackPushValue ( Parser , StackTop , BottomValue ) ;
}
else
{
/* it was a "then" - return the TopValue */
ExpressionStackPushValue ( Parser , StackTop , TopValue ) ;
}
}
2009-03-12 06:49:57 -04:00
/* evaluate a prefix operator */
2009-03-28 07:10:34 -04:00
void ExpressionPrefixOperator ( struct ParseState * Parser , struct ExpressionStack * * StackTop , enum LexToken Op , struct Value * TopValue )
2009-03-12 06:49:57 -04:00
{
2009-03-28 07:10:34 -04:00
struct Value * Result ;
2009-11-06 17:16:12 -05:00
union AnyValue * ValPtr ;
2009-03-28 07:10:34 -04:00
2009-04-13 02:57:32 -04:00
debugf ( " ExpressionPrefixOperator() \n " ) ;
2009-03-28 07:10:34 -04:00
switch ( Op )
2009-03-12 06:49:57 -04:00
{
case TokenAmpersand :
if ( ! TopValue - > IsLValue )
ProgramFail ( Parser , " can't get the address of this " ) ;
2009-11-06 17:16:12 -05:00
ValPtr = TopValue - > Val ;
2011-02-17 21:31:56 -05:00
Result = VariableAllocValueFromType ( Parser , TypeGetMatching ( Parser , TopValue - > Typ , TypePointer , 0 , StrEmpty , TRUE ) , FALSE , NULL , FALSE ) ;
2010-06-13 10:41:03 -04:00
Result - > Val - > Pointer = ( void * ) ValPtr ;
2009-03-12 06:49:57 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , Result ) ;
break ;
2009-03-28 07:10:34 -04:00
2009-03-12 06:49:57 -04:00
case TokenAsterisk :
2009-04-25 23:26:04 -04:00
ExpressionStackPushDereference ( Parser , StackTop , TopValue ) ;
2009-03-12 06:49:57 -04:00
break ;
case TokenSizeof :
2009-10-22 16:08:43 -04:00
/* return the size of the argument */
if ( TopValue - > Typ = = & TypeType )
ExpressionPushInt ( Parser , StackTop , TypeSize ( TopValue - > Val - > Typ , TopValue - > Val - > Typ - > ArraySize , TRUE ) ) ;
else
ExpressionPushInt ( Parser , StackTop , TypeSize ( TopValue - > Typ , TopValue - > Typ - > ArraySize , TRUE ) ) ;
2009-03-12 06:49:57 -04:00
break ;
default :
/* an arithmetic operator */
2009-05-26 23:02:30 -04:00
# ifndef NO_FP
if ( TopValue - > Typ = = & FPType )
{
/* floating point prefix arithmetic */
2009-11-22 06:36:15 -05:00
double ResultFP = 0.0 ;
2009-05-26 23:02:30 -04:00
switch ( Op )
{
case TokenPlus : ResultFP = TopValue - > Val - > FP ; break ;
case TokenMinus : ResultFP = - TopValue - > Val - > FP ; break ;
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
}
2009-05-27 00:01:52 -04:00
ExpressionPushFP ( Parser , StackTop , ResultFP ) ;
2009-05-26 23:02:30 -04:00
}
else
# endif
2009-05-27 01:03:48 -04:00
if ( IS_NUMERIC_COERCIBLE ( TopValue ) )
2009-03-12 06:49:57 -04:00
{
/* integer prefix arithmetic */
2009-11-07 16:05:15 -05:00
long ResultInt = 0 ;
long TopInt = ExpressionCoerceInteger ( TopValue ) ;
2009-03-28 07:10:34 -04:00
switch ( Op )
2009-03-12 06:49:57 -04:00
{
case TokenPlus : ResultInt = TopInt ; break ;
case TokenMinus : ResultInt = - TopInt ; break ;
2009-04-22 08:06:58 -04:00
case TokenIncrement : ResultInt = ExpressionAssignInt ( Parser , TopValue , TopInt + 1 , FALSE ) ; break ;
case TokenDecrement : ResultInt = ExpressionAssignInt ( Parser , TopValue , TopInt - 1 , FALSE ) ; break ;
2009-03-12 06:49:57 -04:00
case TokenUnaryNot : ResultInt = ! TopInt ; break ;
case TokenUnaryExor : ResultInt = ~ TopInt ; break ;
2009-03-28 07:10:34 -04:00
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
2009-03-12 06:49:57 -04:00
}
ExpressionPushInt ( Parser , StackTop , ResultInt ) ;
}
2009-04-26 07:39:16 -04:00
else if ( TopValue - > Typ - > Base = = TypePointer )
2009-03-12 06:49:57 -04:00
{
/* pointer prefix arithmetic */
2009-04-28 23:24:15 -04:00
int Size = TypeSize ( TopValue - > Typ - > FromType , 0 , TRUE ) ;
2009-04-26 07:39:16 -04:00
struct Value * StackValue ;
2009-11-07 15:22:11 -05:00
void * ResultPtr ;
2009-11-06 17:34:12 -05:00
2010-06-13 10:41:03 -04:00
if ( TopValue - > Val - > Pointer = = NULL )
2009-05-05 20:25:09 -04:00
ProgramFail ( Parser , " invalid use of a NULL pointer " ) ;
if ( ! TopValue - > IsLValue )
ProgramFail ( Parser , " can't assign to this " ) ;
switch ( Op )
{
2010-06-13 10:41:03 -04:00
case TokenIncrement : TopValue - > Val - > Pointer = ( void * ) ( ( char * ) TopValue - > Val - > Pointer + Size ) ; break ;
case TokenDecrement : TopValue - > Val - > Pointer = ( void * ) ( ( char * ) TopValue - > Val - > Pointer - Size ) ; break ;
2009-05-05 20:25:09 -04:00
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
}
2010-06-13 10:41:03 -04:00
ResultPtr = TopValue - > Val - > Pointer ;
2009-05-05 20:25:09 -04:00
StackValue = ExpressionStackPushValueByType ( Parser , StackTop , TopValue - > Typ ) ;
2010-06-13 10:41:03 -04:00
StackValue - > Val - > Pointer = ResultPtr ;
2009-03-12 06:49:57 -04:00
}
2009-04-26 07:39:16 -04:00
else
ProgramFail ( Parser , " invalid operation " ) ;
2009-03-12 06:49:57 -04:00
break ;
}
}
/* evaluate a postfix operator */
2009-03-28 07:10:34 -04:00
void ExpressionPostfixOperator ( struct ParseState * Parser , struct ExpressionStack * * StackTop , enum LexToken Op , struct Value * TopValue )
2009-03-12 06:49:57 -04:00
{
2009-04-13 02:57:32 -04:00
debugf ( " ExpressionPostfixOperator() \n " ) ;
2009-05-27 01:03:48 -04:00
if ( IS_NUMERIC_COERCIBLE ( TopValue ) )
2009-03-12 06:49:57 -04:00
{
2009-11-07 16:05:15 -05:00
long ResultInt = 0 ;
long TopInt = ExpressionCoerceInteger ( TopValue ) ;
2009-03-28 07:10:34 -04:00
switch ( Op )
2009-03-12 06:49:57 -04:00
{
2009-04-22 08:06:58 -04:00
case TokenIncrement : ResultInt = ExpressionAssignInt ( Parser , TopValue , TopInt + 1 , TRUE ) ; break ;
case TokenDecrement : ResultInt = ExpressionAssignInt ( Parser , TopValue , TopInt - 1 , TRUE ) ; break ;
2009-06-04 20:55:54 -04:00
case TokenRightSquareBracket : ProgramFail ( Parser , " not supported " ) ; break ; /* XXX */
case TokenCloseBracket : ProgramFail ( Parser , " not supported " ) ; break ; /* XXX */
2009-03-28 07:10:34 -04:00
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
2009-03-12 06:49:57 -04:00
}
2009-03-28 07:10:34 -04:00
ExpressionPushInt ( Parser , StackTop , ResultInt ) ;
}
2009-04-26 07:39:16 -04:00
else if ( TopValue - > Typ - > Base = = TypePointer )
{
/* pointer postfix arithmetic */
2009-04-28 23:24:15 -04:00
int Size = TypeSize ( TopValue - > Typ - > FromType , 0 , TRUE ) ;
2009-04-26 07:39:16 -04:00
struct Value * StackValue ;
2010-06-13 10:41:03 -04:00
void * OrigPointer = TopValue - > Val - > Pointer ;
2009-05-05 20:25:09 -04:00
2010-06-13 10:41:03 -04:00
if ( TopValue - > Val - > Pointer = = NULL )
2009-05-05 20:25:09 -04:00
ProgramFail ( Parser , " invalid use of a NULL pointer " ) ;
if ( ! TopValue - > IsLValue )
ProgramFail ( Parser , " can't assign to this " ) ;
switch ( Op )
{
2010-06-13 10:41:03 -04:00
case TokenIncrement : TopValue - > Val - > Pointer = ( void * ) ( ( char * ) TopValue - > Val - > Pointer + Size ) ; break ;
case TokenDecrement : TopValue - > Val - > Pointer = ( void * ) ( ( char * ) TopValue - > Val - > Pointer - Size ) ; break ;
2009-05-05 20:25:09 -04:00
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
}
StackValue = ExpressionStackPushValueByType ( Parser , StackTop , TopValue - > Typ ) ;
2010-06-13 10:41:03 -04:00
StackValue - > Val - > Pointer = OrigPointer ;
2009-04-26 07:39:16 -04:00
}
else
ProgramFail ( Parser , " invalid operation " ) ;
2009-03-12 06:49:57 -04:00
}
/* evaluate an infix operator */
2009-03-28 07:10:34 -04:00
void ExpressionInfixOperator ( struct ParseState * Parser , struct ExpressionStack * * StackTop , enum LexToken Op , struct Value * BottomValue , struct Value * TopValue )
2009-03-12 06:49:57 -04:00
{
2009-11-07 16:05:15 -05:00
long ResultInt = 0 ;
2009-04-22 04:19:52 -04:00
struct Value * StackValue ;
2010-06-13 10:41:03 -04:00
void * Pointer ;
2009-11-06 11:35:34 -05:00
2009-04-13 02:57:32 -04:00
debugf ( " ExpressionInfixOperator() \n " ) ;
2009-11-06 11:35:34 -05:00
if ( BottomValue = = NULL | | TopValue = = NULL )
2009-11-06 13:08:11 -05:00
ProgramFail ( Parser , " invalid expression " ) ;
2009-11-06 11:35:34 -05:00
2009-04-14 02:55:00 -04:00
if ( Op = = TokenLeftSquareBracket )
{
/* array index */
int ArrayIndex ;
2009-11-08 14:23:50 -05:00
struct Value * Result = NULL ;
2009-04-14 02:55:00 -04:00
2009-05-27 01:03:48 -04:00
if ( ! IS_NUMERIC_COERCIBLE ( TopValue ) )
2009-04-14 02:55:00 -04:00
ProgramFail ( Parser , " array index must be an integer " ) ;
2009-10-25 07:54:34 -04:00
ArrayIndex = ExpressionCoerceInteger ( TopValue ) ;
2009-10-23 15:01:32 -04:00
2009-04-14 02:55:00 -04:00
/* make the array element result */
2009-11-01 15:49:23 -05:00
switch ( BottomValue - > Typ - > Base )
{
2010-06-05 08:58:37 -04:00
case TypeArray : Result = VariableAllocValueFromExistingData ( Parser , BottomValue - > Typ - > FromType , ( union AnyValue * ) ( & BottomValue - > Val - > ArrayMem [ 0 ] + TypeSize ( BottomValue - > Typ , ArrayIndex , TRUE ) ) , BottomValue - > IsLValue , BottomValue - > LValueFrom ) ; break ;
2010-06-13 10:41:03 -04:00
case TypePointer : Result = VariableAllocValueFromExistingData ( Parser , BottomValue - > Typ - > FromType , ( union AnyValue * ) ( ( char * ) BottomValue - > Val - > Pointer + TypeSize ( BottomValue - > Typ - > FromType , 0 , TRUE ) * ArrayIndex ) , BottomValue - > IsLValue , BottomValue - > LValueFrom ) ; break ;
2009-11-01 15:49:23 -05:00
default : ProgramFail ( Parser , " this %t is not an array " , BottomValue - > Typ ) ;
}
2009-04-14 02:55:00 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , Result ) ;
}
2010-07-04 15:52:52 -04:00
else if ( Op = = TokenQuestionMark )
ExpressionQuestionMarkOperator ( Parser , StackTop , TopValue , BottomValue ) ;
else if ( Op = = TokenColon )
ExpressionColonOperator ( Parser , StackTop , TopValue , BottomValue ) ;
2009-05-26 20:05:31 -04:00
# ifndef NO_FP
else if ( ( TopValue - > Typ = = & FPType & & BottomValue - > Typ = = & FPType ) | |
2009-05-27 01:03:48 -04:00
( TopValue - > Typ = = & FPType & & IS_NUMERIC_COERCIBLE ( BottomValue ) ) | |
( IS_NUMERIC_COERCIBLE ( TopValue ) & & BottomValue - > Typ = = & FPType ) )
2009-05-26 20:05:31 -04:00
{
/* floating point infix arithmetic */
int ResultIsInt = FALSE ;
double ResultFP = 0.0 ;
2009-10-25 07:54:34 -04:00
double TopFP = ( TopValue - > Typ = = & FPType ) ? TopValue - > Val - > FP : ( double ) ExpressionCoerceInteger ( TopValue ) ;
double BottomFP = ( BottomValue - > Typ = = & FPType ) ? BottomValue - > Val - > FP : ( double ) ExpressionCoerceInteger ( BottomValue ) ;
2009-05-26 20:05:31 -04:00
switch ( Op )
{
case TokenAssign : ResultFP = ExpressionAssignFP ( Parser , BottomValue , TopFP ) ; break ;
case TokenAddAssign : ResultFP = ExpressionAssignFP ( Parser , BottomValue , BottomFP + TopFP ) ; break ;
case TokenSubtractAssign : ResultFP = ExpressionAssignFP ( Parser , BottomValue , BottomFP - TopFP ) ; break ;
case TokenMultiplyAssign : ResultFP = ExpressionAssignFP ( Parser , BottomValue , BottomFP * TopFP ) ; break ;
case TokenDivideAssign : ResultFP = ExpressionAssignFP ( Parser , BottomValue , BottomFP / TopFP ) ; break ;
case TokenEqual : ResultInt = BottomFP = = TopFP ; ResultIsInt = TRUE ; break ;
case TokenNotEqual : ResultInt = BottomFP ! = TopFP ; ResultIsInt = TRUE ; break ;
case TokenLessThan : ResultInt = BottomFP < TopFP ; ResultIsInt = TRUE ; break ;
case TokenGreaterThan : ResultInt = BottomFP > TopFP ; ResultIsInt = TRUE ; break ;
case TokenLessEqual : ResultInt = BottomFP < = TopFP ; ResultIsInt = TRUE ; break ;
case TokenGreaterEqual : ResultInt = BottomFP > = TopFP ; ResultIsInt = TRUE ; break ;
case TokenPlus : ResultFP = BottomFP + TopFP ; break ;
case TokenMinus : ResultFP = BottomFP - TopFP ; break ;
case TokenAsterisk : ResultFP = BottomFP * TopFP ; break ;
case TokenSlash : ResultFP = BottomFP / TopFP ; break ;
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
}
if ( ResultIsInt )
ExpressionPushInt ( Parser , StackTop , ResultInt ) ;
else
ExpressionPushFP ( Parser , StackTop , ResultFP ) ;
}
# endif
2009-05-27 01:03:48 -04:00
else if ( IS_NUMERIC_COERCIBLE ( TopValue ) & & IS_NUMERIC_COERCIBLE ( BottomValue ) )
2009-04-14 02:55:00 -04:00
{
/* integer operation */
2009-11-07 16:05:15 -05:00
long TopInt = ExpressionCoerceInteger ( TopValue ) ;
long BottomInt = ExpressionCoerceInteger ( BottomValue ) ;
2009-04-13 23:18:40 -04:00
switch ( Op )
{
2009-04-22 08:06:58 -04:00
case TokenAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , TopInt , FALSE ) ; break ;
case TokenAddAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt + TopInt , FALSE ) ; break ;
case TokenSubtractAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt - TopInt , FALSE ) ; break ;
case TokenMultiplyAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt * TopInt , FALSE ) ; break ;
case TokenDivideAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt / TopInt , FALSE ) ; break ;
2009-04-18 21:15:01 -04:00
# ifndef NO_MODULUS
2009-04-22 08:06:58 -04:00
case TokenModulusAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt % TopInt , FALSE ) ; break ;
2009-04-18 21:15:01 -04:00
# endif
2009-04-22 08:06:58 -04:00
case TokenShiftLeftAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt < < TopInt , FALSE ) ; break ;
case TokenShiftRightAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt > > TopInt , FALSE ) ; break ;
case TokenArithmeticAndAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt & TopInt , FALSE ) ; break ;
case TokenArithmeticOrAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt | TopInt , FALSE ) ; break ;
case TokenArithmeticExorAssign : ResultInt = ExpressionAssignInt ( Parser , BottomValue , BottomInt ^ TopInt , FALSE ) ; break ;
2009-04-13 23:18:40 -04:00
case TokenLogicalOr : ResultInt = BottomInt | | TopInt ; break ;
case TokenLogicalAnd : ResultInt = BottomInt & & TopInt ; break ;
case TokenArithmeticOr : ResultInt = BottomInt | TopInt ; break ;
case TokenArithmeticExor : ResultInt = BottomInt ^ TopInt ; break ;
case TokenAmpersand : ResultInt = BottomInt & TopInt ; break ;
case TokenEqual : ResultInt = BottomInt = = TopInt ; break ;
case TokenNotEqual : ResultInt = BottomInt ! = TopInt ; break ;
case TokenLessThan : ResultInt = BottomInt < TopInt ; break ;
case TokenGreaterThan : ResultInt = BottomInt > TopInt ; break ;
case TokenLessEqual : ResultInt = BottomInt < = TopInt ; break ;
case TokenGreaterEqual : ResultInt = BottomInt > = TopInt ; break ;
case TokenShiftLeft : ResultInt = BottomInt < < TopInt ; break ;
2011-01-06 14:36:40 -05:00
case TokenShiftRight : ResultInt = BottomInt > > TopInt ; break ;
2009-04-13 23:18:40 -04:00
case TokenPlus : ResultInt = BottomInt + TopInt ; break ;
case TokenMinus : ResultInt = BottomInt - TopInt ; break ;
case TokenAsterisk : ResultInt = BottomInt * TopInt ; break ;
case TokenSlash : ResultInt = BottomInt / TopInt ; break ;
2009-04-18 21:15:01 -04:00
# ifndef NO_MODULUS
2009-04-13 23:18:40 -04:00
case TokenModulus : ResultInt = BottomInt % TopInt ; break ;
2009-04-18 21:15:01 -04:00
# endif
2009-04-13 23:18:40 -04:00
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
}
ExpressionPushInt ( Parser , StackTop , ResultInt ) ;
}
2009-05-27 01:03:48 -04:00
else if ( BottomValue - > Typ - > Base = = TypePointer & & IS_NUMERIC_COERCIBLE ( TopValue ) )
2009-04-13 23:18:40 -04:00
{
2009-04-19 07:49:01 -04:00
/* pointer/integer infix arithmetic */
2009-11-07 16:05:15 -05:00
long TopInt = ExpressionCoerceInteger ( TopValue ) ;
2009-04-19 07:49:01 -04:00
if ( Op = = TokenEqual | | Op = = TokenNotEqual )
2009-04-13 23:18:40 -04:00
{
2009-04-19 07:49:01 -04:00
/* comparison to a NULL pointer */
if ( TopInt ! = 0 )
ProgramFail ( Parser , " invalid operation " ) ;
2009-05-05 20:25:09 -04:00
if ( Op = = TokenEqual )
2010-06-13 10:41:03 -04:00
ExpressionPushInt ( Parser , StackTop , BottomValue - > Val - > Pointer = = NULL ) ;
2009-05-05 20:25:09 -04:00
else
2010-06-13 10:41:03 -04:00
ExpressionPushInt ( Parser , StackTop , BottomValue - > Val - > Pointer ! = NULL ) ;
2009-04-19 07:49:01 -04:00
}
else if ( Op = = TokenPlus | | Op = = TokenMinus )
{
/* pointer arithmetic */
2009-04-28 23:24:15 -04:00
int Size = TypeSize ( BottomValue - > Typ - > FromType , 0 , TRUE ) ;
2009-04-19 07:49:01 -04:00
2010-06-13 10:41:03 -04:00
Pointer = BottomValue - > Val - > Pointer ;
if ( Pointer = = NULL )
2009-05-05 20:25:09 -04:00
ProgramFail ( Parser , " invalid use of a NULL pointer " ) ;
if ( Op = = TokenPlus )
2010-06-13 10:41:03 -04:00
Pointer = ( void * ) ( ( char * ) Pointer + TopInt * Size ) ;
2009-05-05 20:25:09 -04:00
else
2010-06-13 10:41:03 -04:00
Pointer = ( void * ) ( ( char * ) Pointer - TopInt * Size ) ;
2009-05-05 20:25:09 -04:00
StackValue = ExpressionStackPushValueByType ( Parser , StackTop , BottomValue - > Typ ) ;
2010-06-13 10:41:03 -04:00
StackValue - > Val - > Pointer = Pointer ;
2009-04-19 07:49:01 -04:00
}
else if ( Op = = TokenAssign & & TopInt = = 0 )
{
/* assign a NULL pointer */
2010-07-24 12:07:56 -04:00
HeapUnpopStack ( sizeof ( struct Value ) ) ;
2009-10-10 13:59:55 -04:00
ExpressionAssign ( Parser , BottomValue , TopValue , FALSE , NULL , 0 , FALSE ) ;
2009-06-02 01:51:51 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , BottomValue ) ;
2009-04-13 23:18:40 -04:00
}
2010-07-21 01:45:44 -04:00
else if ( Op = = TokenAddAssign | | Op = = TokenSubtractAssign )
{
/* pointer arithmetic */
int Size = TypeSize ( BottomValue - > Typ - > FromType , 0 , TRUE ) ;
Pointer = BottomValue - > Val - > Pointer ;
if ( Pointer = = NULL )
ProgramFail ( Parser , " invalid use of a NULL pointer " ) ;
if ( Op = = TokenAddAssign )
Pointer = ( void * ) ( ( char * ) Pointer + TopInt * Size ) ;
else
Pointer = ( void * ) ( ( char * ) Pointer - TopInt * Size ) ;
2010-07-24 12:07:56 -04:00
HeapUnpopStack ( sizeof ( struct Value ) ) ;
2010-07-21 01:45:44 -04:00
BottomValue - > Val - > Pointer = Pointer ;
ExpressionStackPushValueNode ( Parser , StackTop , BottomValue ) ;
}
2009-04-13 23:18:40 -04:00
else
2009-04-19 07:49:01 -04:00
ProgramFail ( Parser , " invalid operation " ) ;
2009-03-12 06:49:57 -04:00
}
2009-04-22 04:19:52 -04:00
else if ( BottomValue - > Typ - > Base = = TypePointer & & TopValue - > Typ - > Base = = TypePointer & & Op ! = TokenAssign )
{
/* pointer/pointer operations */
2010-06-13 10:41:03 -04:00
char * TopLoc = ( char * ) TopValue - > Val - > Pointer ;
char * BottomLoc = ( char * ) BottomValue - > Val - > Pointer ;
2009-04-22 04:19:52 -04:00
switch ( Op )
{
case TokenEqual : ExpressionPushInt ( Parser , StackTop , BottomLoc = = TopLoc ) ; break ;
case TokenNotEqual : ExpressionPushInt ( Parser , StackTop , BottomLoc ! = TopLoc ) ; break ;
case TokenMinus : ExpressionPushInt ( Parser , StackTop , BottomLoc - TopLoc ) ; break ;
default : ProgramFail ( Parser , " invalid operation " ) ; break ;
}
}
2009-04-15 01:26:46 -04:00
else if ( Op = = TokenAssign )
{
/* assign a non-numeric type */
2009-06-02 03:50:46 -04:00
HeapUnpopStack ( sizeof ( struct Value ) ) ; /* XXX - possible bug if lvalue is a temp value and takes more than sizeof(struct Value) */
2009-10-10 13:59:55 -04:00
ExpressionAssign ( Parser , BottomValue , TopValue , FALSE , NULL , 0 , FALSE ) ;
2009-06-02 01:51:51 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , BottomValue ) ;
2009-04-15 01:26:46 -04:00
}
2009-10-10 10:49:49 -04:00
else if ( Op = = TokenCast )
{
2009-10-10 13:59:55 -04:00
/* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */
struct Value * ValueLoc = ExpressionStackPushValueByType ( Parser , StackTop , BottomValue - > Val - > Typ ) ;
ExpressionAssign ( Parser , ValueLoc , TopValue , TRUE , NULL , 0 , TRUE ) ;
2009-10-10 10:49:49 -04:00
}
2009-04-13 23:18:40 -04:00
else
ProgramFail ( Parser , " invalid operation " ) ;
2009-03-12 06:49:57 -04:00
}
2009-03-08 04:40:05 -04:00
/* take the contents of the expression stack and compute the top until there's nothing greater than the given precedence */
2011-02-15 19:13:11 -05:00
void ExpressionStackCollapse ( struct ParseState * Parser , struct ExpressionStack * * StackTop , int Precedence , int * IgnorePrecedence )
2009-03-08 04:40:05 -04:00
{
2009-03-12 06:49:57 -04:00
int FoundPrecedence = Precedence ;
struct Value * TopValue ;
struct Value * BottomValue ;
struct ExpressionStack * TopStackNode = * StackTop ;
struct ExpressionStack * TopOperatorNode ;
2009-06-03 20:18:28 -04:00
debugf ( " ExpressionStackCollapse(%d): \n " , Precedence ) ;
2009-04-13 02:57:32 -04:00
# ifdef DEBUG_EXPRESSIONS
ExpressionStackShow ( * StackTop ) ;
# endif
2009-03-29 07:08:03 -04:00
while ( TopStackNode ! = NULL & & TopStackNode - > Next ! = NULL & & FoundPrecedence > = Precedence )
2009-03-12 06:49:57 -04:00
{
/* find the top operator on the stack */
2009-04-13 05:02:45 -04:00
if ( TopStackNode - > Order = = OrderNone )
2009-03-12 06:49:57 -04:00
TopOperatorNode = TopStackNode - > Next ;
else
TopOperatorNode = TopStackNode ;
2009-04-13 02:57:32 -04:00
FoundPrecedence = TopOperatorNode - > Precedence ;
2009-03-12 06:49:57 -04:00
/* does it have a high enough precedence? */
2009-03-29 07:08:03 -04:00
if ( FoundPrecedence > = Precedence & & TopOperatorNode ! = NULL )
2009-03-12 06:49:57 -04:00
{
/* execute this operator */
switch ( TopOperatorNode - > Order )
{
case OrderPrefix :
/* prefix evaluation */
2009-04-13 02:57:32 -04:00
debugf ( " prefix evaluation \n " ) ;
2009-10-04 12:22:19 -04:00
TopValue = TopStackNode - > Val ;
2009-03-12 06:49:57 -04:00
/* pop the value and then the prefix operator - assume they'll still be there until we're done */
2009-11-06 17:16:12 -05:00
HeapPopStack ( NULL , sizeof ( struct ExpressionStack ) + sizeof ( struct Value ) + TypeStackSizeValue ( TopValue ) ) ;
HeapPopStack ( TopOperatorNode , sizeof ( struct ExpressionStack ) ) ;
2009-04-13 05:02:45 -04:00
* StackTop = TopOperatorNode - > Next ;
2009-03-12 06:49:57 -04:00
/* do the prefix operation */
2011-02-15 19:13:11 -05:00
if ( Parser - > Mode = = RunModeRun & & FoundPrecedence < * IgnorePrecedence )
{
/* run the operator */
ExpressionPrefixOperator ( Parser , StackTop , TopOperatorNode - > Op , TopValue ) ;
}
else
{
/* we're not running it so just return 0 */
ExpressionPushInt ( Parser , StackTop , 0 ) ;
}
2009-03-12 06:49:57 -04:00
break ;
case OrderPostfix :
/* postfix evaluation */
2009-04-13 02:57:32 -04:00
debugf ( " postfix evaluation \n " ) ;
2009-10-04 12:22:19 -04:00
TopValue = TopStackNode - > Next - > Val ;
2009-03-12 06:49:57 -04:00
2009-04-13 05:02:45 -04:00
/* pop the postfix operator and then the value - assume they'll still be there until we're done */
2009-11-06 17:16:12 -05:00
HeapPopStack ( NULL , sizeof ( struct ExpressionStack ) ) ;
HeapPopStack ( TopValue , sizeof ( struct ExpressionStack ) + sizeof ( struct Value ) + TypeStackSizeValue ( TopValue ) ) ;
2009-03-28 07:10:34 -04:00
* StackTop = TopStackNode - > Next - > Next ;
2009-03-12 06:49:57 -04:00
/* do the postfix operation */
2011-02-15 19:13:11 -05:00
if ( Parser - > Mode = = RunModeRun & & FoundPrecedence < * IgnorePrecedence )
{
/* run the operator */
ExpressionPostfixOperator ( Parser , StackTop , TopOperatorNode - > Op , TopValue ) ;
}
else
{
/* we're not running it so just return 0 */
ExpressionPushInt ( Parser , StackTop , 0 ) ;
}
2009-03-12 06:49:57 -04:00
break ;
case OrderInfix :
/* infix evaluation */
2009-04-13 02:57:32 -04:00
debugf ( " infix evaluation \n " ) ;
2009-10-04 12:22:19 -04:00
TopValue = TopStackNode - > Val ;
2009-11-06 11:35:34 -05:00
if ( TopValue ! = NULL )
{
BottomValue = TopOperatorNode - > Next - > Val ;
/* pop a value, the operator and another value - assume they'll still be there until we're done */
2009-11-06 17:16:12 -05:00
HeapPopStack ( NULL , sizeof ( struct ExpressionStack ) + sizeof ( struct Value ) + TypeStackSizeValue ( TopValue ) ) ;
HeapPopStack ( NULL , sizeof ( struct ExpressionStack ) ) ;
HeapPopStack ( BottomValue , sizeof ( struct ExpressionStack ) + sizeof ( struct Value ) + TypeStackSizeValue ( BottomValue ) ) ;
2009-11-06 11:35:34 -05:00
* StackTop = TopOperatorNode - > Next - > Next ;
/* do the infix operation */
2011-02-15 22:58:48 -05:00
if ( Parser - > Mode = = RunModeRun & & FoundPrecedence < = * IgnorePrecedence )
2011-02-15 19:13:11 -05:00
{
/* run the operator */
ExpressionInfixOperator ( Parser , StackTop , TopOperatorNode - > Op , BottomValue , TopValue ) ;
}
else
{
/* we're not running it so just return 0 */
ExpressionPushInt ( Parser , StackTop , 0 ) ;
}
2009-11-06 11:35:34 -05:00
}
else
FoundPrecedence = - 1 ;
2009-03-12 06:49:57 -04:00
break ;
2009-03-29 07:08:03 -04:00
case OrderNone :
2009-05-27 01:59:44 -04:00
/* this should never happen */
assert ( TopOperatorNode - > Order ! = OrderNone ) ;
2009-03-29 07:08:03 -04:00
break ;
2009-03-12 06:49:57 -04:00
}
2011-02-15 19:13:11 -05:00
/* if we've returned above the ignored precedence level turn ignoring off */
if ( FoundPrecedence < = * IgnorePrecedence )
* IgnorePrecedence = DEEP_PRECEDENCE ;
2009-03-12 06:49:57 -04:00
}
2009-04-13 02:57:32 -04:00
# ifdef DEBUG_EXPRESSIONS
ExpressionStackShow ( * StackTop ) ;
# endif
TopStackNode = * StackTop ;
2009-03-12 06:49:57 -04:00
}
2009-04-13 02:57:32 -04:00
debugf ( " ExpressionStackCollapse() finished \n " ) ;
2009-04-15 06:47:51 -04:00
# ifdef DEBUG_EXPRESSIONS
ExpressionStackShow ( * StackTop ) ;
# endif
2009-03-08 04:40:05 -04:00
}
/* push an operator on to the expression stack */
2009-03-12 06:49:57 -04:00
void ExpressionStackPushOperator ( struct ParseState * Parser , struct ExpressionStack * * StackTop , enum OperatorOrder Order , enum LexToken Token , int Precedence )
2009-03-08 04:40:05 -04:00
{
2009-03-11 22:21:12 -04:00
struct ExpressionStack * StackNode = VariableAlloc ( Parser , sizeof ( struct ExpressionStack ) , FALSE ) ;
StackNode - > Next = * StackTop ;
StackNode - > Order = Order ;
2009-10-04 12:22:19 -04:00
StackNode - > Op = Token ;
2009-03-11 22:21:12 -04:00
StackNode - > Precedence = Precedence ;
* StackTop = StackNode ;
2009-04-13 02:57:32 -04:00
debugf ( " ExpressionStackPushOperator() \n " ) ;
2009-06-04 03:41:06 -04:00
# ifdef FANCY_ERROR_MESSAGES
StackNode - > Line = Parser - > Line ;
StackNode - > CharacterPos = Parser - > CharacterPos ;
# endif
2009-04-13 02:57:32 -04:00
# ifdef DEBUG_EXPRESSIONS
ExpressionStackShow ( * StackTop ) ;
# endif
2009-03-08 04:40:05 -04:00
}
2009-04-13 23:18:40 -04:00
/* do the '.' and '->' operators */
void ExpressionGetStructElement ( struct ParseState * Parser , struct ExpressionStack * * StackTop , enum LexToken Token )
{
struct Value * Ident ;
/* get the identifier following the '.' or '->' */
if ( LexGetToken ( Parser , & Ident , TRUE ) ! = TokenIdentifier )
ProgramFail ( Parser , " need an structure or union member after '%s' " , ( Token = = TokenDot ) ? " . " : " -> " ) ;
if ( Parser - > Mode = = RunModeRun )
2009-04-14 02:55:00 -04:00
{
/* look up the struct element */
2009-10-04 12:22:19 -04:00
struct Value * ParamVal = ( * StackTop ) - > Val ;
2009-04-15 02:40:56 -04:00
struct Value * StructVal = ParamVal ;
2009-04-25 23:26:04 -04:00
struct ValueType * StructType = ParamVal - > Typ ;
2009-06-02 03:50:46 -04:00
char * DerefDataLoc = ( char * ) ParamVal - > Val ;
2009-04-13 23:18:40 -04:00
struct Value * MemberValue ;
struct Value * Result ;
2009-04-25 23:26:04 -04:00
/* if we're doing '->' dereference the struct pointer first */
2009-04-13 23:18:40 -04:00
if ( Token = = TokenArrow )
2009-06-04 20:55:54 -04:00
DerefDataLoc = VariableDereferencePointer ( Parser , ParamVal , & StructVal , NULL , & StructType , NULL ) ;
2009-04-13 23:18:40 -04:00
2009-04-25 23:26:04 -04:00
if ( StructType - > Base ! = TypeStruct & & StructType - > Base ! = TypeUnion )
2009-04-23 21:02:25 -04:00
ProgramFail ( Parser , " can't use '%s' on something that's not a struct or union %s : it's a %t " , ( Token = = TokenDot ) ? " . " : " -> " , ( Token = = TokenArrow ) ? " pointer " : " " , ParamVal - > Typ ) ;
2009-04-13 23:18:40 -04:00
2011-02-16 18:38:41 -05:00
if ( ! TableGet ( StructType - > Members , Ident - > Val - > Identifier , & MemberValue , NULL , NULL , NULL ) )
2009-04-13 23:18:40 -04:00
ProgramFail ( Parser , " doesn't have a member called '%s' " , Ident - > Val - > Identifier ) ;
/* pop the value - assume it'll still be there until we're done */
2009-04-15 02:40:56 -04:00
HeapPopStack ( ParamVal , sizeof ( struct ExpressionStack ) + sizeof ( struct Value ) + TypeStackSizeValue ( StructVal ) ) ;
2009-04-13 23:18:40 -04:00
* StackTop = ( * StackTop ) - > Next ;
/* make the result value for this member only */
2009-06-04 20:55:54 -04:00
Result = VariableAllocValueFromExistingData ( Parser , MemberValue - > Typ , ( void * ) ( DerefDataLoc + MemberValue - > Val - > Integer ) , TRUE , ( StructVal ! = NULL ) ? StructVal - > LValueFrom : NULL ) ;
2009-04-13 23:18:40 -04:00
ExpressionStackPushValueNode ( Parser , StackTop , Result ) ;
}
}
2009-03-08 03:56:28 -04:00
/* parse an expression with operator precedence */
int ExpressionParse ( struct ParseState * Parser , struct Value * * Result )
{
struct Value * LexValue ;
2009-03-29 07:08:03 -04:00
int PrefixState = TRUE ;
2009-03-28 07:10:34 -04:00
int Done = FALSE ;
2009-03-08 03:56:28 -04:00
int BracketPrecedence = 0 ;
2009-03-11 22:21:12 -04:00
int LocalPrecedence ;
2009-03-08 03:56:28 -04:00
int Precedence = 0 ;
2011-02-15 19:13:11 -05:00
int IgnorePrecedence = DEEP_PRECEDENCE ;
2009-03-08 04:40:05 -04:00
struct ExpressionStack * StackTop = NULL ;
2009-04-14 04:44:47 -04:00
int TernaryDepth = 0 ;
2009-03-08 03:56:28 -04:00
2009-04-14 04:44:47 -04:00
debugf ( " ExpressionParse(): \n " ) ;
2009-03-08 03:56:28 -04:00
do
{
2011-02-11 23:04:51 -05:00
struct ParseState PreState ;
enum LexToken Token ;
ParserCopy ( & PreState , Parser ) ;
Token = LexGetToken ( Parser , & LexValue , TRUE ) ;
2009-04-14 19:44:49 -04:00
if ( ( ( ( int ) Token > TokenComma & & ( int ) Token < = ( int ) TokenOpenBracket ) | |
2010-07-04 15:52:52 -04:00
( Token = = TokenCloseBracket & & BracketPrecedence ! = 0 ) ) & &
( Token ! = TokenColon | | TernaryDepth > 0 ) )
2009-04-14 02:55:00 -04:00
{
/* it's an operator with precedence */
2009-03-08 03:56:28 -04:00
if ( PrefixState )
2009-04-14 02:55:00 -04:00
{
/* expect a prefix operator */
2009-03-08 03:56:28 -04:00
if ( OperatorPrecedence [ ( int ) Token ] . PrefixPrecedence = = 0 )
ProgramFail ( Parser , " operator not expected here " ) ;
2009-04-13 05:02:45 -04:00
LocalPrecedence = OperatorPrecedence [ ( int ) Token ] . PrefixPrecedence ;
Precedence = BracketPrecedence + LocalPrecedence ;
2009-10-10 10:49:49 -04:00
2009-04-14 02:55:00 -04:00
if ( Token = = TokenOpenBracket )
{
2009-10-10 10:49:49 -04:00
/* it's either a new bracket level or a cast */
enum LexToken BracketToken = LexGetToken ( Parser , & LexValue , FALSE ) ;
2010-09-04 09:39:58 -04:00
if ( IS_TYPE_TOKEN ( BracketToken ) & & ( StackTop = = NULL | | StackTop - > Op ! = TokenSizeof ) )
2009-10-10 10:49:49 -04:00
{
/* it's a cast - get the new type */
struct ValueType * CastType ;
char * CastIdentifier ;
struct Value * CastTypeValue ;
2011-02-16 18:38:41 -05:00
TypeParse ( Parser , & CastType , & CastIdentifier , NULL ) ;
2009-10-10 10:49:49 -04:00
if ( LexGetToken ( Parser , & LexValue , TRUE ) ! = TokenCloseBracket )
ProgramFail ( Parser , " brackets not closed " ) ;
/* scan and collapse the stack to the precedence of this infix cast operator, then push */
Precedence = BracketPrecedence + OperatorPrecedence [ ( int ) TokenCast ] . PrefixPrecedence ;
2011-02-15 19:13:11 -05:00
ExpressionStackCollapse ( Parser , & StackTop , Precedence + 1 , & IgnorePrecedence ) ;
2009-10-10 13:59:55 -04:00
CastTypeValue = VariableAllocValueFromType ( Parser , & TypeType , FALSE , NULL , FALSE ) ;
CastTypeValue - > Val - > Typ = CastType ;
ExpressionStackPushValueNode ( Parser , & StackTop , CastTypeValue ) ;
2009-10-10 10:49:49 -04:00
ExpressionStackPushOperator ( Parser , & StackTop , OrderInfix , TokenCast , Precedence ) ;
}
else
{
/* boost the bracket operator precedence */
BracketPrecedence + = BRACKET_PRECEDENCE ;
}
2009-04-13 05:02:45 -04:00
}
else
2009-04-14 02:55:00 -04:00
{
/* scan and collapse the stack to the precedence of this operator, then push */
2011-02-15 19:13:11 -05:00
ExpressionStackCollapse ( Parser , & StackTop , Precedence , & IgnorePrecedence ) ;
2009-04-13 05:02:45 -04:00
ExpressionStackPushOperator ( Parser , & StackTop , OrderPrefix , Token , Precedence ) ;
2009-03-08 03:56:28 -04:00
}
}
else
2009-04-14 02:55:00 -04:00
{
/* expect an infix or postfix operator */
2009-03-08 03:56:28 -04:00
if ( OperatorPrecedence [ ( int ) Token ] . PostfixPrecedence ! = 0 )
{
switch ( Token )
{
case TokenCloseBracket :
2009-04-14 02:55:00 -04:00
case TokenRightSquareBracket :
2009-03-08 03:56:28 -04:00
if ( BracketPrecedence = = 0 )
2009-04-14 02:55:00 -04:00
{
/* assume this bracket is after the end of the expression */
2011-02-11 23:04:51 -05:00
ParserCopy ( Parser , & PreState ) ;
2009-03-28 07:10:34 -04:00
Done = TRUE ;
2009-03-08 03:56:28 -04:00
}
else
2011-02-15 22:58:48 -05:00
{
/* collapse to the bracket precedence */
ExpressionStackCollapse ( Parser , & StackTop , BracketPrecedence , & IgnorePrecedence ) ;
2009-03-08 03:56:28 -04:00
BracketPrecedence - = BRACKET_PRECEDENCE ;
2011-02-15 22:58:48 -05:00
}
2009-03-08 03:56:28 -04:00
break ;
default :
2009-03-08 04:40:05 -04:00
/* scan and collapse the stack to the precedence of this operator, then push */
Precedence = BracketPrecedence + OperatorPrecedence [ ( int ) Token ] . PostfixPrecedence ;
2011-02-15 19:13:11 -05:00
ExpressionStackCollapse ( Parser , & StackTop , Precedence , & IgnorePrecedence ) ;
2009-03-08 04:40:05 -04:00
ExpressionStackPushOperator ( Parser , & StackTop , OrderPostfix , Token , Precedence ) ;
2009-03-08 03:56:28 -04:00
break ;
}
}
else if ( OperatorPrecedence [ ( int ) Token ] . InfixPrecedence ! = 0 )
2009-04-14 02:55:00 -04:00
{
/* scan and collapse the stack, then push */
2011-02-15 23:46:04 -05:00
Precedence = BracketPrecedence + OperatorPrecedence [ ( int ) Token ] . InfixPrecedence ;
/* for right to left order, only go down to the next higher precedence so we evaluate it in reverse order */
/* for left to right order, collapse down to this precedence so we evaluate it in forward order */
if ( IS_LEFT_TO_RIGHT ( OperatorPrecedence [ ( int ) Token ] . InfixPrecedence ) )
ExpressionStackCollapse ( Parser , & StackTop , Precedence , & IgnorePrecedence ) ;
else
ExpressionStackCollapse ( Parser , & StackTop , Precedence + 1 , & IgnorePrecedence ) ;
2009-04-13 23:18:40 -04:00
if ( Token = = TokenDot | | Token = = TokenArrow )
2011-02-15 23:46:04 -05:00
{
2009-04-13 23:18:40 -04:00
ExpressionGetStructElement ( Parser , & StackTop , Token ) ; /* this operator is followed by a struct element so handle it as a special case */
2011-02-15 23:46:04 -05:00
}
2009-03-12 06:49:57 -04:00
else
2009-04-14 02:55:00 -04:00
{
2011-02-15 19:13:11 -05:00
/* if it's a && or || operator we may not need to evaluate the right hand side of the expression */
if ( ( Token = = TokenLogicalOr | | Token = = TokenLogicalAnd ) & & IS_NUMERIC_COERCIBLE ( StackTop - > Val ) )
{
long LHSInt = ExpressionCoerceInteger ( StackTop - > Val ) ;
if ( ( ( Token = = TokenLogicalOr & & LHSInt ) | | ( Token = = TokenLogicalAnd & & ! LHSInt ) ) & &
( IgnorePrecedence > Precedence ) )
IgnorePrecedence = Precedence ;
}
/* push the operator on the stack */
2009-04-13 23:18:40 -04:00
ExpressionStackPushOperator ( Parser , & StackTop , OrderInfix , Token , Precedence ) ;
PrefixState = TRUE ;
2010-07-04 15:52:52 -04:00
switch ( Token )
{
case TokenQuestionMark : TernaryDepth + + ; break ;
case TokenColon : TernaryDepth - - ; break ;
default : break ;
}
2009-04-13 23:18:40 -04:00
}
2009-04-14 02:55:00 -04:00
/* treat an open square bracket as an infix array index operator followed by an open bracket */
if ( Token = = TokenLeftSquareBracket )
{
/* boost the bracket operator precedence, then push */
BracketPrecedence + = BRACKET_PRECEDENCE ;
}
2009-03-08 03:56:28 -04:00
}
else
ProgramFail ( Parser , " operator not expected here " ) ;
}
}
2009-04-04 22:24:00 -04:00
else if ( Token = = TokenIdentifier )
2009-04-14 02:55:00 -04:00
{
/* it's a variable, function or a macro */
2009-05-27 01:59:44 -04:00
if ( ! PrefixState )
ProgramFail ( Parser , " identifier not expected here " ) ;
2009-04-04 22:24:00 -04:00
if ( LexGetToken ( Parser , NULL , FALSE ) = = TokenOpenBracket )
2010-07-11 14:44:07 -04:00
{
2011-02-15 19:13:11 -05:00
ExpressionParseFunctionCall ( Parser , & StackTop , LexValue - > Val - > Identifier , Parser - > Mode = = RunModeRun & & Precedence < IgnorePrecedence ) ;
2010-07-11 14:44:07 -04:00
}
2009-04-04 22:24:00 -04:00
else
{
2011-02-15 19:13:11 -05:00
if ( Parser - > Mode = = RunModeRun & & Precedence < IgnorePrecedence )
2009-04-04 22:24:00 -04:00
{
struct Value * VariableValue = NULL ;
VariableGet ( Parser , LexValue - > Val - > Identifier , & VariableValue ) ;
if ( VariableValue - > Typ - > Base = = TypeMacro )
{
2009-04-15 02:57:02 -04:00
/* evaluate a macro as a kind of simple subroutine */
2011-02-11 23:04:51 -05:00
struct ParseState MacroParser ;
2009-04-15 02:57:02 -04:00
struct Value * MacroResult ;
2009-04-04 22:24:00 -04:00
2011-02-11 23:04:51 -05:00
ParserCopy ( & MacroParser , & VariableValue - > Val - > MacroDef . Body ) ;
2010-07-11 14:44:07 -04:00
if ( VariableValue - > Val - > MacroDef . NumParams ! = 0 )
ProgramFail ( & MacroParser , " macro arguments missing " ) ;
2009-04-15 02:57:02 -04:00
if ( ! ExpressionParse ( & MacroParser , & MacroResult ) | | LexGetToken ( & MacroParser , NULL , FALSE ) ! = TokenEndOfFunction )
2009-04-04 22:24:00 -04:00
ProgramFail ( & MacroParser , " expression expected " ) ;
2009-04-15 02:57:02 -04:00
ExpressionStackPushValueNode ( Parser , & StackTop , MacroResult ) ;
2009-04-04 22:24:00 -04:00
}
2011-10-05 06:57:24 -04:00
else if ( VariableValue - > Typ = = & VoidType )
2009-04-04 22:24:00 -04:00
ProgramFail ( Parser , " a void value isn't much use here " ) ;
else
2009-04-22 03:23:26 -04:00
ExpressionStackPushLValue ( Parser , & StackTop , VariableValue , 0 ) ; /* it's a value variable */
2009-04-04 22:24:00 -04:00
}
else /* push a dummy value */
2009-04-13 05:02:45 -04:00
ExpressionPushInt ( Parser , & StackTop , 0 ) ;
2011-02-15 19:13:11 -05:00
2009-04-04 22:24:00 -04:00
}
2009-04-15 06:47:51 -04:00
2011-02-15 19:13:11 -05:00
/* if we've successfully ignored the RHS turn ignoring off */
if ( Precedence < = IgnorePrecedence )
IgnorePrecedence = DEEP_PRECEDENCE ;
2009-04-15 06:47:51 -04:00
PrefixState = FALSE ;
2009-04-04 22:24:00 -04:00
}
2009-04-14 04:44:47 -04:00
else if ( ( int ) Token > TokenCloseBracket & & ( int ) Token < = TokenCharacterConstant )
2009-04-14 02:55:00 -04:00
{
/* it's a value of some sort, push it */
2009-03-08 03:56:28 -04:00
if ( ! PrefixState )
ProgramFail ( Parser , " value not expected here " ) ;
2009-03-28 07:10:34 -04:00
PrefixState = FALSE ;
2009-03-08 04:40:05 -04:00
ExpressionStackPushValue ( Parser , & StackTop , LexValue ) ;
2009-03-08 03:56:28 -04:00
}
2009-10-22 16:08:43 -04:00
else if ( IS_TYPE_TOKEN ( Token ) )
{
/* it's a type. push it on the stack like a value. this is used in sizeof() */
struct ValueType * Typ ;
char * Identifier ;
struct Value * TypeValue ;
if ( ! PrefixState )
ProgramFail ( Parser , " type not expected here " ) ;
PrefixState = FALSE ;
2011-02-11 23:04:51 -05:00
ParserCopy ( Parser , & PreState ) ;
2011-02-16 18:38:41 -05:00
TypeParse ( Parser , & Typ , & Identifier , NULL ) ;
2009-10-22 16:08:43 -04:00
TypeValue = VariableAllocValueFromType ( Parser , & TypeType , FALSE , NULL , FALSE ) ;
TypeValue - > Val - > Typ = Typ ;
ExpressionStackPushValueNode ( Parser , & StackTop , TypeValue ) ;
}
2009-03-08 03:56:28 -04:00
else
2009-04-14 02:55:00 -04:00
{
/* it isn't a token from an expression */
2011-02-11 23:04:51 -05:00
ParserCopy ( Parser , & PreState ) ;
2009-03-28 07:10:34 -04:00
Done = TRUE ;
2009-03-08 03:56:28 -04:00
}
} while ( ! Done ) ;
2009-03-08 04:40:05 -04:00
2009-04-14 04:44:47 -04:00
/* check that brackets have been closed */
if ( BracketPrecedence > 0 )
ProgramFail ( Parser , " brackets not closed " ) ;
2009-03-08 04:40:05 -04:00
/* scan and collapse the stack to precedence 0 */
2011-02-15 19:13:11 -05:00
ExpressionStackCollapse ( Parser , & StackTop , 0 , & IgnorePrecedence ) ;
2009-03-29 07:08:03 -04:00
/* fix up the stack and return the result if we're in run mode */
if ( StackTop ! = NULL )
{
/* all that should be left is a single value on the stack */
2009-03-30 07:16:40 -04:00
if ( Parser - > Mode = = RunModeRun )
2009-04-15 06:47:51 -04:00
{
2009-06-02 02:30:14 -04:00
if ( StackTop - > Order ! = OrderNone | | StackTop - > Next ! = NULL )
ProgramFail ( Parser , " invalid expression " ) ;
2009-10-04 12:22:19 -04:00
* Result = StackTop - > Val ;
2009-04-15 06:47:51 -04:00
HeapPopStack ( StackTop , sizeof ( struct ExpressionStack ) ) ;
}
else
2009-10-04 12:22:19 -04:00
HeapPopStack ( StackTop - > Val , sizeof ( struct ExpressionStack ) + sizeof ( struct Value ) + TypeStackSizeValue ( StackTop - > Val ) ) ;
2009-03-29 07:08:03 -04:00
}
2009-03-28 07:10:34 -04:00
2009-06-02 01:51:51 -04:00
debugf ( " ExpressionParse() done \n \n " ) ;
2009-04-15 06:47:51 -04:00
# ifdef DEBUG_EXPRESSIONS
ExpressionStackShow ( StackTop ) ;
# endif
2009-04-13 05:02:45 -04:00
return StackTop ! = NULL ;
2009-03-08 03:56:28 -04:00
}
2010-07-11 14:44:07 -04:00
/* do a parameterised macro call */
void ExpressionParseMacroCall ( struct ParseState * Parser , struct ExpressionStack * * StackTop , const char * MacroName , struct MacroDef * MDef )
{
struct Value * ReturnValue = NULL ;
struct Value * Param ;
struct Value * * ParamArray = NULL ;
int ArgCount ;
enum LexToken Token ;
if ( Parser - > Mode = = RunModeRun )
{
/* create a stack frame for this macro */
2011-02-10 18:50:05 -05:00
# ifndef NO_FP
2010-07-11 14:44:07 -04:00
ExpressionStackPushValueByType ( Parser , StackTop , & FPType ) ; /* largest return type there is */
2011-02-10 18:50:05 -05:00
# else
2011-02-11 23:23:37 -05:00
ExpressionStackPushValueByType ( Parser , StackTop , & IntType ) ; /* largest return type there is */
2011-02-10 18:50:05 -05:00
# endif
2010-07-11 14:44:07 -04:00
ReturnValue = ( * StackTop ) - > Val ;
HeapPushStackFrame ( ) ;
ParamArray = HeapAllocStack ( sizeof ( struct Value * ) * MDef - > NumParams ) ;
if ( ParamArray = = NULL )
ProgramFail ( Parser , " out of memory " ) ;
}
else
ExpressionPushInt ( Parser , StackTop , 0 ) ;
/* parse arguments */
ArgCount = 0 ;
do {
if ( ExpressionParse ( Parser , & Param ) )
{
if ( Parser - > Mode = = RunModeRun )
{
if ( ArgCount < MDef - > NumParams )
ParamArray [ ArgCount ] = Param ;
else
ProgramFail ( Parser , " too many arguments to %s() " , MacroName ) ;
}
ArgCount + + ;
Token = LexGetToken ( Parser , NULL , TRUE ) ;
if ( Token ! = TokenComma & & Token ! = TokenCloseBracket )
ProgramFail ( Parser , " comma expected " ) ;
}
else
{
/* end of argument list? */
Token = LexGetToken ( Parser , NULL , TRUE ) ;
if ( ! TokenCloseBracket )
ProgramFail ( Parser , " bad argument " ) ;
}
} while ( Token ! = TokenCloseBracket ) ;
if ( Parser - > Mode = = RunModeRun )
{
/* evaluate the macro */
struct ParseState MacroParser ;
int Count ;
struct Value * EvalValue ;
if ( ArgCount < MDef - > NumParams )
ProgramFail ( Parser , " not enough arguments to '%s' " , MacroName ) ;
if ( MDef - > Body . Pos = = NULL )
ProgramFail ( Parser , " '%s' is undefined " , MacroName ) ;
2011-02-11 23:04:51 -05:00
ParserCopy ( & MacroParser , & MDef - > Body ) ;
2011-02-16 18:38:41 -05:00
VariableStackFrameAdd ( Parser , MacroName , 0 ) ;
2010-07-11 14:44:07 -04:00
TopStackFrame - > NumParams = ArgCount ;
TopStackFrame - > ReturnValue = ReturnValue ;
for ( Count = 0 ; Count < MDef - > NumParams ; Count + + )
VariableDefine ( Parser , MDef - > ParamName [ Count ] , ParamArray [ Count ] , NULL , TRUE ) ;
ExpressionParse ( & MacroParser , & EvalValue ) ;
ExpressionAssign ( Parser , ReturnValue , EvalValue , TRUE , MacroName , 0 , FALSE ) ;
VariableStackFramePop ( Parser ) ;
HeapPopStackFrame ( ) ;
}
}
2009-03-08 03:56:28 -04:00
/* do a function call */
2011-02-15 19:13:11 -05:00
void ExpressionParseFunctionCall ( struct ParseState * Parser , struct ExpressionStack * * StackTop , const char * FuncName , int RunIt )
2009-03-08 03:56:28 -04:00
{
2009-04-18 21:15:01 -04:00
struct Value * ReturnValue = NULL ;
2009-03-08 03:56:28 -04:00
struct Value * FuncValue ;
struct Value * Param ;
2009-04-03 23:11:12 -04:00
struct Value * * ParamArray = NULL ;
2009-03-08 03:56:28 -04:00
int ArgCount ;
enum LexToken Token = LexGetToken ( Parser , NULL , TRUE ) ; /* open bracket */
2011-02-15 19:13:11 -05:00
enum RunMode OldMode = Parser - > Mode ;
2009-03-08 03:56:28 -04:00
2011-02-15 19:13:11 -05:00
if ( RunIt )
2009-04-14 02:55:00 -04:00
{
/* get the function definition */
2009-03-08 03:56:28 -04:00
VariableGet ( Parser , FuncName , & FuncValue ) ;
2010-07-11 14:44:07 -04:00
if ( FuncValue - > Typ - > Base = = TypeMacro )
{
/* this is actually a macro, not a function */
ExpressionParseMacroCall ( Parser , StackTop , FuncName , & FuncValue - > Val - > MacroDef ) ;
return ;
}
2009-03-08 03:56:28 -04:00
if ( FuncValue - > Typ - > Base ! = TypeFunction )
2009-04-23 21:02:25 -04:00
ProgramFail ( Parser , " %t is not a function - can't call " , FuncValue - > Typ ) ;
2009-03-08 03:56:28 -04:00
2009-04-04 22:24:00 -04:00
ExpressionStackPushValueByType ( Parser , StackTop , FuncValue - > Val - > FuncDef . ReturnType ) ;
2009-10-04 12:22:19 -04:00
ReturnValue = ( * StackTop ) - > Val ;
2009-03-08 03:56:28 -04:00
HeapPushStackFrame ( ) ;
2009-05-26 23:02:30 -04:00
ParamArray = HeapAllocStack ( sizeof ( struct Value * ) * FuncValue - > Val - > FuncDef . NumParams ) ;
2009-03-08 03:56:28 -04:00
if ( ParamArray = = NULL )
ProgramFail ( Parser , " out of memory " ) ;
}
2009-04-15 06:47:51 -04:00
else
2011-02-15 19:13:11 -05:00
{
2009-04-15 06:47:51 -04:00
ExpressionPushInt ( Parser , StackTop , 0 ) ;
2011-02-15 19:13:11 -05:00
Parser - > Mode = RunModeSkip ;
}
2009-03-08 03:56:28 -04:00
/* parse arguments */
ArgCount = 0 ;
do {
2011-02-15 19:13:11 -05:00
if ( RunIt & & ArgCount < FuncValue - > Val - > FuncDef . NumParams )
2009-06-02 01:51:51 -04:00
ParamArray [ ArgCount ] = VariableAllocValueFromType ( Parser , FuncValue - > Val - > FuncDef . ParamType [ ArgCount ] , FALSE , NULL , FALSE ) ;
2009-03-08 03:56:28 -04:00
if ( ExpressionParse ( Parser , & Param ) )
{
2011-02-15 19:13:11 -05:00
if ( RunIt )
2009-03-08 03:56:28 -04:00
{
2009-06-02 01:51:51 -04:00
if ( ArgCount < FuncValue - > Val - > FuncDef . NumParams )
2009-03-08 03:56:28 -04:00
{
2009-10-10 13:59:55 -04:00
ExpressionAssign ( Parser , ParamArray [ ArgCount ] , Param , TRUE , FuncName , ArgCount + 1 , FALSE ) ;
2009-06-02 01:51:51 -04:00
VariableStackPop ( Parser , Param ) ;
2009-03-08 03:56:28 -04:00
}
else
{
2009-06-02 01:51:51 -04:00
if ( ! FuncValue - > Val - > FuncDef . VarArgs )
ProgramFail ( Parser , " too many arguments to %s() " , FuncName ) ;
2009-05-26 23:02:30 -04:00
}
2009-03-08 03:56:28 -04:00
}
ArgCount + + ;
Token = LexGetToken ( Parser , NULL , TRUE ) ;
if ( Token ! = TokenComma & & Token ! = TokenCloseBracket )
ProgramFail ( Parser , " comma expected " ) ;
}
else
2009-04-14 02:55:00 -04:00
{
/* end of argument list? */
2009-03-08 03:56:28 -04:00
Token = LexGetToken ( Parser , NULL , TRUE ) ;
if ( ! TokenCloseBracket )
ProgramFail ( Parser , " bad argument " ) ;
}
2009-06-02 01:51:51 -04:00
2009-03-08 03:56:28 -04:00
} while ( Token ! = TokenCloseBracket ) ;
2011-02-15 19:13:11 -05:00
if ( RunIt )
2009-04-14 02:55:00 -04:00
{
/* run the function */
2009-03-08 03:56:28 -04:00
if ( ArgCount < FuncValue - > Val - > FuncDef . NumParams )
ProgramFail ( Parser , " not enough arguments to '%s' " , FuncName ) ;
if ( FuncValue - > Val - > FuncDef . Intrinsic = = NULL )
2009-04-14 02:55:00 -04:00
{
/* run a user-defined function */
2009-11-07 10:17:53 -05:00
struct ParseState FuncParser ;
2009-03-08 03:56:28 -04:00
int Count ;
2010-03-01 15:39:08 -05:00
if ( FuncValue - > Val - > FuncDef . Body . Pos = = NULL )
ProgramFail ( Parser , " '%s' is undefined " , FuncName ) ;
2011-02-11 23:04:51 -05:00
ParserCopy ( & FuncParser , & FuncValue - > Val - > FuncDef . Body ) ;
2011-02-16 18:38:41 -05:00
VariableStackFrameAdd ( Parser , FuncName , FuncValue - > Val - > FuncDef . Intrinsic ? FuncValue - > Val - > FuncDef . NumParams : 0 ) ;
2009-03-08 03:56:28 -04:00
TopStackFrame - > NumParams = ArgCount ;
2009-04-04 22:24:00 -04:00
TopStackFrame - > ReturnValue = ReturnValue ;
2009-03-08 03:56:28 -04:00
for ( Count = 0 ; Count < FuncValue - > Val - > FuncDef . NumParams ; Count + + )
2009-06-02 01:51:51 -04:00
VariableDefine ( Parser , FuncValue - > Val - > FuncDef . ParamName [ Count ] , ParamArray [ Count ] , NULL , TRUE ) ;
2009-03-08 03:56:28 -04:00
2009-11-22 06:36:15 -05:00
if ( ParseStatement ( & FuncParser , TRUE ) ! = ParseResultOk )
2009-03-08 03:56:28 -04:00
ProgramFail ( & FuncParser , " function body expected " ) ;
2011-02-20 23:44:16 -05:00
if ( RunIt )
{
if ( FuncParser . Mode = = RunModeRun & & FuncValue - > Val - > FuncDef . ReturnType ! = & VoidType )
ProgramFail ( & FuncParser , " no value returned from a function returning %t " , FuncValue - > Val - > FuncDef . ReturnType ) ;
2009-03-08 03:56:28 -04:00
2011-02-20 23:44:16 -05:00
else if ( FuncParser . Mode = = RunModeGoto )
ProgramFail ( & FuncParser , " couldn't find goto label '%s' " , FuncParser . SearchGotoLabel ) ;
}
2009-03-08 03:56:28 -04:00
VariableStackFramePop ( Parser ) ;
}
else
2009-04-04 22:24:00 -04:00
FuncValue - > Val - > FuncDef . Intrinsic ( Parser , ReturnValue , ParamArray , ArgCount ) ;
2009-03-08 03:56:28 -04:00
HeapPopStackFrame ( ) ;
}
2011-02-15 19:13:11 -05:00
Parser - > Mode = OldMode ;
2009-03-08 03:56:28 -04:00
}
2009-04-04 22:24:00 -04:00
2011-02-15 19:13:11 -05:00
/* parse an expression */
2009-11-07 16:05:15 -05:00
long ExpressionParseInt ( struct ParseState * Parser )
2009-04-04 22:24:00 -04:00
{
struct Value * Val ;
2009-11-07 16:05:15 -05:00
long Result = 0 ;
2009-04-04 22:24:00 -04:00
if ( ! ExpressionParse ( Parser , & Val ) )
ProgramFail ( Parser , " expression expected " ) ;
if ( Parser - > Mode = = RunModeRun )
{
2009-05-27 01:03:48 -04:00
if ( ! IS_NUMERIC_COERCIBLE ( Val ) )
2009-04-23 21:02:25 -04:00
ProgramFail ( Parser , " integer value expected instead of %t " , Val - > Typ ) ;
2009-04-04 22:24:00 -04:00
2009-10-25 07:54:34 -04:00
Result = ExpressionCoerceInteger ( Val ) ;
2009-04-04 22:24:00 -04:00
VariableStackPop ( Parser , Val ) ;
}
return Result ;
}