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

70
parse.c
View file

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

View file

@ -5,7 +5,8 @@
/* configurable options */ /* configurable options */
#define USE_MALLOC #define USE_MALLOC
#define GLOBAL_TABLE_SIZE 199 #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 */ #define LARGE_INT_POWER_OF_TEN 1000000000 /* the largest power of ten which fits in an int on this architecture */
/* handy definitions */ /* handy definitions */
@ -139,7 +140,6 @@ struct LexState
const char *Pos; const char *Pos;
const char *End; const char *End;
const Str *FileName; const Str *FileName;
union AnyValue Value;
}; };
@ -163,8 +163,8 @@ int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val);
/* lex.c */ /* lex.c */
void LexInit(struct LexState *Lexer, const Str *Source, const Str *FileName, int Line); void LexInit(struct LexState *Lexer, const Str *Source, const Str *FileName, int Line);
enum LexToken LexGetToken(struct LexState *Lexer); enum LexToken LexGetToken(struct LexState *Lexer, union AnyValue *Value);
enum LexToken LexPeekToken(struct LexState *Lexer); enum LexToken LexPeekToken(struct LexState *Lexer, union AnyValue *Value);
/* parse.c */ /* parse.c */
void ParseInit(void); void ParseInit(void);