All non-ASM TODO comments replaced with code. Now the debugging begins
This commit is contained in:
parent
a12a8a866b
commit
f7e7cf19ee
20
stats.d
20
stats.d
|
@ -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;
|
||||||
|
|
31
std/d/ast.d
31
std/d/ast.d
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
582
std/d/parser.d
582
std/d/parser.d
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue