Structs now work in the new expression system.

Tests 03 and 04 now pass.


git-svn-id: http://picoc.googlecode.com/svn/trunk@230 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-04-14 03:18:40 +00:00
parent 9e24449497
commit d034ded5fc

View file

@ -11,8 +11,10 @@
#define COERCE_INTEGER(v) ((v)->Val->Integer) #define COERCE_INTEGER(v) ((v)->Val->Integer)
#endif #endif
/* helper macros for assignment */
#define ASSIGN_INT(d,s) { if (!(d)->IsLValue) ProgramFail(Parser, "can't assign to this"); ResultInt = (s); (d)->Val->Integer = ResultInt; } #define ASSIGN_INT(d,s) { if (!(d)->IsLValue) ProgramFail(Parser, "can't assign to this"); ResultInt = (s); (d)->Val->Integer = ResultInt; }
#define ASSIGN_INT_AFTER(d,s) { if (!(d)->IsLValue) ProgramFail(Parser, "can't assign to this"); ResultInt = (d)->Val->Integer; (d)->Val->Integer = (s); } #define ASSIGN_INT_AFTER(d,s) { if (!(d)->IsLValue) ProgramFail(Parser, "can't assign to this"); ResultInt = (d)->Val->Integer; (d)->Val->Integer = (s); }
#define ASSIGN_FP(d,s) { if (!(d)->IsLValue) ProgramFail(Parser, "can't assign to this"); ResultFP = (s); (d)->Val->FP = ResultFP; }
#define BRACKET_PRECEDENCE 20 #define BRACKET_PRECEDENCE 20
@ -592,6 +594,7 @@ void ExpressionStackShow(struct ExpressionStack *StackTop)
switch (StackTop->p.Val->Typ->Base) switch (StackTop->p.Val->Typ->Base)
{ {
case TypeVoid: printf("void"); break;
case TypeInt: case TypeChar: printf("%d:int", StackTop->p.Val->Val->Integer); break; 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 TypeFP: printf("%f:fp", StackTop->p.Val->Val->FP); break;
case TypeFunction: printf("%s:function", StackTop->p.Val->Val->Identifier); break; case TypeFunction: printf("%s:function", StackTop->p.Val->Val->Identifier); break;
@ -809,13 +812,6 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
} }
debugf("ExpressionInfixOperator()\n"); debugf("ExpressionInfixOperator()\n");
switch (Op)
{
case TokenComma:
case TokenAssign:
case TokenDot:
case TokenArrow:
default:
if (IS_INTEGER_COERCIBLE(TopValue) && IS_INTEGER_COERCIBLE(BottomValue)) if (IS_INTEGER_COERCIBLE(TopValue) && IS_INTEGER_COERCIBLE(BottomValue))
{ {
int TopInt = COERCE_INTEGER(TopValue); int TopInt = COERCE_INTEGER(TopValue);
@ -870,11 +866,11 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
switch (Op) switch (Op)
{ {
case TokenAddAssign: break; // XXX case TokenAssign: ASSIGN_FP(BottomValue, TopFP); break;
case TokenSubtractAssign: break; // XXX case TokenAddAssign: ASSIGN_FP(BottomValue, BottomFP + TopFP); break;
case TokenMultiplyAssign: break; // XXX case TokenSubtractAssign: ASSIGN_FP(BottomValue, BottomFP - TopFP); break;
case TokenDivideAssign: break; // XXX case TokenMultiplyAssign: ASSIGN_FP(BottomValue, BottomFP * TopFP); break;
case TokenModulusAssign: break; // XXX case TokenDivideAssign: ASSIGN_FP(BottomValue, BottomFP / TopFP); break;
case TokenEqual: ResultInt = BottomFP == TopFP; ResultIsInt = TRUE; break; case TokenEqual: ResultInt = BottomFP == TopFP; ResultIsInt = TRUE; break;
case TokenNotEqual: ResultInt = BottomFP != TopFP; ResultIsInt = TRUE; break; case TokenNotEqual: ResultInt = BottomFP != TopFP; ResultIsInt = TRUE; break;
case TokenLessThan: ResultInt = BottomFP < TopFP; ResultIsInt = TRUE; break; case TokenLessThan: ResultInt = BottomFP < TopFP; ResultIsInt = TRUE; break;
@ -921,9 +917,7 @@ XXX - finish this
} }
#endif #endif
else else
ProgramFail(Parser, "invalid operation"); break; ProgramFail(Parser, "invalid operation");
break;
}
} }
/* take the contents of the expression stack and compute the top until there's nothing greater than the given precedence */ /* take the contents of the expression stack and compute the top until there's nothing greater than the given precedence */
@ -1022,6 +1016,40 @@ void ExpressionStackPushOperator(struct ParseState *Parser, struct ExpressionSta
#endif #endif
} }
/* 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)
{ /* look up the struct element */
struct Value *StructVal = (*StackTop)->p.Val;
struct Value *MemberValue;
struct Value *Result;
if (Token == TokenArrow)
ProgramFail(Parser, "'->' not implemented yet");
if (StructVal->Typ->Base != TypeStruct && StructVal->Typ->Base != TypeUnion)
ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : "");
if (!TableGet(StructVal->Typ->Members, Ident->Val->Identifier, &MemberValue))
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 */
HeapPopStack(StructVal, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StructVal));
*StackTop = (*StackTop)->Next;
/* make the result value for this member only */
Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, (void *)StructVal->Val + MemberValue->Val->Integer, TRUE, StructVal->LValueFrom);
ExpressionStackPushValueNode(Parser, StackTop, Result);
}
}
/* parse an expression with operator precedence */ /* parse an expression with operator precedence */
int ExpressionParse(struct ParseState *Parser, struct Value **Result) int ExpressionParse(struct ParseState *Parser, struct Value **Result)
{ {
@ -1096,6 +1124,10 @@ 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)
ExpressionGetStructElement(Parser, &StackTop, Token); /* this operator is followed by a struct element so handle it as a special case */
else
{ /* 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 */
@ -1108,6 +1140,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence); ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, Token, Precedence);
PrefixState = TRUE; PrefixState = TRUE;
} }
}
else else
ProgramFail(Parser, "operator not expected here"); ProgramFail(Parser, "operator not expected here");
} }