Fixed an index out of bounds bug. Updated ddoc

This commit is contained in:
Hackerpilot 2013-07-12 16:17:14 +00:00
parent e91316cc9a
commit 50ddf8abf8
1 changed files with 69 additions and 45 deletions

View File

@ -90,8 +90,8 @@ Module parseModule(const(Token)[] tokens, string fileName)
parser.fileName = fileName; parser.fileName = fileName;
parser.tokens = tokens; parser.tokens = tokens;
auto mod = parser.parseModule(); auto mod = parser.parseModule();
writefln("Parsing finished with %d errors and %d warnings.", // writefln("Parsing finished with %d errors and %d warnings.",
parser.errorCount, parser.warningCount); // parser.errorCount, parser.warningCount);
return mod; return mod;
} }
@ -1654,14 +1654,14 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
node.classDeclaration = parseClassDeclaration(); node.classDeclaration = parseClassDeclaration();
break; break;
case this_: case this_:
if (startsWith(this_, lParen, this_)) if (startsWith(this_, lParen, this_))
{ {
node.postblit = parsePostblit(); node.postblit = parsePostblit();
if (node.postblit is null) return null; if (node.postblit is null) return null;
} }
else else
{ {
node.constructor = parseConstructor(); node.constructor = parseConstructor();
if (node.constructor is null) return null; if (node.constructor is null) return null;
} }
break; break;
@ -1719,9 +1719,9 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
case union_: case union_:
node.unionDeclaration = parseUnionDeclaration(); node.unionDeclaration = parseUnionDeclaration();
break; break;
case invariant_: case invariant_:
node.invariant_ = parseInvariant(); node.invariant_ = parseInvariant();
break; break;
case unittest_: case unittest_:
node.unittest_ = parseUnittest(); node.unittest_ = parseUnittest();
break; break;
@ -1733,8 +1733,8 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
node.variableDeclaration = parseVariableDeclaration(null, true); node.variableDeclaration = parseVariableDeclaration(null, true);
else if (peekIs(lParen)) else if (peekIs(lParen))
node.functionDeclaration = parseFunctionDeclaration(null, true); node.functionDeclaration = parseFunctionDeclaration(null, true);
else else
goto type; goto type;
} }
else else
goto type; goto type;
@ -1774,7 +1774,8 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
break; break;
default: default:
error("Declaration expected"); error("Declaration expected");
advance(); if (moreTokens())
advance();
return null; return null;
} }
return node; return node;
@ -1785,7 +1786,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
* *
* $(GRAMMAR $(RULEDEF declarationsAndStatements): * $(GRAMMAR $(RULEDEF declarationsAndStatements):
* $(RULE declarationOrStatement)+ * $(RULE declarationOrStatement)+
* ; * ;)
*/ */
DeclarationsAndStatements parseDeclarationsAndStatements() DeclarationsAndStatements parseDeclarationsAndStatements()
{ {
@ -3176,7 +3177,10 @@ invariant() foo();
* Parses a LambdaExpression * Parses a LambdaExpression
* *
* $(GRAMMAR $(RULEDEF lambdaExpression): * $(GRAMMAR $(RULEDEF lambdaExpression):
* ($(LITERAL Identifier) | $(RULE parameters) $(RULE functionAttribute)* ) $(LITERAL '=>') $(RULE assignExpression) * $(LITERAL Identifier) $(LITERAL '=>') $(RULE assignExpression)
* | $(LITERAL 'function') $(RULE parameters) $(RULE functionAttribute)* $(LITERAL '=>') $(RULE assignExpression)
* | $(LITERAL 'delegate') $(RULE parameters) $(RULE functionAttribute)* $(LITERAL '=>') $(RULE assignExpression)
* | $(RULE parameters) $(RULE functionAttribute)* $(LITERAL '=>') $(RULE assignExpression)
* ;) * ;)
*/ */
LambdaExpression parseLambdaExpression() LambdaExpression parseLambdaExpression()
@ -3301,8 +3305,13 @@ invariant() foo();
auto node = new MixinDeclaration; auto node = new MixinDeclaration;
if (peekIs(TokenType.identifier)) if (peekIs(TokenType.identifier))
node.templateMixinExpression = parseTemplateMixinExpression(); node.templateMixinExpression = parseTemplateMixinExpression();
else else if (peekIs(TokenType.lParen))
node.mixinExpression = parseMixinExpression(); node.mixinExpression = parseMixinExpression();
else
{
error(`"(" or identifier expected`);
return null;
}
expect(TokenType.semicolon); expect(TokenType.semicolon);
return node; return node;
} }
@ -3735,11 +3744,11 @@ invariant() foo();
node.vararg = true; node.vararg = true;
advance(); advance();
} }
else if (currentIs(TokenType.assign)) else if (currentIs(TokenType.assign))
{ {
advance(); advance();
node.default_ = parseAssignExpression(); node.default_ = parseAssignExpression();
} }
return node; return node;
} }
@ -3759,7 +3768,7 @@ invariant() foo();
*/ */
TokenType parseParameterAttribute(bool validate = false) TokenType parseParameterAttribute(bool validate = false)
{ {
mixin(traceEnterAndExit!(__FUNCTION__)); mixin(traceEnterAndExit!(__FUNCTION__));
with (TokenType) switch (current.type) with (TokenType) switch (current.type)
{ {
case immutable_: case immutable_:
@ -4034,6 +4043,20 @@ q{(int a, ...)
break; break;
case function_: case function_:
case delegate_: case delegate_:
if (peekIs(lParen))
{
auto b = setBookmark();
advance(); // function | delegate
skipParens();
if (currentIs(goesTo))
{
goToBookmark(b);
goto lambda;
}
else
goToBookmark(b);
}
goto case;
case lBrace: case lBrace:
case in_: case in_:
case out_: case out_:
@ -4063,6 +4086,7 @@ q{(int a, ...)
if (currentIs(goesTo)) if (currentIs(goesTo))
{ {
goToBookmark(b); goToBookmark(b);
lambda:
node.lambdaExpression = parseLambdaExpression(); node.lambdaExpression = parseLambdaExpression();
} }
else if (currentIs(lBrace)) else if (currentIs(lBrace))
@ -4533,10 +4557,10 @@ q{(int a, ...)
mixin(traceEnterAndExit!(__FUNCTION__)); mixin(traceEnterAndExit!(__FUNCTION__));
auto node = new StructDeclaration; auto node = new StructDeclaration;
expect(TokenType.struct_); expect(TokenType.struct_);
if (currentIs(TokenType.identifier)) if (currentIs(TokenType.identifier))
{ {
node.name = advance(); node.name = advance();
} }
if (currentIs(TokenType.lParen)) if (currentIs(TokenType.lParen))
{ {
@ -4802,8 +4826,8 @@ q{(int a, ...)
if (currentIs(TokenType.lParen)) if (currentIs(TokenType.lParen))
{ {
advance(); advance();
if (!currentIs(TokenType.rParen)) if (!currentIs(TokenType.rParen))
node.templateArgumentList = parseTemplateArgumentList(); node.templateArgumentList = parseTemplateArgumentList();
expect(TokenType.rParen); expect(TokenType.rParen);
} }
else else
@ -4830,13 +4854,13 @@ q{(int a, ...)
if (currentIs(TokenType.if_)) if (currentIs(TokenType.if_))
node.constraint = parseConstraint(); node.constraint = parseConstraint();
if (expect(TokenType.lBrace) is null) return null; if (expect(TokenType.lBrace) is null) return null;
while (moreTokens() && !currentIs(TokenType.rBrace)) while (moreTokens() && !currentIs(TokenType.rBrace))
{ {
auto decl = parseDeclaration(); auto decl = parseDeclaration();
if (decl !is null) if (decl !is null)
node.declarations ~= decl; node.declarations ~= decl;
} }
expect(TokenType.rBrace); expect(TokenType.rBrace);
return node; return node;
} }
@ -5449,12 +5473,12 @@ q{(int a, ...)
goToBookmark(bookmark); goToBookmark(bookmark);
node.low = parseAssignExpression(); node.low = parseAssignExpression();
if (node.low is null) return null; if (node.low is null) return null;
if (currentIs(slice)) if (currentIs(slice))
{ {
advance(); advance();
node.high = parseAssignExpression(); node.high = parseAssignExpression();
if (node.high is null) return null; if (node.high is null) return null;
} }
} }
end: end:
if (expect(TokenType.rBracket) is null) return null; if (expect(TokenType.rBracket) is null) return null;
@ -6140,7 +6164,7 @@ private:
auto column = index < tokens.length ? tokens[index].column : 0; auto column = index < tokens.length ? tokens[index].column : 0;
auto line = index < tokens.length ? tokens[index].line : 0; auto line = index < tokens.length ? tokens[index].line : 0;
if (messageFunction is null) if (messageFunction is null)
writefln("^^ %s(%d:%d): %s", fileName, line, column, message); writefln("%s(%d:%d)[warn]: %s", fileName, line, column, message);
else else
messageFunction(fileName, line, column, message); messageFunction(fileName, line, column, message);
} }
@ -6155,7 +6179,7 @@ private:
column++; column++;
auto line = index < tokens.length ? tokens[index].line : 0; auto line = index < tokens.length ? tokens[index].line : 0;
if (messageFunction is null) if (messageFunction is null)
stderr.writefln("!! %s(%d:%d): %s", fileName, line, column, message); writefln("%s(%d:%d)[error]: %s", fileName, line, column, message);
else else
messageFunction(fileName, line, column, message); messageFunction(fileName, line, column, message);
} }
@ -6275,7 +6299,7 @@ private:
* Returns a token of the specified type if it was the next token, otherwise * Returns a token of the specified type if it was the next token, otherwise
* calls the error function and returns null. * calls the error function and returns null.
*/ */
const(Token)* expect(TokenType type, string loc = __PRETTY_FUNCTION__) const(Token)* expect(TokenType type)
{ {
if (index < tokens.length && tokens[index].type == type) if (index < tokens.length && tokens[index].type == type)
return &tokens[index++]; return &tokens[index++];
@ -6283,10 +6307,10 @@ private:
{ {
if (tokenValues[type] is null) if (tokenValues[type] is null)
error("Expected " ~ to!string(type) ~ " instead of " error("Expected " ~ to!string(type) ~ " instead of "
~ (index < tokens.length ? tokens[index].value : "EOF") ~ " at " ~ loc); ~ (index < tokens.length ? tokens[index].value : "EOF"));
else else
error("Expected " ~ tokenValues[type] ~ " instead of " error("Expected " ~ tokenValues[type] ~ " instead of "
~ (index < tokens.length ? tokens[index].value : "EOF") ~ " at " ~ loc); ~ (index < tokens.length ? tokens[index].value : "EOF"));
return null; return null;
} }
} }