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:
parent
a9494ff382
commit
c9abac9fad
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
|||
CC=gcc
|
||||
CFLAGS=-Wall -g -DDEBUG_HEAP
|
||||
CFLAGS=-Wall -g
|
||||
LIBS=-lm
|
||||
|
||||
TARGET = picoc
|
||||
|
|
10
heap.c
10
heap.c
|
@ -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
2
lex.c
|
@ -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
58
parse.c
|
@ -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)
|
||||
|
|
2
table.c
2
table.c
|
@ -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)
|
||||
{
|
||||
|
|
14
variable.c
14
variable.c
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue