Changes to help with implementing switch/case/break/continue/return

git-svn-id: http://picoc.googlecode.com/svn/trunk@82 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-02-18 08:19:06 +00:00
parent d94b70212b
commit fdad9f8d30
5 changed files with 129 additions and 78 deletions

View file

@ -41,7 +41,7 @@ void IntrinsicInit(struct Table *GlobalTable)
for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++) for (Count = 0; Count < sizeof(Intrinsics) / sizeof(struct IntrinsicFunction); Count++)
{ {
Tokens = LexAnalyse(IntrinsicName, Intrinsics[Count].Prototype, strlen(Intrinsics[Count].Prototype)); Tokens = LexAnalyse(IntrinsicName, Intrinsics[Count].Prototype, strlen(Intrinsics[Count].Prototype));
LexInitParser(&Parser, Tokens, IntrinsicName, Count+1); LexInitParser(&Parser, Tokens, IntrinsicName, Count+1, TRUE);
TypeParse(&Parser, &ReturnType, &Identifier); TypeParse(&Parser, &ReturnType, &Identifier);
NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier, TRUE); NewValue = ParseFunctionDefinition(&Parser, ReturnType, Identifier, TRUE);
NewValue->Val->FuncDef.Intrinsic = Intrinsics[Count].Func; NewValue->Val->FuncDef.Intrinsic = Intrinsics[Count].Func;

5
lex.c
View file

@ -276,6 +276,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
case '~': GotToken = TokenUnaryExor; break; case '~': GotToken = TokenUnaryExor; break;
case ',': GotToken = TokenComma; break; case ',': GotToken = TokenComma; break;
case '.': GotToken = TokenDot; break; case '.': GotToken = TokenDot; break;
case ':': GotToken = TokenColon; break;
default: LexFail(Lexer, "illegal character '%c'", ThisChar); break; default: LexFail(Lexer, "illegal character '%c'", ThisChar); break;
} }
} while (GotToken == TokenNone); } while (GotToken == TokenNone);
@ -362,11 +363,13 @@ void *LexAnalyse(const char *FileName, const char *Source, int SourceLen)
} }
/* prepare to parse a pre-tokenised buffer */ /* prepare to parse a pre-tokenised buffer */
void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line) void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line, int RunIt)
{ {
Parser->Pos = TokenSource; Parser->Pos = TokenSource;
Parser->Line = Line; Parser->Line = Line;
Parser->FileName = FileName; Parser->FileName = FileName;
Parser->Mode = RunIt ? RunModeRun : RunModeSkip;
Parser->SearchLabel = 0;
} }
/* get the next token given a parser state */ /* get the next token given a parser state */

170
parse.c
View file

