More intelligent allocation/deallocation of parser data. It should now be possible to report error messages from previously-parsed files.

git-svn-id: http://picoc.googlecode.com/svn/trunk@480 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2010-07-27 18:16:05 +00:00
parent 43174676ca
commit 1301fe7a8f
5 changed files with 52 additions and 32 deletions

View file

@ -87,7 +87,7 @@ void IncludeFile(char *FileName)
/* parse the setup C source code - may define types etc. */
if (LInclude->SetupCSource != NULL)
Parse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE);
Parse(FileName, LInclude->SetupCSource, strlen(LInclude->SetupCSource), TRUE, TRUE, FALSE);
/* set up the library functions */
if (LInclude->FuncList != NULL)

57
parse.c
View file

@ -1,13 +1,30 @@
#include "picoc.h"
/* a chunk of heap-allocated tokens we should cleanup when we're done */
static void *CleanupTokens = NULL;
/* a chunk of heap-allocated tokens we'll cleanup when we're done */
struct CleanupTokenNode
{
void *Tokens;
const char *SourceText;
struct CleanupTokenNode *Next;
};
static struct CleanupTokenNode *CleanupTokenList = NULL;
/* deallocate any memory */
void ParseCleanup()
{
if (CleanupTokens != NULL)
HeapFreeMem(CleanupTokens);
while (CleanupTokenList != NULL)
{
struct CleanupTokenNode *Next = CleanupTokenList->Next;
HeapFreeMem(CleanupTokenList->Tokens);
if (CleanupTokenList->SourceText != NULL)
HeapFreeMem((void *)CleanupTokenList->SourceText);
HeapFreeMem(CleanupTokenList);
CleanupTokenList = Next;
}
}
/* parse a statement, but only run it if Condition is TRUE */
@ -725,16 +742,32 @@ enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemi
}
/* quick scan a source file for definitions */
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource)
{
struct ParseState Parser;
enum ParseResult Ok;
struct CleanupTokenNode *NewCleanupNode;
void *OldCleanupTokens = CleanupTokens;
void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL);
if (OldCleanupTokens == NULL)
CleanupTokens = Tokens;
/* allocate a cleanup node so we can clean up the tokens later */
if (!CleanupNow)
{
NewCleanupNode = HeapAllocMem(sizeof(struct CleanupTokenNode));
if (NewCleanupNode == NULL)
ProgramFail(NULL, "out of memory");
NewCleanupNode->Tokens = Tokens;
if (CleanupSource)
NewCleanupNode->SourceText = Source;
else
NewCleanupNode->SourceText = NULL;
NewCleanupNode->Next = CleanupTokenList;
CleanupTokenList = NewCleanupNode;
}
/* do the parsing */
LexInitParser(&Parser, Source, Tokens, FileName, RunIt);
do {
@ -744,9 +777,9 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
if (Ok == ParseResultError)
ProgramFail(&Parser, "parse error");
HeapFreeMem(Tokens);
if (OldCleanupTokens == NULL)
CleanupTokens = NULL;
/* clean up */
if (CleanupNow)
HeapFreeMem(Tokens);
}
/* parse interactively */

View file

@ -59,18 +59,18 @@ void CallMain(int argc, char **argv)
if (FuncValue->Val->FuncDef.ReturnType == &VoidType)
{
if (FuncValue->Val->FuncDef.NumParams == 0)
Parse("", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE);
Parse("startup", CALL_MAIN_NO_ARGS_RETURN_VOID, strlen(CALL_MAIN_NO_ARGS_RETURN_VOID), TRUE, TRUE, FALSE);
else
Parse("", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE);
Parse("startup", CALL_MAIN_WITH_ARGS_RETURN_VOID, strlen(CALL_MAIN_WITH_ARGS_RETURN_VOID), TRUE, TRUE, FALSE);
}
else
{
VariableDefinePlatformVar(NULL, "__exit_value", &IntType, (union AnyValue *)&ExitValue, TRUE);
if (FuncValue->Val->FuncDef.NumParams == 0)
Parse("", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), TRUE);
Parse("startup", CALL_MAIN_NO_ARGS_RETURN_INT, strlen(CALL_MAIN_NO_ARGS_RETURN_INT), TRUE, TRUE, FALSE);
else
Parse("", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), TRUE);
Parse("startup", CALL_MAIN_WITH_ARGS_RETURN_INT, strlen(CALL_MAIN_WITH_ARGS_RETURN_INT), TRUE, TRUE, FALSE);
}
}

View file

@ -342,7 +342,7 @@ void LexInteractiveStatementPrompt();
/* parse.c */
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier);
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt);
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt, int CleanupNow, int CleanupSource);
void ParseInteractive();
void ParseCleanup();
void ParserCopyPos(struct ParseState *To, struct ParseState *From);

View file

@ -5,14 +5,8 @@
#include <readline/history.h>
#endif
/* a source file we need to clean up */
static char *CleanupText = NULL;
/* deallocate any storage */
void PlatformCleanup()
{
if (CleanupText != NULL)
free(CleanupText);
}
/* get a line of interactive input */
@ -91,15 +85,8 @@ char *PlatformReadFile(const char *FileName)
void PlatformScanFile(const char *FileName)
{
char *SourceStr = PlatformReadFile(FileName);
char *OrigCleanupText = CleanupText;
if (CleanupText == NULL)
CleanupText = SourceStr;
Parse(FileName, SourceStr, strlen(SourceStr), TRUE);
free(SourceStr);
if (OrigCleanupText == NULL)
CleanupText = NULL;
Parse(FileName, SourceStr, strlen(SourceStr), TRUE, FALSE, TRUE);
}
/* mark where to end the program for platforms which require this */