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. */
|
/* parse the setup C source code - may define types etc. */
|
||||||
if (LInclude->SetupCSource != NULL)
|
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 */
|
/* set up the library functions */
|
||||||
if (LInclude->FuncList != NULL)
|
if (LInclude->FuncList != NULL)
|
||||||
|
|
53
parse.c
53
parse.c
|
@ -1,13 +1,30 @@
|
||||||
#include "picoc.h"
|
#include "picoc.h"
|
||||||
|
|
||||||
/* a chunk of heap-allocated tokens we should cleanup when we're done */
|
/* a chunk of heap-allocated tokens we'll cleanup when we're done */
|
||||||
static void *CleanupTokens = NULL;
|
struct CleanupTokenNode
|
||||||
|
{
|
||||||
|
void *Tokens;
|
||||||
|
const char *SourceText;
|
||||||
|
struct CleanupTokenNode *Next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct CleanupTokenNode *CleanupTokenList = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* deallocate any memory */
|
/* deallocate any memory */
|
||||||
void ParseCleanup()
|
void ParseCleanup()
|
||||||
{
|
{
|
||||||
if (CleanupTokens != NULL)
|
while (CleanupTokenList != NULL)
|
||||||
HeapFreeMem(CleanupTokens);
|
{
|
||||||
|
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 */
|
/* 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 */
|
/* 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;
|
struct ParseState Parser;
|
||||||
enum ParseResult Ok;
|
enum ParseResult Ok;
|
||||||
|
struct CleanupTokenNode *NewCleanupNode;
|
||||||
|
|
||||||
void *OldCleanupTokens = CleanupTokens;
|
|
||||||
void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL);
|
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);
|
LexInitParser(&Parser, Source, Tokens, FileName, RunIt);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -744,9 +777,9 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
|
||||||
if (Ok == ParseResultError)
|
if (Ok == ParseResultError)
|
||||||
ProgramFail(&Parser, "parse error");
|
ProgramFail(&Parser, "parse error");
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
if (CleanupNow)
|
||||||
HeapFreeMem(Tokens);
|
HeapFreeMem(Tokens);
|
||||||
if (OldCleanupTokens == NULL)
|
|
||||||
CleanupTokens = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse interactively */
|
/* 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.ReturnType == &VoidType)
|
||||||
{
|
{
|
||||||
if (FuncValue->Val->FuncDef.NumParams == 0)
|
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
|
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
|
else
|
||||||
{
|
{
|
||||||
VariableDefinePlatformVar(NULL, "__exit_value", &IntType, (union AnyValue *)&ExitValue, TRUE);
|
VariableDefinePlatformVar(NULL, "__exit_value", &IntType, (union AnyValue *)&ExitValue, TRUE);
|
||||||
|
|
||||||
if (FuncValue->Val->FuncDef.NumParams == 0)
|
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
|
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 */
|
/* parse.c */
|
||||||
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
|
enum ParseResult ParseStatement(struct ParseState *Parser, int CheckTrailingSemicolon);
|
||||||
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier);
|
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 ParseInteractive();
|
||||||
void ParseCleanup();
|
void ParseCleanup();
|
||||||
void ParserCopyPos(struct ParseState *To, struct ParseState *From);
|
void ParserCopyPos(struct ParseState *To, struct ParseState *From);
|
||||||
|
|
|
@ -5,14 +5,8 @@
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* a source file we need to clean up */
|
|
||||||
static char *CleanupText = NULL;
|
|
||||||
|
|
||||||
/* deallocate any storage */
|
|
||||||
void PlatformCleanup()
|
void PlatformCleanup()
|
||||||
{
|
{
|
||||||
if (CleanupText != NULL)
|
|
||||||
free(CleanupText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get a line of interactive input */
|
/* get a line of interactive input */
|
||||||
|
@ -91,15 +85,8 @@ char *PlatformReadFile(const char *FileName)
|
||||||
void PlatformScanFile(const char *FileName)
|
void PlatformScanFile(const char *FileName)
|
||||||
{
|
{
|
||||||
char *SourceStr = PlatformReadFile(FileName);
|
char *SourceStr = PlatformReadFile(FileName);
|
||||||
char *OrigCleanupText = CleanupText;
|
|
||||||
if (CleanupText == NULL)
|
|
||||||
CleanupText = SourceStr;
|
|
||||||
|
|
||||||
Parse(FileName, SourceStr, strlen(SourceStr), TRUE);
|
Parse(FileName, SourceStr, strlen(SourceStr), TRUE, FALSE, TRUE);
|
||||||
free(SourceStr);
|
|
||||||
|
|
||||||
if (OrigCleanupText == NULL)
|
|
||||||
CleanupText = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark where to end the program for platforms which require this */
|
/* mark where to end the program for platforms which require this */
|
||||||
|
|
Loading…
Reference in a new issue