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:
parent
9e24449497
commit
d034ded5fc
63
expression.c
63
expression.c
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue