Fixed an EOF lexing problem.

Added some optional debug.
Turned debug off.
Fixed handling of LValues to work with stack frames better.
Fixed the handling of stack frames in function calls.
Fixed a bug in popping variable stack frames.

git-svn-id: http://picoc.googlecode.com/svn/trunk@65 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-02-04 00:17:30 +00:00
parent a9494ff382
commit c9abac9fad
6 changed files with 58 additions and 30 deletions

View file

@ -1,5 +1,5 @@
CC=gcc
CFLAGS=-Wall -g -DDEBUG_HEAP
CFLAGS=-Wall -g
LIBS=-lm
TARGET = picoc

10
heap.c
View file

@ -66,6 +66,9 @@ void *HeapStackGetFreeSpace(int *MemAvailable)
/* push a new stack frame on to the stack */
void HeapPushStackFrame()
{
#ifdef DEBUG_HEAP
printf("Adding stack frame at 0x%lx\n", (unsigned long)StackTop);
#endif
*(void **)StackTop = StackFrame;
StackFrame = StackTop;
StackTop += sizeof(void *);
@ -74,10 +77,13 @@ void HeapPushStackFrame()
/* pop the current stack frame, freeing all memory in the frame. can return NULL */
int HeapPopStackFrame()
{
if (*(void **)StackFrame == NULL)
if (*(void **)StackFrame != NULL)
{
StackTop = StackFrame;
StackFrame = *(void **)StackFrame;
#ifdef DEBUG_HEAP
printf("Popping stack frame back to 0x%lx\n", (unsigned long)StackTop);
#endif
return TRUE;
}
else
@ -97,7 +103,7 @@ void *HeapAlloc(int Size)
if (Bucket < FREELIST_BUCKETS && FreeListBucket[Bucket] != NULL)
{ /* try to allocate from a freelist bucket first */
#ifdef DEBUG_HEAP
#ifdef DEBUG_HEAP
printf("allocating %d(%d) from bucket", Size, AllocSize);
#endif
NewMem = FreeListBucket[Bucket];

2
lex.c
View file

@ -402,7 +402,7 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I
}
else
{
if (IncPos && Token != TokenEndOfLine)
if (IncPos && Token != TokenEOF)
Parser->Pos++;
}

58
parse.c
View file

@ -32,6 +32,12 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
VariableGet(Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base != TypeFunction)
ProgramFail(Parser, "not a function - can't call");
*Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, ResultOnHeap);
if (FuncValue->Val->FuncDef.Intrinsic == NULL)
VariableStackFrameAdd(Parser);
else
HeapPushStackFrame();
}
/* parse arguments */
@ -43,7 +49,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
ProgramFail(Parser, "parameter %d to %s is the wrong type", ParameterUsed, FuncName);
ParameterUsed++;
if (RunIt && ParameterUsed >= FuncValue->Val->FuncDef.NumParams)
if (RunIt && ParameterUsed > FuncValue->Val->FuncDef.NumParams)
ProgramFail(Parser, "too many arguments");
Token = LexGetToken(Parser, NULL, TRUE);
@ -62,9 +68,6 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
{ /* run the function */
int Count;
VariableStackFrameAdd(Parser);
*Result = VariableAllocValueFromType(Parser, FuncValue->Val->FuncDef.ReturnType, ResultOnHeap);
if (FuncValue->Val->FuncDef.Intrinsic == NULL)
{ /* run a user-defined function */
struct ParseState FuncParser = FuncValue->Val->FuncDef.Body;
@ -77,24 +80,26 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
if (FuncValue->Val->FuncDef.ReturnType != (*Result)->Typ)
ProgramFail(&FuncParser, "bad type of return value");
VariableStackFramePop(Parser);
}
else
{
FuncValue->Val->FuncDef.Intrinsic();
VariableStackFramePop(Parser);
for (Count = ParameterUsed-1; Count >= 0; Count--) /* free stack space used by parameters */
VariableStackPop(Parser, Parameter[Count]);
HeapPopStackFrame();
}
}
}
/* parse a single value */
int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, int RunIt)
int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, struct Value **LValue, int RunIt)
{
struct ParseState PreState = *Parser;
struct Value *LexValue;
int IntValue;
enum LexToken Token = LexGetToken(Parser, &LexValue, TRUE);
struct Value *LocalLValue = NULL;
int Success = TRUE;
switch (Token)
{
@ -136,27 +141,32 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
{
if (RunIt)
{
struct Value *IdentValue;
VariableGet(Parser, LexValue->Val->String, &IdentValue);
if (IdentValue->Typ->Base == TypeMacro)
VariableGet(Parser, LexValue->Val->String, &LocalLValue);
if (LocalLValue->Typ->Base == TypeMacro)
{
struct ParseState MacroLexer = IdentValue->Val->Parser;
struct ParseState MacroLexer = LocalLValue->Val->Parser;
if (!ParseExpression(&MacroLexer, Result, ResultOnHeap, TRUE))
ProgramFail(&MacroLexer, "expression expected");
}
else if (!ISVALUETYPE(IdentValue->Typ))
else if (!ISVALUETYPE(LocalLValue->Typ))
ProgramFail(Parser, "bad variable type");
else
*Result = VariableAllocValueAndCopy(Parser, LocalLValue, ResultOnHeap);
}
}
break;
default:
*Parser = PreState;
return FALSE;
Success = FALSE;
break;
}
return TRUE;
if (LValue != NULL)
*LValue = LocalLValue;
return Success;
}
struct Value *ParsePushFP(struct ParseState *Parser, int ResultOnHeap, double NewFP)
@ -178,8 +188,9 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
{
struct Value *CurrentValue;
struct Value *TotalValue;
struct Value *LValue;
if (!ParseValue(Parser, &TotalValue, ResultOnHeap, RunIt))
if (!ParseValue(Parser, &TotalValue, ResultOnHeap, &LValue, RunIt))
return FALSE;
while (TRUE)
@ -202,16 +213,17 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
if (RunIt)
{
if (CurrentValue->Typ->Base != TypeInt || TotalValue->Typ->Base != TypeInt)
if (CurrentValue->Typ->Base != TypeInt || LValue == NULL || LValue->Typ->Base != TypeInt)
ProgramFail(Parser, "can't assign");
switch (Token)
{
case TokenAddAssign: TotalValue->Val->Integer += CurrentValue->Val->Integer; break;
case TokenSubtractAssign: TotalValue->Val->Integer -= CurrentValue->Val->Integer; break;
default: TotalValue->Val->Integer = CurrentValue->Val->Integer; break;
case TokenAddAssign: LValue->Val->Integer += CurrentValue->Val->Integer; break;
case TokenSubtractAssign: LValue->Val->Integer -= CurrentValue->Val->Integer; break;
default: LValue->Val->Integer = CurrentValue->Val->Integer; break;
}
VariableStackPop(Parser, CurrentValue);
TotalValue->Val->Integer = LValue->Val->Integer;
}
// fallthrough
@ -221,7 +233,7 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
return TRUE;
}
if (!ParseValue(Parser, &CurrentValue, ResultOnHeap, RunIt))
if (!ParseValue(Parser, &CurrentValue, ResultOnHeap, NULL, RunIt))
return FALSE;
if (RunIt)

