Native pointers feature added

git-svn-id: http://picoc.googlecode.com/svn/trunk@331 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-06-05 00:55:54 +00:00
parent 3a1e39f9d3
commit 32727cc365
9 changed files with 61 additions and 47 deletions

View file

@ -1,5 +1,5 @@
CC=gcc
CFLAGS=-Wall -pedantic -g -DUNIX_HOST
CFLAGS=-Wall -pedantic -g -DUNIX_HOST
LIBS=#-lm
TARGET = picoc

View file

@ -206,25 +206,23 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
{
case 's':
{
#ifndef NATIVE_POINTERS
struct Value *CharArray;
char *Str;
if (NextArg->Typ == CharPtrType || (NextArg->Typ->Base == TypePointer && NextArg->Typ->FromType->Base == TypeArray && NextArg->Typ->FromType->FromType->Base == TypeChar) )
{
CharArray = NextArg->Val->Pointer.Segment;
#ifndef NATIVE_POINTERS
struct Value *CharArray = NextArg->Val->Pointer.Segment;
if (NextArg->Val->Pointer.Offset < 0 || NextArg->Val->Pointer.Offset >= CharArray->Val->Array.Size)
Str = StrEmpty;
else
Str = (char *)CharArray->Val->Array.Data + NextArg->Val->Pointer.Offset;
#else
Str = NextArg->Val->NativePointer;
#endif
}
else
Str = NextArg->Val->Array.Data;
#else
char *Str = NextArg->Val->NativePointer;
/* XXX - dereference this properly */
#endif
PrintStr(Str, Stream);
break;
@ -261,15 +259,14 @@ void LibSPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Val
struct OutputStream StrStream;
struct Value *DerefVal;
int DerefOffset;
struct ValueType *DerefType;
StrStream.i.Str.WritePos = VariableDereferencePointer(StrStream.i.Str.Parser, Param[0], &DerefVal, &DerefOffset, &DerefType);
StrStream.i.Str.WritePos = VariableDereferencePointer(StrStream.i.Str.Parser, Param[0], &DerefVal, &DerefOffset, NULL, NULL);
if (DerefVal->Typ->Base != TypeArray)
ProgramFail(Parser, "can only print to arrays of char");
StrStream.Putch = &SPutc;
StrStream.i.Str.Parser = Parser;
StrStream.i.Str.MaxPos = StrStream.i.Str.WritePos- DerefOffset + DerefVal->Val->Array.Size;
StrStream.i.Str.MaxPos = StrStream.i.Str.WritePos - DerefOffset + DerefVal->Val->Array.Size;
GenericPrintf(Parser, ReturnValue, Param+1, NumArgs-1, &StrStream);
PrintCh(0, &StrStream);
#ifndef NATIVE_POINTERS

View file

@ -200,8 +200,9 @@ void ExpressionStackPushDereference(struct ParseState *Parser, struct Expression
struct Value *DerefVal;
int Offset;
struct ValueType *DerefType;
void *DerefDataLoc = VariableDereferencePointer(Parser, DereferenceValue, &DerefVal, &Offset, &DerefType);
struct Value *ValueLoc = VariableAllocValueFromExistingData(Parser, DerefType, (union AnyValue *)DerefDataLoc, DerefVal->IsLValue, DerefVal);
int DerefIsLValue;
void *DerefDataLoc = VariableDereferencePointer(Parser, DereferenceValue, &DerefVal, &Offset, &DerefType, &DerefIsLValue);
struct Value *ValueLoc = VariableAllocValueFromExistingData(Parser, DerefType, (union AnyValue *)DerefDataLoc, DerefIsLValue, DerefVal);
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
}
@ -225,8 +226,10 @@ void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackT
void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, struct Value *FromValue, const char *FuncName, int ParamNo)
{
struct ValueType *PointedToType = ToValue->Typ->FromType;
#ifndef NATIVE_POINTERS
struct Value *DerefVal = NULL;
int DerefOffset;
#endif
if (FromValue->Typ == ToValue->Typ)
{
@ -251,14 +254,12 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue,
else if (FromValue->Typ->Base == TypePointer && FromValue->Typ->FromType->Base == TypeArray && PointedToType == FromValue->Typ->FromType->FromType)
{
/* the form is: blah *x = pointer to array of blah */
struct ValueType *DerefType;
VariableDereferencePointer(Parser, FromValue, &DerefVal, &DerefOffset, &DerefType);
#ifndef NATIVE_POINTERS
VariableDereferencePointer(Parser, FromValue, &DerefVal, &DerefOffset, NULL, NULL);
ToValue->Val->Pointer.Segment = DerefVal;
ToValue->Val->Pointer.Offset = DerefOffset;
#else
ToValue->Val->NativePointer = DerefVal;
ToValue->Val->NativePointer = VariableDereferencePointer(Parser, FromValue, NULL, NULL, NULL, NULL);
#endif
}
else if (IS_NUMERIC_COERCIBLE(FromValue) && COERCE_INTEGER(FromValue) == 0)
@ -360,7 +361,10 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
if (Result->LValueFrom != NULL)
Result->Val->Pointer.Offset = (char *)Result->Val - (char *)Result->LValueFrom;
#else
Result->Val->NativePointer = TempLValue;
if (TempLValue->Typ->Base == TypeArray)
Result->Val->NativePointer = TempLValue->Val->Array.Data;
else
Result->Val->NativePointer = TempLValue->Val;
#endif
ExpressionStackPushValueNode(Parser, StackTop, Result);
break;
@ -371,14 +375,17 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
case TokenSizeof:
/* XXX */
ProgramFail(Parser, "not supported");
break;
case TokenLeftSquareBracket:
/* XXX */
ProgramFail(Parser, "not supported");
break;
case TokenOpenBracket:
/* XXX - cast */
ProgramFail(Parser, "not supported");
break;
default:
@ -453,8 +460,8 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
switch (Op)
{
case TokenIncrement: TopValue->Val->NativePointer += Size; break;
case TokenDecrement: TopValue->Val->NativePointer -= Size; break;
case TokenIncrement: TopValue->Val->NativePointer = (void *)((char *)TopValue->Val->NativePointer + Size); break;
case TokenDecrement: TopValue->Val->NativePointer = (void *)((char *)TopValue->Val->NativePointer - Size); break;
default: ProgramFail(Parser, "invalid operation"); break;
}
@ -487,8 +494,8 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
{
case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, TRUE); break;
case TokenDecrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt-1, TRUE); break;
case TokenRightSquareBracket: break; /* XXX */
case TokenCloseBracket: break; /* XXX */
case TokenRightSquareBracket: ProgramFail(Parser, "not supported"); break; /* XXX */
case TokenCloseBracket: ProgramFail(Parser, "not supported"); break; /* XXX */
default: ProgramFail(Parser, "invalid operation"); break;
}
@ -534,8 +541,8 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
switch (Op)
{
case TokenIncrement: TopValue->Val->NativePointer += Size; break;
case TokenDecrement: TopValue->Val->NativePointer -= Size; break;
case TokenIncrement: TopValue->Val->NativePointer = (void *)((char *)TopValue->Val->NativePointer + Size); break;
case TokenDecrement: TopValue->Val->NativePointer = (void *)((char *)TopValue->Val->NativePointer - Size); break;
default: ProgramFail(Parser, "invalid operation"); break;
}
@ -643,8 +650,8 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
case TokenArithmeticAndAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt & TopInt, FALSE); break;
case TokenArithmeticOrAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt | TopInt, FALSE); break;
case TokenArithmeticExorAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt ^ TopInt, FALSE); break;
case TokenQuestionMark: break; /* XXX */
case TokenColon: break; /* XXX */
case TokenQuestionMark: ProgramFail(Parser, "not supported"); break; /* XXX */
case TokenColon: ProgramFail(Parser, "not supported"); break; /* XXX */
case TokenLogicalOr: ResultInt = BottomInt || TopInt; break;
case TokenLogicalAnd: ResultInt = BottomInt && TopInt; break;
case TokenArithmeticOr: ResultInt = BottomInt | TopInt; break;
@ -720,9 +727,9 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ProgramFail(Parser, "invalid use of a NULL pointer");
if (Op == TokenPlus)
NativePointer += TopInt * Size;
NativePointer = (void *)((char *)NativePointer + TopInt * Size);
else
NativePointer -= TopInt * Size;
NativePointer = (void *)((char *)NativePointer - TopInt * Size);
StackValue = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Typ);
StackValue->Val->NativePointer = NativePointer;
@ -887,7 +894,6 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
/* look up the struct element */
struct Value *ParamVal = (*StackTop)->p.Val;
struct Value *StructVal = ParamVal;
int StructOffset = 0;
struct ValueType *StructType = ParamVal->Typ;
char *DerefDataLoc = (char *)ParamVal->Val;
struct Value *MemberValue;
@ -895,7 +901,7 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
/* if we're doing '->' dereference the struct pointer first */
if (Token == TokenArrow)
DerefDataLoc = VariableDereferencePointer(Parser, ParamVal, &StructVal, &StructOffset, &StructType);
DerefDataLoc = VariableDereferencePointer(Parser, ParamVal, &StructVal, NULL, &StructType, NULL);
if (StructType->Base != TypeStruct && StructType->Base != TypeUnion)
ProgramFail(Parser, "can't use '%s' on something that's not a struct or union %s : it's a %t", (Token == TokenDot) ? "." : "->", (Token == TokenArrow) ? "pointer" : "", ParamVal->Typ);
@ -908,7 +914,7 @@ void ExpressionGetStructElement(struct ParseState *Parser, struct ExpressionStac
*StackTop = (*StackTop)->Next;
/* make the result value for this member only */
Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, (void *)(DerefDataLoc + MemberValue->Val->Integer), TRUE, StructVal->LValueFrom);
Result = VariableAllocValueFromExistingData(Parser, MemberValue->Typ, (void *)(DerefDataLoc + MemberValue->Val->Integer), TRUE, (StructVal != NULL) ? StructVal->LValueFrom : NULL);
ExpressionStackPushValueNode(Parser, StackTop, Result);
}
}

