New expression system now successfully evaluates simple expressions.
git-svn-id: http://picoc.googlecode.com/svn/trunk@228 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
45054b4498
commit
1877ab67aa
213
expression.c
213
expression.c
|
@ -11,8 +11,17 @@
|
||||||
#define COERCE_INTEGER(v) ((v)->Val->Integer)
|
#define COERCE_INTEGER(v) ((v)->Val->Integer)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ASSIGN_INT(d,s) { if (!(d)->IsLValue) ProgramFail(Parser, "can't assign to this"); ResultInt = (s); (d)->Val->Integer = ResultInt; }
|
||||||
|
|
||||||
#define BRACKET_PRECEDENCE 20
|
#define BRACKET_PRECEDENCE 20
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXPRESSIONS
|
||||||
|
#define debugf printf
|
||||||
|
#else
|
||||||
|
void debugf(char *Format, ...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
/* local prototypes */
|
/* local prototypes */
|
||||||
|
@ -280,7 +289,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
if (TotalValue->Val->Array.Size != CurrentValue->Val->Array.Size)
|
if (TotalValue->Val->Array.Size != CurrentValue->Val->Array.Size)
|
||||||
ProgramFail(Parser, "incompatible array sizes in assignment");
|
ProgramFail(Parser, "incompatible array sizes in assignment");
|
||||||
|
|
||||||
//memcpy(TotalValue->Val->Array.Data, CurrentValue->Val->Array.Data, CurrentValue->Typ->Sizeof * CurrentValue->Val->Array.Size);
|
// XXX - fix this memcpy(TotalValue->Val->Array.Data, CurrentValue->Val->Array.Data, CurrentValue->Typ->Sizeof * CurrentValue->Val->Array.Size);
|
||||||
}
|
}
|
||||||
VariableStackPop(Parser, CurrentValue);
|
VariableStackPop(Parser, CurrentValue);
|
||||||
*Result = TotalValue;
|
*Result = TotalValue;
|
||||||
|
@ -521,10 +530,13 @@ enum OperatorOrder
|
||||||
struct ExpressionStack
|
struct ExpressionStack
|
||||||
{
|
{
|
||||||
struct ExpressionStack *Next; /* the next lower item on the stack */
|
struct ExpressionStack *Next; /* the next lower item on the stack */
|
||||||
|
union
|
||||||
|
{
|
||||||
struct Value *Val; /* the value for this stack node */
|
struct Value *Val; /* the value for this stack node */
|
||||||
enum OperatorOrder Order; /* the evaluation order of this operator */
|
|
||||||
enum LexToken Op; /* the operator */
|
enum LexToken Op; /* the operator */
|
||||||
int Precedence; /* the operator precedence of this node */
|
} p;
|
||||||
|
short unsigned int Precedence; /* the operator precedence of this node */
|
||||||
|
unsigned char Order; /* the evaluation order of this operator */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* operator precedence definitions */
|
/* operator precedence definitions */
|
||||||
|
@ -533,48 +545,102 @@ struct OpPrecedence
|
||||||
unsigned char PrefixPrecedence:4;
|
unsigned char PrefixPrecedence:4;
|
||||||
unsigned char PostfixPrecedence:4;
|
unsigned char PostfixPrecedence:4;
|
||||||
unsigned char InfixPrecedence:4;
|
unsigned char InfixPrecedence:4;
|
||||||
|
char *Name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct OpPrecedence OperatorPrecedence[] =
|
static struct OpPrecedence OperatorPrecedence[] =
|
||||||
{
|
{
|
||||||
/* TokenNone, */ { 0, 0, 0 },
|
/* TokenNone, */ { 0, 0, 0, "none" },
|
||||||
/* TokenComma, */ { 0, 0, 1 },
|
/* TokenComma, */ { 0, 0, 0, "," },
|
||||||
/* TokenAssign, */ { 0, 0, 2 }, /* TokenAddAssign, */ { 0, 0, 2 }, /* TokenSubtractAssign, */ { 0, 0, 2 },
|
/* TokenAssign, */ { 0, 0, 2, "=" }, /* TokenAddAssign, */ { 0, 0, 2, "+=" }, /* TokenSubtractAssign, */ { 0, 0, 2, "-=" },
|
||||||
/* TokenMultiplyAssign, */ { 0, 0, 2 }, /* TokenDivideAssign, */ { 0, 0, 2 }, /* TokenModulusAssign, */ { 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 },
|
/* TokenShiftLeftAssign, */ { 0, 0, 2, "<<=" }, /* TokenShiftRightAssign, */ { 0, 0, 2, ">>=" }, /* TokenArithmeticAndAssign, */ { 0, 0, 2, "&=" },
|
||||||
/* TokenArithmeticOrAssign, */ { 0, 0, 2 }, /* TokenArithmeticExorAssign, */ { 0, 0, 2 },
|
/* TokenArithmeticOrAssign, */ { 0, 0, 2, "|=" }, /* TokenArithmeticExorAssign, */ { 0, 0, 2, "^=" },
|
||||||
/* TokenQuestionMark, */ { 0, 0, 3 }, /* TokenColon, */ { 0, 0, 3 },
|
/* TokenQuestionMark, */ { 0, 0, 3, "?" }, /* TokenColon, */ { 0, 0, 3, ":" },
|
||||||
/* TokenLogicalOr, */ { 0, 0, 4 },
|
/* TokenLogicalOr, */ { 0, 0, 4, "||" },
|
||||||
/* TokenLogicalAnd, */ { 0, 0, 5 },
|
/* TokenLogicalAnd, */ { 0, 0, 5, "&&" },
|
||||||
/* TokenArithmeticOr, */ { 0, 0, 6 },
|
/* TokenArithmeticOr, */ { 0, 0, 6, "|" },
|
||||||
/* TokenArithmeticExor, */ { 0, 0, 7 },
|
/* TokenArithmeticExor, */ { 0, 0, 7, "^" },
|
||||||
/* TokenAmpersand, */ { 14, 0, 8 },
|
/* TokenAmpersand, */ { 14, 0, 8, "&" },
|
||||||
/* TokenEqual, */ { 0, 0, 9 }, /* TokenNotEqual, */ { 0, 0, 9 },
|
/* TokenEqual, */ { 0, 0, 9, "==" }, /* TokenNotEqual, */ { 0, 0, 9, "!=" },
|
||||||
/* TokenLessThan, */ { 0, 0, 10 }, /* TokenGreaterThan, */ { 0, 0, 10 }, /* TokenLessEqual, */ { 0, 0, 10 }, /* TokenGreaterEqual, */ { 0, 0, 10 },
|
/* TokenLessThan, */ { 0, 0, 10, "<" }, /* TokenGreaterThan, */ { 0, 0, 10, ">" }, /* TokenLessEqual, */ { 0, 0, 10, "<=" }, /* TokenGreaterEqual, */ { 0, 0, 10, ">=" },
|
||||||
/* TokenShiftLeft, */ { 0, 0, 11 }, /* TokenShiftRight, */ { 0, 0, 11 },
|
/* TokenShiftLeft, */ { 0, 0, 11, "<<" }, /* TokenShiftRight, */ { 0, 0, 11, ">>" },
|
||||||
/* TokenPlus, */ { 14, 0, 12 }, /* TokenMinus, */ { 14, 0, 12 },
|
/* TokenPlus, */ { 14, 0, 12, "+" }, /* TokenMinus, */ { 14, 0, 12, "-" },
|
||||||
/* TokenAsterisk, */ { 14, 0, 13 }, /* TokenSlash, */ { 0, 0, 13 }, /* TokenModulus, */ { 0, 0, 13 },
|
/* TokenAsterisk, */ { 14, 0, 13, "*" }, /* TokenSlash, */ { 0, 0, 13, "/" }, /* TokenModulus, */ { 0, 0, 13, "%" },
|
||||||
/* TokenIncrement, */ { 14, 15, 0 }, /* TokenDecrement, */ { 14, 15, 0 }, /* TokenUnaryNot, */ { 14, 0, 0 }, /* TokenUnaryExor, */ { 14, 0, 0 }, /* TokenSizeof, */ { 14, 0, 0 },
|
/* TokenIncrement, */ { 14, 15, 0, "++" }, /* TokenDecrement, */ { 14, 15, 0, "--" }, /* TokenUnaryNot, */ { 14, 0, 0, "!" }, /* TokenUnaryExor, */ { 14, 0, 0, "~" }, /* TokenSizeof, */ { 14, 0, 0, "sizeof" },
|
||||||
/* TokenLeftSquareBracket, */ { 15, 0, 0 }, /* TokenRightSquareBracket, */ { 0, 15, 0 }, /* TokenDot, */ { 0, 0, 15 }, /* TokenArrow, */ { 0, 0, 15 },
|
/* TokenLeftSquareBracket, */ { 15, 0, 0, "[" }, /* TokenRightSquareBracket, */ { 0, 15, 0, "]" }, /* TokenDot, */ { 0, 0, 15, "." }, /* TokenArrow, */ { 0, 0, 15, "->" },
|
||||||
/* TokenOpenBracket, */ { 15, 0, 0 }, /* TokenCloseBracket, */ { 0, 15, 0 }
|
/* TokenOpenBracket, */ { 15, 0, 0, "(" }, /* TokenCloseBracket, */ { 0, 15, 0, ")" }
|
||||||
};
|
};
|
||||||
|
|
||||||
void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *FuncName);
|
void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionStack **StackTop, const char *FuncName);
|
||||||
|
|
||||||
|
#ifdef DEBUG_EXPRESSIONS
|
||||||
|
/* show the contents of the expression stack */
|
||||||
|
void ExpressionStackShow(struct ExpressionStack *StackTop)
|
||||||
|
{
|
||||||
|
printf("Expression stack: ");
|
||||||
|
|
||||||
|
while (StackTop != NULL)
|
||||||
|
{
|
||||||
|
if (StackTop->Order == OrderNone)
|
||||||
|
{ /* it's a value */
|
||||||
|
if (StackTop->p.Val->IsLValue)
|
||||||
|
printf("lvalue=");
|
||||||
|
else
|
||||||
|
printf("value=");
|
||||||
|
|
||||||
|
switch (StackTop->p.Val->Typ->Base)
|
||||||
|
{
|
||||||
|
case TypeInt: case TypeChar: printf("%d:int", StackTop->p.Val->Val->Integer); break;
|
||||||
|
case TypeFP: printf("%f:fp", StackTop->p.Val->Val->FP); break;
|
||||||
|
case TypeFunction: printf("%s:function", StackTop->p.Val->Val->Identifier); break;
|
||||||
|
case TypeMacro: printf("%s:macro", StackTop->p.Val->Val->Identifier); break;
|
||||||
|
case TypePointer:
|
||||||
|
if (StackTop->p.Val->Typ->FromType->Base == TypeChar)
|
||||||
|
printf("\"%s\":string", (char *)StackTop->p.Val->Val->Pointer.Segment->Val->Array.Data);
|
||||||
|
else
|
||||||
|
printf("ptr(0x%lx,%d)", (long)StackTop->p.Val->Val->Pointer.Segment, StackTop->p.Val->Val->Pointer.Offset);
|
||||||
|
break;
|
||||||
|
case TypeArray: printf("array"); break;
|
||||||
|
case TypeStruct: printf("%s:struct", StackTop->p.Val->Val->Identifier); break;
|
||||||
|
case TypeUnion: printf("%s:union", StackTop->p.Val->Val->Identifier); break;
|
||||||
|
case TypeEnum: printf("%s:enum", StackTop->p.Val->Val->Identifier); break;
|
||||||
|
default: printf("unknown"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* it's an operator */
|
||||||
|
printf("op='%s' %s %d", OperatorPrecedence[(int)StackTop->p.Op].Name,
|
||||||
|
(StackTop->Order == OrderPrefix) ? "prefix" : ((StackTop->Order == OrderPostfix) ? "postfix" : "infix"),
|
||||||
|
StackTop->Precedence);
|
||||||
|
}
|
||||||
|
|
||||||
|
StackTop = StackTop->Next;
|
||||||
|
if (StackTop != NULL)
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* push a node on to the expression stack */
|
/* push a node on to the expression stack */
|
||||||
void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *ValueLoc)
|
void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *ValueLoc)
|
||||||
{
|
{
|
||||||
struct ExpressionStack *StackNode = VariableAlloc(Parser, sizeof(struct ExpressionStack), FALSE);
|
struct ExpressionStack *StackNode = VariableAlloc(Parser, sizeof(struct ExpressionStack), FALSE);
|
||||||
StackNode->Next = *StackTop;
|
StackNode->Next = *StackTop;
|
||||||
StackNode->Val = ValueLoc;
|
StackNode->p.Val = ValueLoc;
|
||||||
*StackTop = StackNode;
|
*StackTop = StackNode;
|
||||||
|
#ifdef DEBUG_EXPRESSIONS
|
||||||
|
ExpressionStackShow(*StackTop);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push a blank value on to the expression stack by type */
|
/* push a blank value on to the expression stack by type */
|
||||||
void ExpressionStackPushValueByType(struct ParseState *Parser, struct ExpressionStack **StackTop, struct ValueType *PushType)
|
void ExpressionStackPushValueByType(struct ParseState *Parser, struct ExpressionStack **StackTop, struct ValueType *PushType)
|
||||||
{
|
{
|
||||||
struct Value *ValueLoc = VariableAllocValueFromType(Parser, PushType, FALSE, NULL);
|
struct Value *ValueLoc = VariableAllocValueFromType(Parser, PushType, FALSE, NULL);
|
||||||
|
debugf("ExpressionStackPushValueByType()\n");
|
||||||
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,6 +648,14 @@ void ExpressionStackPushValueByType(struct ParseState *Parser, struct Expression
|
||||||
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 Value *ValueLoc = VariableAllocValueAndCopy(Parser, PushValue, FALSE);
|
||||||
|
debugf("ExpressionStackPushValue()\n");
|
||||||
|
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionStackPushLValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue)
|
||||||
|
{
|
||||||
|
struct Value *ValueLoc = VariableAllocValueShared(Parser, PushValue);
|
||||||
|
debugf("ExpressionStackPushLValue()\n");
|
||||||
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,6 +663,7 @@ void ExpressionPushInt(struct ParseState *Parser, struct ExpressionStack **Stack
|
||||||
{
|
{
|
||||||
struct Value *ValueLoc = VariableAllocValueFromType(Parser, &IntType, FALSE, NULL);
|
struct Value *ValueLoc = VariableAllocValueFromType(Parser, &IntType, FALSE, NULL);
|
||||||
ValueLoc->Val->Integer = IntValue;
|
ValueLoc->Val->Integer = IntValue;
|
||||||
|
debugf("ExpressionPushInt()\n");
|
||||||
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,6 +671,7 @@ void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackT
|
||||||
{
|
{
|
||||||
struct Value *ValueLoc = VariableAllocValueFromType(Parser, &FPType, FALSE, NULL);
|
struct Value *ValueLoc = VariableAllocValueFromType(Parser, &FPType, FALSE, NULL);
|
||||||
ValueLoc->Val->FP = FPValue;
|
ValueLoc->Val->FP = FPValue;
|
||||||
|
debugf("ExpressionPushFP()\n");
|
||||||
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,6 +681,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
|
||||||
struct Value *TempLValue;
|
struct Value *TempLValue;
|
||||||
struct Value *Result;
|
struct Value *Result;
|
||||||
|
|
||||||
|
debugf("ExpressionPrefixOperator()\n");
|
||||||
switch (Op)
|
switch (Op)
|
||||||
{
|
{
|
||||||
case TokenAmpersand:
|
case TokenAmpersand:
|
||||||
|
@ -622,8 +699,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
|
||||||
if (TopValue->Typ->Base != TypePointer)
|
if (TopValue->Typ->Base != TypePointer)
|
||||||
ProgramFail(Parser, "can't dereference this non-pointer");
|
ProgramFail(Parser, "can't dereference this non-pointer");
|
||||||
|
|
||||||
Result = VariableAllocValueShared(Parser, TopValue->Val->Pointer.Segment);
|
ExpressionStackPushLValue(Parser, StackTop, TopValue->Val->Pointer.Segment);
|
||||||
ExpressionStackPushValueNode(Parser, StackTop, Result);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TokenSizeof:
|
case TokenSizeof:
|
||||||
|
@ -686,6 +762,7 @@ XXX - finish this
|
||||||
/* evaluate a postfix operator */
|
/* evaluate a postfix operator */
|
||||||
void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue)
|
void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *TopValue)
|
||||||
{
|
{
|
||||||
|
debugf("ExpressionPostfixOperator()\n");
|
||||||
if (IS_INTEGER_COERCIBLE(TopValue))
|
if (IS_INTEGER_COERCIBLE(TopValue))
|
||||||
{
|
{
|
||||||
int ResultInt;
|
int ResultInt;
|
||||||
|
@ -709,6 +786,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
|
||||||
int ResultIsInt = FALSE;
|
int ResultIsInt = FALSE;
|
||||||
int ResultInt;
|
int ResultInt;
|
||||||
|
|
||||||
|
debugf("ExpressionInfixOperator()\n");
|
||||||
switch (Op)
|
switch (Op)
|
||||||
{
|
{
|
||||||
case TokenComma:
|
case TokenComma:
|
||||||
|
@ -722,16 +800,17 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
|
||||||
int BottomInt = COERCE_INTEGER(BottomValue);
|
int BottomInt = COERCE_INTEGER(BottomValue);
|
||||||
switch (Op)
|
switch (Op)
|
||||||
{
|
{
|
||||||
case TokenAddAssign: break; // XXX
|
case TokenAssign: ASSIGN_INT(BottomValue, TopInt); break;
|
||||||
case TokenSubtractAssign: break; // XXX
|
case TokenAddAssign: ASSIGN_INT(BottomValue, BottomInt + TopInt); break;
|
||||||
case TokenMultiplyAssign: break; // XXX
|
case TokenSubtractAssign: ASSIGN_INT(BottomValue, BottomInt - TopInt); break;
|
||||||
case TokenDivideAssign: break; // XXX
|
case TokenMultiplyAssign: ASSIGN_INT(BottomValue, BottomInt * TopInt); break;
|
||||||
case TokenModulusAssign: break; // XXX
|
case TokenDivideAssign: ASSIGN_INT(BottomValue, BottomInt / TopInt); break;
|
||||||
case TokenShiftLeftAssign: break; // XXX
|
case TokenModulusAssign: ASSIGN_INT(BottomValue, BottomInt % TopInt); break;
|
||||||
case TokenShiftRightAssign: break; // XXX
|
case TokenShiftLeftAssign: ASSIGN_INT(BottomValue, BottomInt << TopInt); break;
|
||||||
case TokenArithmeticAndAssign: break; // XXX
|
case TokenShiftRightAssign: ASSIGN_INT(BottomValue, BottomInt >> TopInt); break;
|
||||||
case TokenArithmeticOrAssign: break; // XXX
|
case TokenArithmeticAndAssign: ASSIGN_INT(BottomValue, BottomInt & TopInt); break;
|
||||||
case TokenArithmeticExorAssign: break; // XXX
|
case TokenArithmeticOrAssign: ASSIGN_INT(BottomValue, BottomInt | TopInt); break;
|
||||||
|
case TokenArithmeticExorAssign: ASSIGN_INT(BottomValue, BottomInt ^ TopInt); break;
|
||||||
case TokenQuestionMark: break; // XXX
|
case TokenQuestionMark: break; // XXX
|
||||||
case TokenColon: break; // XXX
|
case TokenColon: break; // XXX
|
||||||
case TokenLogicalOr: ResultInt = BottomInt || TopInt; break;
|
case TokenLogicalOr: ResultInt = BottomInt || TopInt; break;
|
||||||
|
@ -834,14 +913,20 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
|
||||||
struct ExpressionStack *TopStackNode = *StackTop;
|
struct ExpressionStack *TopStackNode = *StackTop;
|
||||||
struct ExpressionStack *TopOperatorNode;
|
struct ExpressionStack *TopOperatorNode;
|
||||||
|
|
||||||
|
debugf("ExpressionStackCollapse():\n");
|
||||||
|
#ifdef DEBUG_EXPRESSIONS
|
||||||
|
ExpressionStackShow(*StackTop);
|
||||||
|
#endif
|
||||||
while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence)
|
while (TopStackNode != NULL && TopStackNode->Next != NULL && FoundPrecedence >= Precedence)
|
||||||
{
|
{
|
||||||
/* find the top operator on the stack */
|
/* find the top operator on the stack */
|
||||||
if (TopStackNode->Val != NULL)
|
if (TopStackNode->p.Val != NULL)
|
||||||
TopOperatorNode = TopStackNode->Next;
|
TopOperatorNode = TopStackNode->Next;
|
||||||
else
|
else
|
||||||
TopOperatorNode = TopStackNode;
|
TopOperatorNode = TopStackNode;
|
||||||
|
|
||||||
|
FoundPrecedence = TopOperatorNode->Precedence;
|
||||||
|
|
||||||
/* does it have a high enough precedence? */
|
/* does it have a high enough precedence? */
|
||||||
if (FoundPrecedence >= Precedence && TopOperatorNode != NULL)
|
if (FoundPrecedence >= Precedence && TopOperatorNode != NULL)
|
||||||
{
|
{
|
||||||
|
@ -850,45 +935,54 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack *
|
||||||
{
|
{
|
||||||
case OrderPrefix:
|
case OrderPrefix:
|
||||||
/* prefix evaluation */
|
/* prefix evaluation */
|
||||||
TopValue = TopStackNode->Val;
|
debugf("prefix evaluation\n");
|
||||||
|
TopValue = TopStackNode->p.Val;
|
||||||
|
|
||||||
/* pop the value and then the prefix operator - assume they'll still be there until we're done */
|
/* pop the value and then the prefix operator - assume they'll still be there until we're done */
|
||||||
*StackTop = TopOperatorNode->Next;
|
*StackTop = TopOperatorNode->Next;
|
||||||
HeapPopStack(TopOperatorNode, sizeof(struct ExpressionStack)*2 + TypeStackSizeValue(TopValue));
|
HeapPopStack(TopOperatorNode, sizeof(struct ExpressionStack)*2 + sizeof(struct Value) + TypeStackSizeValue(TopValue));
|
||||||
|
|
||||||
/* do the prefix operation */
|
/* do the prefix operation */
|
||||||
ExpressionPrefixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue);
|
ExpressionPrefixOperator(Parser, StackTop, TopOperatorNode->p.Op, TopValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OrderPostfix:
|
case OrderPostfix:
|
||||||
/* postfix evaluation */
|
/* postfix evaluation */
|
||||||
TopValue = TopStackNode->Next->Val;
|
debugf("postfix evaluation\n");
|
||||||
|
TopValue = TopStackNode->Next->p.Val;
|
||||||
|
|
||||||
/* pop the prefix operator and then the value - assume they'll still be there until we're done */
|
/* pop the prefix operator and then the value - assume they'll still be there until we're done */
|
||||||
*StackTop = TopStackNode->Next->Next;
|
*StackTop = TopStackNode->Next->Next;
|
||||||
HeapPopStack(TopOperatorNode, sizeof(struct ExpressionStack)*2 + TypeStackSizeValue(TopValue));
|
HeapPopStack(TopOperatorNode, sizeof(struct ExpressionStack)*2 + sizeof(struct Value) + TypeStackSizeValue(TopValue));
|
||||||
|
|
||||||
/* do the postfix operation */
|
/* do the postfix operation */
|
||||||
ExpressionPostfixOperator(Parser, StackTop, TopOperatorNode->Op, TopValue);
|
ExpressionPostfixOperator(Parser, StackTop, TopOperatorNode->p.Op, TopValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OrderInfix:
|
case OrderInfix:
|
||||||
/* infix evaluation */
|
/* infix evaluation */
|
||||||
TopValue = TopStackNode->Val;
|
debugf("infix evaluation\n");
|
||||||
BottomValue = TopOperatorNode->Next->Val;
|
TopValue = TopStackNode->p.Val;
|
||||||
|
BottomValue = TopOperatorNode->Next->p.Val;
|
||||||
|
|
||||||
/* pop a value, the operator and another value */
|
/* pop a value, the operator and another value - assume they'll still be there until we're done */
|
||||||
HeapPopStack(TopOperatorNode, sizeof(struct ExpressionStack)*3 + TypeStackSizeValue(TopValue) + TypeStackSizeValue(BottomValue));
|
HeapPopStack(BottomValue, sizeof(struct ExpressionStack)*3 + sizeof(struct Value)*2 + TypeStackSizeValue(TopValue) + TypeStackSizeValue(BottomValue));
|
||||||
|
*StackTop = TopOperatorNode->Next->Next;
|
||||||
|
|
||||||
/* do the infix operation */
|
/* do the infix operation */
|
||||||
ExpressionInfixOperator(Parser, StackTop, TopOperatorNode->Op, BottomValue, TopValue);
|
ExpressionInfixOperator(Parser, StackTop, TopOperatorNode->p.Op, BottomValue, TopValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OrderNone:
|
case OrderNone:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_EXPRESSIONS
|
||||||
|
ExpressionStackShow(*StackTop);
|
||||||
|
#endif
|
||||||
|
TopStackNode = *StackTop;
|
||||||
}
|
}
|
||||||
|
debugf("ExpressionStackCollapse() finished\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push an operator on to the expression stack */
|
/* push an operator on to the expression stack */
|
||||||
|
@ -897,9 +991,13 @@ void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionSta
|
||||||
struct ExpressionStack *StackNode = VariableAlloc(Parser, sizeof(struct ExpressionStack), FALSE);
|
struct ExpressionStack *StackNode = VariableAlloc(Parser, sizeof(struct ExpressionStack), FALSE);
|
||||||
StackNode->Next = *StackTop;
|
StackNode->Next = *StackTop;
|
||||||
StackNode->Order = Order;
|
StackNode->Order = Order;
|
||||||
StackNode->Op = Token;
|
StackNode->p.Op = Token;
|
||||||
StackNode->Precedence = Precedence;
|
StackNode->Precedence = Precedence;
|
||||||
*StackTop = StackNode;
|
*StackTop = StackNode;
|
||||||
|
debugf("ExpressionStackPushOperator()\n");
|
||||||
|
#ifdef DEBUG_EXPRESSIONS
|
||||||
|
ExpressionStackShow(*StackTop);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse an expression with operator precedence */
|
/* parse an expression with operator precedence */
|
||||||
|
@ -912,12 +1010,13 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
int LocalPrecedence;
|
int LocalPrecedence;
|
||||||
int Precedence = 0;
|
int Precedence = 0;
|
||||||
struct ExpressionStack *StackTop = NULL;
|
struct ExpressionStack *StackTop = NULL;
|
||||||
|
debugf("ExpressionParse():\n");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
struct ParseState PreState = *Parser;
|
struct ParseState PreState = *Parser;
|
||||||
enum LexToken Token = LexGetToken(Parser, &LexValue, TRUE);
|
enum LexToken Token = LexGetToken(Parser, &LexValue, TRUE);
|
||||||
if ((int)Token <= (int)TokenCloseBracket)
|
if ((int)Token > TokenComma && (int)Token <= (int)TokenCloseBracket)
|
||||||
{ /* it's an operator with precedence */
|
{ /* it's an operator with precedence */
|
||||||
if (PrefixState)
|
if (PrefixState)
|
||||||
{ /* expect a prefix operator */
|
{ /* expect a prefix operator */
|
||||||
|
@ -949,6 +1048,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
case TokenCloseBracket:
|
case TokenCloseBracket:
|
||||||
if (BracketPrecedence == 0)
|
if (BracketPrecedence == 0)
|
||||||
{ /* assume this bracket is after the end of the expression */
|
{ /* assume this bracket is after the end of the expression */
|
||||||
|
*Parser = PreState;
|
||||||
Done = TRUE;
|
Done = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -981,7 +1081,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
|
|
||||||
/* for right to left order, only go down to the next higher precedence so we evaluate it in reverse order */
|
/* 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 */
|
/* for left to right order, collapse down to this precedence so we evaluate it in forward order */
|
||||||
if (IS_LEFT_TO_RIGHT(Precedence))
|
if (IS_LEFT_TO_RIGHT(OperatorPrecedence[(int)Token].InfixPrecedence))
|
||||||
ExpressionStackCollapse(Parser, &StackTop, Precedence);
|
ExpressionStackCollapse(Parser, &StackTop, Precedence);
|
||||||
else
|
else
|
||||||
ExpressionStackCollapse(Parser, &StackTop, Precedence+1);
|
ExpressionStackCollapse(Parser, &StackTop, Precedence+1);
|
||||||
|
@ -1018,14 +1118,16 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
ProgramFail(Parser, "a void value isn't much use here");
|
ProgramFail(Parser, "a void value isn't much use here");
|
||||||
else
|
else
|
||||||
{ /* it's a value variable */
|
{ /* it's a value variable */
|
||||||
ExpressionStackPushValue(Parser, &StackTop, VariableValue);
|
ExpressionStackPushLValue(Parser, &StackTop, VariableValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* push a dummy value */
|
else /* push a dummy value */
|
||||||
ExpressionStackPushValueByType(Parser, &StackTop, &VoidType);
|
ExpressionStackPushValueByType(Parser, &StackTop, &VoidType);
|
||||||
|
|
||||||
|
PrefixState = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((int)Token <= (int)TokenCharacterConstant)
|
else if ((int)Token > TokenComma && (int)Token <= (int)TokenCharacterConstant)
|
||||||
{ /* it's a value of some sort, push it */
|
{ /* it's a value of some sort, push it */
|
||||||
if (!PrefixState)
|
if (!PrefixState)
|
||||||
ProgramFail(Parser, "value not expected here");
|
ProgramFail(Parser, "value not expected here");
|
||||||
|
@ -1049,11 +1151,12 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
|
||||||
{
|
{
|
||||||
/* all that should be left is a single value on the stack */
|
/* all that should be left is a single value on the stack */
|
||||||
if (Parser->Mode == RunModeRun)
|
if (Parser->Mode == RunModeRun)
|
||||||
*Result = StackTop->Val;
|
*Result = StackTop->p.Val;
|
||||||
|
|
||||||
HeapPopStack(StackTop, sizeof(struct ExpressionStack));
|
HeapPopStack(StackTop, sizeof(struct ExpressionStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugf("ExpressionParse() done\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,7 +1178,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
|
||||||
ProgramFail(Parser, "not a function - can't call");
|
ProgramFail(Parser, "not a function - can't call");
|
||||||
|
|
||||||
ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType);
|
ExpressionStackPushValueByType(Parser, StackTop, FuncValue->Val->FuncDef.ReturnType);
|
||||||
ReturnValue = (*StackTop)->Val;
|
ReturnValue = (*StackTop)->p.Val;
|
||||||
HeapPushStackFrame();
|
HeapPushStackFrame();
|
||||||
ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams);
|
ParamArray = HeapAllocStack(sizeof(struct Value *) * FuncValue->Val->FuncDef.NumParams);
|
||||||
if (ParamArray == NULL)
|
if (ParamArray == NULL)
|
||||||
|
|
Loading…
Reference in a new issue