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()
{
printf("Hello world\n");
}
int a;
a = 4;
main();

90
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 */
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, &ValPos))
if (!TableGet(&GlobalTable, Ident, LVal))
ProgramFail(Lexer, "'%S' is undefined", Ident);
*Val = *ValPos;
*Val = **LVal;
}
/* 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;
enum LexToken Token = LexGetToken(Lexer);
*LValue = NULL;
switch (Token)
{
@ -88,12 +87,12 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
ProgramFail(Lexer, "not implemented");
case TokenIdentifier:
VariableGet(Lexer, &Lexer->Value.String, Result);
VariableGet(Lexer, &Lexer->Value.String, Result, LValue);
break;
default:
*Lexer = PreState;
break;
return FALSE;
}
return TRUE;
@ -103,9 +102,11 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
int ParseExpression(struct LexState *Lexer, struct Value *Result)
{
struct Value CurrentValue;
struct Value *CurrentLValue;
struct Value TotalValue;
struct Value *TotalLValue;
if (!ParseValue(Lexer, &TotalValue))
if (!ParseValue(Lexer, &TotalValue, &TotalLValue))
return FALSE;
while (TRUE)
@ -116,19 +117,36 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result)
case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash:
case TokenEquality: case TokenLessThan: case TokenGreaterThan:
case TokenLessEqual: case TokenGreaterEqual: case TokenLogicalAnd:
case TokenLogicalOr: case TokenArithmeticOr: case TokenArithmeticExor:
case TokenDot:
case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr:
case TokenArithmeticExor: case TokenDot:
LexGetToken(Lexer);
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:
*Result = TotalValue;
return TRUE;
}
if (!ParseValue(Lexer, &CurrentValue))
if (!ParseValue(Lexer, &CurrentValue, &CurrentLValue))
return FALSE;
if (CurrentValue.Typ != TypeInt || TotalValue.Typ != TypeInt)
ProgramFail(Lexer, "bad operand types");
@ -166,13 +184,6 @@ void ParseIntExpression(struct LexState *Lexer, struct Value *Result)
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 */
int ParseStatement(struct LexState *Lexer, int RunIt)
{
@ -180,10 +191,15 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer);
printf("Token=%d\n", (int)Token);
switch (Token)
{
case TokenEOF:
return FALSE;
case TokenIdentifier:
ParseIdentStatement(&PreState, RunIt);
ParseExpression(&PreState, &Conditional);
break;
case TokenLeftBrace:
@ -296,6 +312,8 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
if (LexGetToken(Lexer) != TokenIdentifier)
ProgramFail(Lexer, "identifier expected");
/* XXX - need to handle function definitions here too */
VariableDefine(Lexer, &Lexer->Value.String, (Token == TokenVoidType) ? TypeVoid : TypeInt);
break;
@ -307,35 +325,17 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
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 */
void ParseScan(const Str *FileName, const Str *Source)
void Parse(const Str *FileName, const Str *Source, int RunIt)
{
enum LexToken Token;
struct LexState Lexer;
LexInit(&Lexer, Source, FileName, 1);
while ( (Token = LexGetToken(&Lexer)) != TokenEOF)
{
/* do parsey things here */
StrPrintf("token %d\n", (int)Token);
}
while (ParseStatement(&Lexer, RunIt))
{}
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);
StrFromC(&SourceStr, Source);
ParseScan(FileName, &SourceStr);
Parse(FileName, &SourceStr, TRUE);
}
int main(int argc, char **argv)
@ -81,8 +81,5 @@ int main(int argc, char **argv)
StrFromC(&FileName, argv[1]);
ScanFile(&FileName);
StrFromC(&StartFunc, "main");
ParseCallFunction(&StartFunc, argc-1, &argv[1]);
return 0;
}

View file

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