6
lex.c
View file

@ -310,7 +310,7 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value)
Value->Val->Pointer.Segment = ArrayValue;
Value->Val->Pointer.Offset = 0;
#else
Value->Val->NativePointer = ArrayValue;
Value->Val->NativePointer = RegString;
#endif
if (*Lexer->Pos == '"')
LEXER_INC(Lexer);
@ -634,7 +634,11 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I
{
switch (Token)
{
#ifndef NATIVE_POINTERS
case TokenStringConstant: LexValue.Typ = CharPtrType; LexValue.Val->Pointer.Offset = 0; break;
#else
case TokenStringConstant: LexValue.Typ = CharPtrType; break;
#endif
case TokenIdentifier: LexValue.Typ = NULL; break;
case TokenIntegerConstant: LexValue.Typ = &IntType; break;
case TokenCharacterConstant: LexValue.Typ = &CharType; break;

View file

@ -424,7 +424,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser)
#ifndef NATIVE_POINTERS
PlatformScanFile(LexerValue->Val->Pointer.Segment->Val->Array.Data);
#else
PlatformScanFile(((struct Value *)(LexerValue->Val->NativePointer))->Val->Array.Data);
PlatformScanFile((char *)LexerValue->Val->NativePointer);
#endif
CheckTrailingSemicolon = FALSE;
break;

View file

@ -372,7 +372,7 @@ void VariableStackFrameAdd(struct ParseState *Parser, int NumParams);
void VariableStackFramePop(struct ParseState *Parser);
struct Value *VariableStringLiteralGet(char *Ident);
void VariableStringLiteralDefine(char *Ident, struct Value *Val);
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType);
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue);
/* clibrary.c */
void LibraryInit(struct Table *GlobalTable, const char *LibraryName, struct LibraryFunction (*FuncList)[]);

