Neatened calling and error handling.

Parser now handles assignment.


git-svn-id: http://picoc.googlecode.com/svn/trunk@13 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2008-12-20 10:24:34 +00:00
parent 553e501460
commit 42c28c78c7
4 changed files with 49 additions and 57 deletions

View file

@ -1,6 +1,3 @@
int main() int a;
{ a = 4;
printf("Hello world\n");
}
main();

88
parse.c
View file

@ -38,21 +38,20 @@ void VariableSet(struct LexState *Lexer, Str *Ident, struct Value *Val)
} }
/* get the value of a variable. must be defined */ /* get the value of a variable. must be defined */
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val) void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct Value **LVal)
{ {
struct Value *ValPos; if (!TableGet(&GlobalTable, Ident, LVal))
if (!TableGet(&GlobalTable, Ident, &ValPos))
ProgramFail(Lexer, "'%S' is undefined", Ident); ProgramFail(Lexer, "'%S' is undefined", Ident);
*Val = *ValPos; *Val = **LVal;
} }
/* parse a single value */ /* parse a single value */
int ParseValue(struct LexState *Lexer, struct Value *Result) int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue)
{ {
struct LexState PreState = *Lexer; struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer); enum LexToken Token = LexGetToken(Lexer);
*LValue = NULL;
switch (Token) switch (Token)
{ {
@ -88,12 +87,12 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
ProgramFail(Lexer, "not implemented"); ProgramFail(Lexer, "not implemented");
case TokenIdentifier: case TokenIdentifier:
VariableGet(Lexer, &Lexer->Value.String, Result); VariableGet(Lexer, &Lexer->Value.String, Result, LValue);
break; break;
default: default:
*Lexer = PreState; *Lexer = PreState;
break; return FALSE;
} }
return TRUE; return TRUE;
@ -103,9 +102,11 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
int ParseExpression(struct LexState *Lexer, struct Value *Result) int ParseExpression(struct LexState *Lexer, struct Value *Result)
{ {
struct Value CurrentValue; struct Value CurrentValue;
struct Value *CurrentLValue;
struct Value TotalValue; struct Value TotalValue;
struct Value *TotalLValue;
if (!ParseValue(Lexer, &TotalValue)) if (!ParseValue(Lexer, &TotalValue, &TotalLValue))
return FALSE; return FALSE;
while (TRUE) while (TRUE)
@ -116,17 +117,34 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result)
case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash: case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash:
case TokenEquality: case TokenLessThan: case TokenGreaterThan: case TokenEquality: case TokenLessThan: case TokenGreaterThan:
case TokenLessEqual: case TokenGreaterEqual: case TokenLogicalAnd: case TokenLessEqual: case TokenGreaterEqual: case TokenLogicalAnd:
case TokenLogicalOr: case TokenArithmeticOr: case TokenArithmeticExor: case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr:
case TokenDot: case TokenArithmeticExor: case TokenDot:
LexGetToken(Lexer); LexGetToken(Lexer);
break; break;
case TokenAssign: case TokenAddAssign: case TokenSubtractAssign:
LexGetToken(Lexer);
if (!ParseExpression(Lexer, &CurrentValue))
ProgramFail(Lexer, "expression expected");
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt)
ProgramFail(Lexer, "can't assign");
switch (Token)
{
case TokenAddAssign: TotalValue.Val.Integer += CurrentValue.Val.Integer; break;
case TokenSubtractAssign: TotalValue.Val.Integer -= CurrentValue.Val.Integer; break;
case TokenAssign: TotalValue.Val.Integer += CurrentValue.Val.Integer; break;
default: break;
}
// fallthrough
default: default:
*Result = TotalValue; *Result = TotalValue;
return TRUE; return TRUE;
} }
if (!ParseValue(Lexer, &CurrentValue)) if (!ParseValue(Lexer, &CurrentValue, &CurrentLValue))
return FALSE; return FALSE;
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt) if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt)
@ -166,13 +184,6 @@ void ParseIntExpression(struct LexState *Lexer, struct Value *Result)
ProgramFail(Lexer, "integer value expected"); ProgramFail(Lexer, "integer value expected");
} }
/* parse a statement which starts with an identifier - either an function or an assignment */
int ParseIdentStatement(struct LexState *Lexer, int RunIt)
{
/* XXX */
return FALSE;
}
/* parse a statement */ /* parse a statement */
int ParseStatement(struct LexState *Lexer, int RunIt) int ParseStatement(struct LexState *Lexer, int RunIt)
{ {
@ -180,10 +191,15 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
struct LexState PreState = *Lexer; struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer); enum LexToken Token = LexGetToken(Lexer);
printf("Token=%d\n", (int)Token);
switch (Token) switch (Token)
{ {
case TokenEOF:
return FALSE;
case TokenIdentifier: case TokenIdentifier:
ParseIdentStatement(&PreState, RunIt); ParseExpression(&PreState, &Conditional);
break; break;
case TokenLeftBrace: case TokenLeftBrace:
@ -296,6 +312,8 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
if (LexGetToken(Lexer) != TokenIdentifier) if (LexGetToken(Lexer) != TokenIdentifier)
ProgramFail(Lexer, "identifier expected"); ProgramFail(Lexer, "identifier expected");
/* XXX - need to handle function definitions here too */
VariableDefine(Lexer, &Lexer->Value.String, (Token == TokenVoidType) ? TypeVoid : TypeInt); VariableDefine(Lexer, &Lexer->Value.String, (Token == TokenVoidType) ? TypeVoid : TypeInt);
break; break;
@ -307,35 +325,17 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
return TRUE; return TRUE;
} }
/* parse and run some code */
void ParseRun(const Str *FileName, const Str *Source, int LineNo)
{
struct LexState Lexer;
LexInit(&Lexer, Source, FileName, 1);
while (ParseStatement(&Lexer, TRUE))
{}
}
/* quick scan a source file for definitions */ /* quick scan a source file for definitions */
void ParseScan(const Str *FileName, const Str *Source) void Parse(const Str *FileName, const Str *Source, int RunIt)
{ {
enum LexToken Token;
struct LexState Lexer; struct LexState Lexer;
LexInit(&Lexer, Source, FileName, 1); LexInit(&Lexer, Source, FileName, 1);
while ( (Token = LexGetToken(&Lexer)) != TokenEOF) while (ParseStatement(&Lexer, RunIt))
{ {}
/* do parsey things here */
StrPrintf("token %d\n", (int)Token); if (Lexer.Pos != Lexer.End)
} ProgramFail(&Lexer, "parse error");
} }
void ParseCallFunction(const Str *FuncIdent, int argc, char **argv)
{
}

View file

@ -65,7 +65,7 @@ void ScanFile(const Str *FileName)
Source = ReadFile(FileName); Source = ReadFile(FileName);
StrFromC(&SourceStr, Source); StrFromC(&SourceStr, Source);
ParseScan(FileName, &SourceStr); Parse(FileName, &SourceStr, TRUE);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -81,8 +81,5 @@ int main(int argc, char **argv)
StrFromC(&FileName, argv[1]); StrFromC(&FileName, argv[1]);
ScanFile(&FileName); ScanFile(&FileName);
StrFromC(&StartFunc, "main");
ParseCallFunction(&StartFunc, argc-1, &argv[1]);
return 0; return 0;
} }

View file

@ -152,7 +152,6 @@ void vStrPrintf(const char *Format, va_list Args);
/* picoc.c */ /* picoc.c */
void Fail(const char *Message, ...); void Fail(const char *Message, ...);
void ProgramError(const Str *FileName, int Line, const char *Message, ...);
void ProgramFail(struct LexState *Lexer, const char *Message, ...); void ProgramFail(struct LexState *Lexer, const char *Message, ...);
void ScanFile(const Str *FileName); void ScanFile(const Str *FileName);
@ -168,8 +167,7 @@ enum LexToken LexPeekToken(struct LexState *Lexer);
/* parse.c */ /* parse.c */
void ParseInit(void); void ParseInit(void);
void ParseScan(const Str *FileName, const Str *Source); void Parse(const Str *FileName, const Str *Source, int RunIt);
void ParseCallFunction(const Str *FuncIdent, int argc, char **argv);
#endif /* PICOC_H */ #endif /* PICOC_H */