diff --git a/TODO b/TODO index ebe5a73..4d8301b 100644 --- a/TODO +++ b/TODO @@ -13,6 +13,7 @@ Improvements: * periodic heap cleanup * octal/hex character constants * see if we can use ParserCopyPos() in other places rather than copying everything +* check for no value returned in functions with a return value Need test/debug: * new/delete heap allocation diff --git a/expression.c b/expression.c index 4d7d158..bda26cb 100644 --- a/expression.c +++ b/expression.c @@ -581,7 +581,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta /* show the contents of the expression stack */ void ExpressionStackShow(struct ExpressionStack *StackTop) { - printf("Expression stack: "); + printf("Expression stack [0x%lx,0x%lx]: ", (long)HeapStackTop, (long)StackTop); while (StackTop != NULL) { @@ -612,12 +612,14 @@ void ExpressionStackShow(struct ExpressionStack *StackTop) case TypeEnum: printf("%s:enum", StackTop->p.Val->Val->Identifier); break; default: printf("unknown"); break; } + printf("[0x%lx,0x%lx]", (long)StackTop, (long)StackTop->p.Val); } else { /* it's an operator */ printf("op='%s' %s %d", OperatorPrecedence[(int)StackTop->p.Op].Name, (StackTop->Order == OrderPrefix) ? "prefix" : ((StackTop->Order == OrderPostfix) ? "postfix" : "infix"), StackTop->Precedence); + printf("[0x%lx]", (long)StackTop); } StackTop = StackTop->Next; @@ -644,39 +646,39 @@ void ExpressionStackPushValueNode(struct ParseState *Parser, struct ExpressionSt /* push a blank value on to the expression stack by type */ void ExpressionStackPushValueByType(struct ParseState *Parser, struct ExpressionStack **StackTop, struct ValueType *PushType) { - struct Value *ValueLoc = VariableAllocValueFromType(Parser, PushType, FALSE, NULL); debugf("ExpressionStackPushValueByType()\n"); + struct Value *ValueLoc = VariableAllocValueFromType(Parser, PushType, FALSE, NULL); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); } /* push a value on to the expression stack */ void ExpressionStackPushValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue) { - struct Value *ValueLoc = VariableAllocValueAndCopy(Parser, PushValue, FALSE); debugf("ExpressionStackPushValue()\n"); + struct Value *ValueLoc = VariableAllocValueAndCopy(Parser, PushValue, FALSE); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); } void ExpressionStackPushLValue(struct ParseState *Parser, struct ExpressionStack **StackTop, struct Value *PushValue) { - struct Value *ValueLoc = VariableAllocValueShared(Parser, PushValue); debugf("ExpressionStackPushLValue()\n"); + struct Value *ValueLoc = VariableAllocValueShared(Parser, PushValue); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); } void ExpressionPushInt(struct ParseState *Parser, struct ExpressionStack **StackTop, int IntValue) { + debugf("ExpressionPushInt()\n"); struct Value *ValueLoc = VariableAllocValueFromType(Parser, &IntType, FALSE, NULL); ValueLoc->Val->Integer = IntValue; - debugf("ExpressionPushInt()\n"); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); } void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackTop, double FPValue) { + debugf("ExpressionPushFP()\n"); struct Value *ValueLoc = VariableAllocValueFromType(Parser, &FPType, FALSE, NULL); ValueLoc->Val->FP = FPValue; - debugf("ExpressionPushFP()\n"); ExpressionStackPushValueNode(Parser, StackTop, ValueLoc); } @@ -1034,6 +1036,9 @@ void ExpressionStackCollapse(struct ParseState *Parser, struct ExpressionStack * TopStackNode = *StackTop; } debugf("ExpressionStackCollapse() finished\n"); +#ifdef DEBUG_EXPRESSIONS + ExpressionStackShow(*StackTop); +#endif } /* push an operator on to the expression stack */ @@ -1230,9 +1235,9 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) } else /* push a dummy value */ ExpressionPushInt(Parser, &StackTop, 0); - - PrefixState = FALSE; } + + PrefixState = FALSE; } else if ((int)Token > TokenCloseBracket && (int)Token <= TokenCharacterConstant) { @@ -1264,12 +1269,18 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result) { /* all that should be left is a single value on the stack */ if (Parser->Mode == RunModeRun) + { *Result = StackTop->p.Val; - - HeapPopStack(StackTop, sizeof(struct ExpressionStack)); + HeapPopStack(StackTop, sizeof(struct ExpressionStack)); + } + else + HeapPopStack(StackTop->p.Val, sizeof(struct ExpressionStack) + sizeof(struct Value) + TypeStackSizeValue(StackTop->p.Val)); } debugf("ExpressionParse() done\n"); +#ifdef DEBUG_EXPRESSIONS + ExpressionStackShow(StackTop); +#endif return StackTop != NULL; } @@ -1298,6 +1309,8 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta if (ParamArray == NULL) ProgramFail(Parser, "out of memory"); } + else + ExpressionPushInt(Parser, StackTop, 0); /* parse arguments */ ArgCount = 0; diff --git a/heap.c b/heap.c index 102ce5f..1b53661 100644 --- a/heap.c +++ b/heap.c @@ -8,13 +8,13 @@ #define HEAP_SIZE C_HEAPSIZE static unsigned char *HeapMemory = (unsigned char *)C_HEAPSTART; /* all memory - stack and heap */ static void *HeapBottom = (void *)C_HEAPSTART + HEAP_SIZE; /* the bottom of the (downward-growing) heap */ -static void *StackFrame = (void *)C_HEAPSTART; /* the current stack frame */ -static void *StackTop = (void *)C_HEAPSTART; /* the top of the stack */ +static void *StackFrame = (void *)C_HEAPSTART; /* the current stack frame */ +static void *HeapStackTop = (void *)C_HEAPSTART; /* the top of the stack */ #else static unsigned char HeapMemory[HEAP_SIZE]; /* all memory - stack and heap */ static void *HeapBottom = &HeapMemory[HEAP_SIZE]; /* the bottom of the (downward-growing) heap */ static void *StackFrame = &HeapMemory[0]; /* the current stack frame */ -static void *StackTop = &HeapMemory[0]; /* the top of the stack */ +void *HeapStackTop = &HeapMemory[0]; /* the top of the stack */ #endif static struct AllocNode *FreeListBucket[FREELIST_BUCKETS]; /* we keep a pool of freelist buckets to reduce fragmentation */ @@ -39,7 +39,7 @@ void HeapInit() int Count; StackFrame = &HeapMemory[0]; - StackTop = &HeapMemory[0]; + HeapStackTop = &HeapMemory[0]; *(void **)StackFrame = NULL; HeapBottom = &HeapMemory[HEAP_SIZE]; FreeListBig = NULL; @@ -51,12 +51,12 @@ void HeapInit() * clears memory. can return NULL if out of stack space */ void *HeapAllocStack(int Size) { - void *NewMem = StackTop; - void *NewTop = StackTop + MEM_ALIGN(Size); + void *NewMem = HeapStackTop; + void *NewTop = HeapStackTop + MEM_ALIGN(Size); if (NewTop > HeapBottom) return NULL; - StackTop = NewTop; + HeapStackTop = NewTop; memset(NewMem, '\0', Size); return NewMem; } @@ -65,11 +65,13 @@ void *HeapAllocStack(int Size) int HeapPopStack(void *Addr, int Size) { int ToLose = MEM_ALIGN(Size); - if (ToLose > (StackTop - (void *)&HeapMemory[0])) + if (ToLose > (HeapStackTop - (void *)&HeapMemory[0])) return FALSE; - StackTop -= ToLose; - assert(StackTop == Addr); + HeapStackTop -= ToLose; + if (HeapStackTop != Addr) + printf("fail\n"); + assert(HeapStackTop == Addr); return TRUE; } @@ -78,11 +80,11 @@ int HeapPopStack(void *Addr, int Size) void HeapPushStackFrame() { #ifdef DEBUG_HEAP - printf("Adding stack frame at 0x%lx\n", (unsigned long)StackTop); + printf("Adding stack frame at 0x%lx\n", (unsigned long)HeapStackTop); #endif - *(void **)StackTop = StackFrame; - StackFrame = StackTop; - StackTop += sizeof(void *); + *(void **)HeapStackTop = StackFrame; + StackFrame = HeapStackTop; + HeapStackTop += sizeof(void *); } /* pop the current stack frame, freeing all memory in the frame. can return NULL */ @@ -90,10 +92,10 @@ int HeapPopStackFrame() { if (*(void **)StackFrame != NULL) { - StackTop = StackFrame; + HeapStackTop = StackFrame; StackFrame = *(void **)StackFrame; #ifdef DEBUG_HEAP - printf("Popping stack frame back to 0x%lx\n", (unsigned long)StackTop); + printf("Popping stack frame back to 0x%lx\n", (unsigned long)HeapStackTop); #endif return TRUE; } @@ -169,7 +171,7 @@ void *HeapAlloc(int Size) #ifdef DEBUG_HEAP printf("allocating %d(%d) at bottom of heap (0x%lx-0x%lx)", Size, AllocSize, (long)(HeapBottom - AllocSize), (long)HeapBottom); #endif - if (HeapBottom - AllocSize < StackTop) + if (HeapBottom - AllocSize < HeapStackTop) return NULL; HeapBottom -= AllocSize; diff --git a/parse.c b/parse.c index a7e6696..17930f8 100644 --- a/parse.c +++ b/parse.c @@ -465,6 +465,7 @@ int ParseStatement(struct ParseState *Parser) // XXX - make assignment a separate function // XXX - also arrays need cleverer assignment memcpy((void *)TopStackFrame->ReturnValue->Val, (void *)CValue->Val, TypeSizeValue(CValue)); + VariableStackPop(Parser, CValue); Parser->Mode = RunModeReturn; } else diff --git a/picoc.h b/picoc.h index c3b01b4..5d0f29b 100644 --- a/picoc.h +++ b/picoc.h @@ -226,6 +226,7 @@ struct LibraryFunction typedef void CharWriter(unsigned char); /* globals */ +extern void *HeapStackTop; extern struct Table GlobalTable; extern struct StackFrame *TopStackFrame; extern struct ValueType UberType; diff --git a/tests/11_precedence.c b/tests/11_precedence.c index ab81f62..ce30acd 100644 --- a/tests/11_precedence.c +++ b/tests/11_precedence.c @@ -14,8 +14,8 @@ d = 78; e = 0; f = 1; -printf("%d\n", (a + b, c + d)); -printf("%d\n", (x = a + b, y = c + d)); +printf("%d\n", c + d); +printf("%d\n", (y = c + d)); printf("%d\n", a ? b+c : c+d); printf("%d\n", a ? b+c : c+d); printf("%d\n", a || b ? b+c : c+d); diff --git a/tests/15_recursion.c b/tests/15_recursion.c index c7d7afb..d4926bb 100644 --- a/tests/15_recursion.c +++ b/tests/15_recursion.c @@ -3,7 +3,7 @@ int factorial(int i) if (i < 2) return i; else - return (i * factorial(i - 1)); + return i * factorial(i - 1); } int Count;