View file

@ -32,7 +32,7 @@ void TableInit(struct Table *Tbl, struct TableEntry **HashTable, int Size, int O
static int TableSearch(struct Table *Tbl, const char *Key, int *AddAt)
{
struct TableEntry *Entry;
int HashValue = ((unsigned long)Key) % Tbl->Size;
int HashValue = ((unsigned long)Key) % Tbl->Size; /* shared strings have unique addresses so we don't need to hash them */
for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next)
{

View file

@ -30,6 +30,11 @@ void *VariableAlloc(struct ParseState *Parser, int Size, int OnHeap)
if (NewValue == NULL)
ProgramFail(Parser, "out of memory");
#ifdef DEBUG_HEAP
if (!OnHeap)
printf("pushing %d at 0x%lx\n", Size, (unsigned long)NewValue);
#endif
return NewValue;
}
@ -97,8 +102,13 @@ void VariableStackPop(struct ParseState *Parser, struct Value *Var)
{
int Success;
#ifdef DEBUG_HEAP
if (Var->ValOnStack)
printf("popping %d at 0x%lx\n", sizeof(struct Value) + Var->Typ->Sizeof, (unsigned long)Var);
#endif
if (Var->ValOnHeap)
{
{ // XXX - is this a mismatch with allocation?
HeapFree(Var->Val);
Success = HeapPopStack(Var, sizeof(struct Value)); /* free from heap */
}
@ -130,7 +140,7 @@ void VariableStackFramePop(struct ParseState *Parser)
if (TopStackFrame == NULL)
ProgramFail(Parser, "stack is empty - can't go back");
TopStackFrame = TopStackFrame->PreviousStackFrame;
*Parser = TopStackFrame->ReturnParser;
TopStackFrame = TopStackFrame->PreviousStackFrame;
HeapPopStackFrame();
}