Native pointers feature added
git-svn-id: http://picoc.googlecode.com/svn/trunk@331 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
3a1e39f9d3
commit
32727cc365
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall -pedantic -g -DUNIX_HOST
|
||||
CFLAGS=-Wall -pedantic -g -DUNIX_HOST
|
||||
LIBS=#-lm
|
||||
|
||||
TARGET = picoc
|
||||
|
|
17
clibrary.c
17
clibrary.c
|
@ -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
|
||||
|
|
46
expression.c
46
expression.c
|
@ -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
6
lex.c
|
@ -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;
|
||||
|
|
2
parse.c
2
parse.c
|
@ -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;
|
||||
|
|
2
picoc.h
2
picoc.h
|
@ -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)[]);
|
||||
|
|
|
@ -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
2
type.c
|
@ -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;
|
||||
|
|
30
variable.c
30
variable.c
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue