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];
|
struct LexState FunctionStore[FUNCTION_STORE_MAX];
|
||||||
int FunctionStoreUsed = 0;
|
int FunctionStoreUsed = 0;
|
||||||
|
|
||||||
|
/* the stack */
|
||||||
|
struct StackFrame Stack[STACK_MAX];
|
||||||
|
int StackUsed = 0;
|
||||||
|
|
||||||
/* local prototypes */
|
/* local prototypes */
|
||||||
int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt);
|
int ParseExpression(struct LexState *Lexer, struct Value *Result, int RunIt);
|
||||||
void ParseIntExpression(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 */
|
/* initialise the parser */
|
||||||
void ParseInit()
|
void ParseInit()
|
||||||
{
|
{
|
||||||
TableInit(&GlobalTable, &GlobalHashTable[0], "global", GLOBAL_TABLE_SIZE);
|
TableInit(&GlobalTable, &GlobalHashTable[0], GLOBAL_TABLE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define a variable */
|
/* define a variable */
|
||||||
|
@ -30,19 +34,44 @@ void VariableDefine(struct LexState *Lexer, const Str *Ident, enum ValueType Typ
|
||||||
|
|
||||||
memset(&NewValue, '\0', sizeof(NewValue));
|
memset(&NewValue, '\0', sizeof(NewValue));
|
||||||
NewValue.Typ = Typ;
|
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);
|
ProgramFail(Lexer, "'%S' is already defined", Ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the value of a variable. must be defined */
|
/* get the value of a variable. must be defined */
|
||||||
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal)
|
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))
|
if (!TableGet(&GlobalTable, Ident, LVal))
|
||||||
ProgramFail(Lexer, "'%S' is undefined", Ident);
|
ProgramFail(Lexer, "'%S' is undefined", Ident);
|
||||||
|
|
||||||
*Val = **LVal;
|
*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 */
|
/* parse a single value */
|
||||||
int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue, int RunIt)
|
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)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Str FileName;
|
Str FileName;
|
||||||
Str StartFunc;
|
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
Fail("Format: picoc <program.c> <args>...\n");
|
Fail("Format: picoc <program.c> <args>...\n");
|
||||||
|
|
13
picoc.h
13
picoc.h
|
@ -7,6 +7,8 @@
|
||||||
#define USE_MALLOC
|
#define USE_MALLOC
|
||||||
#define GLOBAL_TABLE_SIZE 199 /* global variable table */
|
#define GLOBAL_TABLE_SIZE 199 /* global variable table */
|
||||||
#define FUNCTION_STORE_MAX 50 /* maximum number of used-defined functions */
|
#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 */
|
#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
|
||||||
|
|
||||||
/* handy definitions */
|
/* handy definitions */
|
||||||
|
@ -128,7 +130,6 @@ struct TableEntry
|
||||||
|
|
||||||
struct Table
|
struct Table
|
||||||
{
|
{
|
||||||
const char *Name;
|
|
||||||
short Size;
|
short Size;
|
||||||
struct TableEntry *HashTable;
|
struct TableEntry *HashTable;
|
||||||
};
|
};
|
||||||
|
@ -142,6 +143,14 @@ struct LexState
|
||||||
const Str *FileName;
|
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 */
|
/* str.c */
|
||||||
void StrToC(char *Dest, int DestSize, const Str *Source);
|
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);
|
void ScanFile(const Str *FileName);
|
||||||
|
|
||||||
/* table.c */
|
/* 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 TableSet(struct Table *Tbl, const Str *Key, struct Value *Val);
|
||||||
int TableGet(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 <string.h>
|
||||||
|
|
||||||
#include "picoc.h"
|
#include "picoc.h"
|
||||||
|
|
||||||
|
|
||||||
static unsigned int TableHash(const Str *Key)
|
static unsigned int TableHash(const Str *Key)
|
||||||
{
|
{
|
||||||
unsigned int Hash;
|
unsigned int Hash;
|
||||||
|
@ -24,10 +22,8 @@ static unsigned int TableHash(const Str *Key)
|
||||||
return Hash;
|
return Hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, int Size)
|
||||||
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, const char *Name, int Size)
|
|
||||||
{
|
{
|
||||||
Tbl->Name = Name;
|
|
||||||
Tbl->Size = Size;
|
Tbl->Size = Size;
|
||||||
Tbl->HashTable = HashTable;
|
Tbl->HashTable = HashTable;
|
||||||
memset(HashTable, '\0', sizeof(struct TableEntry) * Size);
|
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 */
|
return -2; /* wrong key */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
|
static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
|
||||||
{
|
{
|
||||||
int HashValue;
|
int HashValue;
|
||||||
|
@ -76,7 +71,6 @@ static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
|
int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
|
||||||
{
|
{
|
||||||
int HashPos;
|
int HashPos;
|
||||||
|
@ -87,7 +81,7 @@ int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
|
||||||
if (HashPos == -1)
|
if (HashPos == -1)
|
||||||
{
|
{
|
||||||
if (AddAt == -1)
|
if (AddAt == -1)
|
||||||
Fail("table '%s' is full\n", Tbl->Name);
|
Fail("variable table is full\n");
|
||||||
|
|
||||||
else
|
else
|
||||||
{ /* add it to the table */
|
{ /* add it to the table */
|
||||||
|
@ -100,7 +94,6 @@ int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val)
|
int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val)
|
||||||
{
|
{
|
||||||
int HashPos;
|
int HashPos;
|
||||||
|
|
Loading…
Reference in a new issue