diff --git a/cstdlib/stdio.c b/cstdlib/stdio.c index 44ffd26..1004f8f 100644 --- a/cstdlib/stdio.c +++ b/cstdlib/stdio.c @@ -1,6 +1,7 @@ /* */ #include #include +#include #include "../interpreter.h" @@ -95,8 +96,7 @@ void StdioOutPuts(const char *Str, StdOutStream *Stream) } /* printf-style format of an int or other word-sized object */ -void StdioFprintfWord(StdOutStream *Stream, const char *Format, - unsigned long Value) +void StdioFprintfWord(StdOutStream *Stream, const char *Format, unsigned int Value) { if (Stream->FilePtr != NULL) Stream->CharCount += fprintf(Stream->FilePtr, Format, Value); @@ -118,6 +118,64 @@ void StdioFprintfWord(StdOutStream *Stream, const char *Format, } } +/* printf-style format of a long */ +void StdioFprintfLong(StdOutStream *Stream, const char *Format, uint64_t Value) { + char PlatformFormat[MAX_FORMAT+1], *FPos = PlatformFormat; + + while (*Format) { + char *UseFormat = NULL; + + switch (*Format) { + case 'd': + UseFormat = PRId64; + break; + case 'i': + UseFormat = PRIi64; + break; + case 'o': + UseFormat = PRIo64; + break; + case 'u': + UseFormat = PRIu64; + break; + case 'x': + UseFormat = PRIx64; + break; + case 'X': + UseFormat = PRIX64; + break; + /* Ignore the %l (long) specifier, because of course we're doing longs in this function */ + case 'l': + break; + default: + *FPos++ = *Format; + break; + } + ++Format; + if (UseFormat) { + strcpy(FPos, UseFormat); + FPos += strlen(UseFormat); + } + } + + if (Stream->FilePtr != NULL) + Stream->CharCount += fprintf(Stream->FilePtr, PlatformFormat, Value); + else if (Stream->StrOutLen >= 0) { +#ifndef WIN32 + int CCount = snprintf(Stream->StrOutPtr, Stream->StrOutLen, PlatformFormat, Value); +#else + int CCount = _snprintf(Stream->StrOutPtr, Stream->StrOutLen, PlatformFormat, Value); +#endif + Stream->StrOutPtr += CCount; + Stream->StrOutLen -= CCount; + Stream->CharCount += CCount; + } else { + int CCount = sprintf(Stream->StrOutPtr, PlatformFormat, Value); + Stream->CharCount += CCount; + Stream->StrOutPtr += CCount; + } +} + /* printf-style format of a floating point number */ void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value) { @@ -174,6 +232,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, char *FPos; char OneFormatBuf[MAX_FORMAT+1]; int OneFormatCount; + int ShowLong = 0; struct ValueType *ShowType; StdOutStream SOStream; Picoc *pc = Parser->pc; @@ -207,6 +266,9 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, case 'X': ShowType = &pc->IntType; break; /* integer base conversions */ + case 'l': + ShowLong = 1; + break; /* long integer */ case 'e': case 'E': ShowType = &pc->FPType; @@ -247,9 +309,10 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, } /* copy one character of format across to the OneFormatBuf */ - OneFormatBuf[OneFormatCount] = *FPos; - OneFormatCount++; - + if (*FPos != 'l') { + OneFormatBuf[OneFormatCount] = *FPos; + OneFormatCount++; + } /* do special actions depending on the conversion type */ if (ShowType == &pc->VoidType) { switch (*FPos) { @@ -265,7 +328,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, break; case 'n': ThisArg = (struct Value*)((char*)ThisArg + - MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg))); + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); if (ThisArg->Typ->Base == TypeArray && ThisArg->Typ->FromType->Base == TypeInt) *(int *)ThisArg->Val->Pointer = SOStream.CharCount; @@ -289,10 +352,12 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut, MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg))); if (ShowType == &pc->IntType) { /* show a signed integer */ - if (IS_NUMERIC_COERCIBLE(ThisArg)) - StdioFprintfWord(&SOStream, OneFormatBuf, - ExpressionCoerceUnsignedInteger(ThisArg)); - else + if (IS_NUMERIC_COERCIBLE(ThisArg)) { + if (ShowLong && ShowType == &pc->IntType) + StdioFprintfLong(&SOStream, OneFormatBuf, ExpressionCoerceUnsignedInteger(ThisArg)); + else + StdioFprintfWord(&SOStream, OneFormatBuf, (unsigned int)ExpressionCoerceUnsignedInteger(ThisArg)); + } else StdioOutPuts("XXX", &SOStream); } else if (ShowType == &pc->FPType) { /* show a floating point number */ @@ -354,7 +419,7 @@ int StdioBaseScanf(struct ParseState *Parser, FILE *Stream, char *StrIn, for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) { ThisArg = (struct Value*)((char*)ThisArg + - MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg))); + MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg))); if (ThisArg->Typ->Base == TypePointer) ScanfArg[ArgCount] = ThisArg->Val->Pointer; diff --git a/expression.c b/expression.c index 03a8067..cf3e8b9 100644 --- a/expression.c +++ b/expression.c @@ -160,9 +160,9 @@ void ExpressionStackShow(Picoc *pc, struct ExpressionStack *StackTop) printf("%ld:unsigned long", StackTop->Val->Val->UnsignedLongInteger); break; case TypeFP: - printf("%f:fp", StackTop->Val->Val->FP); + printf("%f:fp", StackTop->Val->Val->FP); break; - case TypeFunction: + case TypeFunction: printf("%s:function", StackTop->Val->Val->Identifier); break; case TypeMacro: @@ -245,17 +245,17 @@ long ExpressionCoerceInteger(struct Value *Val) case TypeShort: return (long)Val->Val->ShortInteger; case TypeLong: - return (long)Val->Val->LongInteger; + return (int64_t)Val->Val->LongInteger; case TypeUnsignedInt: - return (long)Val->Val->UnsignedInteger; + return (unsigned long)Val->Val->UnsignedInteger; case TypeUnsignedShort: - return (long)Val->Val->UnsignedShortInteger; + return (unsigned long)Val->Val->UnsignedShortInteger; case TypeUnsignedLong: - return (long)Val->Val->UnsignedLongInteger; + return (uint64_t)Val->Val->UnsignedLongInteger; case TypeUnsignedChar: - return (long)Val->Val->UnsignedCharacter; + return (unsigned long)Val->Val->UnsignedCharacter; case TypePointer: - return (long)Val->Val->Pointer; + return (uintptr_t)Val->Val->Pointer; case TypeFP: return (long)Val->Val->FP; default: @@ -273,17 +273,17 @@ unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val) case TypeShort: return (unsigned long)Val->Val->ShortInteger; case TypeLong: - return (unsigned long)Val->Val->LongInteger; + return (uint64_t)Val->Val->LongInteger; case TypeUnsignedInt: return (unsigned long)Val->Val->UnsignedInteger; case TypeUnsignedShort: return (unsigned long)Val->Val->UnsignedShortInteger; case TypeUnsignedLong: - return (unsigned long)Val->Val->UnsignedLongInteger; + return (uint64_t)Val->Val->UnsignedLongInteger; case TypeUnsignedChar: return (unsigned long)Val->Val->UnsignedCharacter; case TypePointer: - return (unsigned long)Val->Val->Pointer; + return (uintptr_t)Val->Val->Pointer; case TypeFP: return (unsigned long)Val->Val->FP; default: @@ -342,7 +342,7 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, DestValue->Val->Character = (char)FromInt; break; case TypeLong: - DestValue->Val->LongInteger = (long)FromInt; + DestValue->Val->LongInteger = (int64_t)FromInt; break; case TypeUnsignedInt: DestValue->Val->UnsignedInteger = (unsigned int)FromInt; @@ -351,7 +351,7 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt; break; case TypeUnsignedLong: - DestValue->Val->UnsignedLongInteger = (unsigned long)FromInt; + DestValue->Val->UnsignedLongInteger = (uint64_t)FromInt; break; case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = (unsigned char)FromInt; @@ -519,7 +519,7 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue); break; case TypeLong: - DestValue->Val->LongInteger = (long)ExpressionCoerceInteger(SourceValue); + DestValue->Val->LongInteger = ExpressionCoerceInteger(SourceValue); break; case TypeUnsignedInt: DestValue->Val->UnsignedInteger = @@ -531,7 +531,7 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, break; case TypeUnsignedLong: DestValue->Val->UnsignedLongInteger = - (unsigned long)ExpressionCoerceUnsignedInteger(SourceValue); + ExpressionCoerceUnsignedInteger(SourceValue); break; case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = @@ -718,8 +718,8 @@ void ExpressionPrefixOperator(struct ParseState *Parser, ExpressionPushFP(Parser, StackTop, ResultFP); } else if (IS_NUMERIC_COERCIBLE(TopValue)) { /* integer prefix arithmetic */ - long ResultInt = 0; - long TopInt = ExpressionCoerceInteger(TopValue); + int64_t ResultInt = 0; + int64_t TopInt = ExpressionCoerceInteger(TopValue); switch (Op) { case TokenPlus: ResultInt = TopInt; @@ -811,8 +811,8 @@ void ExpressionPostfixOperator(struct ParseState *Parser, } ExpressionPushFP(Parser, StackTop, ResultFP); } else if (IS_NUMERIC_COERCIBLE(TopValue)) { - long ResultInt = 0; - long TopInt = ExpressionCoerceInteger(TopValue); + int64_t ResultInt = 0; + int64_t TopInt = ExpressionCoerceInteger(TopValue); switch (Op) { case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, true); @@ -991,8 +991,8 @@ void ExpressionInfixOperator(struct ParseState *Parser, ExpressionPushFP(Parser, StackTop, ResultFP); } else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) { /* integer operation */ - long TopInt = ExpressionCoerceInteger(TopValue); - long BottomInt = ExpressionCoerceInteger(BottomValue); + int64_t TopInt = ExpressionCoerceInteger(TopValue); + int64_t BottomInt = ExpressionCoerceInteger(BottomValue); switch (Op) { case TokenAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, false); @@ -1022,8 +1022,12 @@ void ExpressionInfixOperator(struct ParseState *Parser, BottomInt<>TopInt, false); + //ResultInt = ExpressionAssignInt(Parser, BottomValue, + // BottomInt>>TopInt, false); + if (BottomValue->Typ->Base == TypeUnsignedInt || BottomValue->Typ->Base == TypeUnsignedLong) + ResultInt = ExpressionAssignInt(Parser, BottomValue, (uint64_t) BottomInt >> TopInt, false); + else + ResultInt = ExpressionAssignInt(Parser, BottomValue, BottomInt >> TopInt, false); break; case TokenArithmeticAndAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, @@ -1072,6 +1076,12 @@ void ExpressionInfixOperator(struct ParseState *Parser, break; case TokenShiftLeft: ResultInt = BottomInt << TopInt; + /* + if (BottomValue->Typ->Base == TypeUnsignedInt || BottomValue->Typ->Base == TypeUnsignedLong) + ResultInt = (uint64_t) BottomInt >> TopInt; + else + ResultInt = BottomInt >> TopInt; + */ break; case TokenShiftRight: ResultInt = BottomInt >> TopInt; diff --git a/interpreter.h b/interpreter.h index 7d3f84f..02b90ae 100644 --- a/interpreter.h +++ b/interpreter.h @@ -18,6 +18,28 @@ #define max(a, b) (((a) > (b)) ? (a) : (b)) #endif */ +/* Get the name of a type */ +// #define typename(x) _Generic((x), \ +// _Bool: "_Bool", \ +// unsigned char: "unsigned char", \ +// char: "char", \ +// signed char: "signed char", \ +// short int: "short int", \ +// unsigned short int: "unsigned short int", \ +// int: "int", \ +// unsigned int: "unsigned int", \ +// long int: "long int", \ +// unsigned long int: "unsigned long int", \ +// long long int: "long long int", \ +// unsigned long long int: "unsigned long long int", \ +// float: "float", \ +// double: "double", \ +// long double: "long double", \ +// char *: "pointer to char", \ +// void *: "pointer to void", \ +// int *: "pointer to int", \ +// default: "other") (x) + #define MEM_ALIGN(x) (((x) + sizeof(ALIGN_TYPE)-1) & ~(sizeof(ALIGN_TYPE)-1)) diff --git a/tests/jpoirier/00_linked_list.c b/tests/jpoirier/00_linked_list.c index a1ead0b..cb7f7fa 100644 --- a/tests/jpoirier/00_linked_list.c +++ b/tests/jpoirier/00_linked_list.c @@ -22,8 +22,10 @@ void enqueue_tail(int d) { new_node->data = d; new_node->next = tail; new_node->prev = NULL; + if (tail != NULL) tail->prev = new_node; + tail = new_node; if (head == NULL) head = tail; @@ -36,12 +38,14 @@ void enqueue_tail(int d) { void enqueue_head(int d) { struct Node *new_node = malloc(sizeof(*new_node)); - +// printf("enqueue_head head: %p\n", (void*)head); new_node->data = d; new_node->next = NULL; new_node->prev = head; + if (head != NULL) head->next = new_node; + head = new_node; if (tail == NULL) tail = head; @@ -64,7 +68,11 @@ int dequeue_tail(void) { int d = tail->data; if (tail->next != NULL) tail->next->prev = NULL; + tail = tail->next; + if (t == head) + head = NULL; + free(t); return d; } @@ -79,14 +87,19 @@ int dequeue_head(void) { struct Node *t = head; int d = head->data; + if (head->prev != NULL) { head->prev->next = NULL; } + head = head->prev; +// printf("B. dequeue_head t: %p\n", (void*)t); // printf("B. dequeue_head head: %p\n", (void*)head); // printf("B. dequeue_head head next: %p\n", (void*)((head == NULL) ? NULL : head->next)); // printf("B. dequeue_head head prev: %p\n", (void*)((head == NULL) ? NULL : head->prev)); + if (t == tail) + tail = NULL; free(t); return d; @@ -99,6 +112,7 @@ void reverse_list(void) { tmp1 = tail; tail = head; head = tmp1; + while (tmp1 != NULL) { tmp2 = tmp1->next; tmp1->next = tmp1->prev; @@ -117,7 +131,6 @@ int main(int argc, char **argv) { for (i = 0; i < COUNT; i++) { printf("dequeue tail: %d\n", dequeue_tail()); } - for (i = 0; i < COUNT; i++) { printf("enqueue head: %d\n", i); enqueue_head(i); @@ -125,7 +138,6 @@ int main(int argc, char **argv) { for (i = 0; i < COUNT; i++) { printf("dequeue head: %d\n", dequeue_head()); } - for (i = 0; i < 10; i++) { printf("enqueue head: %d\n", i); enqueue_head(i);