Pointer comparison operations implemented
git-svn-id: http://picoc.googlecode.com/svn/trunk@260 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
e5fa7017f0
commit
16c5b72f4d
11
TODO
11
TODO
|
@ -2,14 +2,23 @@ TODO
|
||||||
|
|
||||||
Bugs:
|
Bugs:
|
||||||
* assignment in declarators: int *b = &a;
|
* assignment in declarators: int *b = &a;
|
||||||
|
* struct it
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
} c;
|
||||||
|
int *x;
|
||||||
|
x = &c.a;
|
||||||
|
printf("%d\n", *x);
|
||||||
|
XXX
|
||||||
|
|
||||||
Implement:
|
Implement:
|
||||||
* pointer arithmetic
|
|
||||||
* ternary operator
|
* ternary operator
|
||||||
* casts
|
* casts
|
||||||
* char access/char array access/char * access
|
* char access/char array access/char * access
|
||||||
* an easier way of checking pointers in library code
|
* an easier way of checking pointers in library code
|
||||||
* evaluate only first argument of && and || if possible
|
* evaluate only first argument of && and || if possible
|
||||||
|
* array assignment
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
* #define with arguments
|
* #define with arguments
|
||||||
|
|
20
expression.c
20
expression.c
|
@ -316,6 +316,8 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
|
||||||
void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *BottomValue, struct Value *TopValue)
|
void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack **StackTop, enum LexToken Op, struct Value *BottomValue, struct Value *TopValue)
|
||||||
{
|
{
|
||||||
int ResultInt = 0;
|
int ResultInt = 0;
|
||||||
|
struct PointerValue Pointer;
|
||||||
|
struct Value *StackValue;
|
||||||
|
|
||||||
if (Parser->Mode != RunModeRun)
|
if (Parser->Mode != RunModeRun)
|
||||||
{
|
{
|
||||||
|
@ -433,8 +435,6 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
|
||||||
{
|
{
|
||||||
/* pointer/integer infix arithmetic */
|
/* pointer/integer infix arithmetic */
|
||||||
int TopInt = COERCE_INTEGER(TopValue);
|
int TopInt = COERCE_INTEGER(TopValue);
|
||||||
struct PointerValue Pointer;
|
|
||||||
struct Value *StackValue;
|
|
||||||
|
|
||||||
if (Op == TokenEqual || Op == TokenNotEqual)
|
if (Op == TokenEqual || Op == TokenNotEqual)
|
||||||
{
|
{
|
||||||
|
@ -462,7 +462,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
|
||||||
Pointer.Offset -= TopInt * Size;
|
Pointer.Offset -= TopInt * Size;
|
||||||
|
|
||||||
/* check pointer bounds */
|
/* check pointer bounds */
|
||||||
if (Pointer.Offset < 0 || Pointer.Offset > TypeSizeValue(BottomValue->Val->Pointer.Segment) - Size)
|
if (Pointer.Offset < 0 || Pointer.Offset > TypeLastAccessibleOffset(Pointer.Segment))
|
||||||
Pointer.Offset = BottomValue->Val->Pointer.Offset;
|
Pointer.Offset = BottomValue->Val->Pointer.Offset;
|
||||||
|
|
||||||
StackValue = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Typ);
|
StackValue = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Typ);
|
||||||
|
@ -479,6 +479,20 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
|
||||||
else
|
else
|
||||||
ProgramFail(Parser, "invalid operation");
|
ProgramFail(Parser, "invalid operation");
|
||||||
}
|
}
|
||||||
|
else if (BottomValue->Typ->Base == TypePointer && TopValue->Typ->Base == TypePointer && Op != TokenAssign)
|
||||||
|
{
|
||||||
|
/* pointer/pointer operations */
|
||||||
|
void *TopLoc = (void *)TopValue->Val->Pointer.Segment->Val + TopValue->Val->Pointer.Offset;
|
||||||
|
void *BottomLoc = (void *)BottomValue->Val->Pointer.Segment->Val + BottomValue->Val->Pointer.Offset;
|
||||||
|
|
||||||
|
switch (Op)
|
||||||
|
{
|
||||||
|
case TokenEqual: ExpressionPushInt(Parser, StackTop, BottomLoc == TopLoc); break;
|
||||||
|
case TokenNotEqual: ExpressionPushInt(Parser, StackTop, BottomLoc != TopLoc); break;
|
||||||
|
case TokenMinus: ExpressionPushInt(Parser, StackTop, BottomLoc - TopLoc); break;
|
||||||
|
default: ProgramFail(Parser, "invalid operation"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (Op == TokenAssign)
|
else if (Op == TokenAssign)
|
||||||
{
|
{
|
||||||
/* assign a non-numeric type */
|
/* assign a non-numeric type */
|
||||||
|
|
|
@ -17,7 +17,8 @@ TESTS= 00_assignment.test \
|
||||||
16_nesting.test \
|
16_nesting.test \
|
||||||
17_enum.test \
|
17_enum.test \
|
||||||
18_include.test \
|
18_include.test \
|
||||||
19_pointer_arithmetic.test
|
19_pointer_arithmetic.test \
|
||||||
|
20_pointer_comparison.test
|
||||||
|
|
||||||
%.test: %.expect %.c
|
%.test: %.expect %.c
|
||||||
@echo Test: $*...
|
@echo Test: $*...
|
||||||
|
|
Loading…
Reference in a new issue