Array indexing now works in the new expression system.

git-svn-id: http://picoc.googlecode.com/svn/trunk@231 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-14 06:55:00 +00:00
parent d034ded5fc
commit ca628b8cb3

View file

@ -26,7 +26,7 @@ void debugf(char *Format, ...)
} }
#endif #endif
#if 1 #ifndef NEW_EXPRESSION_SYSTEM
/* 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);
@ -571,7 +571,7 @@ static struct OpPrecedence OperatorPrecedence[] =
/* 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, "sizeof" }, /* 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, */ { 0, 0, 15, "[" }, /* 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, ")" }
}; };
@ -586,7 +586,8 @@ void ExpressionStackShow(struct ExpressionStack *StackTop)
while (StackTop != NULL) while (StackTop != NULL)
{ {
if (StackTop->Order == OrderNone) if (StackTop->Order == OrderNone)
{ /* it's a value */ {
/* it's a value */
if (StackTop->p.Val->IsLValue) if (StackTop->p.Val->IsLValue)
printf("lvalue="); printf("lvalue=");
else else
@ -722,7 +723,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
break; break;
case TokenOpenBracket: case TokenOpenBracket:
// XXX // XXX - cast
break; break;
default: default:
@ -812,8 +813,29 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
} }
debugf("ExpressionInfixOperator()\n"); debugf("ExpressionInfixOperator()\n");
if (IS_INTEGER_COERCIBLE(TopValue) && IS_INTEGER_COERCIBLE(BottomValue)) if (Op == TokenLeftSquareBracket)
{ {
/* array index */
int ArrayIndex;
struct Value *Result;
if (BottomValue->Typ->Base != TypeArray)
ProgramFail(Parser, "not an array");
if (!IS_INTEGER_COERCIBLE(TopValue))
ProgramFail(Parser, "array index must be an integer");
ArrayIndex = COERCE_INTEGER(TopValue);
if (ArrayIndex < 0 || ArrayIndex >= BottomValue->Val->Array.Size)
ProgramFail(Parser, "illegal array index %d [0..%d]", ArrayIndex, BottomValue->Val->Array.Size-1);
/* make the array element result */
Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)(BottomValue->Val->Array.Data + TypeSize(BottomValue->Typ->FromType, 0) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom);
ExpressionStackPushValueNode(Parser, StackTop, Result);
}
else if (IS_INTEGER_COERCIBLE(TopValue) && IS_INTEGER_COERCIBLE(BottomValue))
{
/* integer operation */
int TopInt = COERCE_INTEGER(TopValue); int TopInt = COERCE_INTEGER(TopValue);
int BottomInt = COERCE_INTEGER(BottomValue); int BottomInt = COERCE_INTEGER(BottomValue);
switch (Op) switch (Op)
@ -1026,7 +1048,8 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
ProgramFail(Parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->"); ProgramFail(Parser, "need an structure or union member after '%s'", (Token == TokenDot) ? "." : "->");
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
{ /* look up the struct element */ {
/* look up the struct element */
struct Value *StructVal = (*StackTop)->p.Val; struct Value *StructVal = (*StackTop)->p.Val;
struct Value *MemberValue; struct Value *MemberValue;
struct Value *Result; struct Value *Result;
@ -1067,34 +1090,41 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
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 > TokenComma && (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 */
if (OperatorPrecedence[(int)Token].PrefixPrecedence == 0) if (OperatorPrecedence[(int)Token].PrefixPrecedence == 0)
ProgramFail(Parser, "operator not expected here"); ProgramFail(Parser, "operator not expected here");
LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence; LocalPrecedence = OperatorPrecedence[(int)Token].PrefixPrecedence;
Precedence = BracketPrecedence + LocalPrecedence; Precedence = BracketPrecedence + LocalPrecedence;
if (Token == TokenOpenBracket || Token == TokenLeftSquareBracket) if (Token == TokenOpenBracket)
{ /* boost the bracket operator precedence, then push */ {
/* boost the bracket operator precedence, then push */
BracketPrecedence += BRACKET_PRECEDENCE; BracketPrecedence += BRACKET_PRECEDENCE;
ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence); // XXX ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence);
} }
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 */
ExpressionStackCollapse(Parser, &StackTop, Precedence); ExpressionStackCollapse(Parser, &StackTop, Precedence);
ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence);
} }
} }
else else
{ /* expect an infix or postfix operator */ {
/* expect an infix or postfix operator */
if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0) if (OperatorPrecedence[(int)Token].PostfixPrecedence != 0)
{ {
switch (Token) switch (Token)
{ {
case TokenCloseBracket: case TokenCloseBracket:
case TokenRightSquareBracket:
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; *Parser = PreState;
Done = TRUE; Done = TRUE;
} }
@ -1102,18 +1132,6 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
BracketPrecedence -= BRACKET_PRECEDENCE; BracketPrecedence -= BRACKET_PRECEDENCE;
break; break;
case TokenRightSquareBracket:
if (BracketPrecedence == 0)
ProgramFail(Parser, "no matching open square bracket");
/* scan and collapse the stack to bracket precedence */
ExpressionStackCollapse(Parser, &StackTop, BracketPrecedence);
BracketPrecedence -= BRACKET_PRECEDENCE;
/* apply the array index operator */
// XXX
break;
default: default:
/* 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 */
Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence; Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].PostfixPrecedence;
@ -1123,11 +1141,13 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
} }
} }
else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0) else if (OperatorPrecedence[(int)Token].InfixPrecedence != 0)
{ /* scan and collapse the stack, then push */ {
/* scan and collapse the stack, then push */
if (Token == TokenDot || Token == TokenArrow) if (Token == TokenDot || Token == TokenArrow)
ExpressionGetStructElement(Parser, &StackTop, Token); /* this operator is followed by a struct element so handle it as a special case */ ExpressionGetStructElement(Parser, &StackTop, Token); /* this operator is followed by a struct element so handle it as a special case */
else else
{ /* a standard infix operator */ {
/* a standard infix operator */
Precedence = BracketPrecedence + OperatorPrecedence[(int)Token].InfixPrecedence; 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 right to left order, only go down to the next higher precedence so we evaluate it in reverse order */
@ -1140,13 +1160,22 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence);
PrefixState = TRUE; PrefixState = TRUE;
} }
/* 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;
// XXX ExpressionStackPushOperator(Parser, &StackTop, OrderPrefix, Token, Precedence);
}
} }
else else
ProgramFail(Parser, "operator not expected here"); ProgramFail(Parser, "operator not expected here");
} }
} }
else if (Token == TokenIdentifier) else if (Token == TokenIdentifier)
{ /* it's a variable, function or a macro */ {
/* it's a variable, function or a macro */
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket)
ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier); ExpressionParseFunctionCall(Parser, &StackTop, LexValue->Val->Identifier);
else else
@ -1169,9 +1198,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
else if (VariableValue->Typ == TypeVoid) else if (VariableValue->Typ == TypeVoid)
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 */ ExpressionStackPushLValue(Parser, &StackTop, VariableValue); /* it's a value variable */
ExpressionStackPushLValue(Parser, &StackTop, VariableValue);
}
} }
else /* push a dummy value */ else /* push a dummy value */
ExpressionPushInt(Parser, &StackTop, 0); ExpressionPushInt(Parser, &StackTop, 0);
@ -1180,7 +1207,8 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
} }
} }
else if ((int)Token > TokenComma && (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");
@ -1188,7 +1216,8 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackPushValue(Parser, &StackTop, LexValue); ExpressionStackPushValue(Parser, &StackTop, LexValue);
} }
else else
{ /* it isn't a token from an expression */ {
/* it isn't a token from an expression */
*Parser = PreState; *Parser = PreState;
Done = TRUE; Done = TRUE;
} }
@ -1224,7 +1253,8 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */ enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
{ /* get the function definition */ {
/* get the function definition */
VariableGet(Parser, FuncName, &FuncValue); VariableGet(Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base != TypeFunction) if (FuncValue->Typ->Base != TypeFunction)
ProgramFail(Parser, "not a function - can't call"); ProgramFail(Parser, "not a function - can't call");
@ -1265,7 +1295,8 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
ProgramFail(Parser, "comma expected"); ProgramFail(Parser, "comma expected");
} }
else else
{ /* end of argument list? */ {
/* end of argument list? */
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
if (!TokenCloseBracket) if (!TokenCloseBracket)
ProgramFail(Parser, "bad argument"); ProgramFail(Parser, "bad argument");
@ -1273,12 +1304,14 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
} while (Token != TokenCloseBracket); } while (Token != TokenCloseBracket);
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
{ /* run the function */ {
/* run the function */
if (ArgCount < FuncValue->Val->FuncDef.NumParams) if (ArgCount < FuncValue->Val->FuncDef.NumParams)
ProgramFail(Parser, "not enough arguments to '%s'", FuncName); ProgramFail(Parser, "not enough arguments to '%s'", FuncName);
if (FuncValue->Val->FuncDef.Intrinsic == NULL) if (FuncValue->Val->FuncDef.Intrinsic == NULL)
{ /* run a user-defined function */ {
/* run a user-defined function */
struct ParseState FuncParser = FuncValue->Val->FuncDef.Body; struct ParseState FuncParser = FuncValue->Val->FuncDef.Body;
int Count; int Count;