Can now parse the ast and tester modules
This commit is contained in:
parent
859ddd3d20
commit
a12a8a866b
23
std/d/ast.d
23
std/d/ast.d
|
@ -209,12 +209,10 @@ abstract class ASTVisitor
|
|||
/** */ void visit(TemplateValueParameterDefault templateValueParameterDefault) { templateValueParameterDefault.accept(this); }
|
||||
/** */ void visit(TernaryExpression ternaryExpression) { ternaryExpression.accept(this); }
|
||||
/** */ void visit(ThrowStatement throwStatement) { throwStatement.accept(this); }
|
||||
/** */ void visit(TraitsArgument traitsArgument) { traitsArgument.accept(this); }
|
||||
/** */ void visit(TraitsExpression traitsExpression) { traitsExpression.accept(this); }
|
||||
/** */ void visit(TryStatement tryStatement) { tryStatement.accept(this); }
|
||||
/** */ void visit(Type type) { type.accept(this); }
|
||||
/** */ void visit(Type2 type2) { type2.accept(this); }
|
||||
/** */ void visit(TypeConstructors typeConstructors) { typeConstructors.accept(this); }
|
||||
/** */ void visit(TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); }
|
||||
/** */ void visit(TypeSuffix typeSuffix) { typeSuffix.accept(this); }
|
||||
/** */ void visit(TypeidExpression typeidExpression) { typeidExpression.accept(this); }
|
||||
|
@ -1045,7 +1043,7 @@ class ForeachType : ASTNode
|
|||
{
|
||||
public:
|
||||
mixin(DEFAULT_ACCEPT);
|
||||
/** */ bool isRef;
|
||||
/** */ TokenType[] typeConstructors;
|
||||
/** */ Type type;
|
||||
/** */ Token identifier;
|
||||
}
|
||||
|
@ -2047,22 +2045,13 @@ public:
|
|||
/** */ Expression expression;
|
||||
}
|
||||
|
||||
///
|
||||
class TraitsArgument : ASTNode
|
||||
{
|
||||
public:
|
||||
mixin(DEFAULT_ACCEPT);
|
||||
/** */ AssignExpression assignExpression;
|
||||
/** */ Type type;
|
||||
}
|
||||
|
||||
///
|
||||
class TraitsExpression : ASTNode
|
||||
{
|
||||
public:
|
||||
mixin(DEFAULT_ACCEPT);
|
||||
/** */ Token identifier;
|
||||
/** */ TraitsArgument[] traitsArguments;
|
||||
/** */ TemplateArgumentList templateArgumentList;
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -2098,14 +2087,6 @@ public:
|
|||
/** */ Type type;
|
||||
}
|
||||
|
||||
///
|
||||
class TypeConstructors : ASTNode
|
||||
{
|
||||
public:
|
||||
mixin(DEFAULT_ACCEPT);
|
||||
/** */ TokenType[] items;
|
||||
}
|
||||
|
||||
///
|
||||
class TypeSpecialization : ASTNode
|
||||
{
|
||||
|
|
320
std/d/parser.d
320
std/d/parser.d
|
@ -102,7 +102,7 @@ struct Parser
|
|||
*/
|
||||
AddExpression parseAddExpression()
|
||||
{
|
||||
version(verbose) writeln("parseAddExpression");
|
||||
version(verbose) writeln("parseAddExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
|
||||
TokenType.plus, TokenType.minus, TokenType.tilde)();
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
*/
|
||||
AndAndExpression parseAndAndExpression()
|
||||
{
|
||||
version(verbose) writeln("parseAndAndExpression");
|
||||
version(verbose) writeln("parseAndAndExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
|
||||
TokenType.logicAnd)();
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
*/
|
||||
AndExpression parseAndExpression()
|
||||
{
|
||||
version(verbose) writeln("parseAndExpression");
|
||||
version(verbose) writeln("parseAndExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
|
||||
TokenType.bitAnd)();
|
||||
}
|
||||
|
@ -252,6 +252,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
*/
|
||||
ArgumentList parseArgumentList()
|
||||
{
|
||||
version(verbose) writeln("parseArgumentList ", current.line);
|
||||
return parseCommaSeparatedRule!(ArgumentList, AssignExpression)();
|
||||
}
|
||||
|
||||
|
@ -265,6 +266,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
Arguments parseArguments()
|
||||
{
|
||||
auto node = new Arguments;
|
||||
version (verbose) writeln("parseArguments");
|
||||
if (expect(TokenType.lParen) is null) return null;
|
||||
node.argumentList = parseArgumentList();
|
||||
if (expect(TokenType.rParen) is null) return null;
|
||||
|
@ -375,7 +377,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmAndExp parseAsmAndExp()
|
||||
{
|
||||
auto node = new AsmAndExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -390,7 +392,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmBrExp parseAsmBrExp()
|
||||
{
|
||||
auto node = new AsmBrExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -404,7 +406,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmEqualExp parseAsmEqualExp()
|
||||
{
|
||||
auto node = new AsmEqualExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -418,7 +420,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmExp parseAsmExp()
|
||||
{
|
||||
auto node = new AsmExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -437,7 +439,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmInstruction parseAsmInstruction()
|
||||
{
|
||||
auto node = new AsmInstruction;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -451,7 +453,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmLogAndExp parseAsmLogAndExp()
|
||||
{
|
||||
auto node = new AsmLogAndExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -465,7 +467,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmLogOrExp parseAsmLogOrExp()
|
||||
{
|
||||
auto node = new AsmLogOrExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -479,7 +481,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmMulExp parseAsmMulExp()
|
||||
{
|
||||
auto node = new AsmMulExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -493,7 +495,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmOrExp parseAsmOrExp()
|
||||
{
|
||||
auto node = new AsmOrExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -511,7 +513,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmPrimaryExp parseAsmPrimaryExp()
|
||||
{
|
||||
auto node = new AsmPrimaryExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -525,7 +527,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmRelExp parseAsmRelExp()
|
||||
{
|
||||
auto node = new AsmRelExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -539,7 +541,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmShiftExp parseAsmShiftExp()
|
||||
{
|
||||
auto node = new AsmShiftExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -553,7 +555,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmStatement parseAsmStatement()
|
||||
{
|
||||
auto node = new AsmStatement;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -573,7 +575,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmTypePrefix parseAsmTypePrefix()
|
||||
{
|
||||
auto node = new AsmTypePrefix;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -593,7 +595,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmUnaExp parseAsmUnaExp()
|
||||
{
|
||||
auto node = new AsmUnaExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -607,7 +609,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AsmXorExp parseAsmXorExp()
|
||||
{
|
||||
auto node = new AsmXorExp;
|
||||
// TODO asm
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -658,7 +660,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
*/
|
||||
AssignExpression parseAssignExpression()
|
||||
{
|
||||
version(verbose) writeln("parseAssignExpression");
|
||||
version(verbose) writeln("parseAssignExpression ", current.line);
|
||||
auto node = new AssignExpression;
|
||||
node.ternaryExpression = parseTernaryExpression();
|
||||
if (currentIsOneOf(TokenType.assign, TokenType.unsignedShiftRightEqual,
|
||||
|
@ -701,7 +703,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
{
|
||||
auto node = new AtAttribute;
|
||||
if (expect(TokenType.at) is null) return null;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case identifier:
|
||||
if (peekIsOneOf(lParen, dot, not))
|
||||
|
@ -754,7 +756,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
Attribute parseAttribute()
|
||||
{
|
||||
auto node = new Attribute;
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.extern_:
|
||||
if (peekIs(TokenType.lParen))
|
||||
|
@ -810,7 +812,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
{
|
||||
auto node = new AttributedDeclaration;
|
||||
node.attribute = parseAttribute();
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.colon:
|
||||
advance();
|
||||
|
@ -840,6 +842,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
AutoDeclaration parseAutoDeclaration()
|
||||
{
|
||||
auto node = new AutoDeclaration;
|
||||
version(verbose) writeln("parseAutoDeclaration ", current.line);
|
||||
node.storageClass = parseStorageClass();
|
||||
if (node.storageClass is null) return null;
|
||||
do
|
||||
|
@ -903,7 +906,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
{
|
||||
expect(TokenType.break_);
|
||||
auto node = new BreakStatement;
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.identifier:
|
||||
node.identifier = advance();
|
||||
|
@ -980,7 +983,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
*/
|
||||
Token parseBasicType()
|
||||
{
|
||||
if (isBasicType(current().type))
|
||||
if (isBasicType(current.type))
|
||||
return advance();
|
||||
error("Basic type expected");
|
||||
Token t;
|
||||
|
@ -1048,7 +1051,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
|
||||
private bool isCastQualifier() const
|
||||
{
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.const_:
|
||||
return peekIsOneOf(TokenType.shared_, TokenType.rParen);
|
||||
|
@ -1080,7 +1083,7 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
CastQualifier parseCastQualifier()
|
||||
{
|
||||
auto node = new CastQualifier;
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.inout_:
|
||||
case TokenType.const_:
|
||||
|
@ -1338,10 +1341,10 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
*/
|
||||
CmpExpression parseCmpExpression()
|
||||
{
|
||||
version(verbose) writeln("parseCmpExpression");
|
||||
version(verbose) writeln("parseCmpExpression ", current.line);
|
||||
auto node = new CmpExpression;
|
||||
auto shift = parseShiftExpression();
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case is_:
|
||||
node.identityExpression = parseIdentityExpression(shift);
|
||||
|
@ -1392,7 +1395,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
CompileCondition parseCompileCondition()
|
||||
{
|
||||
auto node = new CompileCondition;
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.version_:
|
||||
node.versionCondition = parseVersionCondition();
|
||||
|
@ -1534,7 +1537,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
{
|
||||
if (expect(TokenType.continue_) is null) return null;
|
||||
auto node = new ContinueStatement;
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.identifier:
|
||||
node.identifier = advance();
|
||||
|
@ -1635,7 +1638,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
{
|
||||
import std.stdio;
|
||||
auto node = new Declaration;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case alias_:
|
||||
if (startsWith(alias_, identifier, this_))
|
||||
|
@ -2015,6 +2018,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
{
|
||||
auto node = new EnumMember;
|
||||
// TODO: ambiguity between type and identifier
|
||||
assert (false);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -2027,7 +2031,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
*/
|
||||
EqualExpression parseEqualExpression(ShiftExpression shift = null)
|
||||
{
|
||||
version(verbose) writeln("parseEqualExpression");
|
||||
version(verbose) writeln("parseEqualExpression ", current.line);
|
||||
auto node = new EqualExpression;
|
||||
node.left = shift is null ? parseShiftExpression() : shift;
|
||||
if (currentIsOneOf(TokenType.equal, TokenType.notEqual))
|
||||
|
@ -2110,7 +2114,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
if (expect(TokenType.for_) is null) return null;
|
||||
if (expect(TokenType.lParen) is null) return null;
|
||||
// TODO
|
||||
assert (0);
|
||||
assert (false);
|
||||
if (expect(TokenType.rParen) is null) return null;
|
||||
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
|
||||
if (node.statementNoCaseNoDefault is null) return null;
|
||||
|
@ -2122,20 +2126,23 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
*
|
||||
* $(GRAMMAR $(RULEDEF foreachStatement):
|
||||
* ($(LITERAL 'foreach') | $(LITERAL 'foreach_reverse')) $(LITERAL '$(LPAREN)') $(RULE foreachTypeList) $(LITERAL ';') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
|
||||
* | $(LITERAL 'foreach') $(LITERAL '$(LPAREN)') $(RULE foreachType) $(LITERAL ';') $(RULE expression) $(LITERAL '..') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
|
||||
* | ($(LITERAL 'foreach') | $(LITERAL 'foreach_reverse')) $(LITERAL '$(LPAREN)') $(RULE foreachType) $(LITERAL ';') $(RULE expression) $(LITERAL '..') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault)
|
||||
* ;)
|
||||
*/
|
||||
ForeachStatement parseForeachStatement()
|
||||
{
|
||||
auto node = new ForeachStatement;
|
||||
|
||||
if (currentIs(TokenType.foreach_))
|
||||
advance();
|
||||
else
|
||||
if (expect(TokenType.foreach_reverse_) is null) return null;
|
||||
if (currentIsOneOf(TokenType.foreach_, TokenType.foreach_reverse_))
|
||||
node.foreachType = advance().type;
|
||||
else
|
||||
{
|
||||
error(`"foreach" or "foreach_reverse" expected`);
|
||||
return null;
|
||||
}
|
||||
if (expect(TokenType.lParen) is null) return null;
|
||||
auto feType = parseForeachTypeList();
|
||||
bool canBeRange = feType.items.length == 0;
|
||||
bool canBeRange = feType.items.length == 1;
|
||||
expect(TokenType.semicolon);
|
||||
node.low = parseExpression();
|
||||
if (node.low is null) return null;
|
||||
|
@ -2160,16 +2167,17 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
* Parses a ForeachType
|
||||
*
|
||||
* $(GRAMMAR $(RULEDEF foreachType):
|
||||
* $(LITERAL 'ref')? $(RULE type)? $(LITERAL Identifier)
|
||||
* $(RULE typeConstructors)? $(RULE type)? $(LITERAL Identifier)
|
||||
* ;)
|
||||
*/
|
||||
ForeachType parseForeachType()
|
||||
{
|
||||
auto node = new ForeachType;
|
||||
if (currentIs(TokenType.ref_))
|
||||
if (currentIsOneOf(TokenType.ref_, TokenType.const_, TokenType.immutable_,
|
||||
TokenType.shared_, TokenType.inout_))
|
||||
{
|
||||
node.isRef = true;
|
||||
advance();
|
||||
if ((node.typeConstructors = parseTypeConstructors()) is null)
|
||||
return null;
|
||||
}
|
||||
if (currentIs(TokenType.identifier) && peekIsOneOf(TokenType.comma, TokenType.semicolon))
|
||||
{
|
||||
|
@ -2207,7 +2215,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c;
|
|||
FunctionAttribute parseFunctionAttribute(bool validate = true)
|
||||
{
|
||||
auto node = new FunctionAttribute;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case at:
|
||||
node.atAttribute = parseAtAttribute();
|
||||
|
@ -2313,8 +2321,9 @@ body {} // six
|
|||
* ;)
|
||||
*/
|
||||
FunctionCallExpression parseFunctionCallExpression(UnaryExpression unary = null)
|
||||
{
|
||||
{
|
||||
auto node = new FunctionCallExpression;
|
||||
version (verbose) writeln("parseFunctionCallExpression ", current.line);
|
||||
node.unaryExpression = unary is null ? parseUnaryExpression() : unary;
|
||||
if (currentIs(TokenType.not))
|
||||
node.templateArguments = parseTemplateArguments();
|
||||
|
@ -2460,7 +2469,7 @@ body {} // six
|
|||
{
|
||||
auto node = new GotoStatement;
|
||||
if (expect(TokenType.goto_) is null) return null;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case identifier:
|
||||
case default_:
|
||||
|
@ -2504,19 +2513,6 @@ body {} // six
|
|||
return node;
|
||||
}
|
||||
|
||||
unittest // TODO
|
||||
{
|
||||
auto input = cast(ubyte[]) "abcde.frocegu.creou.faowe"c;
|
||||
LexerConfig config;
|
||||
auto tokens = byToken(input, config);
|
||||
Parser p;
|
||||
p.fileName = "test";
|
||||
p.tokens = tokens.array();
|
||||
auto chain = p.parseIdentifierChain();
|
||||
assert (chain.identifiers == ["abcde", "frocegu", "creou", "faowe"]);
|
||||
stderr.writeln("Unittest for parseIdentifierChain() passed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an IdentifierList
|
||||
*
|
||||
|
@ -2558,6 +2554,8 @@ body {} // six
|
|||
node.identifierOrTemplateInstances ~= parseIdentifierOrTemplateInstance();
|
||||
if (!currentIs(TokenType.dot))
|
||||
break;
|
||||
else
|
||||
advance();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -2593,7 +2591,7 @@ body {} // six
|
|||
*/
|
||||
IdentityExpression parseIdentityExpression(ShiftExpression shift = null)
|
||||
{
|
||||
version(verbose) writeln("parseIdentityExpression");
|
||||
version(verbose) writeln("parseIdentityExpression ", current.line);
|
||||
auto node = new IdentityExpression;
|
||||
node.left = shift is null ? parseShiftExpression() : shift;
|
||||
if (currentIs(TokenType.not))
|
||||
|
@ -2800,6 +2798,7 @@ import core.stdc.stdio, std.string : KeepTerminator;
|
|||
IndexExpression parseIndexExpression(UnaryExpression unaryExpression = null)
|
||||
{
|
||||
auto node = new IndexExpression;
|
||||
version (verbose) writeln("parseIndexExpression ", current.line);
|
||||
node.unaryExpression = unaryExpression is null ? parseUnaryExpression() : unaryExpression;
|
||||
if (expect(TokenType.lBracket) is null) return null;
|
||||
node.argumentList = parseArgumentList();
|
||||
|
@ -2852,6 +2851,7 @@ import core.stdc.stdio, std.string : KeepTerminator;
|
|||
{
|
||||
auto node = new Initialize;
|
||||
// TODO
|
||||
assert (false);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -3005,6 +3005,7 @@ invariant() foo();
|
|||
if (expect(TokenType.is_) is null) return null;
|
||||
if (expect(TokenType.lParen) is null) return null;
|
||||
// TODO
|
||||
assert (false);
|
||||
if (expect(TokenType.rParen) is null) return null;
|
||||
return node;
|
||||
}
|
||||
|
@ -3159,6 +3160,7 @@ invariant() foo();
|
|||
{
|
||||
auto node = new MemberFunctionAttribute;
|
||||
// TODO
|
||||
assert (false);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -3259,7 +3261,7 @@ invariant() foo();
|
|||
*/
|
||||
MulExpression parseMulExpression()
|
||||
{
|
||||
version(verbose) writeln("parseMulExpression");
|
||||
version(verbose) writeln("parseMulExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
|
||||
TokenType.star, TokenType.div, TokenType.mod)();
|
||||
}
|
||||
|
@ -3326,13 +3328,14 @@ invariant() foo();
|
|||
NonEmptyStatement parseNonEmptyStatement()
|
||||
{
|
||||
auto node = new NonEmptyStatement;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case default_:
|
||||
node.defaultStatement = parseDefaultStatement();
|
||||
break;
|
||||
case case_:
|
||||
// TODO
|
||||
assert (false);
|
||||
break;
|
||||
default:
|
||||
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
|
||||
|
@ -3376,7 +3379,7 @@ invariant() foo();
|
|||
StatementNoCaseNoDefault parseStatementNoCaseNoDefault()
|
||||
{
|
||||
auto node = new StatementNoCaseNoDefault;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case lBrace:
|
||||
node.blockStatement = parseBlockStatement();
|
||||
|
@ -3487,7 +3490,7 @@ invariant() foo();
|
|||
Operands parseOperands()
|
||||
{
|
||||
auto node = new Operands;
|
||||
// TODO
|
||||
assert (false); // TODO asm
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -3501,7 +3504,7 @@ invariant() foo();
|
|||
*/
|
||||
OrExpression parseOrExpression()
|
||||
{
|
||||
version(verbose) writeln("parseOrExpression");
|
||||
version(verbose) writeln("parseOrExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
|
||||
TokenType.bitOr)();
|
||||
}
|
||||
|
@ -3516,7 +3519,7 @@ invariant() foo();
|
|||
*/
|
||||
OrOrExpression parseOrOrExpression()
|
||||
{
|
||||
version(verbose) writeln("parseOrOrExpression");
|
||||
version(verbose) writeln("parseOrOrExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
|
||||
TokenType.logicOr)();
|
||||
}
|
||||
|
@ -3600,7 +3603,7 @@ invariant() foo();
|
|||
*/
|
||||
TokenType parseParameterAttribute(bool validate = false)
|
||||
{
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case immutable_:
|
||||
case shared_:
|
||||
|
@ -3845,9 +3848,10 @@ q{(int a, ...)
|
|||
*/
|
||||
PrimaryExpression parsePrimaryExpression()
|
||||
{
|
||||
version(verbose) writeln("parsePrimaryExpression");
|
||||
version(verbose) writeln("parsePrimaryExpression ", current.line);
|
||||
version(verbose) scope(exit) writeln("finished parsePrimaryExpression ", current.line, " ", current.column);
|
||||
auto node = new PrimaryExpression;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case identifier:
|
||||
if (peekIs(TokenType.goesTo))
|
||||
|
@ -4067,7 +4071,7 @@ q{(int a, ...)
|
|||
*/
|
||||
ShiftExpression parseShiftExpression()
|
||||
{
|
||||
version(verbose) writeln("parseShiftExpression");
|
||||
version(verbose) writeln("parseShiftExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
|
||||
TokenType.shiftLeft, TokenType.shiftRight,
|
||||
TokenType.unsignedShiftRight)();
|
||||
|
@ -4124,10 +4128,11 @@ q{(int a, ...)
|
|||
Statement parseStatement()
|
||||
{
|
||||
auto node = new Statement;
|
||||
switch (current().type)
|
||||
switch (current.type)
|
||||
{
|
||||
case TokenType.case_:
|
||||
// TODO
|
||||
assert (false);
|
||||
break;
|
||||
case TokenType.default_:
|
||||
node.defaultStatement = parseDefaultStatement();
|
||||
|
@ -4150,6 +4155,7 @@ q{(int a, ...)
|
|||
{
|
||||
auto node = new StaticAssertDeclaration;
|
||||
// TODO
|
||||
assert (false);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4232,7 +4238,35 @@ q{(int a, ...)
|
|||
StorageClass parseStorageClass()
|
||||
{
|
||||
auto node = new StorageClass;
|
||||
// TODO
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case at:
|
||||
node.atAttribute = parseAtAttribute();
|
||||
if (node.atAttribute is null) return null;
|
||||
break;
|
||||
case abstract_:
|
||||
case auto_:
|
||||
case deprecated_:
|
||||
case enum_:
|
||||
case extern_:
|
||||
case final_:
|
||||
case nothrow_:
|
||||
case override_:
|
||||
case pure_:
|
||||
case gshared:
|
||||
case scope_:
|
||||
case static_:
|
||||
case synchronized_:
|
||||
case const_:
|
||||
case immutable_:
|
||||
case inout_:
|
||||
case shared_:
|
||||
node.token = advance();
|
||||
break;
|
||||
default:
|
||||
error(`Storage class expected`);
|
||||
return null;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4354,7 +4388,20 @@ q{(int a, ...)
|
|||
StructMemberInitializers parseStructMemberInitializers()
|
||||
{
|
||||
auto node = new StructMemberInitializers;
|
||||
// TODO
|
||||
do
|
||||
{
|
||||
auto structMemberInitializer = parseStructMemberInitializer();
|
||||
if (currentIs(TokenType.comma))
|
||||
{
|
||||
advance();
|
||||
if (currentIs(TokenType.identifier))
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while (true);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4444,7 +4491,33 @@ q{(int a, ...)
|
|||
{
|
||||
auto node = new TemplateAliasParameter;
|
||||
expect(TokenType.alias_);
|
||||
// TODO
|
||||
if (currentIs(TokenType.identifier) && peekIsOneOf(TokenType.comma,
|
||||
TokenType.rParen))
|
||||
{
|
||||
node.identifier = advance();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((node.type = parseType()) is null) return null;
|
||||
auto ident = expect(TokenType.identifier);
|
||||
if (ident is null) return null;
|
||||
node.identifier = *ident;
|
||||
}
|
||||
if (currentIs(TokenType.colon))
|
||||
{
|
||||
advance();
|
||||
if (isType())
|
||||
node.colonType = parseType();
|
||||
else
|
||||
node.colonExpression = parseExpression();
|
||||
}
|
||||
if (currentIs(TokenType.assign))
|
||||
{
|
||||
if (isType())
|
||||
node.assignType = parseType();
|
||||
else
|
||||
node.assignExpression = parseExpression();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4454,13 +4527,19 @@ q{(int a, ...)
|
|||
* $(GRAMMAR $(RULEDEF templateArgument):
|
||||
* $(RULE type)
|
||||
* | $(RULE assignExpression)
|
||||
* | $(RULE symbol)
|
||||
* ;)
|
||||
*/
|
||||
TemplateArgument parseTemplateArgument()
|
||||
{
|
||||
auto node = new TemplateArgument;
|
||||
// TODO
|
||||
if (isType())
|
||||
{
|
||||
if ((node.type = parseType()) is null) return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((node.assignExpression = parseAssignExpression()) is null) return null;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4659,7 +4738,7 @@ q{(int a, ...)
|
|||
TemplateSingleArgument parseTemplateSingleArgument()
|
||||
{
|
||||
auto node = new TemplateSingleArgument;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case true_:
|
||||
case false_:
|
||||
|
@ -4748,7 +4827,20 @@ q{(int a, ...)
|
|||
TemplateValueParameter parseTemplateValueParameter()
|
||||
{
|
||||
auto node = new TemplateValueParameter;
|
||||
// TODO
|
||||
if ((node.type = parseType) is null) return null;
|
||||
auto ident = expect(TokenType.identifier);
|
||||
if (ident is null) return null;
|
||||
node.identifier = *ident;
|
||||
if (currentIs(TokenType.colon))
|
||||
{
|
||||
advance();
|
||||
if ((node.expression = parseExpression()) is null) return null;
|
||||
}
|
||||
if (currentIs(TokenType.assign))
|
||||
{
|
||||
if ((node.templateValueParameterDefault = parseTemplateValueParameterDefault()) is null)
|
||||
return null;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4763,7 +4855,7 @@ q{(int a, ...)
|
|||
{
|
||||
auto node = new TemplateValueParameterDefault;
|
||||
expect(TokenType.assign);
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case specialFile:
|
||||
case specialModule:
|
||||
|
@ -4788,7 +4880,7 @@ q{(int a, ...)
|
|||
*/
|
||||
TernaryExpression parseTernaryExpression()
|
||||
{
|
||||
version(verbose) writeln("parseTernaryExpression");
|
||||
version(verbose) writeln("parseTernaryExpression ", current.line);
|
||||
auto node = new TernaryExpression;
|
||||
node.orOrExpression = parseOrOrExpression();
|
||||
if (currentIs(TokenType.ternary))
|
||||
|
@ -4817,44 +4909,23 @@ q{(int a, ...)
|
|||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an TraitsArgument
|
||||
*
|
||||
* $(GRAMMAR $(RULEDEF traitsArgument):
|
||||
* $(RULE assignExpression)
|
||||
* | $(RULE type)
|
||||
* ;)
|
||||
*/
|
||||
TraitsArgument parseTraitsArgument()
|
||||
{
|
||||
auto node = new TraitsArgument;
|
||||
if ()
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an TraitsExpression
|
||||
*
|
||||
* $(GRAMMAR $(RULEDEF traitsExpression):
|
||||
* $(LITERAL '__traits') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) ($(LITERAL ',') $(RULE traitsArgument))+ $(LITERAL '$(RPAREN)')
|
||||
* $(LITERAL '__traits') $(LITERAL '$(LPAREN)') $(LITERAL Identifier) ($(LITERAL ',') $(RULE TemplateArgumentList)) $(LITERAL '$(RPAREN)')
|
||||
* ;)
|
||||
*/
|
||||
TraitsExpression parseTraitsExpression()
|
||||
{
|
||||
auto node = new TraitsExpression;
|
||||
expect(TokenType.traits);
|
||||
expect(TokenType.lParen);
|
||||
if (expect(TokenType.traits) is null) return null;
|
||||
if (expect(TokenType.lParen) is null) return null;
|
||||
auto ident = expect(TokenType.identifier);
|
||||
if (ident is null)
|
||||
return null;
|
||||
if (ident is null) return null;
|
||||
node.identifier = *ident;
|
||||
do
|
||||
{
|
||||
if(expect(TokenType.comma) is null) return null;
|
||||
node.traitsArguments ~= parseTraitsArgument();
|
||||
}
|
||||
while (moreTokens() && currentIs(TokenType.comma));
|
||||
expect(TokenType.rParen);
|
||||
if ((node.templateArgumentList = parseTemplateArgumentList()) is null) return null;
|
||||
if (expect(TokenType.rParen) is null) return null;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -4983,7 +5054,7 @@ q{(int a, ...)
|
|||
*/
|
||||
TokenType parseTypeConstructor(bool validate = true)
|
||||
{
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case const_:
|
||||
case immutable_:
|
||||
|
@ -5042,7 +5113,7 @@ q{(int a, ...)
|
|||
TypeSpecialization parseTypeSpecialization()
|
||||
{
|
||||
auto node = new TypeSpecialization;
|
||||
with (TokenType) switch (current().type)
|
||||
with (TokenType) switch (current.type)
|
||||
{
|
||||
case struct_:
|
||||
case union_:
|
||||
|
@ -5079,7 +5150,7 @@ q{(int a, ...)
|
|||
{
|
||||
auto node = new TypeSuffix;
|
||||
version (verbose) writeln("parseTypeSuffix");
|
||||
with (TokenType) switch(current().type)
|
||||
with (TokenType) switch(current.type)
|
||||
{
|
||||
case star:
|
||||
node.star = true;
|
||||
|
@ -5188,9 +5259,9 @@ q{(int a, ...)
|
|||
*/
|
||||
UnaryExpression parseUnaryExpression()
|
||||
{
|
||||
version(verbose) writeln("parseUnaryExpression");
|
||||
version(verbose) writeln("parseUnaryExpression ", current.line);
|
||||
auto node = new UnaryExpression;
|
||||
with(TokenType) switch (current().type)
|
||||
with(TokenType) switch (current.type)
|
||||
{
|
||||
case bitAnd:
|
||||
case not:
|
||||
|
@ -5219,7 +5290,7 @@ q{(int a, ...)
|
|||
node.primaryExpression = parsePrimaryExpression();
|
||||
}
|
||||
|
||||
loop: while (moreTokens()) with (TokenType) switch (current().type)
|
||||
loop: while (moreTokens()) with (TokenType) switch (current.type)
|
||||
{
|
||||
case not:
|
||||
index++;
|
||||
|
@ -5466,7 +5537,7 @@ q{doStuff(5)}c;
|
|||
*/
|
||||
XorExpression parseXorExpression()
|
||||
{
|
||||
version(verbose) writeln("parseXorExpression");
|
||||
version(verbose) writeln("parseXorExpression ", current.line);
|
||||
return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
|
||||
TokenType.xor)();
|
||||
}
|
||||
|
@ -5490,14 +5561,14 @@ private:
|
|||
if (!currentIs(TokenType.lBracket))
|
||||
return false;
|
||||
advance();
|
||||
while (moreTokens()) with (TokenType) switch (current().type)
|
||||
while (moreTokens()) with (TokenType) switch (current.type)
|
||||
{
|
||||
case lBrace: skipBraceContent(); break;
|
||||
case lParen: skipParenContent(); break;
|
||||
case lBracket: skipBracketContent(); break;
|
||||
case rBracket: return false;
|
||||
case T: return true;
|
||||
default: break;
|
||||
default: advance(); break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -5524,6 +5595,13 @@ private:
|
|||
return parseExpression() !is null;
|
||||
}
|
||||
|
||||
bool isType()
|
||||
{
|
||||
auto b = setBookmark();
|
||||
scope (exit) goToBookmark(b);
|
||||
return parseType() !is null;
|
||||
}
|
||||
|
||||
bool currentIsMemberFunctionAttribute() const
|
||||
{
|
||||
switch (current.type)
|
||||
|
@ -5695,7 +5773,7 @@ private:
|
|||
* Returns a token of the specified type if it was the next token, otherwise
|
||||
* calls the error function and returns null.
|
||||
*/
|
||||
const(Token)* expect(TokenType type)
|
||||
const(Token)* expect(TokenType type, string loc = __PRETTY_FUNCTION__)
|
||||
{
|
||||
if (tokens[index].type == type)
|
||||
return &tokens[index++];
|
||||
|
@ -5703,10 +5781,10 @@ private:
|
|||
{
|
||||
if (tokenValues[type] is null)
|
||||
error("Expected " ~ to!string(type) ~ " instead of "
|
||||
~ tokens[index].value);
|
||||
~ tokens[index].value ~ " at " ~ loc);
|
||||
else
|
||||
error("Expected " ~ tokenValues[type] ~ " instead of "
|
||||
~ tokens[index].value);
|
||||
~ tokens[index].value ~ " at " ~ loc);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -5740,7 +5818,7 @@ private:
|
|||
*/
|
||||
bool currentIsOneOf(TokenType[] types...) const
|
||||
{
|
||||
return canFind(types, current().type);
|
||||
return canFind(types, current.type);
|
||||
}
|
||||
|
||||
bool startsWith(TokenType[] types...) const
|
||||
|
|
|
@ -7,63 +7,63 @@ import std.array;
|
|||
|
||||
class TestVisitor : ASTVisitor
|
||||
{
|
||||
override void visit(ClassDeclaration classDeclaration)
|
||||
{
|
||||
writeln("class ", classDeclaration.name.value, " on line ", classDeclaration.name.line);
|
||||
}
|
||||
override void visit(ClassDeclaration classDeclaration)
|
||||
{
|
||||
writeln("class ", classDeclaration.name.value, " on line ", classDeclaration.name.line);
|
||||
}
|
||||
|
||||
override void visit(StructDeclaration structDeclaration)
|
||||
{
|
||||
writeln("struct ", structDeclaration.name.value, " on line ", structDeclaration.name.line);
|
||||
}
|
||||
{
|
||||
writeln("struct ", structDeclaration.name.value, " on line ", structDeclaration.name.line);
|
||||
}
|
||||
|
||||
override void visit(ModuleDeclaration md)
|
||||
{
|
||||
writeln("module declaration found");
|
||||
}
|
||||
override void visit(ModuleDeclaration md)
|
||||
{
|
||||
writeln("module declaration found");
|
||||
}
|
||||
|
||||
override void visit(FunctionDeclaration funDec)
|
||||
{
|
||||
writeln("function ", funDec.name.value, " on line ", funDec.name.line);
|
||||
}
|
||||
override void visit(FunctionDeclaration funDec)
|
||||
{
|
||||
writeln("function ", funDec.name.value, " on line ", funDec.name.line);
|
||||
}
|
||||
|
||||
override void visit(VariableDeclaration varDec)
|
||||
{
|
||||
foreach (decl; varDec.declarators)
|
||||
{
|
||||
writeln("variable ", decl.identifier.value,
|
||||
" on line ", decl.identifier.line);
|
||||
}
|
||||
}
|
||||
override void visit(VariableDeclaration varDec)
|
||||
{
|
||||
foreach (decl; varDec.declarators)
|
||||
{
|
||||
writeln("variable ", decl.identifier.value,
|
||||
" on line ", decl.identifier.line);
|
||||
}
|
||||
}
|
||||
|
||||
override void visit(ImportDeclaration impDec)
|
||||
{
|
||||
writeln("import declaration found");
|
||||
}
|
||||
override void visit(ImportDeclaration impDec)
|
||||
{
|
||||
writeln("import declaration found");
|
||||
}
|
||||
|
||||
override void visit(InterfaceDeclaration intDec)
|
||||
{
|
||||
writeln("Interface ", intDec.identifier.value,
|
||||
" on line ", intDec.identifier.line);
|
||||
}
|
||||
override void visit(InterfaceDeclaration intDec)
|
||||
{
|
||||
writeln("Interface ", intDec.identifier.value,
|
||||
" on line ", intDec.identifier.line);
|
||||
}
|
||||
|
||||
override void visit(VersionSpecification verSpec)
|
||||
{
|
||||
writeln("Version specification");
|
||||
}
|
||||
override void visit(VersionSpecification verSpec)
|
||||
{
|
||||
writeln("Version specification");
|
||||
}
|
||||
|
||||
alias ASTVisitor.visit visit;
|
||||
alias ASTVisitor.visit visit;
|
||||
}
|
||||
|
||||
void main(string[] args)
|
||||
{
|
||||
auto de = dirEntry(args[1]);
|
||||
ubyte[] sourceBuffer = new ubyte[de.size];
|
||||
auto f = File(args[1]);
|
||||
ubyte[] rawSource = f.rawRead(sourceBuffer);
|
||||
LexerConfig config;
|
||||
auto tokens = byToken(rawSource, config).array();
|
||||
Module m = parseModule(tokens, args[1]);
|
||||
ASTVisitor visitor = new TestVisitor;
|
||||
visitor.visit(m);
|
||||
auto de = dirEntry(args[1]);
|
||||
ubyte[] sourceBuffer = new ubyte[de.size];
|
||||
auto f = File(args[1]);
|
||||
ubyte[] rawSource = f.rawRead(sourceBuffer);
|
||||
LexerConfig config;
|
||||
auto tokens = byToken(rawSource, config).array();
|
||||
Module m = parseModule(tokens, args[1]);
|
||||
ASTVisitor visitor = new TestVisitor;
|
||||
visitor.visit(m);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue