Stack handling for new expression evaluator

git-svn-id: http://picoc.googlecode.com/svn/trunk@200 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-03-12 02:21:12 +00:00
parent 48a6472c68
commit 36e58ab475

View file

@ -1,5 +1,10 @@
#include "picoc.h" #include "picoc.h"
/* whether evaluation is left to right for a given precedence level */
#define IS_LEFT_TO_RIGHT(p) ((p) != 2 && (p) != 3 && (p) != 14)
/* local prototypes */ /* local prototypes */
void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName); void ExpressionParseFunctionCall(struct ParseState *Parser, struct Value **Result, const char *FuncName);
@ -396,6 +401,24 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
} }
#else #else
enum OperatorOrder
{
OrderPrefix,
OrderInfix,
OrderPostfix
};
/* a stack of expressions we use in evaluation */
struct ExpressionStack
{
struct ExprStack *Next; /* the next lower item on the stack */
struct Value *Val; /* the value for this stack node */
enum EvaluationOrder Order; /* the evaluation order of this operator */
enum LexToken Op; /* the operator */
short Precedence; /* the operator precedence of this node */
short LeftToRight; /* indicates left to right evaluation, otherwise right to left */
};
/* operator precedence definitions */ /* operator precedence definitions */
struct OpPrecedence struct OpPrecedence
{ {
@ -433,13 +456,25 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
} }
/* push an operator on to the expression stack */ /* push an operator on to the expression stack */
void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum OperatorOrder Order, enum LexToken Token, int Precedence) void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum OperatorOrder Order, enum LexToken Token, int Precedence, int LeftToRight)
{ {
struct ExpressionStack *StackNode = VariableAlloc(Parser, sizeof(struct ExpressionStack), FALSE);
StackNode->Next = *StackTop;
StackNode->Order = Order;
StackNode->Op = Token;
StackNode->Precedence = Precedence;
StackNode->LeftToRight = LeftToRight;
*StackTop = StackNode;
} }
/* push a value on to the expression stack */ /* push a value on to the expression stack */
void ExpressionStackPushValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue) void ExpressionStackPushValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue)
{ {
struct Value *ValueLoc = VariableAllocValueAndCopy(Parser, PushValue, FALSE);
struct ExpressionStack *StackNode = VariableAlloc(Parser, sizeof(struct ExpressionStack), FALSE);
StackNode->Next = *StackTop;
StackNode->Val = ValueLoc;
*StackTop = StackNode;
} }
/* parse an expression with operator precedence */ /* parse an expression with operator precedence */
@ -449,6 +484,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
bool PrefixState = false; bool PrefixState = false;
bool Done = false; bool Done = false;
int BracketPrecedence = 0; int BracketPrecedence = 0;
int LocalPrecedence;
int Precedence = 0; int Precedence = 0;
struct ExpressionStack *StackTop = NULL; struct ExpressionStack *StackTop = NULL;
@ -464,11 +500,12 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
{ {
Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PrefixPrecedence; LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence;
Precedence = BracketPrecedence + LocalPrecedence;
if (Token == TokenOpenBracket || Token == TokenLeftSquareBracket) if (Token == TokenOpenBracket || Token == TokenLeftSquareBracket)
{ /* boost the bracket operator precedence, then push */ { /* boost the bracket operator precedence, then push */
BracketPrecedence += BRACKET_PREDECENCE; BracketPrecedence += BRACKET_PREDECENCE;
ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence, IS_LEFT_TO_RIGHT(LocalPrecedence));
} }
else else
{ /* scan and collapse the stack to the precedence of this operator, then push */ { /* scan and collapse the stack to the precedence of this operator, then push */