All non-ASM TODO comments replaced with code. Now the debugging begins

This commit is contained in:
Hackerpilot 2013-06-29 01:54:52 -07:00
parent a12a8a866b
commit f7e7cf19ee
3 changed files with 358 additions and 275 deletions

20
stats.d
View File

@ -10,15 +10,19 @@ import std.d.lexer;
pure nothrow bool isLineOfCode(TokenType t) pure nothrow bool isLineOfCode(TokenType t)
{ {
switch(t) with (TokenType) switch(t)
{ {
case TokenType.semicolon: case semicolon:
case TokenType.while_: case while_:
case TokenType.if_: case if_:
case TokenType.for_: case do_:
case TokenType.foreach_: case else_:
case TokenType.foreach_reverse_: case switch_:
case TokenType.case_: case for_:
case foreach_:
case foreach_reverse_:
case default_:
case case_:
return true; return true;
default: default:
return false; return false;

View File

@ -56,7 +56,6 @@ abstract class ASTVisitor
/** */ void visit(AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); } /** */ void visit(AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); }
/** */ void visit(AsmXorExp asmXorExp) { asmXorExp.accept(this); } /** */ void visit(AsmXorExp asmXorExp) { asmXorExp.accept(this); }
/** */ void visit(AssertExpression assertExpression) { assertExpression.accept(this); } /** */ void visit(AssertExpression assertExpression) { assertExpression.accept(this); }
/** */ void visit(AssertStatement assertStatement) { assertStatement.accept(this); }
/** */ void visit(AssignExpression assignExpression) { assignExpression.accept(this); } /** */ void visit(AssignExpression assignExpression) { assignExpression.accept(this); }
/** */ void visit(AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); } /** */ void visit(AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); }
/** */ void visit(AtAttribute atAttribute) { atAttribute.accept(this); } /** */ void visit(AtAttribute atAttribute) { atAttribute.accept(this); }
@ -148,7 +147,6 @@ abstract class ASTVisitor
/** */ void visit(MulExpression mulExpression) { mulExpression.accept(this); } /** */ void visit(MulExpression mulExpression) { mulExpression.accept(this); }
/** */ void visit(NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); } /** */ void visit(NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); }
/** */ void visit(NewExpression newExpression) { newExpression.accept(this); } /** */ void visit(NewExpression newExpression) { newExpression.accept(this); }
/** */ void visit(NonEmptyStatement nonEmptyStatement) { nonEmptyStatement.accept(this); }
/** */ void visit(NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); } /** */ void visit(NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); }
/** */ void visit(Operand operand) { operand.accept(this); } /** */ void visit(Operand operand) { operand.accept(this); }
/** */ void visit(Operands operands) { operands.accept(this); } /** */ void visit(Operands operands) { operands.accept(this); }
@ -521,14 +519,6 @@ public:
/** */ AssignExpression message; /** */ AssignExpression message;
} }
///
class AssertStatement : ASTNode
{
public:
mixin(DEFAULT_ACCEPT);
/** */ AssertExpression assertExpression;
}
/// ///
class AssignExpression : ASTNode class AssignExpression : ASTNode
{ {
@ -1019,8 +1009,7 @@ class ForStatement : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Declaration initializationDeclaration; /** */ DeclarationOrStatement declarationOrStatement;
/** */ Statement initializationStatement;
/** */ Expression test; /** */ Expression test;
/** */ Expression increment; /** */ Expression increment;
/** */ StatementNoCaseNoDefault statementNoCaseNoDefault; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
@ -1301,7 +1290,7 @@ public:
/** */ Token identifier; /** */ Token identifier;
/** */ TypeSpecialization typeSpecialization; /** */ TypeSpecialization typeSpecialization;
/** */ TemplateParameterList templateParameterList; /** */ TemplateParameterList templateParameterList;
/** */ Token equalsOrColon; /** */ TokenType equalsOrColon;
} }
/// ///
@ -1363,8 +1352,8 @@ class MemberFunctionAttribute : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ Token token; /** */ TokenType tokenType;
/** */ FunctionAttribute functionAttribute; /** */ AtAttribute atAttribute;
} }
/// ///
@ -1449,16 +1438,6 @@ public:
/** */ AssignExpression assignExpression; /** */ AssignExpression assignExpression;
} }
///
class NonEmptyStatement : ASTNode
{
public:
mixin(DEFAULT_ACCEPT);
/** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
/** */ CaseStatement caseStatement;
/** */ CaseRangeStatement caseRangeStatement;
/** */ DefaultStatement defaultStatement;
}
/// ///
class StatementNoCaseNoDefault : ASTNode class StatementNoCaseNoDefault : ASTNode
@ -1749,7 +1728,7 @@ class StaticAssertStatement : ASTNode
{ {
public: public:
mixin(DEFAULT_ACCEPT); mixin(DEFAULT_ACCEPT);
/** */ AssertStatement assertStatement; /** */ AssertExpression assertExpression;
} }
/// ///

View File

