Function definitions implemented.

Lexer changed to not carry values in LexState.


git-svn-id: http://picoc.googlecode.com/svn/trunk@15 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2008-12-21 01:36:09 +00:00
parent 19fbe151ff
commit eba1492fcb
3 changed files with 67 additions and 49 deletions

36
lex.c
View file

@ -56,7 +56,7 @@ enum LexToken LexCheckReservedWord(const Str *Word)
return TokenNone;
}
enum LexToken LexGetNumber(struct LexState *Lexer)
enum LexToken LexGetNumber(struct LexState *Lexer, union AnyValue *Value)
{
int Result = 0;
@ -66,11 +66,11 @@ enum LexToken LexGetNumber(struct LexState *Lexer)
Lexer->Pos++;
}
Lexer->Value.Integer = Result;
Value->Integer = Result;
return TokenIntegerConstant;
}
enum LexToken LexGetWord(struct LexState *Lexer)
enum LexToken LexGetWord(struct LexState *Lexer, union AnyValue *Value)
{
const char *Pos = Lexer->Pos + 1;
enum LexToken Token;
@ -78,22 +78,22 @@ enum LexToken LexGetWord(struct LexState *Lexer)
while (Lexer->Pos != Lexer->End && isCident(*Pos))
Pos++;
Lexer->Value.String.Str = Lexer->Pos;
Lexer->Value.String.Len = Pos - Lexer->Pos;
Value->String.Str = Lexer->Pos;
Value->String.Len = Pos - Lexer->Pos;
Lexer->Pos = Pos;
Token = LexCheckReservedWord(&Lexer->Value.String);
Token = LexCheckReservedWord(&Value->String);
if (Token != TokenNone)
return Token;
return TokenIdentifier;
}
enum LexToken LexGetStringConstant(struct LexState *Lexer)
enum LexToken LexGetStringConstant(struct LexState *Lexer, union AnyValue *Value)
{
int Escape = FALSE;
Lexer->Value.String.Str = Lexer->Pos;
Value->String.Str = Lexer->Pos;
while (Lexer->Pos != Lexer->End && (*Lexer->Pos != '"' || Escape))
{
if (Escape)
@ -103,16 +103,16 @@ enum LexToken LexGetStringConstant(struct LexState *Lexer)
Lexer->Pos++;
}
Lexer->Value.String.Len = Lexer->Pos - Lexer->Value.String.Str;
Value->String.Len = Lexer->Pos - Value->String.Str;
if (*Lexer->Pos == '"')
Lexer->Pos++;
return TokenStringConstant;
}
enum LexToken LexGetCharacterConstant(struct LexState *Lexer)
enum LexToken LexGetCharacterConstant(struct LexState *Lexer, union AnyValue *Value)
{
Lexer->Value.Integer = Lexer->Pos[1];
Value->Integer = Lexer->Pos[1];
if (Lexer->Pos[2] != '\'')
ProgramFail(Lexer, "illegal character '%c'", Lexer->Pos[2]);
@ -120,7 +120,7 @@ enum LexToken LexGetCharacterConstant(struct LexState *Lexer)
return TokenCharacterConstant;
}
enum LexToken LexGetToken(struct LexState *Lexer)
enum LexToken LexGetToken(struct LexState *Lexer, union AnyValue *Value)
{
char ThisChar;
char NextChar;
@ -138,17 +138,17 @@ enum LexToken LexGetToken(struct LexState *Lexer)
ThisChar = *Lexer->Pos;
if (isCidstart(ThisChar))
return LexGetWord(Lexer);
return LexGetWord(Lexer, Value);
if (isdigit(ThisChar))
return LexGetNumber(Lexer);
return LexGetNumber(Lexer, Value);
NextChar = (Lexer->Pos+1 != Lexer->End) ? *(Lexer->Pos+1) : 0;
LEXINC;
switch (ThisChar)
{
case '"': return LexGetStringConstant(Lexer);
case '\'': return LexGetCharacterConstant(Lexer);
case '"': return LexGetStringConstant(Lexer, Value);
case '\'': return LexGetCharacterConstant(Lexer, Value);
case '(': return TokenOpenBracket;
case ')': return TokenCloseBracket;
case '=': NEXTIS('=', TokenEquality, TokenAssign);
@ -177,9 +177,9 @@ enum LexToken LexGetToken(struct LexState *Lexer)
}
/* look at the next token without changing the lexer state */
enum LexToken LexPeekToken(struct LexState *Lexer)
enum LexToken LexPeekToken(struct LexState *Lexer, union AnyValue *Value)
{
struct LexState LocalState = *Lexer;
return LexGetToken(&LocalState);
return LexGetToken(&LocalState, Value);
}

70
parse.c
View file

@ -7,10 +7,14 @@
struct Table GlobalTable;
struct TableEntry GlobalHashTable[GLOBAL_TABLE_SIZE];
/* the table of function definitions */
struct LexState FunctionStore[FUNCTION_STORE_MAX];
int FunctionStoreUsed = 0;
/* local prototypes */
int ParseExpression(struct LexState *Lexer, struct Value *Result);
void ParseIntExpression(struct LexState *Lexer, struct Value *Result);
int ParseStatement(struct LexState *Lexer, int RunIt);
/* initialise the parser */
@ -50,14 +54,13 @@ void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val, struct V
int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LValue)
{
struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer);
enum LexToken Token = LexGetToken(Lexer, &Result->Val);
*LValue = NULL;
switch (Token)
{
case TokenIntegerConstant: case TokenCharacterConstant: case TokenStringConstant:
Result->Typ = TypeInt;
Result->Val = Lexer->Value;
if (Token == TokenStringConstant)
Result->Typ = TypeString;
break;
@ -78,7 +81,7 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal
if (!ParseExpression(Lexer, Result))
ProgramFail(Lexer, "invalid expression");
if (LexGetToken(Lexer) != TokenCloseBracket)
if (LexGetToken(Lexer, &Result->Val) != TokenCloseBracket)
ProgramFail(Lexer, "')' expected");
break;
@ -87,7 +90,7 @@ int ParseValue(struct LexState *Lexer, struct Value *Result, struct Value **LVal
ProgramFail(Lexer, "not implemented");
case TokenIdentifier:
VariableGet(Lexer, &Lexer->Value.String, Result, LValue);
VariableGet(Lexer, &Result->Val.String, Result, LValue);
break;
default:
@ -111,7 +114,7 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result)
while (TRUE)
{
enum LexToken Token = LexPeekToken(Lexer);
enum LexToken Token = LexPeekToken(Lexer, &CurrentValue.Val);
switch (Token)
{
case TokenPlus: case TokenMinus: case TokenAsterisk: case TokenSlash:
@ -119,11 +122,11 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result)
case TokenLessEqual: case TokenGreaterEqual: case TokenLogicalAnd:
case TokenLogicalOr: case TokenAmpersand: case TokenArithmeticOr:
case TokenArithmeticExor: case TokenDot:
LexGetToken(Lexer);
LexGetToken(Lexer, &CurrentValue.Val);
break;
case TokenAssign: case TokenAddAssign: case TokenSubtractAssign:
LexGetToken(Lexer);
LexGetToken(Lexer, &CurrentValue.Val);
if (!ParseExpression(Lexer, &CurrentValue))
ProgramFail(Lexer, "expression expected");
@ -184,11 +187,29 @@ void ParseIntExpression(struct LexState *Lexer, struct Value *Result)
ProgramFail(Lexer, "integer value expected");
}
/* parse a function definition */
void ParseFunctionDefinition(struct LexState *Lexer)
/* parse a function definition and store it for later */
void ParseFunctionDefinition(struct LexState *Lexer, Str *Identifier, struct LexState *PreState)
{
LexGetToken(Lexer);
/* XXX - finish this */
struct Value FuncValue;
if (FunctionStoreUsed >= FUNCTION_STORE_MAX)
ProgramFail(Lexer, "too many functions defined");
FunctionStore[FunctionStoreUsed] = *PreState;
LexGetToken(Lexer, &FuncValue.Val);
if (LexGetToken(Lexer, &FuncValue.Val) != TokenCloseBracket || LexPeekToken(Lexer, &FuncValue.Val) != TokenLeftBrace)
ProgramFail(Lexer, "bad function definition");
if (!ParseStatement(Lexer, FALSE))
ProgramFail(Lexer, "function definition expected");
FunctionStore[FunctionStoreUsed].End = Lexer->Pos;
FuncValue.Typ = TypeFunction;
FuncValue.Val.Integer = FunctionStoreUsed;
FunctionStoreUsed++;
if (!TableSet(&GlobalTable, Identifier, &FuncValue, FALSE))
ProgramFail(Lexer, "'%S' is already defined", Identifier);
}
/* parse a statement */
@ -196,9 +217,8 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
{
struct Value Conditional;
struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer);
enum LexToken AfterToken;
Str Identifier;
union AnyValue LexerValue;
enum LexToken Token = LexGetToken(Lexer, &LexerValue);
printf("Token=%d\n", (int)Token);
@ -216,7 +236,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
while (ParseStatement(Lexer, RunIt))
{}
if (LexGetToken(Lexer) != TokenRightBrace)
if (LexGetToken(Lexer, &LexerValue) != TokenRightBrace)
ProgramFail(Lexer, "'}' expected");
break;
@ -226,9 +246,9 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
if (!ParseStatement(Lexer, RunIt && Conditional.Val.Integer))
ProgramFail(Lexer, "statement expected");
if (LexPeekToken(Lexer) == TokenElse)
if (LexPeekToken(Lexer, &LexerValue) == TokenElse)
{
LexGetToken(Lexer);
LexGetToken(Lexer, &LexerValue);
if (!ParseStatement(Lexer, RunIt && !Conditional.Val.Integer))
ProgramFail(Lexer, "statement expected");
}
@ -271,7 +291,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
struct LexState PreStatement;
struct LexState After;
if (LexGetToken(Lexer) != TokenOpenBracket)
if (LexGetToken(Lexer, &LexerValue) != TokenOpenBracket)
ProgramFail(Lexer, "'(' expected");
if (!ParseStatement(Lexer, RunIt))
@ -280,13 +300,13 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
PreConditional = *Lexer;
ParseIntExpression(Lexer, &Conditional);
if (LexGetToken(Lexer) != TokenSemicolon)
if (LexGetToken(Lexer, &LexerValue) != TokenSemicolon)
ProgramFail(Lexer, "';' expected");
PreIncrement = *Lexer;
ParseStatement(Lexer, FALSE);
if (LexGetToken(Lexer) != TokenCloseBracket)
if (LexGetToken(Lexer, &LexerValue) != TokenCloseBracket)
ProgramFail(Lexer, "')' expected");
PreStatement = *Lexer;
@ -319,16 +339,14 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
case TokenIntType:
case TokenCharType:
case TokenVoidType:
if (LexGetToken(Lexer) != TokenIdentifier)
if (LexGetToken(Lexer, &LexerValue) != TokenIdentifier)
ProgramFail(Lexer, "identifier expected");
/* handle function definitions */
Identifier = Lexer->Value.String;
AfterToken = LexPeekToken(Lexer);
if (AfterToken == TokenOpenBracket)
ParseFunctionDefinition(Lexer);
if (LexPeekToken(Lexer, &LexerValue) == TokenOpenBracket)
ParseFunctionDefinition(Lexer, &LexerValue.String, &PreState);
else
VariableDefine(Lexer, &Identifier, (Token == TokenVoidType) ? TypeVoid : TypeInt);
VariableDefine(Lexer, &LexerValue.String, (Token == TokenVoidType) ? TypeVoid : TypeInt);
break;
default:

10
picoc.h
View file

@ -5,8 +5,9 @@
/* configurable options */
#define USE_MALLOC
#define GLOBAL_TABLE_SIZE 199
#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
#define GLOBAL_TABLE_SIZE 199 /* global variable table */
#define FUNCTION_STORE_MAX 50 /* maximum number of used-defined functions */
#define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
/* handy definitions */
#ifndef TRUE
@ -139,7 +140,6 @@ struct LexState
const char *Pos;
const char *End;
const Str *FileName;
union AnyValue Value;
};
@ -163,8 +163,8 @@ int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val);
/* lex.c */
void LexInit(struct LexState *Lexer, const Str *Source, const Str *FileName, int Line);
enum LexToken LexGetToken(struct LexState *Lexer);
enum LexToken LexPeekToken(struct LexState *Lexer);
enum LexToken LexGetToken(struct LexState *Lexer, union AnyValue *Value);
enum LexToken LexPeekToken(struct LexState *Lexer, union AnyValue *Value);
/* parse.c */
void ParseInit(void);