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:
parent
553e501460
commit
42c28c78c7
90
parse.c
90
parse.c
|
@ -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,19 +117,36 @@ 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)
|
||||||
ProgramFail(Lexer, "bad operand types");
|
ProgramFail(Lexer, "bad operand types");
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
5
picoc.c
5
picoc.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
4
picoc.h
4
picoc.h
|
@ -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 */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue