Local variables implemented
git-svn-id: http://picoc.googlecode.com/svn/trunk@18 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
b57f0eac65
commit
e5920c041c
33
parse.c
33
parse.c
|
@ -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)
|
||||
{
|
||||
|
|
1
picoc.c
1
picoc.c
|
@ -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
13
picoc.h
|
@ -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
13
table.c
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue