Local variables implemented

git-svn-id: http://picoc.googlecode.com/svn/trunk@18 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2008-12-22 02:29:19 +00:00
parent b57f0eac65
commit e5920c041c
4 changed files with 45 additions and 15 deletions

33
parse.c
View file

@ -11,6 +11,10 @@ struct TableEntry GlobalHashTable[GLOBAL_TABLE_SIZE];
struct LexState FunctionStore[FUNCTION_STORE_MAX];
int FunctionStoreUsed = 0;
/* the stack */
struct StackFrame Stack[STACK_MAX];
int StackUsed = 0;
/* local prototypes */
int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt);
void ParseIntExpression(struct LexState *Lexer, struct Value *Result, int RunIt);
@ -20,7 +24,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt);
/* initialise the parser */
void ParseInit()
{
TableInit(&GlobalTable, &GlobalHashTable[0], "global", GLOBAL_TABLE_SIZE);
TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE);
}
/* define a variable */
@ -30,19 +34,44 @@ void VariableDefine(struct LexState *Lexer, const Str *Ident, enum ValueType Typ
memset(&NewValue, '\0', sizeof(NewValue));
NewValue.Typ = Typ;
if (!TableSet(&GlobalTable, Ident, &NewValue))
if (!TableSet((StackUsed == 0) ? &GlobalTable : &Stack[StackUsed-1].LocalTable, Ident, &NewValue))
ProgramFail(Lexer, "'%S' is already defined", Ident);
}
/* get the value of a variable. must be defined */
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal)
{
int Frame;
for (Frame = StackUsed-1; Frame >= 0; Frame--)
{
if (TableGet(&Stack[Frame].LocalTable, Ident, LVal))
{
*Val = **LVal;
return;
}
}
if (!TableGet(&GlobalTable, Ident, LVal))
ProgramFail(Lexer, "'%S' is undefined", Ident);
*Val = **LVal;
}
/* add a stack frame when doing a function call */
void StackFrameAdd(struct LexState *Lexer)
{
struct StackFrame *NewFrame = &Stack[StackUsed];
if (StackUsed >= STACK_MAX)
ProgramFail(Lexer, "too many nested function calls");
NewFrame->ReturnLex = *Lexer;
TableInit(&NewFrame->LocalTable, &NewFrame->LocalHashTable[0], LOCAL_TABLE_SIZE);
StackUsed++;
}
/* parse a single value */
int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue, int RunIt)
{

View file

@ -71,7 +71,6 @@ void ScanFile(const Str *FileName)
int main(int argc, char **argv)
{
Str FileName;
Str StartFunc;
if (argc < 2)
Fail("Format: picoc <program.c> <args>...\n");

13
picoc.h
View file

@ -7,6 +7,8 @@
#define USE_MALLOC
#define GLOBAL_TABLE_SIZE 199 /* global variable table */
#define FUNCTION_STORE_MAX 50 /* maximum number of used-defined functions */
#define STACK_MAX 10 /* maximum function call stack depth */
#define LOCAL_TABLE_SIZE 11 /* maximum number of local variables */
#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
/* handy definitions */
@ -128,7 +130,6 @@ struct TableEntry
struct Table
{
const char *Name;
short Size;
struct TableEntry *HashTable;
};
@ -142,6 +143,14 @@ struct LexState
const Str *FileName;
};
/* stack frame for function calls */
struct StackFrame
{
struct LexState ReturnLex; /* how we got here */
struct Table LocalTable; /* the local variables and parameters */
struct TableEntry LocalHashTable[LOCAL_TABLE_SIZE];
};
/* str.c */
void StrToC(char *Dest, int DestSize, const Str *Source);
@ -157,7 +166,7 @@ void ProgramFail(struct LexState *Lexer, const char *Message, ...);
void ScanFile(const Str *FileName);
/* table.c */
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, const char *Name, int Size);
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, int Size);
int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val);
int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val);

13
table.c
View file

@ -1,8 +1,6 @@
#include <string.h>
#include "picoc.h"
static unsigned int TableHash(const Str *Key)
{
unsigned int Hash;
@ -24,10 +22,8 @@ static unsigned int TableHash(const Str *Key)
return Hash;
}
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, const char *Name, int Size)
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, int Size)
{
Tbl->Name = Name;
Tbl->Size = Size;
Tbl->HashTable = HashTable;
memset(HashTable, '\0', sizeof(struct TableEntry) * Size);
@ -48,7 +44,6 @@ static int TableCheckEntry(struct Table *Tbl, const Str *Key, int HashPos)
return -2; /* wrong key */
}
static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
{
int HashValue;
@ -76,7 +71,6 @@ static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
return -1;
}
int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
{
int HashPos;
@ -87,7 +81,7 @@ int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
if (HashPos == -1)
{
if (AddAt == -1)
Fail("table '%s' is full\n", Tbl->Name);
Fail("variable table is full\n");
else
{ /* add it to the table */
@ -100,7 +94,6 @@ int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
return TRUE;
}
int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val)
{
int HashPos;