switch is now working.

did some work on break / continue in loops.


git-svn-id: http://picoc.googlecode.com/svn/trunk@87 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-02-19 09:07:00 +00:00
parent 834a6daca6
commit 6a1d28c1dc

102
parse.c
View file

@ -490,6 +490,13 @@ void ParseMacroDefinition(struct ParseState *Parser)
ProgramFail(Parser, "'%s' is already defined", &MacroName->Val->String);
}
/* copy where we're at in the parsing */
void ParserCopyPos(struct ParseState *To, struct ParseState *From)
{
To->Pos = From->Pos;
To->Line = From->Line;
}
/* parse a "for" statement */
void ParseFor(struct ParseState *Parser)
{
@ -508,40 +515,49 @@ void ParseFor(struct ParseState *Parser)
if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon)
ProgramFail(Parser, "';' expected");
PreConditional = *Parser;
ParserCopyPos(&PreConditional, Parser);
Condition = ParseIntExpression(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon)
ProgramFail(Parser, "';' expected");
PreIncrement = *Parser;
ParserCopyPos(&PreIncrement, Parser);
ParseStatementMaybeRun(Parser, FALSE);
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected");
PreStatement = *Parser;
ParserCopyPos(&PreStatement, Parser);
if (!ParseStatementMaybeRun(Parser, Condition))
ProgramFail(Parser, "statement expected");
After = *Parser;
if (Parser->Mode == RunModeContinue)
Parser->Mode = RunModeRun;
ParserCopyPos(&After, Parser);
while (Condition && Parser->Mode == RunModeRun)
{
*Parser = PreIncrement;
ParserCopyPos(Parser, &PreIncrement);
ParseStatement(Parser);
*Parser = PreConditional;
ParserCopyPos(Parser, &PreConditional);
Condition = ParseIntExpression(Parser);
if (Condition)
{
*Parser = PreStatement;
ParserCopyPos(Parser, &PreStatement);
ParseStatement(Parser);
if (Parser->Mode == RunModeContinue)
Parser->Mode = RunModeRun;
}
}
*Parser = After;
if (Parser->Mode == RunModeBreak)
Parser->Mode = RunModeRun;
ParserCopyPos(Parser, &After);
}
/* parse a statement, but only run it if Condition is TRUE */
@ -559,6 +575,32 @@ int ParseStatementMaybeRun(struct ParseState *Parser, int Condition)
return ParseStatement(Parser);
}
/* parse a block of code and return what mode it returned in */
enum RunMode ParseBlock(struct ParseState *Parser, int AbsorbOpenBrace, int Condition)
{
if (AbsorbOpenBrace && LexGetToken(Parser, NULL, TRUE) != TokenLeftBrace)
ProgramFail(Parser, "'{' expected");
if (Parser->Mode != RunModeSkip && !Condition)
{ /* condition failed - skip this block instead */
enum RunMode OldMode = Parser->Mode;
Parser->Mode = RunModeSkip;
while (ParseStatement(Parser))
{}
Parser->Mode = OldMode;
}
else
{ /* just run it in its current mode */
while (ParseStatement(Parser))
{}
}
if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace)
ProgramFail(Parser, "'}' expected");
return Parser->Mode;
}
/* parse a statement */
int ParseStatement(struct ParseState *Parser)
{
@ -582,11 +624,7 @@ int ParseStatement(struct ParseState *Parser)
break;
case TokenLeftBrace:
while (ParseStatement(Parser))
{}
if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace)
ProgramFail(Parser, "'}' expected");
ParseBlock(Parser, FALSE, TRUE);
break;
case TokenIf:
@ -611,31 +649,40 @@ int ParseStatement(struct ParseState *Parser)
case TokenWhile:
{
struct ParseState PreConditional = *Parser;
struct ParseState PreConditional;
ParserCopyPos(&PreConditional, Parser);
do
{
*Parser = PreConditional;
ParserCopyPos(Parser, &PreConditional);
Condition = ParseIntExpression(Parser);
if (!ParseStatementMaybeRun(Parser, Condition))
ProgramFail(Parser, "statement expected");
ParseBlock(Parser, TRUE, Condition);
if (Parser->Mode == RunModeContinue)
Parser->Mode = RunModeRun;
} while (Parser->Mode == RunModeRun && Condition);
if (Parser->Mode == RunModeBreak)
Parser->Mode = RunModeRun;
}
break;
case TokenDo:
{
struct ParseState PreStatement = *Parser;
struct ParseState PreStatement;
ParserCopyPos(&PreStatement, Parser);
do
{
*Parser = PreStatement;
if (!ParseStatement(Parser))
ProgramFail(Parser, "statement expected");
ParserCopyPos(Parser, &PreStatement);
ParseBlock(Parser, TRUE, TRUE);
if (Parser->Mode == RunModeContinue)
Parser->Mode = RunModeRun;
Condition = ParseIntExpression(Parser);
} while (Condition && Parser->Mode == RunModeRun);
if (Parser->Mode == RunModeBreak)
Parser->Mode = RunModeRun;
}
break;
@ -702,8 +749,7 @@ int ParseStatement(struct ParseState *Parser)
Parser->Mode = RunModeCaseSearch;
Parser->SearchLabel = Condition;
if (!ParseStatement(Parser))
ProgramFail(Parser, "statement expected");
ParseBlock(Parser, TRUE, TRUE);
Parser->Mode = OldMode;
Parser->SearchLabel = OldSearchLabel;
@ -711,7 +757,15 @@ int ParseStatement(struct ParseState *Parser)
break;
case TokenCase:
if (Parser->Mode == RunModeCaseSearch)
{
Parser->Mode = RunModeRun;
Condition = ParseIntExpression(Parser);
Parser->Mode = RunModeCaseSearch;
}
else
Condition = ParseIntExpression(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenColon)
ProgramFail(Parser, "':' expected");