diff --git a/clibrary.c b/clibrary.c index 5a4afa4..d45ce6a 100644 --- a/clibrary.c +++ b/clibrary.c @@ -43,8 +43,10 @@ void SPutc(unsigned char Ch, union OutputStreamInfo *Stream) { struct StringOutputStream *Out = &Stream->Str; *Out->WritePos++ = Ch; +#ifndef NATIVE_POINTERS if (Out->WritePos == Out->MaxPos) Out->WritePos--; +#endif } /* print a character to a stream without using printf/sprintf */ @@ -60,8 +62,15 @@ void PrintStr(const char *Str, struct OutputStream *Stream) PrintCh(*Str++, Stream); } +/* print a single character a given number of times */ +void PrintRepeatedChar(char ShowChar, int Length, struct OutputStream *Stream) +{ + while (Length-- > 0) + PrintCh(ShowChar, Stream); +} + /* print an unsigned integer to a stream without using printf/sprintf */ -void PrintUnsigned(unsigned int Num, unsigned int Base, struct OutputStream *Stream) +void PrintUnsigned(unsigned int Num, unsigned int Base, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream) { char Result[33]; int ResPos = sizeof(Result); @@ -82,19 +91,27 @@ void PrintUnsigned(unsigned int Num, unsigned int Base, struct OutputStream *Str Num = NextNum; } + if (FieldWidth > 0 && !LeftJustify) + PrintRepeatedChar(ZeroPad ? '0' : ' ', FieldWidth - (sizeof(Result) - 1 - ResPos), Stream); + PrintStr(&Result[ResPos], Stream); + + if (FieldWidth > 0 && LeftJustify) + PrintRepeatedChar(' ', FieldWidth - (sizeof(Result) - 1 - ResPos), Stream); } /* print an integer to a stream without using printf/sprintf */ -void PrintInt(int Num, struct OutputStream *Stream) +void PrintInt(int Num, int FieldWidth, int ZeroPad, int LeftJustify, struct OutputStream *Stream) { if (Num < 0) { PrintCh('-', Stream); - Num = -Num; + Num = -Num; + if (FieldWidth != 0) + FieldWidth--; } - PrintUnsigned((unsigned int)Num, 10, Stream); + PrintUnsigned((unsigned int)Num, 10, FieldWidth, ZeroPad, LeftJustify, Stream); } #ifndef NO_FP @@ -116,7 +133,7 @@ void PrintFP(double Num, struct OutputStream *Stream) Exponent = math_log(Num) / LOG10E - 0.999999999; Num /= math_pow(10.0, Exponent); - PrintInt((int)Num, Stream); + PrintInt((int)Num, 0, FALSE, FALSE, Stream); PrintCh('.', Stream); Num = (Num - (int)Num) * 10; if (abs(Num) >= 1e-7) @@ -130,7 +147,7 @@ void PrintFP(double Num, struct OutputStream *Stream) if (Exponent != 0) { PrintCh('e', Stream); - PrintInt(Exponent, Stream); + PrintInt(Exponent, 0, FALSE, FALSE, Stream); } } #endif @@ -150,7 +167,7 @@ void PrintType(struct ValueType *Typ, struct OutputStream *Stream) case TypeFunction: PrintStr("function", Stream); break; case TypeMacro: PrintStr("macro", Stream); break; case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break; - case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, Stream); PrintCh(']', Stream); break; + case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, 0, FALSE, FALSE, Stream); PrintCh(']', Stream); break; case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break; case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break; case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break; @@ -165,6 +182,9 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct struct Value *NextArg = Param[0]; struct ValueType *FormatType; int ArgCount = 1; + int LeftJustify = FALSE; + int ZeroPad = FALSE; + int FieldWidth = 0; #ifndef NATIVE_POINTERS char *Format; struct Value *CharArray = Param[0]->Val->Pointer.Segment; @@ -183,6 +203,25 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct if (*FPos == '%') { FPos++; + if (*FPos == '-') + { + /* a leading '-' means left justify */ + LeftJustify = TRUE; + FPos++; + } + + if (*FPos == '0') + { + /* a leading zero means zero pad a decimal number */ + ZeroPad = TRUE; + FPos++; + } + + /* get any field width in the format */ + while (isdigit(*FPos)) + FieldWidth = FieldWidth * 10 + (*FPos++ - '0'); + + /* now check the format type */ switch (*FPos) { case 's': FormatType = CharPtrType; break; @@ -234,10 +273,10 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct PrintStr(Str, Stream); break; } - case 'd': PrintInt(COERCE_INTEGER(NextArg), Stream); break; - case 'u': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 10, Stream); break; - case 'x': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 16, Stream); break; - case 'b': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 2, Stream); break; + case 'd': PrintInt(COERCE_INTEGER(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'u': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 10, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'x': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 16, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'b': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 2, FieldWidth, ZeroPad, LeftJustify, Stream); break; case 'c': PrintCh(COERCE_INTEGER(NextArg), Stream); break; #ifndef NO_FP case 'f': PrintFP(COERCE_FP(NextArg), Stream); break; @@ -276,7 +315,9 @@ void LibSPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Val StrStream.Putch = &SPutc; StrStream.i.Str.Parser = Parser; +#ifndef NATIVE_POINTERS StrStream.i.Str.MaxPos = StrStream.i.Str.WritePos - DerefOffset + DerefVal->Val->Array.Size; +#endif GenericPrintf(Parser, ReturnValue, Param+1, NumArgs-1, &StrStream); PrintCh(0, &StrStream); #ifndef NATIVE_POINTERS @@ -310,15 +351,10 @@ void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value #else struct Value *CharArray = (struct Value *)(Param[0]->Val->NativePointer); char *ReadBuffer = CharArray->Val->Array.Data; - int MaxLength = CharArray->Val->Array.Size; char *Result; ReturnValue->Val->NativePointer = NULL; - - if (MaxLength < 0) - return; /* no room for data */ - - Result = PlatformGetLine(ReadBuffer, MaxLength); + Result = PlatformGetLine(ReadBuffer, GETS_BUF_MAX); if (Result == NULL) return; diff --git a/expression.c b/expression.c index 3b3b3c2..523981f 100644 --- a/expression.c +++ b/expression.c @@ -327,10 +327,17 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct if (DestValue->Typ != SourceValue->Typ) AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); +#ifndef NATIVE_POINTERS if (DestValue->Val->Array.Size != SourceValue->Val->Array.Size) AssignFail(Parser, "from an array of size %d to one of size %d", NULL, NULL, SourceValue->Val->Array.Size, DestValue->Val->Array.Size, FuncName, ParamNo); - + memcpy((void *)DestValue->Val->Array.Data, (void *)SourceValue->Val->Array.Data, DestValue->Val->Array.Size); +#else + if (DestValue->Typ->ArraySize != SourceValue->Typ->ArraySize) + AssignFail(Parser, "from an array of size %d to one of size %d", NULL, NULL, DestValue->Typ->ArraySize, SourceValue->Typ->ArraySize, FuncName, ParamNo); + + memcpy((void *)DestValue->Val->Array.Data, (void *)SourceValue->Val->Array.Data, DestValue->Typ->ArraySize); +#endif break; case TypeStruct: @@ -603,9 +610,11 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * ProgramFail(Parser, "array index must be an integer"); ArrayIndex = COERCE_INTEGER(TopValue); +#ifndef NATIVE_POINTERS if (ArrayIndex < 0 || ArrayIndex >= BottomValue->Val->Array.Size) ProgramFail(Parser, "illegal array index %d [0..%d]", ArrayIndex, BottomValue->Val->Array.Size-1); - +#endif + /* make the array element result */ Result = VariableAllocValueFromExistingData(Parser, BottomValue->Typ->FromType, (union AnyValue *)((char *)BottomValue->Val->Array.Data + TypeSize(BottomValue->Typ->FromType, 0, FALSE) * ArrayIndex), BottomValue->IsLValue, BottomValue->LValueFrom); ExpressionStackPushValueNode(Parser, StackTop, Result); diff --git a/lex.c b/lex.c index f5716c0..c08de3d 100644 --- a/lex.c +++ b/lex.c @@ -300,7 +300,9 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer, struct Value *Value) /* create and store this string literal */ ArrayValue = VariableAllocValueAndData(NULL, sizeof(struct ArrayValue), FALSE, NULL, TRUE); ArrayValue->Typ = CharArrayType; +#ifndef NATIVE_POINTERS ArrayValue->Val->Array.Size = EscBufPos - EscBuf + 1; +#endif ArrayValue->Val->Array.Data = RegString; VariableStringLiteralDefine(RegString, ArrayValue); } diff --git a/picoc.h b/picoc.h index f698fe1..a6bad68 100644 --- a/picoc.h +++ b/picoc.h @@ -25,6 +25,7 @@ #ifndef PATH_MAX #define PATH_MAX 1024 #endif +#define GETS_BUF_MAX 256 /* coercion of numeric types to other numeric types */ #ifndef NO_FP @@ -170,7 +171,9 @@ struct FuncDef /* values */ struct ArrayValue { +#ifndef NATIVE_POINTERS unsigned int Size; /* the number of elements in the array */ +#endif void *Data; /* pointer to the array data */ }; @@ -276,7 +279,9 @@ union OutputStreamInfo { struct ParseState *Parser; char *WritePos; +#ifndef NATIVE_POINTERS char *MaxPos; +#endif } Str; }; diff --git a/type.c b/type.c index 1be03c4..585edde 100644 --- a/type.c +++ b/type.c @@ -81,6 +81,7 @@ int TypeSizeValue(struct Value *Val) return sizeof(struct ArrayValue) + Val->Typ->FromType->Sizeof * Val->Typ->ArraySize; } +#ifndef NATIVE_POINTERS /* the last accessible offset of a value */ int TypeLastAccessibleOffset(struct Value *Val) { @@ -89,6 +90,7 @@ int TypeLastAccessibleOffset(struct Value *Val) else return Val->Typ->FromType->Sizeof * (Val->Val->Array.Size-1); } +#endif /* memory used by a variable given its type and array size */ int TypeSize(struct ValueType *Typ, int ArraySize, int Compact) diff --git a/variable.c b/variable.c index b62fd5a..fceb834 100644 --- a/variable.c +++ b/variable.c @@ -107,7 +107,9 @@ struct Value *VariableAllocValueFromType(struct ParseState *Parser, struct Value NewValue->Typ = Typ; if (Typ->Base == TypeArray) { +#ifndef NATIVE_POINTERS NewValue->Val->Array.Size = Typ->ArraySize; +#endif NewValue->Val->Array.Data = (void *)((char *)NewValue->Val + sizeof(struct ArrayValue)); } @@ -195,8 +197,11 @@ void VariableDefinePlatformVar(struct ParseState *Parser, char *Ident, struct Va if (Typ->Base != TypeArray) SomeValue->Val = FromValue; else - { /* define an array */ + { + /* define an array */ +#ifndef NATIVE_POINTERS SomeValue->Val->Array.Size = Typ->ArraySize; +#endif SomeValue->Val->Array.Data = FromValue; }