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:
parent
43174676ca
commit
1301fe7a8f
|
@ -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
57
parse.c
|
@ -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 */
|
||||
|
|
8
picoc.c
8
picoc.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
picoc.h
2
picoc.h
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue