commit
7008ce7f9e
|
@ -1,6 +1,7 @@
|
|||
/* */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.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 */
|
||||
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;
|
||||
|
|
56
expression.c
56
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);
|
||||
break;
|
||||
case TokenShiftRightAssign:
|
||||
ResultInt = ExpressionAssignInt(Parser, BottomValue,
|
||||
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;
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue