commit
7008ce7f9e
|
@ -1,6 +1,7 @@
|
||||||
/* */
|
/* */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "../interpreter.h"
|
#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 */
|
/* printf-style format of an int or other word-sized object */
|
||||||
void StdioFprintfWord(StdOutStream *Stream, const char *Format,
|
void StdioFprintfWord(StdOutStream *Stream, const char *Format, unsigned int Value)
|
||||||
unsigned long Value)
|
|
||||||
{
|
{
|
||||||
if (Stream->FilePtr != NULL)
|
if (Stream->FilePtr != NULL)
|
||||||
Stream->CharCount += fprintf(Stream->FilePtr, Format, Value);
|
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 */
|
/* printf-style format of a floating point number */
|
||||||
void StdioFprintfFP(StdOutStream *Stream, const char *Format, double Value)
|
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 *FPos;
|
||||||
char OneFormatBuf[MAX_FORMAT+1];
|
char OneFormatBuf[MAX_FORMAT+1];
|
||||||
int OneFormatCount;
|
int OneFormatCount;
|
||||||
|
int ShowLong = 0;
|
||||||
struct ValueType *ShowType;
|
struct ValueType *ShowType;
|
||||||
StdOutStream SOStream;
|
StdOutStream SOStream;
|
||||||
Picoc *pc = Parser->pc;
|
Picoc *pc = Parser->pc;
|
||||||
|
@ -207,6 +266,9 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut,
|
||||||
case 'X':
|
case 'X':
|
||||||
ShowType = &pc->IntType;
|
ShowType = &pc->IntType;
|
||||||
break; /* integer base conversions */
|
break; /* integer base conversions */
|
||||||
|
case 'l':
|
||||||
|
ShowLong = 1;
|
||||||
|
break; /* long integer */
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
case 'E':
|
||||||
ShowType = &pc->FPType;
|
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 */
|
/* copy one character of format across to the OneFormatBuf */
|
||||||
|
if (*FPos != 'l') {
|
||||||
OneFormatBuf[OneFormatCount] = *FPos;
|
OneFormatBuf[OneFormatCount] = *FPos;
|
||||||
OneFormatCount++;
|
OneFormatCount++;
|
||||||
|
}
|
||||||
/* do special actions depending on the conversion type */
|
/* do special actions depending on the conversion type */
|
||||||
if (ShowType == &pc->VoidType) {
|
if (ShowType == &pc->VoidType) {
|
||||||
switch (*FPos) {
|
switch (*FPos) {
|
||||||
|
@ -265,7 +328,7 @@ int StdioBasePrintf(struct ParseState *Parser, FILE *Stream, char *StrOut,
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
ThisArg = (struct Value*)((char*)ThisArg +
|
ThisArg = (struct Value*)((char*)ThisArg +
|
||||||
MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
|
MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg)));
|
||||||
if (ThisArg->Typ->Base == TypeArray &&
|
if (ThisArg->Typ->Base == TypeArray &&
|
||||||
ThisArg->Typ->FromType->Base == TypeInt)
|
ThisArg->Typ->FromType->Base == TypeInt)
|
||||||
*(int *)ThisArg->Val->Pointer = SOStream.CharCount;
|
*(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)));
|
MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
|
||||||
if (ShowType == &pc->IntType) {
|
if (ShowType == &pc->IntType) {
|
||||||
/* show a signed integer */
|
/* show a signed integer */
|
||||||
if (IS_NUMERIC_COERCIBLE(ThisArg))
|
if (IS_NUMERIC_COERCIBLE(ThisArg)) {
|
||||||
StdioFprintfWord(&SOStream, OneFormatBuf,
|
if (ShowLong && ShowType == &pc->IntType)
|
||||||
ExpressionCoerceUnsignedInteger(ThisArg));
|
StdioFprintfLong(&SOStream, OneFormatBuf, ExpressionCoerceUnsignedInteger(ThisArg));
|
||||||
else
|
else
|
||||||
|
StdioFprintfWord(&SOStream, OneFormatBuf, (unsigned int)ExpressionCoerceUnsignedInteger(ThisArg));
|
||||||
|
} else
|
||||||
StdioOutPuts("XXX", &SOStream);
|
StdioOutPuts("XXX", &SOStream);
|
||||||
} else if (ShowType == &pc->FPType) {
|
} else if (ShowType == &pc->FPType) {
|
||||||
/* show a floating point number */
|
/* 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++) {
|
for (ArgCount = 0; ArgCount < Args->NumArgs; ArgCount++) {
|
||||||
ThisArg = (struct Value*)((char*)ThisArg +
|
ThisArg = (struct Value*)((char*)ThisArg +
|
||||||
MEM_ALIGN(sizeof(struct Value)+TypeStackSizeValue(ThisArg)));
|
MEM_ALIGN(sizeof(struct Value) + TypeStackSizeValue(ThisArg)));
|
||||||
|
|
||||||
if (ThisArg->Typ->Base == TypePointer)
|
if (ThisArg->Typ->Base == TypePointer)
|
||||||
ScanfArg[ArgCount] = ThisArg->Val->Pointer;
|
ScanfArg[ArgCount] = ThisArg->Val->Pointer;
|
||||||
|
|
52
expression.c
52
expression.c
|
@ -245,17 +245,17 @@ long ExpressionCoerceInteger(struct Value *Val)
|
||||||
case TypeShort:
|
case TypeShort:
|
||||||
return (long)Val->Val->ShortInteger;
|
return (long)Val->Val->ShortInteger;
|
||||||
case TypeLong:
|
case TypeLong:
|
||||||
return (long)Val->Val->LongInteger;
|
return (int64_t)Val->Val->LongInteger;
|
||||||
case TypeUnsignedInt:
|
case TypeUnsignedInt:
|
||||||
return (long)Val->Val->UnsignedInteger;
|
return (unsigned long)Val->Val->UnsignedInteger;
|
||||||
case TypeUnsignedShort:
|
case TypeUnsignedShort:
|
||||||
return (long)Val->Val->UnsignedShortInteger;
|
return (unsigned long)Val->Val->UnsignedShortInteger;
|
||||||
case TypeUnsignedLong:
|
case TypeUnsignedLong:
|
||||||
return (long)Val->Val->UnsignedLongInteger;
|
return (uint64_t)Val->Val->UnsignedLongInteger;
|
||||||
case TypeUnsignedChar:
|
case TypeUnsignedChar:
|
||||||
return (long)Val->Val->UnsignedCharacter;
|
return (unsigned long)Val->Val->UnsignedCharacter;
|
||||||
case TypePointer:
|
case TypePointer:
|
||||||
return (long)Val->Val->Pointer;
|
return (uintptr_t)Val->Val->Pointer;
|
||||||
case TypeFP:
|
case TypeFP:
|
||||||
return (long)Val->Val->FP;
|
return (long)Val->Val->FP;
|
||||||
default:
|
default:
|
||||||
|
@ -273,17 +273,17 @@ unsigned long ExpressionCoerceUnsignedInteger(struct Value *Val)
|
||||||
case TypeShort:
|
case TypeShort:
|
||||||
return (unsigned long)Val->Val->ShortInteger;
|
return (unsigned long)Val->Val->ShortInteger;
|
||||||
case TypeLong:
|
case TypeLong:
|
||||||
return (unsigned long)Val->Val->LongInteger;
|
return (uint64_t)Val->Val->LongInteger;
|
||||||
case TypeUnsignedInt:
|
case TypeUnsignedInt:
|
||||||
return (unsigned long)Val->Val->UnsignedInteger;
|
return (unsigned long)Val->Val->UnsignedInteger;
|
||||||
case TypeUnsignedShort:
|
case TypeUnsignedShort:
|
||||||
return (unsigned long)Val->Val->UnsignedShortInteger;
|
return (unsigned long)Val->Val->UnsignedShortInteger;
|
||||||
case TypeUnsignedLong:
|
case TypeUnsignedLong:
|
||||||
return (unsigned long)Val->Val->UnsignedLongInteger;
|
return (uint64_t)Val->Val->UnsignedLongInteger;
|
||||||
case TypeUnsignedChar:
|
case TypeUnsignedChar:
|
||||||
return (unsigned long)Val->Val->UnsignedCharacter;
|
return (unsigned long)Val->Val->UnsignedCharacter;
|
||||||
case TypePointer:
|
case TypePointer:
|
||||||
return (unsigned long)Val->Val->Pointer;
|
return (uintptr_t)Val->Val->Pointer;
|
||||||
case TypeFP:
|
case TypeFP:
|
||||||
return (unsigned long)Val->Val->FP;
|
return (unsigned long)Val->Val->FP;
|
||||||
default:
|
default:
|
||||||
|
@ -342,7 +342,7 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue,
|
||||||
DestValue->Val->Character = (char)FromInt;
|
DestValue->Val->Character = (char)FromInt;
|
||||||
break;
|
break;
|
||||||
case TypeLong:
|
case TypeLong:
|
||||||
DestValue->Val->LongInteger = (long)FromInt;
|
DestValue->Val->LongInteger = (int64_t)FromInt;
|
||||||
break;
|
break;
|
||||||
case TypeUnsignedInt:
|
case TypeUnsignedInt:
|
||||||
DestValue->Val->UnsignedInteger = (unsigned int)FromInt;
|
DestValue->Val->UnsignedInteger = (unsigned int)FromInt;
|
||||||
|
@ -351,7 +351,7 @@ long ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue,
|
||||||
DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt;
|
DestValue->Val->UnsignedShortInteger = (unsigned short)FromInt;
|
||||||
break;
|
break;
|
||||||
case TypeUnsignedLong:
|
case TypeUnsignedLong:
|
||||||
DestValue->Val->UnsignedLongInteger = (unsigned long)FromInt;
|
DestValue->Val->UnsignedLongInteger = (uint64_t)FromInt;
|
||||||
break;
|
break;
|
||||||
case TypeUnsignedChar:
|
case TypeUnsignedChar:
|
||||||
DestValue->Val->UnsignedCharacter = (unsigned char)FromInt;
|
DestValue->Val->UnsignedCharacter = (unsigned char)FromInt;
|
||||||
|
@ -519,7 +519,7 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue,
|
||||||
DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue);
|
DestValue->Val->Character = (char)ExpressionCoerceInteger(SourceValue);
|
||||||
break;
|
break;
|
||||||
case TypeLong:
|
case TypeLong:
|
||||||
DestValue->Val->LongInteger = (long)ExpressionCoerceInteger(SourceValue);
|
DestValue->Val->LongInteger = ExpressionCoerceInteger(SourceValue);
|
||||||
break;
|
break;
|
||||||
case TypeUnsignedInt:
|
case TypeUnsignedInt:
|
||||||
DestValue->Val->UnsignedInteger =
|
DestValue->Val->UnsignedInteger =
|
||||||
|
@ -531,7 +531,7 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue,
|
||||||
break;
|
break;
|
||||||
case TypeUnsignedLong:
|
case TypeUnsignedLong:
|
||||||
DestValue->Val->UnsignedLongInteger =
|
DestValue->Val->UnsignedLongInteger =
|
||||||
(unsigned long)ExpressionCoerceUnsignedInteger(SourceValue);
|
ExpressionCoerceUnsignedInteger(SourceValue);
|
||||||
break;
|
break;
|
||||||
case TypeUnsignedChar:
|
case TypeUnsignedChar:
|
||||||
DestValue->Val->UnsignedCharacter =
|
DestValue->Val->UnsignedCharacter =
|
||||||
|
@ -718,8 +718,8 @@ void ExpressionPrefixOperator(struct ParseState *Parser,
|
||||||
ExpressionPushFP(Parser, StackTop, ResultFP);
|
ExpressionPushFP(Parser, StackTop, ResultFP);
|
||||||
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||||
/* integer prefix arithmetic */
|
/* integer prefix arithmetic */
|
||||||
long ResultInt = 0;
|
int64_t ResultInt = 0;
|
||||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
int64_t TopInt = ExpressionCoerceInteger(TopValue);
|
||||||
switch (Op) {
|
switch (Op) {
|
||||||
case TokenPlus:
|
case TokenPlus:
|
||||||
ResultInt = TopInt;
|
ResultInt = TopInt;
|
||||||
|
@ -811,8 +811,8 @@ void ExpressionPostfixOperator(struct ParseState *Parser,
|
||||||
}
|
}
|
||||||
ExpressionPushFP(Parser, StackTop, ResultFP);
|
ExpressionPushFP(Parser, StackTop, ResultFP);
|
||||||
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
} else if (IS_NUMERIC_COERCIBLE(TopValue)) {
|
||||||
long ResultInt = 0;
|
int64_t ResultInt = 0;
|
||||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
int64_t TopInt = ExpressionCoerceInteger(TopValue);
|
||||||
switch (Op) {
|
switch (Op) {
|
||||||
case TokenIncrement:
|
case TokenIncrement:
|
||||||
ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, true);
|
ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, true);
|
||||||
|
@ -991,8 +991,8 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
ExpressionPushFP(Parser, StackTop, ResultFP);
|
ExpressionPushFP(Parser, StackTop, ResultFP);
|
||||||
} else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
|
} else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) {
|
||||||
/* integer operation */
|
/* integer operation */
|
||||||
long TopInt = ExpressionCoerceInteger(TopValue);
|
int64_t TopInt = ExpressionCoerceInteger(TopValue);
|
||||||
long BottomInt = ExpressionCoerceInteger(BottomValue);
|
int64_t BottomInt = ExpressionCoerceInteger(BottomValue);
|
||||||
switch (Op) {
|
switch (Op) {
|
||||||
case TokenAssign:
|
case TokenAssign:
|
||||||
ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, false);
|
ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, false);
|
||||||
|
@ -1022,8 +1022,12 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
BottomInt<<TopInt, false);
|
BottomInt<<TopInt, false);
|
||||||
break;
|
break;
|
||||||
case TokenShiftRightAssign:
|
case TokenShiftRightAssign:
|
||||||
ResultInt = ExpressionAssignInt(Parser, BottomValue,
|
//ResultInt = ExpressionAssignInt(Parser, BottomValue,
|
||||||
BottomInt>>TopInt, false);
|
// 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;
|
break;
|
||||||
case TokenArithmeticAndAssign:
|
case TokenArithmeticAndAssign:
|
||||||
ResultInt = ExpressionAssignInt(Parser, BottomValue,
|
ResultInt = ExpressionAssignInt(Parser, BottomValue,
|
||||||
|
@ -1072,6 +1076,12 @@ void ExpressionInfixOperator(struct ParseState *Parser,
|
||||||
break;
|
break;
|
||||||
case TokenShiftLeft:
|
case TokenShiftLeft:
|
||||||
ResultInt = BottomInt << TopInt;
|
ResultInt = BottomInt << TopInt;
|
||||||
|
/*
|
||||||
|
if (BottomValue->Typ->Base == TypeUnsignedInt || BottomValue->Typ->Base == TypeUnsignedLong)
|
||||||
|
ResultInt = (uint64_t) BottomInt >> TopInt;
|
||||||
|
else
|
||||||
|
ResultInt = BottomInt >> TopInt;
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
case TokenShiftRight:
|
case TokenShiftRight:
|
||||||
ResultInt = BottomInt >> TopInt;
|
ResultInt = BottomInt >> TopInt;
|
||||||
|
|
|
@ -18,6 +18,28 @@
|
||||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#endif
|
#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))
|
#define MEM_ALIGN(x) (((x) + sizeof(ALIGN_TYPE)-1) & ~(sizeof(ALIGN_TYPE)-1))
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,10 @@ void enqueue_tail(int d) {
|
||||||
new_node->data = d;
|
new_node->data = d;
|
||||||
new_node->next = tail;
|
new_node->next = tail;
|
||||||
new_node->prev = NULL;
|
new_node->prev = NULL;
|
||||||
|
|
||||||
if (tail != NULL)
|
if (tail != NULL)
|
||||||
tail->prev = new_node;
|
tail->prev = new_node;
|
||||||
|
|
||||||
tail = new_node;
|
tail = new_node;
|
||||||
if (head == NULL)
|
if (head == NULL)
|
||||||
head = tail;
|
head = tail;
|
||||||
|
@ -36,12 +38,14 @@ void enqueue_tail(int d) {
|
||||||
|
|
||||||
void enqueue_head(int d) {
|
void enqueue_head(int d) {
|
||||||
struct Node *new_node = malloc(sizeof(*new_node));
|
struct Node *new_node = malloc(sizeof(*new_node));
|
||||||
|
// printf("enqueue_head head: %p\n", (void*)head);
|
||||||
new_node->data = d;
|
new_node->data = d;
|
||||||
new_node->next = NULL;
|
new_node->next = NULL;
|
||||||
new_node->prev = head;
|
new_node->prev = head;
|
||||||
|
|
||||||
if (head != NULL)
|
if (head != NULL)
|
||||||
head->next = new_node;
|
head->next = new_node;
|
||||||
|
|
||||||
head = new_node;
|
head = new_node;
|
||||||
if (tail == NULL)
|
if (tail == NULL)
|
||||||
tail = head;
|
tail = head;
|
||||||
|
@ -64,7 +68,11 @@ int dequeue_tail(void) {
|
||||||
int d = tail->data;
|
int d = tail->data;
|
||||||
if (tail->next != NULL)
|
if (tail->next != NULL)
|
||||||
tail->next->prev = NULL;
|
tail->next->prev = NULL;
|
||||||
|
|
||||||
tail = tail->next;
|
tail = tail->next;
|
||||||
|
if (t == head)
|
||||||
|
head = NULL;
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -79,14 +87,19 @@ int dequeue_head(void) {
|
||||||
|
|
||||||
struct Node *t = head;
|
struct Node *t = head;
|
||||||
int d = head->data;
|
int d = head->data;
|
||||||
|
|
||||||
if (head->prev != NULL) {
|
if (head->prev != NULL) {
|
||||||
head->prev->next = NULL;
|
head->prev->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
head = head->prev;
|
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: %p\n", (void*)head);
|
||||||
// printf("B. dequeue_head head next: %p\n", (void*)((head == NULL) ? NULL : head->next));
|
// 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));
|
// printf("B. dequeue_head head prev: %p\n", (void*)((head == NULL) ? NULL : head->prev));
|
||||||
|
if (t == tail)
|
||||||
|
tail = NULL;
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
return d;
|
return d;
|
||||||
|
@ -99,6 +112,7 @@ void reverse_list(void) {
|
||||||
tmp1 = tail;
|
tmp1 = tail;
|
||||||
tail = head;
|
tail = head;
|
||||||
head = tmp1;
|
head = tmp1;
|
||||||
|
|
||||||
while (tmp1 != NULL) {
|
while (tmp1 != NULL) {
|
||||||
tmp2 = tmp1->next;
|
tmp2 = tmp1->next;
|
||||||
tmp1->next = tmp1->prev;
|
tmp1->next = tmp1->prev;
|
||||||
|
@ -117,7 +131,6 @@ int main(int argc, char **argv) {
|
||||||
for (i = 0; i < COUNT; i++) {
|
for (i = 0; i < COUNT; i++) {
|
||||||
printf("dequeue tail: %d\n", dequeue_tail());
|
printf("dequeue tail: %d\n", dequeue_tail());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < COUNT; i++) {
|
for (i = 0; i < COUNT; i++) {
|
||||||
printf("enqueue head: %d\n", i);
|
printf("enqueue head: %d\n", i);
|
||||||
enqueue_head(i);
|
enqueue_head(i);
|
||||||
|
@ -125,7 +138,6 @@ int main(int argc, char **argv) {
|
||||||
for (i = 0; i < COUNT; i++) {
|
for (i = 0; i < COUNT; i++) {
|
||||||
printf("dequeue head: %d\n", dequeue_head());
|
printf("dequeue head: %d\n", dequeue_head());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
printf("enqueue head: %d\n", i);
|
printf("enqueue head: %d\n", i);
|
||||||
enqueue_head(i);
|
enqueue_head(i);
|
||||||
|
|
Loading…
Reference in a new issue