diff --git a/Makefile b/Makefile index d4a6bb2..498ab38 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wall -pedantic -g -DUNIX_HOST +CFLAGS=-Wall -pedantic -g -DUNIX_HOST LIBS=#-lm TARGET = picoc diff --git a/clibrary.c b/clibrary.c index 54f7acd..c668862 100644 --- a/clibrary.c +++ b/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 diff --git a/expression.c b/expression.c index 4ce84a1..3f36993 100644 --- a/expression.c +++ b/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); } } diff --git a/lex.c b/lex.c index 9b00fee..3c6f0c2 100644 --- a/lex.c +++ b/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; diff --git a/parse.c b/parse.c index 10ab757..e9f861a 100644 --- a/parse.c +++ b/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; diff --git a/picoc.h b/picoc.h index a169f84..6c64591 100644 --- a/picoc.h +++ b/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)[]); diff --git a/platform.h b/platform.h index 078b2e1..ec85a60 100644 --- a/platform.h +++ b/platform.h @@ -68,6 +68,7 @@ extern jmp_buf ExitBuf; # include # define assert(x) # undef BIG_ENDIAN +# undef FANCY_ERROR_REPORTING # else # ifdef SURVEYOR_HOST diff --git a/type.c b/type.c index 3328b45..d71846d 100644 --- a/type.c +++ b/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; diff --git a/variable.c b/variable.c index 52e8b85..b62fd5a 100644 --- a/variable.c +++ b/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