Now compiles

git-svn-id: http://picoc.googlecode.com/svn/trunk@10 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2008-12-19 00:22:52 +00:00
parent 8cfd9c6013
commit a41ac67b50
5 changed files with 119 additions and 64 deletions

6
lex.c
View file

@ -110,7 +110,7 @@ enum LexToken LexGetCharacterConstant(struct LexState *Lexer)
{
Lexer->Value.Integer = Lexer->Pos[1];
if (Lexer->Pos[2] != '\'')
ProgramError(Lexer->FileName, Lexer->Line, "illegal character '%c'", Lexer->Pos[2]);
ProgramFail(Lexer, "illegal character '%c'", Lexer->Pos[2]);
Lexer->Pos += 3;
return TokenCharacterConstant;
@ -168,14 +168,14 @@ enum LexToken LexGetToken(struct LexState *Lexer)
case '.': return TokenDot;
}
ProgramError(Lexer->FileName, Lexer->Line, "illegal character '%c'", ThisChar);
ProgramFail(Lexer, "illegal character '%c'", ThisChar);
return TokenEOF;
}
/* look at the next token without changing the lexer state */
enum LexToken LexPeekToken(struct LexState *Lexer)
{
struct LexToken LocalState = *Lexer;
struct LexState LocalState = *Lexer;
return LexGetToken(&LocalState);
}

102
parse.c
View file

