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:
parent
d94b70212b
commit
fdad9f8d30
|
@ -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
5
lex.c
|
@ -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
170
parse.c
|
@ -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
23
picoc.h
|
@ -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
5
type.c
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue