Can now parse parameterised macros. Can't evaluate them yet though.

git-svn-id: http://picoc.googlecode.com/svn/trunk@462 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2010-07-08 04:52:05 +00:00
parent e977f325ae
commit 7c754bad48
5 changed files with 102 additions and 31 deletions

View file

@ -1110,7 +1110,7 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
if (VariableValue->Typ->Base == TypeMacro)
{
/* evaluate a macro as a kind of simple subroutine */
struct ParseState MacroParser = VariableValue->Val->Parser;
struct ParseState MacroParser = VariableValue->Val->MacroDef.Body;
struct Value *MacroResult;
if (!ExpressionParse(&MacroParser, &MacroResult) || LexGetToken(&MacroParser, NULL, FALSE) != TokenEndOfFunction)

18
lex.c
View file

@ -211,8 +211,12 @@ enum LexToken LexGetWord(struct LexState *Lexer, struct Value *Value)
Value->Val->Identifier = TableStrRegister2(StartPos, Lexer->Pos - StartPos);
Token = LexCheckReservedWord(Value->Val->Identifier);
if (Token == TokenHashInclude)
Lexer->ScanningHashInclude = TRUE;
switch (Token)
{
case TokenHashInclude: Lexer->Mode = LexModeHashInclude; break;
case TokenHashDefine: Lexer->Mode = LexModeHashDefine; break;
default: break;
}
if (Token != TokenNone)
return Token;
@ -373,12 +377,14 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
{
Lexer->Line++;
Lexer->Pos++;
Lexer->ScanningHashInclude = FALSE;
Lexer->Mode = LexModeNormal;
#ifdef FANCY_ERROR_REPORTING
Lexer->CharacterPos = 0;
#endif
return TokenEndOfLine;
}
else if (Lexer->Mode == LexModeHashDefine)
Lexer->Mode = LexModeNormal;
LEXER_INC(Lexer);
}
@ -399,7 +405,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
{
case '"': GotToken = LexGetStringConstant(Lexer, *Value, '"'); break;
case '\'': GotToken = LexGetCharacterConstant(Lexer, *Value); break;
case '(': GotToken = TokenOpenBracket; break;
case '(': if (Lexer->Mode == LexModeHashDefine) { GotToken = TokenOpenMacroBracket; Lexer->Mode = LexModeNormal; } else GotToken = TokenOpenBracket; break;
case ')': GotToken = TokenCloseBracket; break;
case '=': NEXTIS('=', TokenEqual, TokenAssign); break;
case '+': NEXTIS3('=', TokenAddAssign, '+', TokenIncrement, TokenPlus); break;
@ -407,7 +413,7 @@ enum LexToken LexScanGetToken(struct LexState *Lexer, struct Value **Value)
case '*': NEXTIS('=', TokenMultiplyAssign, TokenAsterisk); break;
case '/': if (NextChar == '/' || NextChar == '*') LexSkipComment(Lexer, NextChar); else NEXTIS('=', TokenDivideAssign, TokenSlash); break;
case '%': NEXTIS('=', TokenModulusAssign, TokenModulus); break;
case '<': if (Lexer->ScanningHashInclude) GotToken = LexGetStringConstant(Lexer, *Value, '>'); else { NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); } break;
case '<': if (Lexer->Mode == LexModeHashInclude) GotToken = LexGetStringConstant(Lexer, *Value, '>'); else { NEXTIS3PLUS('=', TokenLessEqual, '<', TokenShiftLeft, '=', TokenShiftLeftAssign, TokenLessThan); } break;
case '>': NEXTIS3PLUS('=', TokenGreaterEqual, '>', TokenShiftRight, '=', TokenShiftRightAssign, TokenGreaterThan); break;
case ';': GotToken = TokenSemicolon; break;
case '&': NEXTIS3('=', TokenArithmeticAndAssign, '&', TokenLogicalAnd, TokenAmpersand); break;
@ -528,7 +534,7 @@ void *LexAnalyse(const char *FileName, const char *Source, int SourceLen, int *T
Lexer.End = Source + SourceLen;
Lexer.Line = 1;
Lexer.FileName = FileName;
Lexer.ScanningHashInclude = FALSE;
Lexer.Mode = LexModeNormal;
#ifdef FANCY_ERROR_REPORTING
Lexer.CharacterPos = 1;
Lexer.SourceText = Source;

86
parse.c
View file

@ -26,24 +26,12 @@ enum ParseResult ParseStatementMaybeRun(struct ParseState *Parser, int Condition
return ParseStatement(Parser, CheckTrailingSemicolon);
}
/* parse a function definition and store it for later */
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier)
/* count the number of parameters to a function or macro */
int ParseCountParams(struct ParseState *Parser)
{
struct ValueType *ParamType;
char *ParamIdentifier;
enum LexToken Token;
struct Value *FuncValue;
struct Value *OldFuncValue;
struct ParseState ParamParser;
struct ParseState FuncBody;
int ParamCount = 0;
if (TopStackFrame != NULL)
ProgramFail(Parser, "nested function definitions are not allowed");
LexGetToken(Parser, NULL, TRUE); /* open bracket */
ParamParser = *Parser;
Token = LexGetToken(Parser, NULL, TRUE);
enum LexToken Token = LexGetToken(Parser, NULL, TRUE);
if (Token != TokenCloseBracket && Token != TokenEOF)
{
/* count the number of parameters */
@ -54,6 +42,28 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp
ParamCount++;
}
}
return ParamCount;
}
/* parse a function definition and store it for later */
struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueType *ReturnType, char *Identifier)
{
struct ValueType *ParamType;
char *ParamIdentifier;
enum LexToken Token;
struct ParseState ParamParser;
struct Value *FuncValue;
struct Value *OldFuncValue;
struct ParseState FuncBody;
int ParamCount = 0;
if (TopStackFrame != NULL)
ProgramFail(Parser, "nested function definitions are not allowed");
LexGetToken(Parser, NULL, TRUE); /* open bracket */
ParamParser = *Parser;
ParamCount = ParseCountParams(Parser);
if (ParamCount > PARAMETER_MAX)
ProgramFail(Parser, "too many parameters");
@ -232,15 +242,53 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
void ParseMacroDefinition(struct ParseState *Parser)
{
struct Value *MacroName;
struct Value *MacroValue = VariableAllocValueAndData(Parser, sizeof(struct ParseState), FALSE, NULL, TRUE);
struct Value *ParamName;
struct Value *MacroValue;
if (LexGetToken(Parser, &MacroName, TRUE) != TokenIdentifier)
ProgramFail(Parser, "identifier expected");
MacroValue->Val->Parser = *Parser;
if (LexGetToken(Parser, NULL, FALSE) == TokenOpenMacroBracket)
{
/* it's a parameterised macro, read the parameters */
enum LexToken Token = LexGetToken(Parser, NULL, TRUE);
struct ParseState ParamParser = *Parser;
int NumParams = ParseCountParams(&ParamParser);
int ParamCount = 0;
MacroValue = VariableAllocValueAndData(Parser, sizeof(struct MacroDef) + sizeof(const char *) * NumParams, FALSE, NULL, TRUE);
MacroValue->Val->MacroDef.NumParams = NumParams;
Token = LexGetToken(Parser, &ParamName, TRUE);
while (Token == TokenIdentifier)
{
/* store a parameter name */
MacroValue->Val->MacroDef.ParamName[ParamCount++] = ParamName->Val->Identifier;
/* get the trailing comma */
Token = LexGetToken(Parser, NULL, TRUE);
if (Token == TokenComma)
Token = LexGetToken(Parser, &ParamName, TRUE);
else if (Token != TokenCloseBracket)
ProgramFail(Parser, "comma expected");
}
if (Token != TokenCloseBracket)
ProgramFail(Parser, "close bracket expected");
}
else
{
/* allocate a simple unparameterised macro */
MacroValue = VariableAllocValueAndData(Parser, sizeof(struct MacroDef), FALSE, NULL, TRUE);
MacroValue->Val->MacroDef.NumParams = 0;
}
/* copy the body of the macro to execute later */
MacroValue->Val->MacroDef.Body = *Parser;
MacroValue->Typ = &MacroType;
LexToEndOfLine(Parser);
MacroValue->Val->Parser.Pos = LexCopyTokens(&MacroValue->Val->Parser, Parser);
MacroValue->Val->MacroDef.Body.Pos = LexCopyTokens(&MacroValue->Val->MacroDef.Body, Parser);
if (!TableSet(&GlobalTable, MacroName->Val->Identifier, MacroValue))
ProgramFail(Parser, "'%s' is already defined", &MacroName->Val->Identifier);

25
picoc.h
View file

@ -76,7 +76,8 @@ enum LexToken
/* 0x3c */ TokenLongType, TokenSignedType, TokenShortType, TokenStructType, TokenUnionType, TokenUnsignedType, TokenTypedef,
/* 0x43 */ TokenContinue, TokenDo, TokenElse, TokenFor, TokenIf, TokenWhile, TokenBreak, TokenSwitch, TokenCase, TokenDefault, TokenReturn,
/* 0x4e */ TokenHashDefine, TokenHashInclude, TokenNew, TokenDelete,
/* 0x52 */ TokenEOF, TokenEndOfLine, TokenEndOfFunction
/* 0x52 */ TokenOpenMacroBracket,
/* 0x53 */ TokenEOF, TokenEndOfLine, TokenEndOfFunction
};
/* used in dynamic memory allocation */
@ -161,6 +162,14 @@ struct FuncDef
struct ParseState Body; /* lexical tokens of the function body if not intrinsic */
};
/* macro definition */
struct MacroDef
{
int NumParams; /* the number of parameters */
char **ParamName; /* array of parameter names */
struct ParseState Body; /* lexical tokens of the function body if not intrinsic */
};
/* values */
union AnyValue
{
@ -173,13 +182,14 @@ union AnyValue
unsigned long UnsignedLongInteger;
char *Identifier;
char ArrayMem[2]; /* placeholder for where the data starts, doesn't point to it */
struct ParseState Parser;
/* struct ParseState Parser; */
struct ValueType *Typ;
struct FuncDef FuncDef;
struct MacroDef MacroDef;
#ifndef NO_FP
double FP;
#endif
void *Pointer; /* unsafe native pointers */
void *Pointer; /* unsafe native pointers */
};
struct Value
@ -228,13 +238,20 @@ struct StackFrame
};
/* lexer state */
enum LexMode
{
LexModeNormal,
LexModeHashInclude,
LexModeHashDefine
};
struct LexState
{
const char *Pos;
const char *End;
const char *FileName;
int Line;
int ScanningHashInclude;
enum LexMode Mode;
#ifdef FANCY_ERROR_REPORTING
int CharacterPos;
const char *SourceText;

View file

@ -34,7 +34,7 @@ void VariableFree(struct Value *Val)
/* free macro bodies */
if (Val->Typ == &MacroType)
HeapFreeMem((void *)Val->Val->Parser.Pos);
HeapFreeMem((void *)Val->Val->MacroDef.Body.Pos);
/* free the value */
HeapFreeMem(Val);