Now handles "4 = b;" correctly (ie. with an error message)
Also fixed a problem with prompting again for more input on EOF. git-svn-id: http://picoc.googlecode.com/svn/trunk@324 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
parent
d38b4fa617
commit
44eb3d3def
|
@ -1187,7 +1187,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
|
||||||
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
|
for (Count = 0; Count < FuncValue->Val->FuncDef.NumParams; Count++)
|
||||||
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count], NULL, TRUE);
|
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], ParamArray[Count], NULL, TRUE);
|
||||||
|
|
||||||
if (!ParseStatement(&FuncParser))
|
if (ParseStatement(&FuncParser) != ParseResultOk)
|
||||||
ProgramFail(&FuncParser, "function body expected");
|
ProgramFail(&FuncParser, "function body expected");
|
||||||
|
|
||||||
if (FuncValue->Val->FuncDef.ReturnType != ReturnValue->Typ)
|
if (FuncValue->Val->FuncDef.ReturnType != ReturnValue->Typ)
|
||||||
|
|
39
parse.c
39
parse.c
|
@ -11,7 +11,7 @@ void ParseCleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse a statement, but only run it if Condition is TRUE */
|
/* parse a statement, but only run it if Condition is TRUE */
|
||||||
int ParseStatementMaybeRun(struct ParseState *Parser, int Condition)
|
enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition)
|
||||||
{
|
{
|
||||||
if (Parser->Mode != RunModeSkip && !Condition)
|
if (Parser->Mode != RunModeSkip && !Condition)
|
||||||
{
|
{
|
||||||
|
@ -95,7 +95,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
|
||||||
ProgramFail(Parser, "bad function definition");
|
ProgramFail(Parser, "bad function definition");
|
||||||
|
|
||||||
FuncBody = *Parser;
|
FuncBody = *Parser;
|
||||||
if (!ParseStatementMaybeRun(Parser, FALSE))
|
if (ParseStatementMaybeRun(Parser, FALSE) != ParseResultOk)
|
||||||
ProgramFail(Parser, "function definition expected");
|
ProgramFail(Parser, "function definition expected");
|
||||||
|
|
||||||
FuncValue->Val->FuncDef.Body = FuncBody;
|
FuncValue->Val->FuncDef.Body = FuncBody;
|
||||||
|
@ -202,7 +202,7 @@ void ParseFor(struct ParseState *Parser)
|
||||||
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
|
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
|
||||||
ProgramFail(Parser, "'(' expected");
|
ProgramFail(Parser, "'(' expected");
|
||||||
|
|
||||||
if (!ParseStatement(Parser))
|
if (ParseStatement(Parser) != ParseResultOk)
|
||||||
ProgramFail(Parser, "statement expected");
|
ProgramFail(Parser, "statement expected");
|
||||||
|
|
||||||
ParserCopyPos(&PreConditional, Parser);
|
ParserCopyPos(&PreConditional, Parser);
|
||||||
|
@ -218,7 +218,7 @@ void ParseFor(struct ParseState *Parser)
|
||||||
ProgramFail(Parser, "')' expected");
|
ProgramFail(Parser, "')' expected");
|
||||||
|
|
||||||
ParserCopyPos(&PreStatement, Parser);
|
ParserCopyPos(&PreStatement, Parser);
|
||||||
if (!ParseStatementMaybeRun(Parser, Condition))
|
if (ParseStatementMaybeRun(Parser, Condition) != ParseResultOk)
|
||||||
ProgramFail(Parser, "statement expected");
|
ProgramFail(Parser, "statement expected");
|
||||||
|
|
||||||
if (Parser->Mode == RunModeContinue)
|
if (Parser->Mode == RunModeContinue)
|
||||||
|
@ -260,13 +260,13 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond
|
||||||
{ /* condition failed - skip this block instead */
|
{ /* condition failed - skip this block instead */
|
||||||
enum RunMode OldMode = Parser->Mode;
|
enum RunMode OldMode = Parser->Mode;
|
||||||
Parser->Mode = RunModeSkip;
|
Parser->Mode = RunModeSkip;
|
||||||
while (ParseStatement(Parser))
|
while (ParseStatement(Parser) == ParseResultOk)
|
||||||
{}
|
{}
|
||||||
Parser->Mode = OldMode;
|
Parser->Mode = OldMode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* just run it in its current mode */
|
{ /* just run it in its current mode */
|
||||||
while (ParseStatement(Parser))
|
while (ParseStatement(Parser) == ParseResultOk)
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Cond
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse a statement */
|
/* parse a statement */
|
||||||
int ParseStatement(struct ParseState *Parser)
|
enum ParseResult ParseStatement(struct ParseState *Parser)
|
||||||
{
|
{
|
||||||
struct Value *CValue;
|
struct Value *CValue;
|
||||||
struct Value *LexerValue;
|
struct Value *LexerValue;
|
||||||
|
@ -289,7 +289,7 @@ int ParseStatement(struct ParseState *Parser)
|
||||||
switch (Token)
|
switch (Token)
|
||||||
{
|
{
|
||||||
case TokenEOF:
|
case TokenEOF:
|
||||||
return FALSE;
|
return ParseResultEOF;
|
||||||
|
|
||||||
case TokenIdentifier:
|
case TokenIdentifier:
|
||||||
case TokenAsterisk:
|
case TokenAsterisk:
|
||||||
|
@ -313,13 +313,13 @@ int ParseStatement(struct ParseState *Parser)
|
||||||
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
|
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
|
||||||
ProgramFail(Parser, "')' expected");
|
ProgramFail(Parser, "')' expected");
|
||||||
|
|
||||||
if (!ParseStatementMaybeRun(Parser, Condition))
|
if (ParseStatementMaybeRun(Parser, Condition) != ParseResultOk)
|
||||||
ProgramFail(Parser, "statement expected");
|
ProgramFail(Parser, "statement expected");
|
||||||
|
|
||||||
if (LexGetToken(Parser, NULL, FALSE) == TokenElse)
|
if (LexGetToken(Parser, NULL, FALSE) == TokenElse)
|
||||||
{
|
{
|
||||||
LexGetToken(Parser, NULL, TRUE);
|
LexGetToken(Parser, NULL, TRUE);
|
||||||
if (!ParseStatementMaybeRun(Parser, !Condition))
|
if (ParseStatementMaybeRun(Parser, !Condition) != ParseResultOk)
|
||||||
ProgramFail(Parser, "statement expected");
|
ProgramFail(Parser, "statement expected");
|
||||||
}
|
}
|
||||||
CheckTrailingSemicolon = FALSE;
|
CheckTrailingSemicolon = FALSE;
|
||||||
|
@ -530,19 +530,20 @@ int ParseStatement(struct ParseState *Parser)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
*Parser = PreState;
|
*Parser = PreState;
|
||||||
return FALSE;
|
return ParseResultError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CheckTrailingSemicolon && LexGetToken(Parser, NULL, FALSE) == TokenSemicolon)
|
if (CheckTrailingSemicolon && LexGetToken(Parser, NULL, FALSE) == TokenSemicolon)
|
||||||
LexGetToken(Parser, NULL, TRUE);
|
LexGetToken(Parser, NULL, TRUE);
|
||||||
|
|
||||||
return TRUE;
|
return ParseResultOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
struct ParseState Parser;
|
struct ParseState Parser;
|
||||||
|
enum ParseResult Ok;
|
||||||
|
|
||||||
void *OldCleanupTokens = CleanupTokens;
|
void *OldCleanupTokens = CleanupTokens;
|
||||||
void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL);
|
void *Tokens = LexAnalyse(FileName, Source, SourceLen, NULL);
|
||||||
|
@ -551,10 +552,11 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
|
||||||
|
|
||||||
LexInitParser(&Parser, Tokens, FileName, 1, RunIt);
|
LexInitParser(&Parser, Tokens, FileName, 1, RunIt);
|
||||||
|
|
||||||
while (ParseStatement(&Parser))
|
do {
|
||||||
{}
|
Ok = ParseStatement(&Parser);
|
||||||
|
} while (Ok == ParseResultOk);
|
||||||
|
|
||||||
if (LexGetToken(&Parser, NULL, FALSE) != TokenEOF)
|
if (Ok == ParseResultError)
|
||||||
ProgramFail(&Parser, "parse error");
|
ProgramFail(&Parser, "parse error");
|
||||||
|
|
||||||
HeapFreeMem(Tokens);
|
HeapFreeMem(Tokens);
|
||||||
|
@ -566,7 +568,7 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
|
||||||
void ParseInteractive()
|
void ParseInteractive()
|
||||||
{
|
{
|
||||||
struct ParseState Parser;
|
struct ParseState Parser;
|
||||||
int Ok;
|
enum ParseResult Ok;
|
||||||
|
|
||||||
PlatformPrintf(INTERACTIVE_PROMPT_START);
|
PlatformPrintf(INTERACTIVE_PROMPT_START);
|
||||||
LexInitParser(&Parser, NULL, StrEmpty, 1, TRUE);
|
LexInitParser(&Parser, NULL, StrEmpty, 1, TRUE);
|
||||||
|
@ -579,7 +581,10 @@ void ParseInteractive()
|
||||||
Ok = ParseStatement(&Parser);
|
Ok = ParseStatement(&Parser);
|
||||||
LexInteractiveCompleted(&Parser);
|
LexInteractiveCompleted(&Parser);
|
||||||
|
|
||||||
} while (Ok);
|
} while (Ok == ParseResultOk);
|
||||||
|
|
||||||
|
if (Ok == ParseResultError)
|
||||||
|
ProgramFail(&Parser, "parse error");
|
||||||
|
|
||||||
PlatformPrintf("\n");
|
PlatformPrintf("\n");
|
||||||
}
|
}
|
||||||
|
|
4
picoc.h
4
picoc.h
|
@ -261,6 +261,8 @@ struct OutputStream
|
||||||
union OutputStreamInfo i;
|
union OutputStreamInfo i;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ParseResult { ParseResultEOF, ParseResultError, ParseResultOk };
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
extern void *HeapStackTop;
|
extern void *HeapStackTop;
|
||||||
extern void *HeapMemStart;
|
extern void *HeapMemStart;
|
||||||
|
@ -307,7 +309,7 @@ void LexInteractiveCompleted(struct ParseState *Parser);
|
||||||
void LexInteractiveStatementPrompt();
|
void LexInteractiveStatementPrompt();
|
||||||
|
|
||||||
/* parse.c */
|
/* parse.c */
|
||||||
int ParseStatement(struct ParseState *Parser);
|
enum ParseResult ParseStatement(struct ParseState *Parser);
|
||||||
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsProtoType);
|
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier, int IsProtoType);
|
||||||
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt);
|
void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt);
|
||||||
void ParseInteractive();
|
void ParseInteractive();
|
||||||
|
|
Loading…
Reference in a new issue