@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
#include "picoc.h"
@ -7,12 +8,47 @@ struct Table GlobalTable;
struct TableEntry GlobalHashTable[GLOBAL_TABLE_SIZE];
/* local prototypes */
int ParseExpression(struct LexState *Lexer, struct Value *Result);
void ParseIntExpression(struct LexState *Lexer, struct Value *Result);
/* initialise the parser */
void ParseInit()
{
TableInit(&GlobalTable, &GlobalHashTable[0], "global", GLOBAL_TABLE_SIZE);
}
/* define a variable */
void VariableDefine(struct LexState *Lexer, const Str *Ident, enum ValueType Typ)
{
struct Value NewValue;
memset(&NewValue, '\0', sizeof(NewValue));
NewValue.Typ = Typ;
if (!TableSet(&GlobalTable, Ident, &NewValue, FALSE))
ProgramFail(Lexer, "'%S' is already defined", Ident);
}
/* set the value of a variable */
void VariableSet(struct LexState *Lexer, Str *Ident, struct Value *Val)
{
if (!TableSet(&GlobalTable, Ident, Val, TRUE))
ProgramFail(Lexer, "'%S' is undefined", Ident);
}
/* get the value of a variable. must be defined */
void VariableGet(struct LexState *Lexer, Str *Ident, struct Value *Val)
{
struct Value *ValPos;
if (!TableGet(&GlobalTable, Ident, &ValPos))
ProgramFail(Lexer, "'%S' is undefined", Ident);
*Val = *ValPos;
}
/* parse a single value */
int ParseValue(struct LexState *Lexer, struct Value *Result)
{
struct LexState PreState = *Lexer;
@ -28,14 +64,14 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
break;
case TokenMinus: case TokenUnaryExor: case TokenUnaryNot:
if (!ParseExpression(Lexer, Result))
ProgramFail(Lexer, "invalid expression");
ParseIntExpression(Lexer, Result);
switch(Token)
{
case TokenMinus: Result = -Result; break;
case TokenUnaryExor: Result = ~Result; break;
case TokenUnaryNot: Result = !Result; break;
case TokenMinus: Result->Val.Integer = -(Result->Val.Integer); break;
case TokenUnaryExor: Result->Val.Integer = ~(Result->Val.Integer); break;
case TokenUnaryNot: Result->Val.Integer = !(Result->Val.Integer); break;
default: break;
}
break;
@ -52,7 +88,7 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
ProgramFail(Lexer, "not implemented");
case TokenIdentifier:
ReadVariable(XXX);
VariableGet(Lexer, &Lexer->Value.String, Result);
break;
default:
@ -63,6 +99,7 @@ int ParseValue(struct LexState *Lexer, struct Value *Result)
return TRUE;
}
/* parse an expression. operator precedence is not supported */
int ParseExpression(struct LexState *Lexer, struct Value *Result)
{
struct Value CurrentValue;
@ -112,16 +149,34 @@ int ParseExpression(struct LexState *Lexer, struct Value *Result)
case TokenArithmeticOr: TotalValue.Val.Integer = TotalValue.Val.Integer | CurrentValue.Val.Integer; break;
case TokenArithmeticExor: TotalValue.Val.Integer = TotalValue.Val.Integer ^ CurrentValue.Val.Integer; break;
case TokenDot: ProgramFail(Lexer, "operator not supported"); break;
default: break;
}
}
return TRUE;
}
/* parse an expression. operator precedence is not supported */
void ParseIntExpression(struct LexState *Lexer, struct Value *Result)
{
if (!ParseExpression(Lexer, Result))
ProgramFail(Lexer, "expression expected");
if (Result->Typ != TypeInt)
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)
{
int Conditional;
struct Value Conditional;
struct LexState PreState = *Lexer;
enum LexToken Token = LexGetToken(Lexer);
@ -140,16 +195,15 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
break;
case TokenIf:
if (!ParseIntExpression(Lexer, &Conditional))
ProgramFail(Lexer, "expression expected");
ParseIntExpression(Lexer, &Conditional);
if (!ParseStatement(Lexer, RunIt && Conditional))
if (!ParseStatement(Lexer, RunIt && Conditional.Val.Integer))
ProgramFail(Lexer, "statement expected");
if (LexPeekToken(Lexer) == TokenElse)
{
LexGetToken(Lexer);
if (!ParseStatement(Lexer, RunIt && !Conditional))
if (!ParseStatement(Lexer, RunIt && !Conditional.Val.Integer))
ProgramFail(Lexer, "statement expected");
}
break;
@ -160,13 +214,12 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
do
{
*Lexer = PreConditional;
if (!ParseIntExpression(Lexer, &Conditional))
ProgramFail(Lexer, "expression expected");
ParseIntExpression(Lexer, &Conditional);
if (!ParseStatement(Lexer, RunIt && Conditional))
if (!ParseStatement(Lexer, RunIt && Conditional.Val.Integer))
ProgramFail(Lexer, "statement expected");
} while (Conditional && RunIt);
} while (Conditional.Val.Integer && RunIt);
}
break;
@ -179,10 +232,9 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
if (!ParseStatement(Lexer, RunIt))
ProgramFail(Lexer, "statement expected");
if (!ParseIntExpression(Lexer, &Conditional))
ProgramFail(Lexer, "expression expected");
ParseIntExpression(Lexer, &Conditional);
} while (Conditional && RunIt);
} while (Conditional.Val.Integer && RunIt);
}
break;
@ -200,8 +252,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
ProgramFail(Lexer, "statement expected");
PreConditional = *Lexer;
if (!ParseIntExpression(Lexer, &Conditional))
ProgramFail(Lexer, "expression expected");
ParseIntExpression(Lexer, &Conditional);
if (LexGetToken(Lexer) != TokenSemicolon)
ProgramFail(Lexer, "';' expected");
@ -213,12 +264,12 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
ProgramFail(Lexer, "')' expected");
PreStatement = *Lexer;
if (!ParseStatement(Lexer, Conditional && RunIt))
if (!ParseStatement(Lexer, Conditional.Val.Integer && RunIt))
ProgramFail(Lexer, "statement expected");
After = *Lexer;
while (Conditional && RunIt)
while (Conditional.Val.Integer && RunIt)
{
*Lexer = PreIncrement;
ParseStatement(Lexer, TRUE);
@ -226,7 +277,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
*Lexer = PreConditional;
ParseIntExpression(Lexer, &Conditional);
if (Conditional)
if (Conditional.Val.Integer)
{
*Lexer = PreStatement;
ParseStatement(Lexer, TRUE);
@ -245,7 +296,7 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
if (LexGetToken(Lexer) != TokenIdentifier)
ProgramFail(Lexer, "identifier expected");
DeclareVariable(Lexer, Lexer->Value.String);
VariableDefine(Lexer, &Lexer->Value.String, (Token == TokenVoidType) ? TypeVoid : TypeInt);
break;
default:
@ -259,12 +310,11 @@ int ParseStatement(struct LexState *Lexer, int RunIt)
/* parse and run some code */
void ParseRun(const Str *FileName, const Str *Source, int LineNo)
{
enum LexToken Token;
struct LexState Lexer;
LexInit(&Lexer, Source, FileName, 1);
while (ParseStatement(Lexer, TRUE))
while (ParseStatement(&Lexer, TRUE))
{}
}

View file

@ -18,11 +18,11 @@ void Fail(const char *Message, ...)
exit(1);
}
void ProgramError(const Str *FileName, int Line, const char *Message, ...)
void ProgramFail(struct LexState *Lexer, const char *Message, ...)
{
va_list Args;
StrPrintf("%S:%d: ", FileName, Line);
StrPrintf("%S:%d: ", Lexer->FileName, Lexer->Line);
va_start(Args, Message);
vStrPrintf(Message, Args);
StrPrintf("\n");

43
picoc.h
View file

@ -74,7 +74,12 @@ enum LexToken
TokenElse,
TokenFor,
TokenIf,
TokenWhile
TokenWhile,
TokenBreak,
TokenSwitch,
TokenCase,
TokenDefault,
TokenReturn
};
/* string type so we can use source file strings */
@ -84,22 +89,6 @@ typedef struct _Str
const char *Str;
} Str;
/* hash table data structure */
struct TableEntry
{
Str Key;
void *Value;
};
struct Table
{
const char *Name;
short Size;
struct TableEntry *HashTable;
};
/* function definition - really just where it is in the source file */
struct FuncDef
{
@ -108,8 +97,10 @@ struct FuncDef
int StartLine;
};
/* values */
enum ValueType
{
TypeVoid,
TypeInt,
TypeString
};
@ -126,6 +117,20 @@ struct Value
union AnyValue Val;
};
/* hash table data structure */
struct TableEntry
{
Str Key;
struct Value Val;
};
struct Table
{
const char *Name;
short Size;
struct TableEntry *HashTable;
};
/* lexer state - so we can lex nested files */
struct LexState
{
@ -153,8 +158,8 @@ void ScanFile(const Str *FileName);
/* table.c */
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, const char *Name, int Size);
void TableSet(struct Table *Tbl, const Str *Key, void *Value);
void *TableLookup(struct Table *Tbl, const Str *Key);
int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val, int Exists);
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);

