diff --git a/lex.c b/lex.c index 1064ee9..f3d5a35 100644 --- a/lex.c +++ b/lex.c @@ -474,21 +474,37 @@ enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int I return Token; } -/* substitute an end of line token for another in the token stream (once only) */ -void LexSubstituteEndOfLine(struct ParseState *Parser, enum LexToken ToToken) +/* find the end of the line */ +void LexToEndOfLine(struct ParseState *Parser) { - enum LexToken Token; - do + while (TRUE) { - Token = (enum LexToken)*(unsigned char *)Parser->Pos; - if (Token == TokenEndOfLine) - { - *(unsigned char *)Parser->Pos = (unsigned char )ToToken; - Parser->Pos++; - Parser->Line++; - } + enum LexToken Token = (enum LexToken)*(unsigned char *)Parser->Pos; + if (Token == TokenEndOfLine || Token == TokenEOF) + return; else LexGetToken(Parser, NULL, TRUE); - - } while (Token != TokenEndOfLine && Token != TokenEOF); + } +} + +/* copy the tokens from StartParser to EndParser into new memory and terminate with a TokenEOF */ +void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser) +{ + int MemSize = 0; + unsigned char *Pos = (unsigned char *)StartParser->Pos; + unsigned char *NewTokens; + enum LexToken Token; + + while ( (Token = (enum LexToken)*Pos) != TokenEOF && (void *)Pos != EndParser->Pos) + { /* count up how much memory we need */ + int ValueSize = LexTokenSize(Token); + Pos += ValueSize + 1; + MemSize += ValueSize + 1; + } + + assert((void *)Pos == EndParser->Pos); + NewTokens = VariableAlloc(StartParser, MemSize + 1, TRUE); + memcpy(NewTokens, StartParser->Pos, MemSize); + NewTokens[MemSize] = (unsigned char)TokenEOF; + return NewTokens; } diff --git a/parse.c b/parse.c index 13929e4..b4132b1 100644 --- a/parse.c +++ b/parse.c @@ -612,6 +612,7 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp enum LexToken Token; struct Value *FuncValue; struct ParseState ParamParser; + struct ParseState FuncBody; int ParamCount = 0; LexGetToken(Parser, NULL, TRUE); /* open bracket */ @@ -636,7 +637,6 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp FuncValue->Val->FuncDef.VarArgs = FALSE; FuncValue->Val->FuncDef.ParamType = (void *)FuncValue->Val + sizeof(struct FuncDef); FuncValue->Val->FuncDef.ParamName = (void *)FuncValue->Val->FuncDef.ParamType + sizeof(struct ValueType *) * ParamCount; - FuncValue->Val->FuncDef.Body = *Parser; for (ParamCount = 0; ParamCount < FuncValue->Val->FuncDef.NumParams; ParamCount++) { /* harvest the parameters into the function definition */ @@ -663,8 +663,12 @@ struct Value *ParseFunctionDefinition(struct ParseState *Parser, struct ValueTyp if (LexGetToken(Parser, NULL, FALSE) != TokenLeftBrace) ProgramFail(Parser, "bad function definition"); + FuncBody = *Parser; if (!ParseStatementMaybeRun(Parser, FALSE)) ProgramFail(Parser, "function definition expected"); + + FuncValue->Val->FuncDef.Body = FuncBody; + FuncValue->Val->FuncDef.Body.Pos = LexCopyTokens(&FuncBody, Parser); } if (!TableSet(&GlobalTable, Identifier, FuncValue)) @@ -731,7 +735,8 @@ void ParseMacroDefinition(struct ParseState *Parser) MacroValue->Val->Parser = *Parser; MacroValue->Typ = &MacroType; - LexSubstituteEndOfLine(Parser, TokenEOF); + LexToEndOfLine(Parser); + MacroValue->Val->Parser.Pos = LexCopyTokens(&MacroValue->Val->Parser, Parser); if (!TableSet(&GlobalTable, MacroName->Val->Identifier, MacroValue)) ProgramFail(Parser, "'%s' is already defined", &MacroName->Val->Identifier); diff --git a/picoc.h b/picoc.h index 1c41ffd..590c839 100644 --- a/picoc.h +++ b/picoc.h @@ -257,7 +257,8 @@ void LexInit(void); void *LexAnalyse(const char *FileName, const char *Source, int SourceLen); void LexInitParser(struct ParseState *Parser, void *TokenSource, const char *FileName, int Line, int RunIt); enum LexToken LexGetToken(struct ParseState *Parser, struct Value **Value, int IncPos); -void LexSubstituteEndOfLine(struct ParseState *Parser, enum LexToken ToToken); +void LexToEndOfLine(struct ParseState *Parser); +void *LexCopyTokens(struct ParseState *StartParser, struct ParseState *EndParser); /* parse.c */ int ParseExpression(struct ParseState *Parser, struct Value **Result);