Unary and Primary expression parsing
This commit is contained in:
parent
38105d542f
commit
1beef6a901
80
std/d/ast.d
80
std/d/ast.d
|
@ -68,7 +68,6 @@ abstract class ASTVisitor
|
||||||
/** */ void visit(BreakStatement breakStatement) { breakStatement.accept(this); }
|
/** */ void visit(BreakStatement breakStatement) { breakStatement.accept(this); }
|
||||||
/** */ void visit(BaseClass baseClass) { baseClass.accept(this); }
|
/** */ void visit(BaseClass baseClass) { baseClass.accept(this); }
|
||||||
/** */ void visit(BaseClassList baseClassList) { baseClassList.accept(this); }
|
/** */ void visit(BaseClassList baseClassList) { baseClassList.accept(this); }
|
||||||
/** */ void visit(BasicType builtinType) { builtinType.accept(this); }
|
|
||||||
/** */ void visit(CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); }
|
/** */ void visit(CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); }
|
||||||
/** */ void visit(CaseStatement caseStatement) { caseStatement.accept(this); }
|
/** */ void visit(CaseStatement caseStatement) { caseStatement.accept(this); }
|
||||||
/** */ void visit(CastExpression castExpression) { castExpression.accept(this); }
|
/** */ void visit(CastExpression castExpression) { castExpression.accept(this); }
|
||||||
|
@ -101,6 +100,7 @@ abstract class ASTVisitor
|
||||||
/** */ void visit(EnumMember enumMember) { enumMember.accept(this); }
|
/** */ void visit(EnumMember enumMember) { enumMember.accept(this); }
|
||||||
/** */ void visit(EqualExpression equalExpression) { equalExpression.accept(this); }
|
/** */ void visit(EqualExpression equalExpression) { equalExpression.accept(this); }
|
||||||
/** */ void visit(Expression expression) { expression.accept(this); }
|
/** */ void visit(Expression expression) { expression.accept(this); }
|
||||||
|
/** */ void visit(ExpressionStatement expressionStatement) { expressionStatement.accept(this); }
|
||||||
/** */ void visit(FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); }
|
/** */ void visit(FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); }
|
||||||
/** */ void visit(Finally finally_) { finally_.accept(this); }
|
/** */ void visit(Finally finally_) { finally_.accept(this); }
|
||||||
/** */ void visit(ForStatement forStatement) { forStatement.accept(this); }
|
/** */ void visit(ForStatement forStatement) { forStatement.accept(this); }
|
||||||
|
@ -157,7 +157,6 @@ abstract class ASTVisitor
|
||||||
/** */ void visit(OrOrExpression orOrExpression) { orOrExpression.accept(this); }
|
/** */ void visit(OrOrExpression orOrExpression) { orOrExpression.accept(this); }
|
||||||
/** */ void visit(OutStatement outStatement) { outStatement.accept(this); }
|
/** */ void visit(OutStatement outStatement) { outStatement.accept(this); }
|
||||||
/** */ void visit(Parameter parameter) { parameter.accept(this); }
|
/** */ void visit(Parameter parameter) { parameter.accept(this); }
|
||||||
/** */ void visit(ParameterAttribute parameterAttribute) { parameterAttribute.accept(this); }
|
|
||||||
/** */ void visit(Parameters parameters) { parameters.accept(this); }
|
/** */ void visit(Parameters parameters) { parameters.accept(this); }
|
||||||
/** */ void visit(Postblit postblit) { postblit.accept(this); }
|
/** */ void visit(Postblit postblit) { postblit.accept(this); }
|
||||||
/** */ void visit(PostIncDecExpression postIncDecExpression) { postIncDecExpression.accept(this); }
|
/** */ void visit(PostIncDecExpression postIncDecExpression) { postIncDecExpression.accept(this); }
|
||||||
|
@ -216,7 +215,6 @@ abstract class ASTVisitor
|
||||||
/** */ void visit(TryStatement tryStatement) { tryStatement.accept(this); }
|
/** */ void visit(TryStatement tryStatement) { tryStatement.accept(this); }
|
||||||
/** */ void visit(Type type) { type.accept(this); }
|
/** */ void visit(Type type) { type.accept(this); }
|
||||||
/** */ void visit(Type2 type2) { type2.accept(this); }
|
/** */ void visit(Type2 type2) { type2.accept(this); }
|
||||||
/** */ void visit(TypeConstructor typeConstructor) { typeConstructor.accept(this); }
|
|
||||||
/** */ void visit(TypeConstructors typeConstructors) { typeConstructors.accept(this); }
|
/** */ void visit(TypeConstructors typeConstructors) { typeConstructors.accept(this); }
|
||||||
/** */ void visit(TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); }
|
/** */ void visit(TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); }
|
||||||
/** */ void visit(TypeSuffix typeSuffix) { typeSuffix.accept(this); }
|
/** */ void visit(TypeSuffix typeSuffix) { typeSuffix.accept(this); }
|
||||||
|
@ -653,15 +651,7 @@ class BaseClassList : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ BaseClass[] baseClasses;
|
/** */ BaseClass[] items;
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
class BasicType : ASTNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
mixin(DEFAULT_ACCEPT);
|
|
||||||
/** */ TokenType type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1005,6 +995,14 @@ public:
|
||||||
/** */ AssignExpression[] items;
|
/** */ AssignExpression[] items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class ExpressionStatement : ASTNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mixin(DEFAULT_ACCEPT);
|
||||||
|
/** */ Expression expression;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
class FinalSwitchStatement : ASTNode
|
class FinalSwitchStatement : ASTNode
|
||||||
{
|
{
|
||||||
|
@ -1070,7 +1068,7 @@ class ForeachTypeList : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ ForeachType[] foreachTypes;
|
/** */ ForeachType[] items;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1078,7 +1076,7 @@ class FunctionAttribute : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token pureOrNothrow;
|
/** */ Token token;
|
||||||
/** */ AtAttribute atAttribute;
|
/** */ AtAttribute atAttribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1130,7 +1128,7 @@ class FunctionLiteralExpression : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token functionOrDelegate;
|
/** */ TokenType functionOrDelegate;
|
||||||
/** */ Type type;
|
/** */ Type type;
|
||||||
/** */ Parameters parameters;
|
/** */ Parameters parameters;
|
||||||
/** */ FunctionAttribute[] functionAttributes;
|
/** */ FunctionAttribute[] functionAttributes;
|
||||||
|
@ -1503,12 +1501,11 @@ public:
|
||||||
/** */ ForeachRangeStatement foreachRangeStatement;
|
/** */ ForeachRangeStatement foreachRangeStatement;
|
||||||
/** */ ConditionalStatement conditionalStatement;
|
/** */ ConditionalStatement conditionalStatement;
|
||||||
/** */ StaticAssertStatement staticAssertStatement;
|
/** */ StaticAssertStatement staticAssertStatement;
|
||||||
/** */ AssertStatement assertStatement;
|
|
||||||
/** */ TemplateMixinStatement templateMixinStatement;
|
/** */ TemplateMixinStatement templateMixinStatement;
|
||||||
/** */ VersionSpecification versionSpecification;
|
/** */ VersionSpecification versionSpecification;
|
||||||
/** */ DebugSpecification debugSpecification;
|
/** */ DebugSpecification debugSpecification;
|
||||||
/** */ FunctionCallStatement functionCallStatement;
|
/** */ FunctionCallStatement functionCallStatement;
|
||||||
/** */ DeleteStatement deleteStatement;
|
/** */ ExpressionStatement expressionStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1570,19 +1567,11 @@ class Parameter : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ ParameterAttribute[] paramaterAttributes;
|
/** */ TokenType[] parameterAttributes;
|
||||||
/** */ Type type;
|
/** */ Type type;
|
||||||
/** */ Token name;
|
/** */ Token name;
|
||||||
/** */ bool vararg;
|
/** */ bool vararg;
|
||||||
}
|
/** */ AssignExpression default_;
|
||||||
|
|
||||||
///
|
|
||||||
class ParameterAttribute: ASTNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
mixin(DEFAULT_ACCEPT);
|
|
||||||
/** */ Token attribute;
|
|
||||||
/** */ TypeConstructor typeConstructor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1590,7 +1579,7 @@ class Parameters : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Parameter[] paramaters;
|
/** */ Parameter[] parameters;
|
||||||
/** */ bool hasVarargs;
|
/** */ bool hasVarargs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,7 +1662,7 @@ class Register : ASTNode
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token identifier;
|
/** */ Token identifier;
|
||||||
/** */ Token integerLiteral;
|
/** */ Token intLiteral;
|
||||||
/** */ bool hasIntegerLiteral;
|
/** */ bool hasIntegerLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1805,8 +1794,7 @@ class StorageClass : ASTNode
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ AtAttribute atAttribute;
|
/** */ AtAttribute atAttribute;
|
||||||
/** */ TypeConstructor typeConstructor;
|
/** */ Token token;
|
||||||
/** */ Token storageClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1927,7 +1915,7 @@ class TemplateArgumentList : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ TemplateArgument[] templateArguments;
|
/** */ TemplateArgument[] items;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1955,7 +1943,7 @@ class TemplateInstance : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token identifier;
|
/** */ Symbol symbol;
|
||||||
/** */ TemplateArguments templateArguments;
|
/** */ TemplateArguments templateArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1986,7 +1974,7 @@ class TemplateParameterList : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ TemplateParameter[] templateParameters;
|
/** */ TemplateParameter[] items;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -2003,7 +1991,6 @@ class TemplateSingleArgument : ASTNode
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token token;
|
/** */ Token token;
|
||||||
/** */ BasicType builtinType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -2103,7 +2090,7 @@ class Type : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ TypeConstructors typeConstructors;
|
/** */ TokenType[] typeConstructors;
|
||||||
/** */ TypeSuffix[] typeSuffixes;
|
/** */ TypeSuffix[] typeSuffixes;
|
||||||
/** */ Type2 type2;
|
/** */ Type2 type2;
|
||||||
}
|
}
|
||||||
|
@ -2113,28 +2100,20 @@ class Type2 : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ BasicType basicType;
|
/** */ Token basicType;
|
||||||
/** */ Symbol symbol;
|
/** */ Symbol symbol;
|
||||||
/** */ TypeofExpression typeofExpression;
|
/** */ TypeofExpression typeofExpression;
|
||||||
/** */ IdentifierOrTemplateChain identifierOrTemplateChain;
|
/** */ IdentifierOrTemplateChain identifierOrTemplateChain;
|
||||||
/** */ TypeConstructor typeConstructor;
|
/** */ TokenType typeConstructor;
|
||||||
/** */ Type type;
|
/** */ Type type;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
class TypeConstructor : ASTNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
mixin(DEFAULT_ACCEPT);
|
|
||||||
/** */ Token typeConstructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
class TypeConstructors : ASTNode
|
class TypeConstructors : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ TypeConstructor[] typeConstructors;
|
/** */ TokenType[] items;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -2183,17 +2162,14 @@ class UnaryExpression : ASTNode
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ PrimaryExpression primaryExpression;
|
/** */ PrimaryExpression primaryExpression;
|
||||||
/** */ UnaryExpression unaryExpression;
|
|
||||||
/** */ Token prefix;
|
/** */ Token prefix;
|
||||||
/** */ PreIncDecExpression preIncDecExpression;
|
/** */ Token suffix;
|
||||||
/** */ PostIncDecExpression postIncDecExpression;
|
/** */ UnaryExpression unaryExpression;
|
||||||
/** */ NewExpression newExpression;
|
/** */ NewExpression newExpression;
|
||||||
/** */ DeleteExpression deleteExpression;
|
/** */ DeleteExpression deleteExpression;
|
||||||
/** */ CastExpression castExpression;
|
/** */ CastExpression castExpression;
|
||||||
/** */ FunctionCallExpression functionCallExpression;
|
/** */ FunctionCallExpression functionCallExpression;
|
||||||
/** */ ArgumentList argumentList;
|
/** */ ArgumentList argumentList;
|
||||||
/** */ AssignExpression low;
|
|
||||||
/** */ AssignExpression high;
|
|
||||||
/** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
|
/** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
|
||||||
/** */ AssertExpression assertExpression;
|
/** */ AssertExpression assertExpression;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2009,6 +2009,7 @@ pure nothrow bool isMisc(ref const Token t)
|
||||||
*/
|
*/
|
||||||
enum TokenType: ushort
|
enum TokenType: ushort
|
||||||
{
|
{
|
||||||
|
invalid, /// Not a valid token
|
||||||
assign, /// =
|
assign, /// =
|
||||||
at, /// @
|
at, /// @
|
||||||
bitAnd, /// &
|
bitAnd, /// &
|
||||||
|
@ -2506,6 +2507,7 @@ bool isRangeEoF(R)(ref R range)
|
||||||
|
|
||||||
// Lookup table for token values
|
// Lookup table for token values
|
||||||
package immutable(string[TokenType.max + 1]) tokenValues = [
|
package immutable(string[TokenType.max + 1]) tokenValues = [
|
||||||
|
null,
|
||||||
"=",
|
"=",
|
||||||
"@",
|
"@",
|
||||||
"&",
|
"&",
|
||||||
|
|
402
std/d/parser.d
402
std/d/parser.d
|
@ -56,7 +56,7 @@
|
||||||
* MACROS:
|
* MACROS:
|
||||||
* GRAMMAR = $(D_CODE $0)
|
* GRAMMAR = $(D_CODE $0)
|
||||||
* RULEDEF = $(DDOC_ANCHOR $0) $(B $0)
|
* RULEDEF = $(DDOC_ANCHOR $0) $(B $0)
|
||||||
* RULE = $(LINK2 #.$0, $(B $0))
|
* RULE = $(LINK2 #$0, $(B $0))
|
||||||
* LITERAL = $(D_STRING $0)
|
* LITERAL = $(D_STRING $0)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -70,7 +70,9 @@ import std.array;
|
||||||
version (unittest) import std.stdio;
|
version (unittest) import std.stdio;
|
||||||
|
|
||||||
version = development;
|
version = development;
|
||||||
|
//version = verbose;
|
||||||
version(development) import std.stdio;
|
version(development) import std.stdio;
|
||||||
|
version(verbose) import std.stdio;
|
||||||
|
|
||||||
// TODO: any place that says *expect(...) needs to be fixed
|
// TODO: any place that says *expect(...) needs to be fixed
|
||||||
|
|
||||||
|
@ -101,6 +103,7 @@ struct Parser
|
||||||
*/
|
*/
|
||||||
AddExpression parseAddExpression()
|
AddExpression parseAddExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseAddExpression");
|
||||||
return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
|
return parseLeftAssocBinaryExpression!(AddExpression, MulExpression,
|
||||||
TokenType.plus, TokenType.minus, TokenType.tilde)();
|
TokenType.plus, TokenType.minus, TokenType.tilde)();
|
||||||
}
|
}
|
||||||
|
@ -182,6 +185,7 @@ struct Parser
|
||||||
*/
|
*/
|
||||||
AndAndExpression parseAndAndExpression()
|
AndAndExpression parseAndAndExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseAndAndExpression");
|
||||||
return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
|
return parseLeftAssocBinaryExpression!(AndAndExpression, OrExpression,
|
||||||
TokenType.logicAnd)();
|
TokenType.logicAnd)();
|
||||||
}
|
}
|
||||||
|
@ -196,6 +200,7 @@ struct Parser
|
||||||
*/
|
*/
|
||||||
AndExpression parseAndExpression()
|
AndExpression parseAndExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseAndExpression");
|
||||||
return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
|
return parseLeftAssocBinaryExpression!(AndExpression, CmpExpression,
|
||||||
TokenType.bitAnd)();
|
TokenType.bitAnd)();
|
||||||
}
|
}
|
||||||
|
@ -605,6 +610,7 @@ struct Parser
|
||||||
*/
|
*/
|
||||||
AssignExpression parseAssignExpression()
|
AssignExpression parseAssignExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseAssignExpression");
|
||||||
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,
|
||||||
|
@ -630,12 +636,7 @@ struct Parser
|
||||||
AssignStatement parseAssignStatement()
|
AssignStatement parseAssignStatement()
|
||||||
{
|
{
|
||||||
auto node = new AssignStatement;
|
auto node = new AssignStatement;
|
||||||
if (currentIsOneOf(TokenType.increment, TokenType.decrement))
|
|
||||||
node.preIncDecExpression = parsePreIncDecExpression();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
|
||||||
expect(TokenType.semicolon);
|
expect(TokenType.semicolon);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -676,9 +677,12 @@ struct Parser
|
||||||
node.identifier = advance();
|
node.identifier = advance();
|
||||||
break;
|
break;
|
||||||
case lParen:
|
case lParen:
|
||||||
node.argumentlist = parseArgumentList();
|
node.argumentList = parseArgumentList();
|
||||||
expect(rParen);
|
expect(rParen);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
error(`"(", or identifier expected`);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -814,9 +818,9 @@ struct Parser
|
||||||
{
|
{
|
||||||
auto node = new BlockStatement();
|
auto node = new BlockStatement();
|
||||||
expect(TokenType.lBrace);
|
expect(TokenType.lBrace);
|
||||||
skipBraceContent();
|
version (development) skipBraceContent();
|
||||||
//if (!currentIs(TokenType.rBrace))
|
if (!currentIs(TokenType.rBrace))
|
||||||
// node.declarationsAndStatements = parseDeclarationsAndStatements();
|
node.declarationsAndStatements = parseDeclarationsAndStatements();
|
||||||
expect(TokenType.rBrace);
|
expect(TokenType.rBrace);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -922,17 +926,13 @@ struct Parser
|
||||||
* | $(LITERAL 'void')
|
* | $(LITERAL 'void')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
BasicType parseBasicType()
|
Token parseBasicType()
|
||||||
{
|
{
|
||||||
auto node = new BasicType;
|
|
||||||
if (isBasicType(current().type))
|
if (isBasicType(current().type))
|
||||||
node.type = advance().type;
|
return advance();
|
||||||
else
|
|
||||||
{
|
|
||||||
error("Basic type expected");
|
error("Basic type expected");
|
||||||
return null;
|
Token t;
|
||||||
}
|
return t;
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1278,6 +1278,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
|
||||||
*/
|
*/
|
||||||
CmpExpression parseCmpExpression()
|
CmpExpression parseCmpExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseCmpExpression");
|
||||||
auto node = new CmpExpression;
|
auto node = new CmpExpression;
|
||||||
auto shift = parseShiftExpression();
|
auto shift = parseShiftExpression();
|
||||||
with (TokenType) switch (current().type)
|
with (TokenType) switch (current().type)
|
||||||
|
@ -1375,7 +1376,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
|
||||||
auto node = new ConditionalStatement;
|
auto node = new ConditionalStatement;
|
||||||
node.compileCondition = parseCompileCondition();
|
node.compileCondition = parseCompileCondition();
|
||||||
node.trueStatement = parseStatementNoCaseNoDefault();
|
node.trueStatement = parseStatementNoCaseNoDefault();
|
||||||
if (currentIs(TokenType.else))
|
if (currentIs(TokenType.else_))
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
node.falseStatement = parseStatementNoCaseNoDefault();
|
node.falseStatement = parseStatementNoCaseNoDefault();
|
||||||
|
@ -1892,6 +1893,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
|
||||||
*/
|
*/
|
||||||
EqualExpression parseEqualExpression(ShiftExpression shift = null)
|
EqualExpression parseEqualExpression(ShiftExpression shift = null)
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseEqualExpression");
|
||||||
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))
|
||||||
|
@ -1909,7 +1911,22 @@ class ClassFour(A, B) if (someTest()) : Super {}};
|
||||||
*/
|
*/
|
||||||
Expression parseExpression()
|
Expression parseExpression()
|
||||||
{
|
{
|
||||||
return parseCommaSeparatedRule!(AssignExpression)();
|
return parseCommaSeparatedRule!(Expression, AssignExpression)();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses an ExpressionStatement
|
||||||
|
*
|
||||||
|
* $(GRAMMAR $(RULEDEF expressionStatement):
|
||||||
|
* $(RULE expression) $(LITERAL ';')
|
||||||
|
* ;)
|
||||||
|
*/
|
||||||
|
ExpressionStatement parseExpressionStatement(Expression expression = null)
|
||||||
|
{
|
||||||
|
auto node = new ExpressionStatement;
|
||||||
|
node.expression = expression is null ? parseExpression() : expression;
|
||||||
|
expect(TokenType.semicolon);
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2022,7 +2039,7 @@ class ClassFour(A, B) if (someTest()) : Super {}};
|
||||||
FunctionAttribute parseFunctionAttribute()
|
FunctionAttribute parseFunctionAttribute()
|
||||||
{
|
{
|
||||||
auto node = new FunctionAttribute;
|
auto node = new FunctionAttribute;
|
||||||
with (TokenType) switch (curent().type)
|
with (TokenType) switch (current().type)
|
||||||
{
|
{
|
||||||
case at:
|
case at:
|
||||||
node.atAttribute = parseAtAttribute();
|
node.atAttribute = parseAtAttribute();
|
||||||
|
@ -2125,10 +2142,10 @@ body {} // six
|
||||||
* $(RULE unaryExpression) $(RULE templateArguments)? $(RULE arguments)
|
* $(RULE unaryExpression) $(RULE templateArguments)? $(RULE arguments)
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
FunctionCallExpression parseFunctionCallExpression()
|
FunctionCallExpression parseFunctionCallExpression(UnaryExpression unary = null)
|
||||||
{
|
{
|
||||||
auto node = new FunctionCallExpression;
|
auto node = new FunctionCallExpression;
|
||||||
node.unaryExpression = parseUnaryExpression();
|
node.unaryExpression = unary is null ? parseUnaryExpression() : unary;
|
||||||
if (currentIs(TokenType.not))
|
if (currentIs(TokenType.not))
|
||||||
node.templateArguments = parseTemplateArguments();
|
node.templateArguments = parseTemplateArguments();
|
||||||
node.arguments = parseArguments();
|
node.arguments = parseArguments();
|
||||||
|
@ -2246,6 +2263,9 @@ body {} // six
|
||||||
node.token = advance();
|
node.token = advance();
|
||||||
node.expression = parseExpression();
|
node.expression = parseExpression();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
error(`Identifier, "default", or "case" expected`);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
expect(TokenType.semicolon);
|
expect(TokenType.semicolon);
|
||||||
return node;
|
return node;
|
||||||
|
@ -2275,7 +2295,7 @@ body {} // six
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest // TODO
|
||||||
{
|
{
|
||||||
auto input = cast(ubyte[]) "abcde.frocegu.creou.faowe"c;
|
auto input = cast(ubyte[]) "abcde.frocegu.creou.faowe"c;
|
||||||
LexerConfig config;
|
LexerConfig config;
|
||||||
|
@ -2370,7 +2390,7 @@ body {} // six
|
||||||
* Parses an IfStatement
|
* Parses an IfStatement
|
||||||
*
|
*
|
||||||
* $(GRAMMAR $(RULEDEF ifStatement):
|
* $(GRAMMAR $(RULEDEF ifStatement):
|
||||||
* $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE nonEmptyStatementNoCaseNoDefault) ($(LITERAL 'else') $(RULE nonEmptyStatementNoCaseNoDefault))?
|
* $(LITERAL 'if') $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)') $(RULE statementNoCaseNoDefault) ($(LITERAL 'else') $(RULE statementNoCaseNoDefault))?
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
IfStatement parseIfStatement()
|
IfStatement parseIfStatement()
|
||||||
|
@ -2380,7 +2400,12 @@ body {} // six
|
||||||
expect(TokenType.lParen);
|
expect(TokenType.lParen);
|
||||||
node.expression = parseExpression();
|
node.expression = parseExpression();
|
||||||
expect(TokenType.rParen);
|
expect(TokenType.rParen);
|
||||||
node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault();
|
node.thenStatement = parseStatementNoCaseNoDefault();
|
||||||
|
if (currentIs(TokenType.else_))
|
||||||
|
{
|
||||||
|
advance();
|
||||||
|
node.elseStatement = parseStatementNoCaseNoDefault();
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2834,7 +2859,7 @@ invariant() foo();
|
||||||
auto node = new LastCatch;
|
auto node = new LastCatch;
|
||||||
if (expect(TokenType.catch_) is null) return null;
|
if (expect(TokenType.catch_) is null) return null;
|
||||||
if ((node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault()) is null)
|
if ((node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault()) is null)
|
||||||
return null;;
|
return null;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2940,7 +2965,7 @@ invariant() foo();
|
||||||
{
|
{
|
||||||
Module m = new Module;
|
Module m = new Module;
|
||||||
if (currentIs(TokenType.module_))
|
if (currentIs(TokenType.module_))
|
||||||
node.moduleDeclaration = parseModuleDeclaration();
|
m.moduleDeclaration = parseModuleDeclaration();
|
||||||
while (moreTokens())
|
while (moreTokens())
|
||||||
{
|
{
|
||||||
auto declaration = parseDeclaration();
|
auto declaration = parseDeclaration();
|
||||||
|
@ -2975,6 +3000,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
MulExpression parseMulExpression()
|
MulExpression parseMulExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseMulExpression");
|
||||||
return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
|
return parseLeftAssocBinaryExpression!(MulExpression, UnaryExpression,
|
||||||
TokenType.star, TokenType.div, TokenType.mod)();
|
TokenType.star, TokenType.div, TokenType.mod)();
|
||||||
}
|
}
|
||||||
|
@ -2994,7 +3020,7 @@ invariant() foo();
|
||||||
node.allocatorArguments = parseArguments();
|
node.allocatorArguments = parseArguments();
|
||||||
expect(TokenType.class_);
|
expect(TokenType.class_);
|
||||||
if (!currentIs(TokenType.lBrace))
|
if (!currentIs(TokenType.lBrace))
|
||||||
node.baseClassList = parseBaseClassList
|
node.baseClassList = parseBaseClassList;
|
||||||
node.classBody = parseClassBody();
|
node.classBody = parseClassBody();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -3010,7 +3036,7 @@ invariant() foo();
|
||||||
NewExpression parseNewExpression()
|
NewExpression parseNewExpression()
|
||||||
{
|
{
|
||||||
auto node = new NewExpression;
|
auto node = new NewExpression;
|
||||||
if (peekIsOneOf(TokenType.class_ TokenType.lParen))
|
if (peekIsOneOf(TokenType.class_, TokenType.lParen))
|
||||||
node.newAnonClassExpression = parseNewAnonClassExpression();
|
node.newAnonClassExpression = parseNewAnonClassExpression();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3145,13 +3171,10 @@ invariant() foo();
|
||||||
case asm_:
|
case asm_:
|
||||||
node.asmStatement = parseAsmStatement();
|
node.asmStatement = parseAsmStatement();
|
||||||
break;
|
break;
|
||||||
case assert_:
|
|
||||||
node.assertStatement = parseAssertStatement();
|
|
||||||
break;
|
|
||||||
case delete_:
|
case delete_:
|
||||||
node.deleteStatement = parseDeleteStatement();
|
case assert_:
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
|
node.expressionStatement = parseExpressionStatement();
|
||||||
break;
|
break;
|
||||||
// TODO: assignStatement
|
// TODO: assignStatement
|
||||||
// TODO: finalSwitchStatement
|
// TODO: finalSwitchStatement
|
||||||
|
@ -3211,6 +3234,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
OrExpression parseOrExpression()
|
OrExpression parseOrExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseOrExpression");
|
||||||
return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
|
return parseLeftAssocBinaryExpression!(OrExpression, XorExpression,
|
||||||
TokenType.bitOr)();
|
TokenType.bitOr)();
|
||||||
}
|
}
|
||||||
|
@ -3225,6 +3249,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
OrOrExpression parseOrOrExpression()
|
OrOrExpression parseOrOrExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseOrOrExpression");
|
||||||
return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
|
return parseLeftAssocBinaryExpression!(OrOrExpression, AndAndExpression,
|
||||||
TokenType.logicOr)();
|
TokenType.logicOr)();
|
||||||
}
|
}
|
||||||
|
@ -3260,7 +3285,27 @@ invariant() foo();
|
||||||
Parameter parseParameter()
|
Parameter parseParameter()
|
||||||
{
|
{
|
||||||
auto node = new Parameter;
|
auto node = new Parameter;
|
||||||
// TODO
|
while (moreTokens())
|
||||||
|
{
|
||||||
|
TokenType type = parseParameterAttribute(false);
|
||||||
|
if (type == TokenType.invalid)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
node.parameterAttributes ~= type;
|
||||||
|
}
|
||||||
|
node.type = parseType();
|
||||||
|
if (node.type is null) return null;
|
||||||
|
if (currentIs(TokenType.identifier))
|
||||||
|
{
|
||||||
|
node.name = advance();
|
||||||
|
if (currentIs(TokenType.vararg))
|
||||||
|
node.vararg = true;
|
||||||
|
else if (currentIs(TokenType.assign))
|
||||||
|
{
|
||||||
|
advance();
|
||||||
|
node.default_ = parseAssignExpression();
|
||||||
|
}
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3278,29 +3323,90 @@ invariant() foo();
|
||||||
* | $(LITERAL 'auto')
|
* | $(LITERAL 'auto')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
ParameterAttribute parseParameterAttribute()
|
TokenType parseParameterAttribute(bool validate = false)
|
||||||
{
|
{
|
||||||
auto node = new ParameterAttribute;
|
with (TokenType) switch (current().type)
|
||||||
// TODO
|
{
|
||||||
return node;
|
case immutable_:
|
||||||
|
case shared_:
|
||||||
|
case const_:
|
||||||
|
case inout_:
|
||||||
|
case final_:
|
||||||
|
case in_:
|
||||||
|
case lazy_:
|
||||||
|
case out_:
|
||||||
|
case ref_:
|
||||||
|
case scope_:
|
||||||
|
case auto_:
|
||||||
|
return advance().type;
|
||||||
|
default:
|
||||||
|
if (validate) error("Parameter attribute expected");
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses Parameters
|
* Parses Parameters
|
||||||
*
|
*
|
||||||
* $(GRAMMAR $(RULEDEF parameters):
|
* $(GRAMMAR $(RULEDEF parameters):
|
||||||
* $(LITERAL '$(LPAREN)') (($(RULE parameter) ($(LITERAL ',') $(RULE parameter))*)? ($(LITERAL ',') $(LITERAL '...'))? | $(LITERAL '...')) $(LITERAL '$(RPAREN)')
|
* $(LITERAL '$(LPAREN)') $(RULE parameter) ($(LITERAL ',') $(RULE parameter))* ($(LITERAL ',') $(LITERAL '...'))? $(LITERAL '$(RPAREN)')
|
||||||
|
* | $(LITERAL '$(LPAREN)') $(LITERAL '...') $(LITERAL '$(RPAREN)')
|
||||||
|
* | $(LITERAL '$(LPAREN)') $(LITERAL '$(RPAREN)')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
Parameters parseParameters()
|
Parameters parseParameters()
|
||||||
{
|
{
|
||||||
auto node = new Parameters;
|
auto node = new Parameters;
|
||||||
expect(TokenType.lParen);
|
expect(TokenType.lParen);
|
||||||
version(development) skipParenContent();
|
if (currentIs(TokenType.rParen))
|
||||||
|
goto end;
|
||||||
|
if (currentIs(TokenType.vararg))
|
||||||
|
{
|
||||||
|
node.hasVarargs = true;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
while (moreTokens())
|
||||||
|
{
|
||||||
|
if (currentIs(TokenType.vararg))
|
||||||
|
{
|
||||||
|
node.hasVarargs = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (currentIs(TokenType.rParen))
|
||||||
|
break;
|
||||||
|
auto param = parseParameter();
|
||||||
|
if (param is null)
|
||||||
|
break;
|
||||||
|
node.parameters ~= param;
|
||||||
|
if (currentIs(TokenType.comma))
|
||||||
|
advance();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
end:
|
||||||
expect(TokenType.rParen);
|
expect(TokenType.rParen);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
string sourceCode =
|
||||||
|
q{(int a, ...)
|
||||||
|
(double ...)}c;
|
||||||
|
|
||||||
|
Parser p = getParserForUnittest(sourceCode, "parseParameters");
|
||||||
|
|
||||||
|
Parameters params1 = p.parseParameters();
|
||||||
|
assert (params1.hasVarargs);
|
||||||
|
assert (params1.paramaters.length == 1);
|
||||||
|
assert (params1.paramaters[0].name == "a");
|
||||||
|
|
||||||
|
Parameters params2 = p.parseParameters();
|
||||||
|
assert (params2.paramaters.length == 1);
|
||||||
|
assert (params2.paramaters[0].vararg);
|
||||||
|
assert (params2.paramaters[0].type !is null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a Postblit
|
* Parses a Postblit
|
||||||
*
|
*
|
||||||
|
@ -3449,6 +3555,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
PrimaryExpression parsePrimaryExpression()
|
PrimaryExpression parsePrimaryExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parsePrimaryExpression");
|
||||||
auto node = new PrimaryExpression;
|
auto node = new PrimaryExpression;
|
||||||
with (TokenType) switch (current().type)
|
with (TokenType) switch (current().type)
|
||||||
{
|
{
|
||||||
|
@ -3491,8 +3598,12 @@ invariant() foo();
|
||||||
case false_:
|
case false_:
|
||||||
case specialDate: .. case specialPrettyFunction:
|
case specialDate: .. case specialPrettyFunction:
|
||||||
case doubleLiteral: .. case wstringLiteral:
|
case doubleLiteral: .. case wstringLiteral:
|
||||||
primary = advance();
|
version(verbose) writeln("special or literal ", index, " ", current());
|
||||||
|
node.primary = advance();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
error(`Primary expression expected`);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -3635,6 +3746,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
ShiftExpression parseShiftExpression()
|
ShiftExpression parseShiftExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseShiftExpression");
|
||||||
return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
|
return parseLeftAssocBinaryExpression!(ShiftExpression, AddExpression,
|
||||||
TokenType.shiftLeft, TokenType.shiftRight,
|
TokenType.shiftLeft, TokenType.shiftRight,
|
||||||
TokenType.unsignedShiftRight)();
|
TokenType.unsignedShiftRight)();
|
||||||
|
@ -3702,22 +3814,7 @@ invariant() foo();
|
||||||
StaticAssertDeclaration parseStaticAssertDeclaration()
|
StaticAssertDeclaration parseStaticAssertDeclaration()
|
||||||
{
|
{
|
||||||
auto node = new StaticAssertDeclaration;
|
auto node = new StaticAssertDeclaration;
|
||||||
node.staticAssertStatement = parseStaticAssertStatement();
|
// TODO
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a StaticAssertStatement
|
|
||||||
*
|
|
||||||
* $(GRAMMAR $(RULEDEF staticAssertStatement):
|
|
||||||
* $(LITERAL 'static') $(RULE assertStatement)
|
|
||||||
* ;)
|
|
||||||
*/
|
|
||||||
StaticAssertStatement parseStaticAssertStatement()
|
|
||||||
{
|
|
||||||
auto node = new StaticAssertStatement;
|
|
||||||
expect(TokenType.static_);
|
|
||||||
node.assertStatement = parseAssertStatement();
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3840,7 +3937,7 @@ invariant() foo();
|
||||||
if (currentIs(TokenType.invariant_))
|
if (currentIs(TokenType.invariant_))
|
||||||
node.invariant_ = parseInvariant();
|
node.invariant_ = parseInvariant();
|
||||||
else if (startsWith(TokenType.this_, TokenType.lParen, TokenType.this_))
|
else if (startsWith(TokenType.this_, TokenType.lParen, TokenType.this_))
|
||||||
node.postBlit = parsePostblit();
|
node.postblit = parsePostblit();
|
||||||
else
|
else
|
||||||
node.declaration = parseDeclaration();
|
node.declaration = parseDeclaration();
|
||||||
return node;
|
return node;
|
||||||
|
@ -4081,12 +4178,12 @@ invariant() foo();
|
||||||
expect(TokenType.template_);
|
expect(TokenType.template_);
|
||||||
node.identifier = *expect(TokenType.identifier);
|
node.identifier = *expect(TokenType.identifier);
|
||||||
node.templateParameters = parseTemplateParameters();
|
node.templateParameters = parseTemplateParameters();
|
||||||
if (currentIs(TokenType.if_));
|
if (currentIs(TokenType.if_))
|
||||||
node.constraint = parseConstraint();
|
node.constraint = parseConstraint();
|
||||||
expect(TokenType.lBrace);
|
expect(TokenType.lBrace);
|
||||||
do
|
do
|
||||||
node.declarations ~= parseDeclaration();
|
node.declarations ~= parseDeclaration();
|
||||||
while (!currentIs(TokenType.rBrace))
|
while (!currentIs(TokenType.rBrace));
|
||||||
expect(TokenType.rBrace);
|
expect(TokenType.rBrace);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -4116,7 +4213,13 @@ invariant() foo();
|
||||||
TemplateMixinStatement parseTemplateMixinStatement()
|
TemplateMixinStatement parseTemplateMixinStatement()
|
||||||
{
|
{
|
||||||
auto node = new TemplateMixinStatement;
|
auto node = new TemplateMixinStatement;
|
||||||
// TODO
|
expect(TokenType.mixin_);
|
||||||
|
node.mixinTemplateName = parseMixinTemplateName();
|
||||||
|
if (currentIs(TokenType.not))
|
||||||
|
node.templateArguments = parseTemplateArguments();
|
||||||
|
if (currentIs(TokenType.identifier))
|
||||||
|
node.identifier = advance();
|
||||||
|
expect(TokenType.semicolon);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4147,9 +4250,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
TemplateParameterList parseTemplateParameterList()
|
TemplateParameterList parseTemplateParameterList()
|
||||||
{
|
{
|
||||||
auto node = new TemplateParameterList;
|
return parseCommaSeparatedRule!(TemplateParameterList, TemplateParameter)();
|
||||||
// TODO
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4163,8 +4264,10 @@ invariant() foo();
|
||||||
{
|
{
|
||||||
auto node = new TemplateParameters;
|
auto node = new TemplateParameters;
|
||||||
expect(TokenType.lParen);
|
expect(TokenType.lParen);
|
||||||
// TODO
|
version (development)
|
||||||
version (development) skipParenContent();
|
skipParenContent();
|
||||||
|
else
|
||||||
|
node.templateParameterList = parseTemplateParameterList();
|
||||||
expect(TokenType.rParen);
|
expect(TokenType.rParen);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -4198,7 +4301,22 @@ invariant() foo();
|
||||||
TemplateSingleArgument parseTemplateSingleArgument()
|
TemplateSingleArgument parseTemplateSingleArgument()
|
||||||
{
|
{
|
||||||
auto node = new TemplateSingleArgument;
|
auto node = new TemplateSingleArgument;
|
||||||
// TODO
|
with (TokenType) switch (current().type)
|
||||||
|
{
|
||||||
|
case true_:
|
||||||
|
case false_:
|
||||||
|
case null_:
|
||||||
|
case this_:
|
||||||
|
case identifier:
|
||||||
|
case specialDate: .. case specialTokenSequence:
|
||||||
|
case doubleLiteral: .. case wstringLiteral:
|
||||||
|
case bool_: .. case wchar_:
|
||||||
|
node.token = advance();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(`Invalid template argument. (Try enclosing in parenthesis?)`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4212,7 +4330,8 @@ invariant() foo();
|
||||||
TemplateThisParameter parseTemplateThisParameter()
|
TemplateThisParameter parseTemplateThisParameter()
|
||||||
{
|
{
|
||||||
auto node = new TemplateThisParameter;
|
auto node = new TemplateThisParameter;
|
||||||
// TODO
|
expect(TokenType.this_);
|
||||||
|
node.templateTypeParameter = parseTemplateTypeParameter();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4294,6 +4413,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
TernaryExpression parseTernaryExpression()
|
TernaryExpression parseTernaryExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseTernaryExpression");
|
||||||
auto node = new TernaryExpression;
|
auto node = new TernaryExpression;
|
||||||
node.orOrExpression = parseOrOrExpression();
|
node.orOrExpression = parseOrOrExpression();
|
||||||
if (currentIs(TokenType.ternary))
|
if (currentIs(TokenType.ternary))
|
||||||
|
@ -4395,6 +4515,7 @@ invariant() foo();
|
||||||
case TokenType.immutable_:
|
case TokenType.immutable_:
|
||||||
case TokenType.inout_:
|
case TokenType.inout_:
|
||||||
case TokenType.shared_:
|
case TokenType.shared_:
|
||||||
|
if (!peekIs(TokenType.lParen))
|
||||||
node.typeConstructors = parseTypeConstructors();
|
node.typeConstructors = parseTypeConstructors();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -4474,11 +4595,20 @@ invariant() foo();
|
||||||
* | $(LITERAL 'shared')
|
* | $(LITERAL 'shared')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
TypeConstructor parseTypeConstructor()
|
TokenType parseTypeConstructor(bool validate = false)
|
||||||
{
|
{
|
||||||
auto node = new TypeConstructor;
|
with (TokenType) switch (current().type)
|
||||||
// TODO
|
{
|
||||||
return node;
|
case const_:
|
||||||
|
case immutable_:
|
||||||
|
case inout_:
|
||||||
|
case shared_:
|
||||||
|
return advance().type;
|
||||||
|
default:
|
||||||
|
if (validate)
|
||||||
|
error(`"const", "immutable", "inout", or "shared" expected`);
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4488,11 +4618,18 @@ invariant() foo();
|
||||||
* $(RULE typeConstructor)+
|
* $(RULE typeConstructor)+
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
TypeConstructors parseTypeConstructors()
|
TokenType[] parseTypeConstructors()
|
||||||
{
|
{
|
||||||
auto node = new TypeConstructors;
|
TokenType[] r;
|
||||||
// TODO
|
while (moreTokens())
|
||||||
return node;
|
{
|
||||||
|
TokenType type = parseTypeConstructor(false);
|
||||||
|
if (type == TokenType.invalid)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
r ~= type;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4519,7 +4656,27 @@ invariant() foo();
|
||||||
TypeSpecialization parseTypeSpecialization()
|
TypeSpecialization parseTypeSpecialization()
|
||||||
{
|
{
|
||||||
auto node = new TypeSpecialization;
|
auto node = new TypeSpecialization;
|
||||||
// TODO
|
with (TokenType) switch (current().type)
|
||||||
|
{
|
||||||
|
case struct_:
|
||||||
|
case union_:
|
||||||
|
case interface_:
|
||||||
|
case enum_:
|
||||||
|
case function_:
|
||||||
|
case delegate_:
|
||||||
|
case super_:
|
||||||
|
case const_:
|
||||||
|
case immutable_:
|
||||||
|
case inout_:
|
||||||
|
case shared_:
|
||||||
|
case return_:
|
||||||
|
case parameters:
|
||||||
|
node.token = advance();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
node.type = parseType();
|
||||||
|
break;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4607,58 +4764,90 @@ invariant() foo();
|
||||||
* | $(LITERAL '+') $(RULE unaryExpression)
|
* | $(LITERAL '+') $(RULE unaryExpression)
|
||||||
* | $(LITERAL '-') $(RULE unaryExpression)
|
* | $(LITERAL '-') $(RULE unaryExpression)
|
||||||
* | $(LITERAL '~') $(RULE unaryExpression)
|
* | $(LITERAL '~') $(RULE unaryExpression)
|
||||||
|
* | $(LITERAL '++') $(RULE unaryExpression)
|
||||||
|
* | $(LITERAL '--') $(RULE unaryExpression)
|
||||||
* | $(RULE newExpression)
|
* | $(RULE newExpression)
|
||||||
* | $(RULE deleteExpression)
|
* | $(RULE deleteExpression)
|
||||||
* | $(RULE castExpression)
|
* | $(RULE castExpression)
|
||||||
|
* | $(RULE assertExpression)
|
||||||
* | $(RULE functionCallExpression)
|
* | $(RULE functionCallExpression)
|
||||||
* | $(RULE preIncDecExpression)
|
|
||||||
* | $(RULE postIncDecExpression)
|
|
||||||
* | $(RULE sliceExpression)
|
* | $(RULE sliceExpression)
|
||||||
* | $(RULE indexExpression)
|
* | $(RULE indexExpression)
|
||||||
* | $(RULE unaryExpression) $(LITERAL '.') $(RULE identifierOrTemplateInstance)
|
* | $(RULE unaryExpression) $(LITERAL '.') $(RULE identifierOrTemplateInstance)
|
||||||
* | $(RULE assertExpression)
|
* | $(RULE unaryExpression) ($(LITERAL '--')
|
||||||
|
* | $(RULE unaryExpression) ($(LITERAL '++')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
UnaryExpression parseUnaryExpression()
|
UnaryExpression parseUnaryExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseUnaryExpression");
|
||||||
auto node = new UnaryExpression;
|
auto node = new UnaryExpression;
|
||||||
switch (current().type)
|
with(TokenType) switch (current().type)
|
||||||
{
|
{
|
||||||
case TokenType.bitAnd:
|
case bitAnd:
|
||||||
case TokenType.not:
|
case not:
|
||||||
case TokenType.star:
|
case star:
|
||||||
case TokenType.plus:
|
case plus:
|
||||||
case TokenType.minus:
|
case minus:
|
||||||
case TokenType.tilde:
|
case tilde:
|
||||||
node.prefix = advance;
|
case increment:
|
||||||
|
case decrement:
|
||||||
|
node.prefix = advance();
|
||||||
node.unaryExpression = parseUnaryExpression();
|
node.unaryExpression = parseUnaryExpression();
|
||||||
return node;
|
return node;
|
||||||
case TokenType.new_:
|
case new_:
|
||||||
node.newExpression = parseNewExpression();
|
node.newExpression = parseNewExpression();
|
||||||
return node;
|
return node;
|
||||||
case TokenType.delete_:
|
case delete_:
|
||||||
node.deleteExpression = parseDeleteExpression();
|
node.deleteExpression = parseDeleteExpression();
|
||||||
return node;
|
return node;
|
||||||
case TokenType.cast_:
|
case cast_:
|
||||||
node.castExpression = parseCastExpression;
|
node.castExpression = parseCastExpression;
|
||||||
return node;
|
return node;
|
||||||
case TokenType.increment:
|
case assert_:
|
||||||
case TokenType.decrement:
|
|
||||||
node.preIncDecExpression = parsePreIncDecExpression();
|
|
||||||
return node;
|
|
||||||
case TokenType.assert_:
|
|
||||||
node.assertExpression = parseAssertExpression();
|
node.assertExpression = parseAssertExpression();
|
||||||
return node;
|
return node;
|
||||||
default:
|
default:
|
||||||
// TODO:
|
node.primaryExpression = parsePrimaryExpression();
|
||||||
// primary
|
|
||||||
// functionCall
|
|
||||||
// postIncDec
|
|
||||||
// slice
|
|
||||||
// index
|
|
||||||
// unary.identifierOrTemplateInstance
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop: while (true) with (TokenType) switch (current().type)
|
||||||
|
{
|
||||||
|
case not:
|
||||||
|
index++;
|
||||||
|
bool jump = peekPastParens().type == TokenType.lParen;
|
||||||
|
index--;
|
||||||
|
if (jump)
|
||||||
|
goto case lParen;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error(`Function call expected`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case lParen:
|
||||||
|
auto n = new UnaryExpression();
|
||||||
|
n.functionCallExpression = parseFunctionCallExpression(node);
|
||||||
|
node = n;
|
||||||
|
break;
|
||||||
|
case increment:
|
||||||
|
case decrement:
|
||||||
|
auto n = new UnaryExpression();
|
||||||
|
n.unaryExpression = node;
|
||||||
|
n.suffix = advance();
|
||||||
|
node = n;
|
||||||
|
break;
|
||||||
|
case lBracket:
|
||||||
|
assert (false);
|
||||||
|
case dot:
|
||||||
|
advance();
|
||||||
|
auto n = new UnaryExpression();
|
||||||
|
n.unaryExpression = node;
|
||||||
|
n.identifierOrTemplateInstance = parseIdentifierOrTemplateInstance();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4833,6 +5022,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
XorExpression parseXorExpression()
|
XorExpression parseXorExpression()
|
||||||
{
|
{
|
||||||
|
version(verbose) writeln("parseXorExpression");
|
||||||
return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
|
return parseLeftAssocBinaryExpression!(XorExpression, AndExpression,
|
||||||
TokenType.xor)();
|
TokenType.xor)();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,11 @@ class TestVisitor : ASTVisitor
|
||||||
|
|
||||||
override void visit(VariableDeclaration varDec)
|
override void visit(VariableDeclaration varDec)
|
||||||
{
|
{
|
||||||
writeln("variable ", varDec.declarators[0].identifier.value,
|
foreach (decl; varDec.declarators)
|
||||||
" on line ", varDec.declarators[0].identifier.line);
|
{
|
||||||
|
writeln("variable ", decl.identifier.value,
|
||||||
|
" on line ", decl.identifier.line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(ImportDeclaration impDec)
|
override void visit(ImportDeclaration impDec)
|
||||||
|
|
Loading…
Reference in New Issue