28
table.c
View file

@ -3,10 +3,6 @@
#include "picoc.h"
#ifdef USE_MALLOC
#include <stdlib.h>
static unsigned int TableHash(const Str *Key)
{
unsigned int Hash;
@ -81,15 +77,18 @@ static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
}
void TableSet(struct Table *Tbl, const Str *Key, void *Value)
int TableSet(struct Table *Tbl, const Str *Key, struct Value *Val, int Exists)
{
int HashPos;
int AddAt;
HashPos = TableSearch(Tbl, Key, &AddAt);
if ( (HashPos != -1) != Exists)
return FALSE;
if (HashPos != -1)
Tbl->HashTable[HashPos].Value = Value; /* found - update value */
Tbl->HashTable[HashPos].Val = *Val; /* found - update value */
else
{
if (AddAt == -1)
@ -99,13 +98,15 @@ void TableSet(struct Table *Tbl, const Str *Key, void *Value)
{ /* add it to the table */
struct TableEntry *Entry = &Tbl->HashTable[AddAt];
Entry->Key = *Key;
Entry->Value = Value;
}
Entry->Val = *Val;
}
}
return TRUE;
}
void *TableLookup(struct Table *Tbl, const Str *Key)
int TableGet(struct Table *Tbl, const Str *Key, struct Value **Val)
{
int HashPos;
int AddAt;
@ -113,10 +114,9 @@ void *TableLookup(struct Table *Tbl, const Str *Key)
HashPos = TableSearch(Tbl, Key, &AddAt);
if (HashPos == -1)
return NULL;
else
return Tbl->HashTable[HashPos].Value;
return FALSE;
*Val = &Tbl->HashTable[HashPos].Val;
return TRUE;
}
#endif