@ -8,9 +8,8 @@ int ParameterUsed = 0;
struct Value *ReturnValue; struct Value *ReturnValue;
/* local prototypes */ /* local prototypes */
int ParseIntExpression(struct ParseState *Parser, int RunIt);
int ParseStatement(struct ParseState *Parser, int RunIt);
int ParseArguments(struct ParseState *Parser, int RunIt); int ParseArguments(struct ParseState *Parser, int RunIt);
int ParseStatementMaybeRun(struct ParseState *Parser, int Condition);
/* initialise the parser */ /* initialise the parser */
@ -22,12 +21,12 @@ void ParseInit()
} }
/* do a function call */ /* do a function call */
void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, const char *FuncName, int RunIt) void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, const char *FuncName)
{ {
struct Value *FuncValue; struct Value *FuncValue;
enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */ enum LexToken Token = LexGetToken(Parser, NULL, TRUE); /* open bracket */
if (RunIt) if (Parser->Mode == RunModeRun)
{ /* get the function definition */ { /* get the function definition */
VariableGet(Parser, FuncName, &FuncValue); VariableGet(Parser, FuncName, &FuncValue);
if (FuncValue->Typ->Base != TypeFunction) if (FuncValue->Typ->Base != TypeFunction)
@ -43,13 +42,13 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
/* parse arguments */ /* parse arguments */
ParameterUsed = 0; ParameterUsed = 0;
do { do {
if (ParseExpression(Parser, &Parameter[ParameterUsed], FALSE, RunIt)) if (ParseExpression(Parser, &Parameter[ParameterUsed], FALSE))
{ {
if (RunIt && FuncValue->Val->FuncDef.ParamType[ParameterUsed] != Parameter[ParameterUsed]->Typ) if (Parser->Mode == RunModeRun && FuncValue->Val->FuncDef.ParamType[ParameterUsed] != Parameter[ParameterUsed]->Typ)
ProgramFail(Parser, "parameter %d to %s is the wrong type", ParameterUsed, FuncName); ProgramFail(Parser, "parameter %d to %s is the wrong type", ParameterUsed, FuncName);
ParameterUsed++; ParameterUsed++;
if (RunIt && ParameterUsed > FuncValue->Val->FuncDef.NumParams) if (Parser->Mode == RunModeRun && ParameterUsed > FuncValue->Val->FuncDef.NumParams)
ProgramFail(Parser, "too many arguments"); ProgramFail(Parser, "too many arguments");
Token = LexGetToken(Parser, NULL, TRUE); Token = LexGetToken(Parser, NULL, TRUE);
@ -64,7 +63,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
} }
} while (Token != TokenCloseBracket); } while (Token != TokenCloseBracket);
if (RunIt) if (Parser->Mode == RunModeRun)
{ /* run the function */ { /* run the function */
int Count; int Count;
@ -75,7 +74,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
for (Count = 0; Count < ParameterUsed; Count++) for (Count = 0; Count < ParameterUsed; Count++)
VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], Parameter[Count]); VariableDefine(Parser, FuncValue->Val->FuncDef.ParamName[Count], Parameter[Count]);
if (!ParseStatement(&FuncParser, TRUE)) if (!ParseStatement(&FuncParser))
ProgramFail(&FuncParser, "function body expected"); ProgramFail(&FuncParser, "function body expected");
if (FuncValue->Val->FuncDef.ReturnType != (*Result)->Typ) if (FuncValue->Val->FuncDef.ReturnType != (*Result)->Typ)
@ -92,7 +91,7 @@ void ParseFunctionCall(struct ParseState *Parser, struct Value **Result, int Res
} }
/* parse a single value */ /* parse a single value */
int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, int RunIt) int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHeap)
{ {
struct ParseState PreState = *Parser; struct ParseState PreState = *Parser;
struct Value *LexValue; struct Value *LexValue;
@ -109,8 +108,8 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
break; break;
case TokenMinus: case TokenUnaryExor: case TokenUnaryNot: case TokenMinus: case TokenUnaryExor: case TokenUnaryNot:
IntValue = ParseIntExpression(Parser, RunIt); IntValue = ParseIntExpression(Parser);
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
*Result = VariableAllocValueFromType(Parser, &IntType, FALSE, ResultOnHeap); *Result = VariableAllocValueFromType(Parser, &IntType, FALSE, ResultOnHeap);
switch(Token) switch(Token)
@ -124,7 +123,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
break; break;
case TokenOpenBracket: case TokenOpenBracket:
if (!ParseExpression(Parser, Result, ResultOnHeap, RunIt)) if (!ParseExpression(Parser, Result, ResultOnHeap))
ProgramFail(Parser, "invalid expression"); ProgramFail(Parser, "invalid expression");
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
@ -132,7 +131,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
break; break;
case TokenAsterisk: case TokenAsterisk:
if (!ParseExpression(Parser, Result, ResultOnHeap, RunIt)) if (!ParseExpression(Parser, Result, ResultOnHeap))
ProgramFail(Parser, "invalid expression"); ProgramFail(Parser, "invalid expression");
if ((*Result)->Typ->Base != TypePointer) if ((*Result)->Typ->Base != TypePointer)
@ -144,7 +143,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
break; break;
case TokenAmpersand: case TokenAmpersand:
if (!ParseValue(Parser, Result, ResultOnHeap, RunIt) || !(*Result)->IsLValue) if (!ParseValue(Parser, Result, ResultOnHeap) || !(*Result)->IsLValue)
ProgramFail(Parser, "can't get the address of this"); ProgramFail(Parser, "can't get the address of this");
VType = (*Result)->Typ; VType = (*Result)->Typ;
@ -156,17 +155,17 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
case TokenIdentifier: case TokenIdentifier:
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket) if (LexGetToken(Parser, NULL, FALSE) == TokenOpenBracket)
ParseFunctionCall(Parser, Result, ResultOnHeap, LexValue->Val->String, RunIt); ParseFunctionCall(Parser, Result, ResultOnHeap, LexValue->Val->String);
else else
{ {
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
VariableGet(Parser, LexValue->Val->String, &LocalLValue); VariableGet(Parser, LexValue->Val->String, &LocalLValue);
if (LocalLValue->Typ->Base == TypeMacro) if (LocalLValue->Typ->Base == TypeMacro)
{ {
struct ParseState MacroLexer = LocalLValue->Val->Parser; struct ParseState MacroLexer = LocalLValue->Val->Parser;
if (!ParseExpression(&MacroLexer, Result, ResultOnHeap, TRUE)) if (!ParseExpression(&MacroLexer, Result, ResultOnHeap))
ProgramFail(&MacroLexer, "expression expected"); ProgramFail(&MacroLexer, "expression expected");
} }
else if (LocalLValue->Typ == TypeVoid) else if (LocalLValue->Typ == TypeVoid)
@ -182,7 +181,7 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
if (Token == TokenIncrement || Token == TokenDecrement) if (Token == TokenIncrement || Token == TokenDecrement)
{ /* it's a postincrement or postdecrement */ { /* it's a postincrement or postdecrement */
LexGetToken(Parser, &LexValue, TRUE); LexGetToken(Parser, &LexValue, TRUE);
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
if (!(*Result)->IsLValue || (*Result)->Typ->Base != TypeInt) if (!(*Result)->IsLValue || (*Result)->Typ->Base != TypeInt)
ProgramFail(Parser, "can't %s this", (Token == TokenIncrement) ? "increment" : "decrement"); ProgramFail(Parser, "can't %s this", (Token == TokenIncrement) ? "increment" : "decrement");
@ -196,11 +195,11 @@ int ParseValue(struct ParseState *Parser, struct Value **Result, int ResultOnHea
else if (Token == TokenLeftSquareBracket) else if (Token == TokenLeftSquareBracket)
{ /* array access */ { /* array access */
LexGetToken(Parser, &LexValue, TRUE); LexGetToken(Parser, &LexValue, TRUE);
IntValue = ParseIntExpression(Parser, RunIt); IntValue = ParseIntExpression(Parser);
if (LexGetToken(Parser, &LexValue, TRUE) != TokenRightSquareBracket) if (LexGetToken(Parser, &LexValue, TRUE) != TokenRightSquareBracket)
ProgramFail(Parser, "expected ']'"); ProgramFail(Parser, "expected ']'");
if (RunIt) if (Parser->Mode == RunModeRun)
{ /* look up the array element */ { /* look up the array element */
if ((*Result)->Typ->Base != TypeArray) if ((*Result)->Typ->Base != TypeArray)
ProgramFail(Parser, "not an array"); ProgramFail(Parser, "not an array");
@ -239,12 +238,12 @@ struct Value *ParsePushInt(struct ParseState *Parser, int ResultOnHeap, int NewI
} }
/* parse an expression. operator precedence is not supported */ /* parse an expression. operator precedence is not supported */
int ParseExpression(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, int RunIt) int ParseExpression(struct ParseState *Parser, struct Value **Result, int ResultOnHeap)
{ {
struct Value *CurrentValue; struct Value *CurrentValue;
struct Value *TotalValue; struct Value *TotalValue;
if (!ParseValue(Parser, &TotalValue, ResultOnHeap, RunIt)) if (!ParseValue(Parser, &TotalValue, ResultOnHeap))
return FALSE; return FALSE;
while (TRUE) while (TRUE)
@ -268,7 +267,7 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
if (LexGetToken(Parser, &Ident, TRUE) != TokenIdentifier) if (LexGetToken(Parser, &Ident, TRUE) != TokenIdentifier)
ProgramFail(Parser, "need an structure or union member after '.'"); ProgramFail(Parser, "need an structure or union member after '.'");
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
void *TotalValueData = (void *)TotalValue->Val; void *TotalValueData = (void *)TotalValue->Val;
@ -285,10 +284,10 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
} }
case TokenAssign: case TokenAddAssign: case TokenSubtractAssign: case TokenAssign: case TokenAddAssign: case TokenSubtractAssign:
LexGetToken(Parser, NULL, TRUE); LexGetToken(Parser, NULL, TRUE);
if (!ParseExpression(Parser, &CurrentValue, ResultOnHeap, RunIt)) if (!ParseExpression(Parser, &CurrentValue, ResultOnHeap))
ProgramFail(Parser, "expression expected"); ProgramFail(Parser, "expression expected");
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
if (CurrentValue->Typ->Base != TypeInt || !TotalValue->IsLValue || TotalValue->Typ->Base != TypeInt) if (CurrentValue->Typ->Base != TypeInt || !TotalValue->IsLValue || TotalValue->Typ->Base != TypeInt)
ProgramFail(Parser, "can't assign"); ProgramFail(Parser, "can't assign");
@ -304,15 +303,15 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
// fallthrough // fallthrough
default: default:
if (RunIt) if (Parser->Mode == RunModeRun)
*Result = TotalValue; *Result = TotalValue;
return TRUE; return TRUE;
} }
if (!ParseValue(Parser, &CurrentValue, ResultOnHeap, RunIt)) if (!ParseValue(Parser, &CurrentValue, ResultOnHeap))
return FALSE; return FALSE;
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
if (CurrentValue->Typ->Base == TypeFP || TotalValue->Typ->Base == TypeFP) if (CurrentValue->Typ->Base == TypeFP || TotalValue->Typ->Base == TypeFP)
{ /* floating point expression */ { /* floating point expression */
@ -396,15 +395,15 @@ int ParseExpression(struct ParseState *Parser, struct Value **Result, int Result
} }
/* parse an expression. operator precedence is not supported */ /* parse an expression. operator precedence is not supported */
int ParseIntExpression(struct ParseState *Parser, int RunIt) int ParseIntExpression(struct ParseState *Parser)
{ {
struct Value *Val; struct Value *Val;
int Result = 0; int Result = 0;
if (!ParseExpression(Parser, &Val, FALSE, RunIt)) if (!ParseExpression(Parser, &Val, FALSE))
ProgramFail(Parser, "expression expected"); ProgramFail(Parser, "expression expected");
if (RunIt) if (Parser->Mode == RunModeRun)
{ {
if (Val->Typ->Base != TypeInt) if (Val->Typ->Base != TypeInt)
ProgramFail(Parser, "integer value expected"); ProgramFail(Parser, "integer value expected");
@ -465,7 +464,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace)
ProgramFail(Parser, "bad function definition"); ProgramFail(Parser, "bad function definition");
if (!ParseStatement(Parser, FALSE)) if (!ParseStatementMaybeRun(Parser, FALSE))
ProgramFail(Parser, "function definition expected"); ProgramFail(Parser, "function definition expected");
} }
@ -492,7 +491,7 @@ void ParseMacroDefinition(struct ParseState *Parser)
} }
/* parse a "for" statement */ /* parse a "for" statement */
void ParseFor(struct ParseState *Parser, int RunIt) void ParseFor(struct ParseState *Parser)
{ {
int Condition; int Condition;
struct ParseState PreConditional; struct ParseState PreConditional;
@ -503,50 +502,65 @@ void ParseFor(struct ParseState *Parser, int RunIt)
if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
if (!ParseStatement(Parser, RunIt)) if (!ParseStatement(Parser))
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon)
ProgramFail(Parser, "';' expected"); ProgramFail(Parser, "';' expected");
PreConditional = *Parser; PreConditional = *Parser;
Condition = ParseIntExpression(Parser, RunIt); Condition = ParseIntExpression(Parser);
if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon) if (LexGetToken(Parser, NULL, TRUE) != TokenSemicolon)
ProgramFail(Parser, "';' expected"); ProgramFail(Parser, "';' expected");
PreIncrement = *Parser; PreIncrement = *Parser;
ParseStatement(Parser, FALSE); ParseStatementMaybeRun(Parser, FALSE);
if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
PreStatement = *Parser; PreStatement = *Parser;
if (!ParseStatement(Parser, RunIt && Condition)) if (!ParseStatementMaybeRun(Parser, Condition))
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
After = *Parser; After = *Parser;
while (Condition && RunIt) while (Condition && Parser->Mode == RunModeRun)
{ {
*Parser = PreIncrement; *Parser = PreIncrement;
ParseStatement(Parser, TRUE); ParseStatement(Parser);
*Parser = PreConditional; *Parser = PreConditional;
Condition = ParseIntExpression(Parser, RunIt); Condition = ParseIntExpression(Parser);
if (Condition) if (Condition)
{ {
*Parser = PreStatement; *Parser = PreStatement;
ParseStatement(Parser, TRUE); ParseStatement(Parser);
} }
} }
*Parser = After; *Parser = After;
} }
/* parse a statement, but only run it if Condition is TRUE */
int ParseStatementMaybeRun(struct ParseState *Parser, int Condition)
{
if (Parser->Mode != RunModeSkip && !Condition)
{
enum RunMode OldMode = Parser->Mode;
Parser->Mode = RunModeSkip;
int Result = ParseStatement(Parser);
Parser->Mode = OldMode;
return Result;
}
else
return ParseStatement(Parser);
}
/* parse a statement */ /* parse a statement */
int ParseStatement(struct ParseState *Parser, int RunIt) int ParseStatement(struct ParseState *Parser)
{ {
struct Value *CValue; struct Value *CValue;
int Condition; int Condition;
@ -562,13 +576,13 @@ int ParseStatement(struct ParseState *Parser, int RunIt)
case TokenIdentifier: case TokenIdentifier:
*Parser = PreState; *Parser = PreState;
ParseExpression(Parser, &CValue, FALSE, RunIt); ParseExpression(Parser, &CValue, FALSE);
if (RunIt) if (Parser->Mode == RunModeRun)
VariableStackPop(Parser, CValue); VariableStackPop(Parser, CValue);
break; break;
case TokenLeftBrace: case TokenLeftBrace:
while (ParseStatement(Parser, RunIt)) while (ParseStatement(Parser))
{} {}
if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace) if (LexGetToken(Parser, NULL, TRUE) != TokenRightBrace)
@ -579,18 +593,18 @@ int ParseStatement(struct ParseState *Parser, int RunIt)
if (!LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (!LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
Condition = ParseIntExpression(Parser, RunIt); Condition = ParseIntExpression(Parser);
if (!LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (!LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
if (!ParseStatement(Parser, RunIt && Condition)) if (!ParseStatementMaybeRun(Parser, Condition))
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 (!ParseStatement(Parser, RunIt && !Condition)) if (!ParseStatementMaybeRun(Parser, !Condition))
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
} }
break; break;
@ -601,12 +615,12 @@ int ParseStatement(struct ParseState *Parser, int RunIt)
do do
{ {
*Parser = PreConditional; *Parser = PreConditional;
Condition = ParseIntExpression(Parser, RunIt); Condition = ParseIntExpression(Parser);
if (!ParseStatement(Parser, RunIt && Condition)) if (!ParseStatementMaybeRun(Parser, Condition))
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
} while (RunIt && Condition); } while (Parser->Mode == RunModeRun && Condition);
} }
break; break;
@ -616,17 +630,17 @@ int ParseStatement(struct ParseState *Parser, int RunIt)
do do
{ {
*Parser = PreStatement; *Parser = PreStatement;
if (!ParseStatement(Parser, RunIt)) if (!ParseStatement(Parser))
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
Condition = ParseIntExpression(Parser, RunIt); Condition = ParseIntExpression(Parser);
} while (Condition && RunIt); } while (Condition && Parser->Mode == RunModeRun);
} }
break; break;
case TokenFor: case TokenFor:
ParseFor(Parser, RunIt); ParseFor(Parser);
break; break;
case TokenSemicolon: break; case TokenSemicolon: break;
@ -674,7 +688,7 @@ int ParseStatement(struct ParseState *Parser, int RunIt)
if (!LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket) if (!LexGetToken(Parser, NULL, TRUE) != TokenOpenBracket)
ProgramFail(Parser, "'(' expected"); ProgramFail(Parser, "'(' expected");
Condition = ParseIntExpression(Parser, RunIt); Condition = ParseIntExpression(Parser);
if (!LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket) if (!LexGetToken(Parser, NULL, TRUE) != TokenCloseBracket)
ProgramFail(Parser, "')' expected"); ProgramFail(Parser, "')' expected");
@ -682,36 +696,54 @@ int ParseStatement(struct ParseState *Parser, int RunIt)
if (!LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) if (!LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace)
ProgramFail(Parser, "'{' expected"); ProgramFail(Parser, "'{' expected");
if (!ParseStatement(Parser, RunIt && Condition)) {
enum RunMode OldMode = Parser->Mode;
int OldSearchLabel = Parser->SearchLabel;
Parser->Mode = RunModeCaseSearch;
Parser->SearchLabel = Condition;
if (!ParseStatement(Parser))
ProgramFail(Parser, "statement expected"); ProgramFail(Parser, "statement expected");
// XXX - implement switch
Parser->Mode = OldMode;
Parser->SearchLabel = OldSearchLabel;
}
break; break;
case TokenCase: case TokenCase:
if (!LexGetToken(Parser, &CValue, TRUE) != TokenIdentifier) Condition = ParseIntExpression(Parser);
ProgramFail(Parser, "case label expected");
if (!LexGetToken(Parser, NULL, TRUE) != TokenColon) if (!LexGetToken(Parser, NULL, TRUE) != TokenColon)
ProgramFail(Parser, "':' expected"); ProgramFail(Parser, "':' expected");
// XXX - implement case
if (Parser->Mode == RunModeCaseSearch && Condition == Parser->SearchLabel)
Parser->Mode = RunModeRun;
break; break;
case TokenDefault: case TokenDefault:
if (!LexGetToken(Parser, NULL, TRUE) != TokenColon) if (!LexGetToken(Parser, NULL, TRUE) != TokenColon)
ProgramFail(Parser, "':' expected"); ProgramFail(Parser, "':' expected");
// XXX - implement default
if (Parser->Mode == RunModeCaseSearch)
Parser->Mode = RunModeRun;
break; break;
case TokenBreak: case TokenBreak:
// XXX - implement break if (Parser->Mode == RunModeRun)
Parser->Mode = RunModeBreak;
break; break;
case TokenContinue: case TokenContinue:
// XXX - implement continue if (Parser->Mode == RunModeRun)
Parser->Mode = RunModeContinue;
break; break;
case TokenReturn: case TokenReturn:
// XXX - implement return if (Parser->Mode == RunModeRun)
{
// XXX - check return type
// XXX - set return value
Parser->Mode = RunModeContinue;
}
break; break;
default: default:
@ -728,9 +760,9 @@ void Parse(const char *FileName, const char *Source, int SourceLen, int RunIt)
struct ParseState Parser; struct ParseState Parser;
void *Tokens = LexAnalyse(FileName, Source, SourceLen); // XXX - some better way of storing tokenised input? void *Tokens = LexAnalyse(FileName, Source, SourceLen); // XXX - some better way of storing tokenised input?
LexInitParser(&Parser, Tokens, FileName, 1); LexInitParser(&Parser, Tokens, FileName, 1, RunIt);
while (ParseStatement(&Parser, RunIt)) while (ParseStatement(&Parser))
{} {}
if (LexGetToken(&Parser, NULL, FALSE) != TokenEOF) if (LexGetToken(&Parser, NULL, FALSE) != TokenEOF)

23
picoc.h
View file

@ -49,7 +49,7 @@ enum LexToken
TokenOpenBracket, TokenCloseBracket, TokenOpenBracket, TokenCloseBracket,
TokenAssign, TokenPlus, TokenMinus, TokenAsterisk, TokenSlash, TokenAssign, TokenPlus, TokenMinus, TokenAsterisk, TokenSlash,
TokenEquality, TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual, TokenEquality, TokenLessThan, TokenGreaterThan, TokenLessEqual, TokenGreaterEqual,
TokenSemicolon, TokenComma, TokenDot, TokenSemicolon, TokenComma, TokenDot, TokenColon,
TokenArrow, TokenAmpersand, TokenArrow, TokenAmpersand,
TokenLeftBrace, TokenRightBrace, TokenLeftBrace, TokenRightBrace,
TokenLeftSquareBracket, TokenRightSquareBracket, TokenLeftSquareBracket, TokenRightSquareBracket,
@ -69,12 +69,25 @@ struct AllocNode
struct AllocNode *NextFree; struct AllocNode *NextFree;
}; };
/* whether we're running or skipping code */
enum RunMode
{
RunModeRun, /* we're running code as we parse it */
RunModeSkip, /* skipping code, not running */
RunModeReturn, /* returning from a function */
RunModeCaseSearch, /* searching for a case label */
RunModeBreak, /* breaking out of a switch/while/do */
RunModeContinue /* as above but repeat the loop */
};
/* parser state - has all this detail so we can parse nested files */ /* parser state - has all this detail so we can parse nested files */
struct ParseState struct ParseState
{ {
const void *Pos; const void *Pos;
int Line; int Line;
const char *FileName; const char *FileName;
enum RunMode Mode; /* whether to skip or run code */
int SearchLabel; /* what case label we're searching for */
}; };
/* values */ /* values */
@ -217,14 +230,14 @@ const char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLe
/* lex.c */ /* lex.c */
void LexInit(void); void LexInit(void);
void *LexAnalyse(const char *FileName, const char *Source, int SourceLen); void *LexAnalyse(const char *FileName, const char *Source, int SourceLen);
void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line); void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line, int RunIt);
enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos); enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos);
/* parse.c */ /* parse.c */
void ParseInit(void); void ParseInit(void);
int ParseExpression(struct ParseState *Parser, struct Value **Result, int ResultOnHeap, int RunIt); int ParseExpression(struct ParseState *Parser, struct Value **Result, int ResultOnHeap);
int ParseIntExpression(struct ParseState *Parser, int RunIt); int ParseIntExpression(struct ParseState *Parser);
int ParseStatement(struct ParseState *Parser, int RunIt); int ParseStatement(struct ParseState *Parser);
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, const char *Identifier, int IsProtoType); struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, const 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);

5
type.c
View file

@ -210,7 +210,10 @@ void TypeParse(struct ParseState *Parser, struct ValueType **Typ, const char **I
{ {
case TokenLeftSquareBracket: case TokenLeftSquareBracket:
{ {
int ArraySize = ParseIntExpression(Parser, TRUE); enum RunMode OldMode = Parser->Mode;
Parser->Mode = RunModeRun;
int ArraySize = ParseIntExpression(Parser);
Parser->Mode = OldMode;
if (LexGetToken(Parser, NULL, TRUE) != TokenRightSquareBracket) if (LexGetToken(Parser, NULL, TRUE) != TokenRightSquareBracket)
ProgramFail(Parser, "']' expected"); ProgramFail(Parser, "']' expected");