View file

@ -68,6 +68,7 @@ extern jmp_buf ExitBuf;
# include <math.h>
# define assert(x)
# undef BIG_ENDIAN
# undef FANCY_ERROR_REPORTING
# else
# ifdef SURVEYOR_HOST

2
type.c
View file

@ -63,7 +63,7 @@ struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *P
/* stack space used by a value */
int TypeStackSizeValue(struct Value *Val)
{
if (Val->ValOnStack)
if (Val != NULL && Val->ValOnStack)
return TypeSizeValue(Val); /* XXX - doesn't handle passing system-memory arrays by value correctly */
else
return 0;

View file

@ -276,7 +276,7 @@ void VariableStringLiteralDefine(char *Ident, struct Value *Val)
}
/* check a pointer for validity and dereference it for use */
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType)
void *VariableDereferencePointer(struct ParseState *Parser, struct Value *PointerValue, struct Value **DerefVal, int *DerefOffset, struct ValueType **DerefType, int *DerefIsLValue)
{
#ifndef NATIVE_POINTERS
struct Value *PointedToValue = PointerValue->Val->Pointer.Segment;
@ -293,11 +293,16 @@ void *VariableDereferencePointer(struct ParseState *Parser, struct Value *Pointe
/* pass back the optional dereferenced pointer, offset and type */
if (DerefVal != NULL)
{
*DerefVal = PointedToValue;
if (DerefOffset != NULL)
*DerefOffset = PointerValue->Val->Pointer.Offset;
if (DerefType != NULL)
*DerefType = PointerValue->Typ->FromType;
}
if (DerefIsLValue != NULL)
*DerefIsLValue = PointedToValue->IsLValue;
/* return a pointer to the data */
if (PointedToValue->Typ->Base == TypeArray)
@ -305,16 +310,17 @@ void *VariableDereferencePointer(struct ParseState *Parser, struct Value *Pointe
else
return (void *)((char *)PointedToValue->Val + PointerValue->Val->Pointer.Offset);
#else
struct Value *PointedToValue = PointerValue->Val->NativePointer;
/* check if the pointed to item is within picoc's memory range */
if (PointerValue->Val->NativePointer - HeapMemStart >= HEAP_SIZE)
if (DerefVal != NULL)
*DerefVal = NULL;
else
*DerefVal = PointedToValue;
*DerefType = PointerValue->Typ->FromType;
*DerefOffset = 0;
if (DerefType != NULL)
*DerefType = PointerValue->Typ->FromType;
if (DerefOffset != NULL)
*DerefOffset = 0;
if (DerefIsLValue != NULL)
*DerefIsLValue = TRUE;
return PointerValue->Val->NativePointer;
#endif