@ -70,7 +70,7 @@ import std.array;
version (unittest) import std.stdio; version (unittest) import std.stdio;
//version = development; //version = development;
//version = verbose; version = verbose;
version(development) import std.stdio; version(development) import std.stdio;
import std.stdio; import std.stdio;
@ -102,7 +102,7 @@ struct Parser
*/ */
AddExpression parseAddExpression() AddExpression parseAddExpression()
{ {
version(verbose) writeln("parseAddExpression ", current.line); version(verbose) writeln(">parseAddExpression ", current.line);
return parseLeftAssocBinaryExpression!(AddExpression, MulExpression, return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
TokenType.plus, TokenType.minus, TokenType.tilde)(); TokenType.plus, TokenType.minus, TokenType.tilde)();
} }
@ -223,7 +223,7 @@ alias core.sys.posix.stdio.fileno fileno;
*/ */
AndAndExpression parseAndAndExpression() AndAndExpression parseAndAndExpression()
{ {
version(verbose) writeln("parseAndAndExpression ", current.line); version(verbose) writeln(">parseAndAndExpression ", current.line);
return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression, return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
TokenType.logicAnd)(); TokenType.logicAnd)();
} }
@ -238,7 +238,7 @@ alias core.sys.posix.stdio.fileno fileno;
*/ */
AndExpression parseAndExpression() AndExpression parseAndExpression()
{ {
version(verbose) writeln("parseAndExpression ", current.line); version(verbose) writeln(">parseAndExpression ", current.line);
return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression, return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
TokenType.bitAnd)(); TokenType.bitAnd)();
} }
@ -252,7 +252,8 @@ alias core.sys.posix.stdio.fileno fileno;
*/ */
ArgumentList parseArgumentList() ArgumentList parseArgumentList()
{ {
version(verbose) writeln("parseArgumentList ", current.line); version(verbose) writeln(">parseArgumentList ", current.line, " ", current.column);
version(verbose) scope(exit) writeln("<parseArgumentList ", current.line, " ", current.column);
return parseCommaSeparatedRule!(ArgumentList, AssignExpression)(); return parseCommaSeparatedRule!(ArgumentList, AssignExpression)();
} }
@ -266,7 +267,7 @@ alias core.sys.posix.stdio.fileno fileno;
Arguments parseArguments() Arguments parseArguments()
{ {
auto node = new Arguments; auto node = new Arguments;
version (verbose) writeln("parseArguments"); version (verbose) writeln(">parseArguments");
if (expect(TokenType.lParen) is null) return null; if (expect(TokenType.lParen) is null) return null;
node.argumentList = parseArgumentList(); node.argumentList = parseArgumentList();
if (expect(TokenType.rParen) is null) return null; if (expect(TokenType.rParen) is null) return null;
@ -554,8 +555,10 @@ alias core.sys.posix.stdio.fileno fileno;
*/ */
AsmStatement parseAsmStatement() AsmStatement parseAsmStatement()
{ {
// TODO asm
auto node = new AsmStatement; auto node = new AsmStatement;
assert (false); // TODO asm advance();
skipBraceContent();
return node; return node;
} }
@ -660,7 +663,7 @@ alias core.sys.posix.stdio.fileno fileno;
*/ */
AssignExpression parseAssignExpression() AssignExpression parseAssignExpression()
{ {
version(verbose) writeln("parseAssignExpression ", current.line); version(verbose) writeln(">parseAssignExpression ", current.line);
auto node = new AssignExpression; auto node = new AssignExpression;
node.ternaryExpression = parseTernaryExpression(); node.ternaryExpression = parseTernaryExpression();
if (currentIsOneOf(TokenType.assign, TokenType.unsignedShiftRightEqual, if (currentIsOneOf(TokenType.assign, TokenType.unsignedShiftRightEqual,
@ -842,7 +845,7 @@ alias core.sys.posix.stdio.fileno fileno;
AutoDeclaration parseAutoDeclaration() AutoDeclaration parseAutoDeclaration()
{ {
auto node = new AutoDeclaration; auto node = new AutoDeclaration;
version(verbose) writeln("parseAutoDeclaration ", current.line); version(verbose) writeln(">parseAutoDeclaration ", current.line);
node.storageClass = parseStorageClass(); node.storageClass = parseStorageClass();
if (node.storageClass is null) return null; if (node.storageClass is null) return null;
do do
@ -997,11 +1000,14 @@ alias core.sys.posix.stdio.fileno fileno;
* $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(LITERAL '...') $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(RULE declarationsAndStatements) * $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(LITERAL '...') $(LITERAL 'case') $(RULE assignExpression) $(LITERAL ':') $(RULE declarationsAndStatements)
* ;) * ;)
*/ */
CaseRangeStatement parseCaseRangeStatement() CaseRangeStatement parseCaseRangeStatement(AssignExpression low = null)
{ {
auto node = new CaseRangeStatement; auto node = new CaseRangeStatement;
expect(TokenType.case_); if (low is null)
node.low = parseAssignExpression(); {
expect(TokenType.case_);
node.low = parseAssignExpression();
}
if (expect(TokenType.colon) is null) return null; if (expect(TokenType.colon) is null) return null;
if (expect(TokenType.vararg) is null) return null; if (expect(TokenType.vararg) is null) return null;
expect(TokenType.case_); expect(TokenType.case_);
@ -1018,11 +1024,12 @@ alias core.sys.posix.stdio.fileno fileno;
* $(LITERAL 'case') $(RULE argumentList) $(LITERAL ':') $(RULE declarationsAndStatements) * $(LITERAL 'case') $(RULE argumentList) $(LITERAL ':') $(RULE declarationsAndStatements)
* ;) * ;)
*/ */
CaseStatement parseCaseStatement() CaseStatement parseCaseStatement(ArgumentList argumentList = null)
{ {
auto node = new CaseStatement; auto node = new CaseStatement;
expect(TokenType.case_); if (argumentList !is null)
node.argumentList = parseArgumentList(); expect(TokenType.case_);
node.argumentList = argumentList is null ? parseArgumentList() : argumentList;
if (expect(TokenType.colon) is null) return null; if (expect(TokenType.colon) is null) return null;
node.declarationsAndStatements = parseDeclarationsAndStatements(); node.declarationsAndStatements = parseDeclarationsAndStatements();
return node; return node;
@ -1341,7 +1348,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
*/ */
CmpExpression parseCmpExpression() CmpExpression parseCmpExpression()
{ {
version(verbose) writeln("parseCmpExpression ", current.line); version(verbose) writeln(">parseCmpExpression ", current.line);
auto node = new CmpExpression; auto node = new CmpExpression;
auto shift = parseShiftExpression(); auto shift = parseShiftExpression();
with (TokenType) switch (current.type) with (TokenType) switch (current.type)
@ -1656,7 +1663,23 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
node.destructor = parseDestructor(); node.destructor = parseDestructor();
break; break;
case enum_: case enum_:
node.enumDeclaration = parseEnumDeclaration(); if (peekIsOneOf(TokenType.lBrace, TokenType.colon))
node.enumDeclaration = parseEnumDeclaration();
if (peekIs(TokenType.identifier))
{
auto b = setBookmark();
advance();
if (peekIsOneOf(TokenType.lBrace, TokenType.colon, TokenType.semicolon))
{
goToBookmark(b);
node.enumDeclaration = parseEnumDeclaration();
}
else
{
goToBookmark(b);
node.variableDeclaration = parseVariableDeclaration();
}
}
break; break;
case import_: case import_:
node.importDeclaration = parseImportDeclaration(); node.importDeclaration = parseImportDeclaration();
@ -1791,13 +1814,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
auto node = new DeclarationsAndStatements; auto node = new DeclarationsAndStatements;
while (!currentIsOneOf(TokenType.rBrace) && moreTokens()) while (!currentIsOneOf(TokenType.rBrace) && moreTokens())
{ {
auto dos = new DeclarationOrStatement; auto dos = parseDeclarationOrStatement();
// "Any ambiguities in the grammar between Statements and
// Declarations are resolved by the declarations taking precedence."
if (isDeclaration())
dos.declaration = parseDeclaration();
else
dos.statement = parseStatementNoCaseNoDefault();
if (dos.statement !is null || dos.declaration !is null) if (dos.statement !is null || dos.declaration !is null)
node.declarationsAndStatements ~= dos; node.declarationsAndStatements ~= dos;
else else
@ -1824,6 +1841,26 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
return node; return node;
} }
/**
* Parses a DeclarationOrStatement
*
* $(GRAMMAR $(RULEDEF declarationOrStatement):
* $(RULE declaration)
* | $(RULE statement)
* ;)
*/
DeclarationOrStatement parseDeclarationOrStatement()
{
auto node = new DeclarationOrStatement;
// "Any ambiguities in the grammar between Statements and
// Declarations are resolved by the declarations taking precedence."
if (isDeclaration())
node.declaration = parseDeclaration();
else
node.statement = parseStatementNoCaseNoDefault();
return node;
}
/** /**
* Parses a Declarator * Parses a Declarator
* *
@ -2017,8 +2054,26 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
EnumMember parseEnumMember() EnumMember parseEnumMember()
{ {
auto node = new EnumMember; auto node = new EnumMember;
// TODO: ambiguity between type and identifier if (currentIs(TokenType.identifier))
assert (false); {
if (peekIsOneOf(TokenType.comma, TokenType.rBrace))
node.identifier = advance();
else if (peekIs(TokenType.assign))
{
node.identifier = advance();
goto assign;
}
else
goto type;
}
else
{
type:
node.type = parseType();
assign:
expect(TokenType.assign);
node.assignExpression = parseAssignExpression();
}
return node; return node;
} }
@ -2031,7 +2086,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
*/ */
EqualExpression parseEqualExpression(ShiftExpression shift = null) EqualExpression parseEqualExpression(ShiftExpression shift = null)
{ {
version(verbose) writeln("parseEqualExpression ", current.line); version(verbose) writeln(">parseEqualExpression ", current.line);
auto node = new EqualExpression; auto node = new EqualExpression;
node.left = shift is null ? parseShiftExpression() : shift; node.left = shift is null ? parseShiftExpression() : shift;
if (currentIsOneOf(TokenType.equal, TokenType.notEqual)) if (currentIsOneOf(TokenType.equal, TokenType.notEqual))
@ -2107,14 +2162,17 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
*/ */
ForStatement parseForStatement() ForStatement parseForStatement()
{ {
// forStatement:
// 'for' '(' declarationOrStatement expression? ';' expression? ')' statementNoCaseNoDefault
// ;
auto node = new ForStatement; auto node = new ForStatement;
if (expect(TokenType.for_) is null) return null; if (expect(TokenType.for_) is null) return null;
if (expect(TokenType.lParen) is null) return null; if (expect(TokenType.lParen) is null) return null;
// TODO node.declarationOrStatement = parseDeclarationOrStatement();
assert (false); if (currentIs(TokenType.semicolon))
advance();
else
node.test = parseExpression();
expect(TokenType.semicolon);
if (!currentIs(TokenType.rParen))
node.increment = parseExpression();
if (expect(TokenType.rParen) is null) return null; if (expect(TokenType.rParen) is null) return null;
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault(); node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
if (node.statementNoCaseNoDefault is null) return null; if (node.statementNoCaseNoDefault is null) return null;
@ -2135,11 +2193,11 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
if (currentIsOneOf(TokenType.foreach_, TokenType.foreach_reverse_)) if (currentIsOneOf(TokenType.foreach_, TokenType.foreach_reverse_))
node.foreachType = advance().type; node.foreachType = advance().type;
else else
{ {
error(`"foreach" or "foreach_reverse" expected`); error(`"foreach" or "foreach_reverse" expected`);
return null; return null;
} }
if (expect(TokenType.lParen) is null) return null; if (expect(TokenType.lParen) is null) return null;
auto feType = parseForeachTypeList(); auto feType = parseForeachTypeList();
bool canBeRange = feType.items.length == 1; bool canBeRange = feType.items.length == 1;
@ -2174,10 +2232,10 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
{ {
auto node = new ForeachType; auto node = new ForeachType;
if (currentIsOneOf(TokenType.ref_, TokenType.const_, TokenType.immutable_, if (currentIsOneOf(TokenType.ref_, TokenType.const_, TokenType.immutable_,
TokenType.shared_, TokenType.inout_)) TokenType.shared_, TokenType.inout_))
{ {
if ((node.typeConstructors = parseTypeConstructors()) is null) if ((node.typeConstructors = parseTypeConstructors()) is null)
return null; return null;
} }
if (currentIs(TokenType.identifier) && peekIsOneOf(TokenType.comma, TokenType.semicolon)) if (currentIs(TokenType.identifier) && peekIsOneOf(TokenType.comma, TokenType.semicolon))
{ {
@ -2321,9 +2379,9 @@ body {} // six
* ;) * ;)
*/ */
FunctionCallExpression parseFunctionCallExpression(UnaryExpression unary = null) FunctionCallExpression parseFunctionCallExpression(UnaryExpression unary = null)
{ {
auto node = new FunctionCallExpression; auto node = new FunctionCallExpression;
version (verbose) writeln("parseFunctionCallExpression ", current.line); version (verbose) writeln(">parseFunctionCallExpression ", current.line);
node.unaryExpression = unary is null ? parseUnaryExpression() : unary; node.unaryExpression = unary is null ? parseUnaryExpression() : unary;
if (currentIs(TokenType.not)) if (currentIs(TokenType.not))
node.templateArguments = parseTemplateArguments(); node.templateArguments = parseTemplateArguments();
@ -2431,30 +2489,30 @@ body {} // six
{ {
auto node = new FunctionLiteralExpression; auto node = new FunctionLiteralExpression;
if (currentIsOneOf(TokenType.function_, TokenType.delegate_)) if (currentIsOneOf(TokenType.function_, TokenType.delegate_))
{ {
node.functionOrDelegate = advance().type; node.functionOrDelegate = advance().type;
if (!currentIsOneOf(TokenType.lParen, TokenType.in_, TokenType.body_, if (!currentIsOneOf(TokenType.lParen, TokenType.in_, TokenType.body_,
TokenType.out_, TokenType.rBrace)) TokenType.out_, TokenType.rBrace))
{ {
node.type = parseType(); node.type = parseType();
if (node.type is null) return null; if (node.type is null) return null;
} }
} }
if (currentIs(TokenType.lParen)) if (currentIs(TokenType.lParen))
{ {
node.parameters = parseParameters(); node.parameters = parseParameters();
if (node.parameters is null) return null; if (node.parameters is null) return null;
do do
{ {
auto attr = parseFunctionAttribute(false); auto attr = parseFunctionAttribute(false);
if (attr is null) if (attr is null)
break; break;
else else
node.functionAttributes ~= attr; node.functionAttributes ~= attr;
} while (true); } while (true);
} }
node.functionBody = parseFunctionBody(); node.functionBody = parseFunctionBody();
if (node.functionBody is null) return null; if (node.functionBody is null) return null;
return node; return node;
} }
@ -2554,8 +2612,8 @@ body {} // six
node.identifierOrTemplateInstances ~= parseIdentifierOrTemplateInstance(); node.identifierOrTemplateInstances ~= parseIdentifierOrTemplateInstance();
if (!currentIs(TokenType.dot)) if (!currentIs(TokenType.dot))
break; break;
else else
advance(); advance();
} }
return node; return node;
} }
@ -2591,7 +2649,7 @@ body {} // six
*/ */
IdentityExpression parseIdentityExpression(ShiftExpression shift = null) IdentityExpression parseIdentityExpression(ShiftExpression shift = null)
{ {
version(verbose) writeln("parseIdentityExpression ", current.line); version(verbose) writeln(">parseIdentityExpression ", current.line);
auto node = new IdentityExpression; auto node = new IdentityExpression;
node.left = shift is null ? parseShiftExpression() : shift; node.left = shift is null ? parseShiftExpression() : shift;
if (currentIs(TokenType.not)) if (currentIs(TokenType.not))
@ -2798,7 +2856,7 @@ import core.stdc.stdio, std.string : KeepTerminator;
IndexExpression parseIndexExpression(UnaryExpression unaryExpression = null) IndexExpression parseIndexExpression(UnaryExpression unaryExpression = null)
{ {
auto node = new IndexExpression; auto node = new IndexExpression;
version (verbose) writeln("parseIndexExpression ", current.line); version (verbose) writeln(">parseIndexExpression ", current.line);
node.unaryExpression = unaryExpression is null ? parseUnaryExpression() : unaryExpression; node.unaryExpression = unaryExpression is null ? parseUnaryExpression() : unaryExpression;
if (expect(TokenType.lBracket) is null) return null; if (expect(TokenType.lBracket) is null) return null;
node.argumentList = parseArgumentList(); node.argumentList = parseArgumentList();
@ -2850,8 +2908,13 @@ import core.stdc.stdio, std.string : KeepTerminator;
Initialize parseInitialize() Initialize parseInitialize()
{ {
auto node = new Initialize; auto node = new Initialize;
// TODO if (!currentIs(TokenType.semicolon))
assert (false); {
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
if (node.statementNoCaseNoDefault is null) return null;
}
else if (expect(TokenType.semicolon) is null)
return null;
return node; return node;
} }
@ -3004,8 +3067,27 @@ invariant() foo();
auto node = new IsExpression; auto node = new IsExpression;
if (expect(TokenType.is_) is null) return null; if (expect(TokenType.is_) is null) return null;
if (expect(TokenType.lParen) is null) return null; if (expect(TokenType.lParen) is null) return null;
// TODO if (isType())
assert (false); {
node.type = parseType();
if (node.type is null) return null;
if (currentIs(TokenType.identifier))
{
node.identifier = advance();
if (currentIsOneOf(TokenType.assign, TokenType.colon))
{
node.equalsOrColon = advance().type;
node.typeSpecialization = parseTypeSpecialization();
if (currentIs(TokenType.comma))
{
advance();
node.templateParameterList = parseTemplateParameterList();
}
}
}
}
else
node.assignExpression = parseAssignExpression();
if (expect(TokenType.rParen) is null) return null; if (expect(TokenType.rParen) is null) return null;
return node; return node;
} }
@ -3159,8 +3241,22 @@ invariant() foo();
MemberFunctionAttribute parseMemberFunctionAttribute() MemberFunctionAttribute parseMemberFunctionAttribute()
{ {
auto node = new MemberFunctionAttribute; auto node = new MemberFunctionAttribute;
// TODO with (TokenType) switch (current.type)
assert (false); {
case at:
node.atAttribute = parseAtAttribute();
break;
case immutable_:
case inout_:
case shared_:
case const_:
case pure_:
case nothrow_:
node.tokenType = advance().type;
break;
default:
error(`Member funtion attribute expected`);
}
return node; return node;
} }
@ -3261,7 +3357,7 @@ invariant() foo();
*/ */
MulExpression parseMulExpression() MulExpression parseMulExpression()
{ {
version(verbose) writeln("parseMulExpression ", current.line); version(verbose) writeln(">parseMulExpression ", current.line);
return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression, return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
TokenType.star, TokenType.div, TokenType.mod)(); TokenType.star, TokenType.div, TokenType.mod)();
} }
@ -3315,35 +3411,6 @@ invariant() foo();
return node; return node;
} }
/**
* Parses a NonEmptyStatement
*
* $(GRAMMAR $(RULEDEF nonEmptyStatement):
* $(RULE statementNoCaseNoDefault)
* | $(RULE caseStatement)
* | $(RULE caseRangeStatement)
* | $(RULE defaultStatement)
* ;)
*/
NonEmptyStatement parseNonEmptyStatement()
{
auto node = new NonEmptyStatement;
with (TokenType) switch (current.type)
{
case default_:
node.defaultStatement = parseDefaultStatement();
break;
case case_:
// TODO
assert (false);
break;
default:
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
break;
}
return node;
}
/** /**
* Parses a StatementNoCaseNoDefault * Parses a StatementNoCaseNoDefault
* *
@ -3370,7 +3437,6 @@ invariant() foo();
* | $(RULE foreachRangeStatement) * | $(RULE foreachRangeStatement)
* | $(RULE conditionalStatement) * | $(RULE conditionalStatement)
* | $(RULE staticAssertStatement) * | $(RULE staticAssertStatement)
* | $(RULE templateMixinStatement)
* | $(RULE versionSpecification) * | $(RULE versionSpecification)
* | $(RULE debugSpecification) * | $(RULE debugSpecification)
* | $(RULE expressionStatement) * | $(RULE expressionStatement)
@ -3444,17 +3510,29 @@ invariant() foo();
error(`"switch" expected`); error(`"switch" expected`);
return null; return null;
} }
case debug_:
if (peekIs(TokenType.assign))
node.debugSpecification = parseDebugSpecification();
else
node.conditionalStatement = parseConditionalStatement();
break;
case version_:
if (peekIs(TokenType.assign))
node.versionSpecification = parseVersionSpecification();
else
node.conditionalStatement = parseConditionalStatement();
break;
case static_:
if (peekIs(TokenType.if_))
node.conditionalStatement = parseConditionalStatement();
else if (peekIs(TokenType.assert_))
node.staticAssertStatement = parseStaticAssertStatement();
break;
case delete_: case delete_:
case assert_: case assert_:
default: default:
node.expressionStatement = parseExpressionStatement(); node.expressionStatement = parseExpressionStatement();
break; break;
// TODO: conditionalStatement
// TODO: staticAssertStatement
// TODO: templateMixinStatement
// TODO: versionSpecification
// TODO: debugSpecification
} }
return node; return node;
} }
@ -3490,7 +3568,7 @@ invariant() foo();
Operands parseOperands() Operands parseOperands()
{ {
auto node = new Operands; auto node = new Operands;
assert (false); // TODO asm assert (false); // TODO asm
return node; return node;
} }
@ -3504,7 +3582,7 @@ invariant() foo();
*/ */
OrExpression parseOrExpression() OrExpression parseOrExpression()
{ {
version(verbose) writeln("parseOrExpression ", current.line); version(verbose) writeln(">parseOrExpression ", current.line);
return parseLeftAssocBinaryExpression!(OrExpression, XorExpression, return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
TokenType.bitOr)(); TokenType.bitOr)();
} }
@ -3519,7 +3597,7 @@ invariant() foo();
*/ */
OrOrExpression parseOrOrExpression() OrOrExpression parseOrOrExpression()
{ {
version(verbose) writeln("parseOrOrExpression ", current.line); version(verbose) writeln(">parseOrOrExpression ", current.line);
return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression, return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
TokenType.logicOr)(); TokenType.logicOr)();
} }
@ -3557,7 +3635,7 @@ invariant() foo();
Parameter parseParameter() Parameter parseParameter()
{ {
auto node = new Parameter; auto node = new Parameter;
version (verbose) writeln("parseParameter"); version (verbose) writeln(">parseParameter");
while (moreTokens()) while (moreTokens())
{ {
TokenType type = parseParameterAttribute(false); TokenType type = parseParameterAttribute(false);
@ -3638,7 +3716,7 @@ invariant() foo();
*/ */
Parameters parseParameters() Parameters parseParameters()
{ {
version (verbose) writeln("parseParameters"); version (verbose) writeln(">parseParameters");
auto node = new Parameters; auto node = new Parameters;
expect(TokenType.lParen); expect(TokenType.lParen);
if (currentIs(TokenType.rParen)) if (currentIs(TokenType.rParen))
@ -3848,7 +3926,7 @@ q{(int a, ...)
*/ */
PrimaryExpression parsePrimaryExpression() PrimaryExpression parsePrimaryExpression()
{ {
version(verbose) writeln("parsePrimaryExpression ", current.line); version(verbose) writeln(">parsePrimaryExpression ", current.line);
version(verbose) scope(exit) writeln("finished parsePrimaryExpression ", current.line, " ", current.column); version(verbose) scope(exit) writeln("finished parsePrimaryExpression ", current.line, " ", current.column);
auto node = new PrimaryExpression; auto node = new PrimaryExpression;
with (TokenType) switch (current.type) with (TokenType) switch (current.type)
@ -4071,7 +4149,7 @@ q{(int a, ...)
*/ */
ShiftExpression parseShiftExpression() ShiftExpression parseShiftExpression()
{ {
version(verbose) writeln("parseShiftExpression ", current.line); version(verbose) writeln(">parseShiftExpression ", current.line);
return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression, return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
TokenType.shiftLeft, TokenType.shiftRight, TokenType.shiftLeft, TokenType.shiftRight,
TokenType.unsignedShiftRight)(); TokenType.unsignedShiftRight)();
@ -4131,8 +4209,11 @@ q{(int a, ...)
switch (current.type) switch (current.type)
{ {
case TokenType.case_: case TokenType.case_:
// TODO auto argumentList = parseArgumentList();
assert (false); if (argumentList.items.length == 1 && startsWith(TokenType.colon, TokenType.slice))
node.caseRangeStatement = parseCaseRangeStatement(argumentList.items[0]);
else
node.caseStatement = parseCaseStatement();
break; break;
case TokenType.default_: case TokenType.default_:
node.defaultStatement = parseDefaultStatement(); node.defaultStatement = parseDefaultStatement();
@ -4154,8 +4235,26 @@ q{(int a, ...)
StaticAssertDeclaration parseStaticAssertDeclaration() StaticAssertDeclaration parseStaticAssertDeclaration()
{ {
auto node = new StaticAssertDeclaration; auto node = new StaticAssertDeclaration;
// TODO node.staticAssertStatement = parseStaticAssertStatement();
assert (false); if (node.staticAssertStatement is null) return null;
return node;
}
/**
* Parses a StaticAssertStatement
*
* $(GRAMMAR $(RULEDEF) staticAssertStatement):
* $(LITERAL 'static') $(RULE assertExpression) $(LITERAL ';')
* ;)
*/
StaticAssertStatement parseStaticAssertStatement()
{
auto node = new StaticAssertStatement;
if (expect(TokenType.static_) is null) return null;
node.assertExpression = parseAssertExpression();
if (node.assertExpression is null) return null;
if (expect(TokenType.semicolon) is null) return null;
return node; return node;
} }
@ -4239,34 +4338,34 @@ q{(int a, ...)
{ {
auto node = new StorageClass; auto node = new StorageClass;
with (TokenType) switch (current.type) with (TokenType) switch (current.type)
{ {
case at: case at:
node.atAttribute = parseAtAttribute(); node.atAttribute = parseAtAttribute();
if (node.atAttribute is null) return null; if (node.atAttribute is null) return null;
break; break;
case abstract_: case abstract_:
case auto_: case auto_:
case deprecated_: case deprecated_:
case enum_: case enum_:
case extern_: case extern_:
case final_: case final_:
case nothrow_: case nothrow_:
case override_: case override_:
case pure_: case pure_:
case gshared: case gshared:
case scope_: case scope_:
case static_: case static_:
case synchronized_: case synchronized_:
case const_: case const_:
case immutable_: case immutable_:
case inout_: case inout_:
case shared_: case shared_:
node.token = advance(); node.token = advance();
break; break;
default: default:
error(`Storage class expected`); error(`Storage class expected`);
return null; return null;
} }
return node; return node;
} }
@ -4389,19 +4488,19 @@ q{(int a, ...)
{ {
auto node = new StructMemberInitializers; auto node = new StructMemberInitializers;
do do
{ {
auto structMemberInitializer = parseStructMemberInitializer(); auto structMemberInitializer = parseStructMemberInitializer();
if (currentIs(TokenType.comma)) if (currentIs(TokenType.comma))
{ {
advance(); advance();
if (currentIs(TokenType.identifier)) if (currentIs(TokenType.identifier))
continue; continue;
else else
break; break;
} }
else else
break; break;
} while (true); } while (true);
return node; return node;
} }
@ -4492,32 +4591,32 @@ q{(int a, ...)
auto node = new TemplateAliasParameter; auto node = new TemplateAliasParameter;
expect(TokenType.alias_); expect(TokenType.alias_);
if (currentIs(TokenType.identifier) && peekIsOneOf(TokenType.comma, if (currentIs(TokenType.identifier) && peekIsOneOf(TokenType.comma,
TokenType.rParen)) TokenType.rParen))
{ {
node.identifier = advance(); node.identifier = advance();
} }
else else
{ {
if ((node.type = parseType()) is null) return null; if ((node.type = parseType()) is null) return null;
auto ident = expect(TokenType.identifier); auto ident = expect(TokenType.identifier);
if (ident is null) return null; if (ident is null) return null;
node.identifier = *ident; node.identifier = *ident;
} }
if (currentIs(TokenType.colon)) if (currentIs(TokenType.colon))
{ {
advance(); advance();
if (isType()) if (isType())
node.colonType = parseType(); node.colonType = parseType();
else else
node.colonExpression = parseExpression(); node.colonExpression = parseExpression();
} }
if (currentIs(TokenType.assign)) if (currentIs(TokenType.assign))
{ {
if (isType()) if (isType())
node.assignType = parseType(); node.assignType = parseType();
else else
node.assignExpression = parseExpression(); node.assignExpression = parseExpression();
} }
return node; return node;
} }
@ -4533,13 +4632,13 @@ q{(int a, ...)
{ {
auto node = new TemplateArgument; auto node = new TemplateArgument;
if (isType()) if (isType())
{ {
if ((node.type = parseType()) is null) return null; if ((node.type = parseType()) is null) return null;
} }
else else
{ {
if ((node.assignExpression = parseAssignExpression()) is null) return null; if ((node.assignExpression = parseAssignExpression()) is null) return null;
} }
return node; return node;
} }
@ -4586,7 +4685,7 @@ q{(int a, ...)
*/ */
TemplateDeclaration parseTemplateDeclaration() TemplateDeclaration parseTemplateDeclaration()
{ {
version(verbose) writeln("parseTemplateDeclaration"); version(verbose) writeln(">parseTemplateDeclaration");
auto node = new TemplateDeclaration; auto node = new TemplateDeclaration;
expect(TokenType.template_); expect(TokenType.template_);
auto ident = expect(TokenType.identifier); auto ident = expect(TokenType.identifier);
@ -4655,7 +4754,7 @@ q{(int a, ...)
*/ */
TemplateParameter parseTemplateParameter() TemplateParameter parseTemplateParameter()
{ {
version(verbose) writeln("parseTemplateParameter"); version(verbose) writeln(">parseTemplateParameter");
auto node = new TemplateParameter; auto node = new TemplateParameter;
with (TokenType) switch (current.type) with (TokenType) switch (current.type)
{ {
@ -4701,7 +4800,7 @@ q{(int a, ...)
*/ */
TemplateParameters parseTemplateParameters() TemplateParameters parseTemplateParameters()
{ {
version(verbose) writeln("parseTemplateParameters"); version(verbose) writeln(">parseTemplateParameters");
auto node = new TemplateParameters; auto node = new TemplateParameters;
assert (expect(TokenType.lParen)); assert (expect(TokenType.lParen));
node.templateParameterList = parseTemplateParameterList(); node.templateParameterList = parseTemplateParameterList();
@ -4781,7 +4880,7 @@ q{(int a, ...)
*/ */
TemplateTupleParameter parseTemplateTupleParameter() TemplateTupleParameter parseTemplateTupleParameter()
{ {
version(verbose) writeln("parseTemplateTupleParameter"); version(verbose) writeln(">parseTemplateTupleParameter");
auto node = new TemplateTupleParameter; auto node = new TemplateTupleParameter;
auto i = expect(TokenType.identifier); auto i = expect(TokenType.identifier);
if (i is null) if (i is null)
@ -4828,19 +4927,19 @@ q{(int a, ...)
{ {
auto node = new TemplateValueParameter; auto node = new TemplateValueParameter;
if ((node.type = parseType) is null) return null; if ((node.type = parseType) is null) return null;
auto ident = expect(TokenType.identifier); auto ident = expect(TokenType.identifier);
if (ident is null) return null; if (ident is null) return null;
node.identifier = *ident; node.identifier = *ident;
if (currentIs(TokenType.colon)) if (currentIs(TokenType.colon))
{ {
advance(); advance();
if ((node.expression = parseExpression()) is null) return null; if ((node.expression = parseExpression()) is null) return null;
} }
if (currentIs(TokenType.assign)) if (currentIs(TokenType.assign))
{ {
if ((node.templateValueParameterDefault = parseTemplateValueParameterDefault()) is null) if ((node.templateValueParameterDefault = parseTemplateValueParameterDefault()) is null)
return null; return null;
} }
return node; return node;
} }
@ -4880,7 +4979,7 @@ q{(int a, ...)
*/ */
TernaryExpression parseTernaryExpression() TernaryExpression parseTernaryExpression()
{ {
version(verbose) writeln("parseTernaryExpression ", current.line); version(verbose) writeln(">parseTernaryExpression ", current.line);
auto node = new TernaryExpression; auto node = new TernaryExpression;
node.orOrExpression = parseOrOrExpression(); node.orOrExpression = parseOrOrExpression();
if (currentIs(TokenType.ternary)) if (currentIs(TokenType.ternary))
@ -4924,7 +5023,7 @@ q{(int a, ...)
auto ident = expect(TokenType.identifier); auto ident = expect(TokenType.identifier);
if (ident is null) return null; if (ident is null) return null;
node.identifier = *ident; node.identifier = *ident;
if ((node.templateArgumentList = parseTemplateArgumentList()) is null) return null; if ((node.templateArgumentList = parseTemplateArgumentList()) is null) return null;
if (expect(TokenType.rParen) is null) return null; if (expect(TokenType.rParen) is null) return null;
return node; return node;
} }
@ -5149,7 +5248,7 @@ q{(int a, ...)
TypeSuffix parseTypeSuffix() TypeSuffix parseTypeSuffix()
{ {
auto node = new TypeSuffix; auto node = new TypeSuffix;
version (verbose) writeln("parseTypeSuffix"); version (verbose) writeln(">parseTypeSuffix");
with (TokenType) switch(current.type) with (TokenType) switch(current.type)
{ {
case star: case star:
@ -5199,15 +5298,15 @@ q{(int a, ...)
expect(TokenType.typeid_); expect(TokenType.typeid_);
expect(TokenType.lParen); expect(TokenType.lParen);
if (isExpression()) if (isExpression())
{ {
node.expression = parseExpression(); node.expression = parseExpression();
if (node.expression is null) return null; if (node.expression is null) return null;
} }
else else
{ {
node.type = parseType(); node.type = parseType();
if (node.type is null) return null; if (node.type is null) return null;
} }
expect(TokenType.rParen); expect(TokenType.rParen);
return node; return node;
} }
@ -5259,7 +5358,8 @@ q{(int a, ...)
*/ */
UnaryExpression parseUnaryExpression() UnaryExpression parseUnaryExpression()
{ {
version(verbose) writeln("parseUnaryExpression ", current.line); version(verbose) writeln(">parseUnaryExpression ", current.line, " ", current.column);
version(verbose) scope(exit) writeln("<parseUnaryExpression ", current.line, " ", current.column);
auto node = new UnaryExpression; auto node = new UnaryExpression;
with(TokenType) switch (current.type) with(TokenType) switch (current.type)
{ {
@ -5395,7 +5495,7 @@ q{doStuff(5)}c;
* Parses a VariableDeclaration * Parses a VariableDeclaration
* *
* $(GRAMMAR $(RULEDEF variableDeclaration): * $(GRAMMAR $(RULEDEF variableDeclaration):
* $(RULE storageClass)? $(RULE type) $(RULE declarator) ($(LITERAL ',') $(RULE declarator))* $(LITERAL ';') * $(RULE storageClass)? $(RULE _type) $(RULE declarator) ($(LITERAL ',') $(RULE declarator))* $(LITERAL ';')
* | $(RULE autoDeclaration) * | $(RULE autoDeclaration)
* ;) * ;)
*/ */
@ -5537,7 +5637,7 @@ q{doStuff(5)}c;
*/ */
XorExpression parseXorExpression() XorExpression parseXorExpression()
{ {
version(verbose) writeln("parseXorExpression ", current.line); version(verbose) writeln(">parseXorExpression ", current.line);
return parseLeftAssocBinaryExpression!(XorExpression, AndExpression, return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
TokenType.xor)(); TokenType.xor)();
} }
@ -5588,19 +5688,19 @@ private:
return parseStatement() !is null; return parseStatement() !is null;
} }
bool isExpression() bool isExpression()
{ {
auto b = setBookmark(); auto b = setBookmark();
scope (exit) goToBookmark(b); scope (exit) goToBookmark(b);
return parseExpression() !is null; return parseExpression() !is null;
} }
bool isType() bool isType()
{ {
auto b = setBookmark(); auto b = setBookmark();
scope (exit) goToBookmark(b); scope (exit) goToBookmark(b);
return parseType() !is null; return parseType() !is null;
} }
bool currentIsMemberFunctionAttribute() const bool currentIsMemberFunctionAttribute() const
{ {