More work on the various expression parsing functions
This commit is contained in:
parent
1beef6a901
commit
635ddf79a0
16
std/d/ast.d
16
std/d/ast.d
|
@ -224,6 +224,7 @@ abstract class ASTVisitor
|
||||||
/** */ void visit(UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); }
|
/** */ void visit(UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); }
|
||||||
/** */ void visit(Unittest unittest_) { unittest_.accept(this); }
|
/** */ void visit(Unittest unittest_) { unittest_.accept(this); }
|
||||||
/** */ void visit(VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); }
|
/** */ void visit(VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); }
|
||||||
|
/** */ void visit(Vector vector) { vector.accept(this); }
|
||||||
/** */ void visit(VersionCondition versionCondition) { versionCondition.accept(this); }
|
/** */ void visit(VersionCondition versionCondition) { versionCondition.accept(this); }
|
||||||
/** */ void visit(VersionSpecification versionSpecification) { versionSpecification.accept(this); }
|
/** */ void visit(VersionSpecification versionSpecification) { versionSpecification.accept(this); }
|
||||||
/** */ void visit(WhileStatement whileStatement) { whileStatement.accept(this); }
|
/** */ void visit(WhileStatement whileStatement) { whileStatement.accept(this); }
|
||||||
|
@ -1641,8 +1642,9 @@ class PrimaryExpression : ASTNode
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token primary;
|
/** */ Token primary;
|
||||||
|
/** */ Token identifier;
|
||||||
/** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
|
/** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
|
||||||
/** */ Type type;
|
/** */ TokenType basicType;
|
||||||
/** */ TypeofExpression typeofExpression;
|
/** */ TypeofExpression typeofExpression;
|
||||||
/** */ TypeidExpression typeidExpression;
|
/** */ TypeidExpression typeidExpression;
|
||||||
/** */ ArrayLiteral arrayLiteral;
|
/** */ ArrayLiteral arrayLiteral;
|
||||||
|
@ -1654,6 +1656,7 @@ public:
|
||||||
/** */ TraitsExpression traitsExpression;
|
/** */ TraitsExpression traitsExpression;
|
||||||
/** */ MixinExpression mixinExpression;
|
/** */ MixinExpression mixinExpression;
|
||||||
/** */ ImportExpression importExpression;
|
/** */ ImportExpression importExpression;
|
||||||
|
/** */ Vector vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -1819,7 +1822,7 @@ class StructDeclaration : ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token identifier;
|
/** */ Token name;
|
||||||
/** */ TemplateParameters templateParameters;
|
/** */ TemplateParameters templateParameters;
|
||||||
/** */ Constraint constraint;
|
/** */ Constraint constraint;
|
||||||
/** */ StructBody structBody;
|
/** */ StructBody structBody;
|
||||||
|
@ -2132,6 +2135,7 @@ public:
|
||||||
mixin(DEFAULT_ACCEPT);
|
mixin(DEFAULT_ACCEPT);
|
||||||
/** */ Token delegateOrFunction;
|
/** */ Token delegateOrFunction;
|
||||||
/** */ bool star;
|
/** */ bool star;
|
||||||
|
/** */ bool array;
|
||||||
/** */ Type type;
|
/** */ Type type;
|
||||||
/** */ AssignExpression assignExpression;
|
/** */ AssignExpression assignExpression;
|
||||||
/** */ Parameters parameters;
|
/** */ Parameters parameters;
|
||||||
|
@ -2204,6 +2208,14 @@ public:
|
||||||
/** */ AutoDeclaration autoDeclaration;
|
/** */ AutoDeclaration autoDeclaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class Vector : ASTNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mixin(DEFAULT_ACCEPT);
|
||||||
|
/** */ Type type;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
class VersionCondition : ASTNode
|
class VersionCondition : ASTNode
|
||||||
{
|
{
|
||||||
|
|
|
@ -2084,7 +2084,6 @@ enum TokenType: ushort
|
||||||
dchar_, /// $(D_KEYWORD dchar)
|
dchar_, /// $(D_KEYWORD dchar)
|
||||||
double_, /// $(D_KEYWORD double)
|
double_, /// $(D_KEYWORD double)
|
||||||
float_, /// $(D_KEYWORD float)
|
float_, /// $(D_KEYWORD float)
|
||||||
function_, /// $(D_KEYWORD function)
|
|
||||||
idouble_, /// $(D_KEYWORD idouble)
|
idouble_, /// $(D_KEYWORD idouble)
|
||||||
ifloat_, /// $(D_KEYWORD ifloat)
|
ifloat_, /// $(D_KEYWORD ifloat)
|
||||||
int_, /// $(D_KEYWORD int)
|
int_, /// $(D_KEYWORD int)
|
||||||
|
@ -2134,6 +2133,7 @@ enum TokenType: ushort
|
||||||
debug_, /// $(D_KEYWORD debug)
|
debug_, /// $(D_KEYWORD debug)
|
||||||
default_, /// $(D_KEYWORD default)
|
default_, /// $(D_KEYWORD default)
|
||||||
delegate_, /// $(D_KEYWORD delegate)
|
delegate_, /// $(D_KEYWORD delegate)
|
||||||
|
function_, /// $(D_KEYWORD function)
|
||||||
delete_, /// $(D_KEYWORD delete)
|
delete_, /// $(D_KEYWORD delete)
|
||||||
do_, /// $(D_KEYWORD do)
|
do_, /// $(D_KEYWORD do)
|
||||||
else_, /// $(D_KEYWORD else)
|
else_, /// $(D_KEYWORD else)
|
||||||
|
@ -2581,7 +2581,6 @@ package immutable(string[TokenType.max + 1]) tokenValues = [
|
||||||
"dchar",
|
"dchar",
|
||||||
"double",
|
"double",
|
||||||
"float",
|
"float",
|
||||||
"function",
|
|
||||||
"idouble",
|
"idouble",
|
||||||
"ifloat",
|
"ifloat",
|
||||||
"int",
|
"int",
|
||||||
|
@ -2629,6 +2628,7 @@ package immutable(string[TokenType.max + 1]) tokenValues = [
|
||||||
"debug",
|
"debug",
|
||||||
"default",
|
"default",
|
||||||
"delegate",
|
"delegate",
|
||||||
|
"function",
|
||||||
"delete",
|
"delete",
|
||||||
"do",
|
"do",
|
||||||
"else",
|
"else",
|
||||||
|
|
289
std/d/parser.d
289
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;
|
||||||
version(verbose) import std.stdio;
|
version(verbose) import std.stdio;
|
||||||
|
|
||||||
|
@ -81,9 +81,10 @@ version(verbose) import std.stdio;
|
||||||
* tokens = the tokens parsed by std.d.lexer
|
* tokens = the tokens parsed by std.d.lexer
|
||||||
* Returns: the parsed module
|
* Returns: the parsed module
|
||||||
*/
|
*/
|
||||||
Module parseModule(const(Token)[] tokens)
|
Module parseModule(const(Token)[] tokens, string fileName)
|
||||||
{
|
{
|
||||||
auto parser = new Parser();
|
auto parser = new Parser();
|
||||||
|
parser.fileName = fileName;
|
||||||
parser.tokens = tokens;
|
parser.tokens = tokens;
|
||||||
return parser.parseModule();
|
return parser.parseModule();
|
||||||
}
|
}
|
||||||
|
@ -3285,6 +3286,7 @@ invariant() foo();
|
||||||
Parameter parseParameter()
|
Parameter parseParameter()
|
||||||
{
|
{
|
||||||
auto node = new Parameter;
|
auto node = new Parameter;
|
||||||
|
version (verbose) writeln("parseParameter");
|
||||||
while (moreTokens())
|
while (moreTokens())
|
||||||
{
|
{
|
||||||
TokenType type = parseParameterAttribute(false);
|
TokenType type = parseParameterAttribute(false);
|
||||||
|
@ -3331,6 +3333,10 @@ invariant() foo();
|
||||||
case shared_:
|
case shared_:
|
||||||
case const_:
|
case const_:
|
||||||
case inout_:
|
case inout_:
|
||||||
|
if (peekIs(TokenType.lParen))
|
||||||
|
return invalid;
|
||||||
|
else
|
||||||
|
goto case auto_;
|
||||||
case final_:
|
case final_:
|
||||||
case in_:
|
case in_:
|
||||||
case lazy_:
|
case lazy_:
|
||||||
|
@ -3356,6 +3362,7 @@ invariant() foo();
|
||||||
*/
|
*/
|
||||||
Parameters parseParameters()
|
Parameters 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))
|
||||||
|
@ -3518,10 +3525,11 @@ q{(int a, ...)
|
||||||
* Parses a PrimaryExpression
|
* Parses a PrimaryExpression
|
||||||
*
|
*
|
||||||
* $(GRAMMAR $(RULEDEF primaryExpression):
|
* $(GRAMMAR $(RULEDEF primaryExpression):
|
||||||
* $(RULE symbol)
|
* $(LITERAL Identifier)
|
||||||
* | $(RULE type) $(LITERAL '.') $(LITERAL Identifier)
|
* | $(RULE basicType) $(LITERAL '.') $(LITERAL Identifier)
|
||||||
* | $(RULE typeofExpression)
|
* | $(RULE typeofExpression)
|
||||||
* | $(RULE typeidExpression)
|
* | $(RULE typeidExpression)
|
||||||
|
* | $(RULE vector)
|
||||||
* | $(RULE arrayLiteral)
|
* | $(RULE arrayLiteral)
|
||||||
* | $(RULE assocArrayLiteral)
|
* | $(RULE assocArrayLiteral)
|
||||||
* | $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)')
|
* | $(LITERAL '$(LPAREN)') $(RULE expression) $(LITERAL '$(RPAREN)')
|
||||||
|
@ -3560,8 +3568,25 @@ q{(int a, ...)
|
||||||
with (TokenType) switch (current().type)
|
with (TokenType) switch (current().type)
|
||||||
{
|
{
|
||||||
case identifier:
|
case identifier:
|
||||||
// TODO
|
if (peekIs(TokenType.goesTo))
|
||||||
// symbol or type.identifier
|
node.lambdaExpression = parseLambdaExpression();
|
||||||
|
else
|
||||||
|
node.identifier = advance();
|
||||||
|
break;
|
||||||
|
mixin (BASIC_TYPE_CASE_RANGE);
|
||||||
|
node.basicType = advance().type;
|
||||||
|
expect(dot);
|
||||||
|
auto t = expect(identifier);
|
||||||
|
if (t !is null)
|
||||||
|
node.identifier = *t;
|
||||||
|
break;
|
||||||
|
case function_:
|
||||||
|
case delegate_:
|
||||||
|
case lBrace:
|
||||||
|
case in_:
|
||||||
|
case out_:
|
||||||
|
case body_:
|
||||||
|
node.functionLiteralExpression = parseFunctionLiteralExpression();
|
||||||
break;
|
break;
|
||||||
case typeof_:
|
case typeof_:
|
||||||
node.typeofExpression = parseTypeofExpression();
|
node.typeofExpression = parseTypeofExpression();
|
||||||
|
@ -3569,19 +3594,28 @@ q{(int a, ...)
|
||||||
case typeid_:
|
case typeid_:
|
||||||
node.typeidExpression = parseTypeidExpression();
|
node.typeidExpression = parseTypeidExpression();
|
||||||
break;
|
break;
|
||||||
|
case vector:
|
||||||
|
node.vector = parseVector();
|
||||||
|
break;
|
||||||
case lBracket:
|
case lBracket:
|
||||||
// TODO: array literal or associative array literal
|
if (isAssociativeArrayLiteral())
|
||||||
|
node.assocArrayLiteral = parseAssocArrayLiteral();
|
||||||
|
else
|
||||||
|
node.arrayLiteral = parseArrayLiteral();
|
||||||
break;
|
break;
|
||||||
case lParen:
|
case lParen:
|
||||||
advance();
|
if (peekPastParens().type == TokenType.goesTo)
|
||||||
node.expression = parseExpression();
|
node.lambdaExpression = parseLambdaExpression();
|
||||||
expect(TokenType.rParen);
|
else
|
||||||
|
{
|
||||||
|
advance();
|
||||||
|
node.expression = parseExpression();
|
||||||
|
expect(TokenType.rParen);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case is_:
|
case is_:
|
||||||
node.isExpression = parseIsExpression();
|
node.isExpression = parseIsExpression();
|
||||||
break;
|
break;
|
||||||
// TODO: lambda
|
|
||||||
// TODO: function literal
|
|
||||||
case traits:
|
case traits:
|
||||||
node.traitsExpression = parseTraitsExpression();
|
node.traitsExpression = parseTraitsExpression();
|
||||||
break;
|
break;
|
||||||
|
@ -3596,8 +3630,8 @@ q{(int a, ...)
|
||||||
case null_:
|
case null_:
|
||||||
case true_:
|
case true_:
|
||||||
case false_:
|
case false_:
|
||||||
case specialDate: .. case specialPrettyFunction:
|
mixin (SPECIAL_CASE_RANGE);
|
||||||
case doubleLiteral: .. case wstringLiteral:
|
mixin (LITERAL_CASE_RANGE);
|
||||||
version(verbose) writeln("special or literal ", index, " ", current());
|
version(verbose) writeln("special or literal ", index, " ", current());
|
||||||
node.primary = advance();
|
node.primary = advance();
|
||||||
break;
|
break;
|
||||||
|
@ -3954,7 +3988,7 @@ q{(int a, ...)
|
||||||
{
|
{
|
||||||
auto node = new StructDeclaration;
|
auto node = new StructDeclaration;
|
||||||
expect(TokenType.struct_);
|
expect(TokenType.struct_);
|
||||||
node.identifier = *expect(TokenType.identifier);
|
node.name = *expect(TokenType.identifier);
|
||||||
if (currentIs(TokenType.lParen))
|
if (currentIs(TokenType.lParen))
|
||||||
{
|
{
|
||||||
node.templateParameters = parseTemplateParameters();
|
node.templateParameters = parseTemplateParameters();
|
||||||
|
@ -4308,9 +4342,9 @@ q{(int a, ...)
|
||||||
case null_:
|
case null_:
|
||||||
case this_:
|
case this_:
|
||||||
case identifier:
|
case identifier:
|
||||||
case specialDate: .. case specialTokenSequence:
|
mixin (SPECIAL_CASE_RANGE);
|
||||||
case doubleLiteral: .. case wstringLiteral:
|
mixin (LITERAL_CASE_RANGE);
|
||||||
case bool_: .. case wchar_:
|
mixin (BASIC_TYPE_CASE_RANGE);
|
||||||
node.token = advance();
|
node.token = advance();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -4339,13 +4373,17 @@ q{(int a, ...)
|
||||||
* Parses an TemplateTupleParameter
|
* Parses an TemplateTupleParameter
|
||||||
*
|
*
|
||||||
* $(GRAMMAR $(RULEDEF templateTupleParameter):
|
* $(GRAMMAR $(RULEDEF templateTupleParameter):
|
||||||
* $(LITERAL Identifier) '...'
|
* $(LITERAL Identifier) $(LITERAL '...')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
TemplateTupleParameter parseTemplateTupleParameter()
|
TemplateTupleParameter parseTemplateTupleParameter()
|
||||||
{
|
{
|
||||||
auto node = new TemplateTupleParameter;
|
auto node = new TemplateTupleParameter;
|
||||||
// TODO
|
auto i = expect(TokenType.identifier);
|
||||||
|
if (i is null)
|
||||||
|
return null;
|
||||||
|
node.identifier = *i;
|
||||||
|
expect(TokenType.vararg);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4522,19 +4560,21 @@ q{(int a, ...)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node.type2 = parseType2();
|
node.type2 = parseType2();
|
||||||
loop: while (true)
|
if (node.type2 is null)
|
||||||
|
return null;
|
||||||
|
loop: while (true) with (TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
switch (current.type)
|
case TokenType.star:
|
||||||
{
|
case TokenType.lBracket:
|
||||||
case TokenType.star:
|
case TokenType.delegate_:
|
||||||
case TokenType.lBracket:
|
case TokenType.function_:
|
||||||
case TokenType.delegate_:
|
auto suffix = parseTypeSuffix();
|
||||||
case TokenType.function_:
|
if (suffix !is null)
|
||||||
node.typeSuffixes ~= parseTypeSuffix();
|
node.typeSuffixes ~= suffix;
|
||||||
break;
|
else
|
||||||
default:
|
return null;
|
||||||
break loop;
|
default:
|
||||||
}
|
break loop;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -4552,35 +4592,40 @@ q{(int a, ...)
|
||||||
Type2 parseType2()
|
Type2 parseType2()
|
||||||
{
|
{
|
||||||
auto node = new Type2;
|
auto node = new Type2;
|
||||||
switch (current.type)
|
with (TokenType) switch (current.type)
|
||||||
{
|
{
|
||||||
case TokenType.identifier:
|
case identifier:
|
||||||
case TokenType.dot:
|
case dot:
|
||||||
node.symbol = parseSymbol();
|
if ((node.symbol = parseSymbol()) is null)
|
||||||
|
return null;
|
||||||
break;
|
break;
|
||||||
case TokenType.bool_: .. case TokenType.wchar_:
|
case bool_: .. case wchar_:
|
||||||
node.basicType = parseBasicType();
|
if ((node.basicType = parseBasicType()) == TokenType.invalid)
|
||||||
|
return null;
|
||||||
break;
|
break;
|
||||||
case TokenType.typeof_:
|
case typeof_:
|
||||||
node.typeofExpression = parseTypeofExpression();
|
if ((node.typeofExpression = parseTypeofExpression()) is null)
|
||||||
|
return null;
|
||||||
if (currentIs(TokenType.dot))
|
if (currentIs(TokenType.dot))
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
node.identifierOrTemplateChain = parseIdentifierOrTemplateChain();
|
node.identifierOrTemplateChain = parseIdentifierOrTemplateChain();
|
||||||
|
if (node.identifierOrTemplateChain is null)
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TokenType.const_:
|
case const_:
|
||||||
case TokenType.immutable_:
|
case immutable_:
|
||||||
case TokenType.inout_:
|
case inout_:
|
||||||
case TokenType.shared_:
|
case shared_:
|
||||||
node.typeConstructor = parseTypeConstructor();
|
node.typeConstructor = parseTypeConstructor();
|
||||||
expect(TokenType.lParen);
|
if (expect(TokenType.lParen) is null) return null;
|
||||||
node.type = parseType();
|
if ((node.type = parseType()) is null) return null;
|
||||||
expect(TokenType.rParen);
|
if (expect(TokenType.rParen) is null) return null;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("Basic type, type constructor, symbol, or typeof expected");
|
error("Basic type, type constructor, symbol, or typeof expected");
|
||||||
break;
|
return null;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -4595,7 +4640,7 @@ q{(int a, ...)
|
||||||
* | $(LITERAL 'shared')
|
* | $(LITERAL 'shared')
|
||||||
* ;)
|
* ;)
|
||||||
*/
|
*/
|
||||||
TokenType parseTypeConstructor(bool validate = false)
|
TokenType parseTypeConstructor(bool validate = true)
|
||||||
{
|
{
|
||||||
with (TokenType) switch (current().type)
|
with (TokenType) switch (current().type)
|
||||||
{
|
{
|
||||||
|
@ -4692,19 +4737,32 @@ q{(int a, ...)
|
||||||
TypeSuffix parseTypeSuffix()
|
TypeSuffix parseTypeSuffix()
|
||||||
{
|
{
|
||||||
auto node = new TypeSuffix;
|
auto node = new TypeSuffix;
|
||||||
switch(current().type)
|
version (verbose) writeln("parseTypeSuffix");
|
||||||
|
with (TokenType) switch(current().type)
|
||||||
{
|
{
|
||||||
case TokenType.star:
|
case star:
|
||||||
node.star = true;
|
node.star = true;
|
||||||
advance();
|
advance();
|
||||||
return node;
|
return node;
|
||||||
case TokenType.lBracket:
|
case lBracket:
|
||||||
|
node.array = true;
|
||||||
advance();
|
advance();
|
||||||
// TODO: magic
|
if (currentIs(rBracket))
|
||||||
|
goto end;
|
||||||
|
auto bookmark = setBookmark();
|
||||||
|
auto type = parseType();
|
||||||
|
if (type is null)
|
||||||
|
{
|
||||||
|
goToBookmark(bookmark);
|
||||||
|
node.assignExpression = parseAssignExpression();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node.type = type;
|
||||||
|
end:
|
||||||
expect(TokenType.rBracket);
|
expect(TokenType.rBracket);
|
||||||
return node;
|
return node;
|
||||||
case TokenType.delegate_:
|
case delegate_:
|
||||||
case TokenType.function_:
|
case function_:
|
||||||
advance();
|
advance();
|
||||||
node.parameters = parseParameters();
|
node.parameters = parseParameters();
|
||||||
while (currentIsMemberFunctionAttribute())
|
while (currentIsMemberFunctionAttribute())
|
||||||
|
@ -4928,6 +4986,23 @@ q{(int a, ...)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a Vector
|
||||||
|
*
|
||||||
|
* $(GRAMMAR $(RULEDEF vector):
|
||||||
|
* $(LITERAL '__vector') $(LITERAL '$(LPAREN)') $(RULE type) $(LITERAL '$(RPAREN)')
|
||||||
|
* ;)
|
||||||
|
*/
|
||||||
|
Vector parseVector()
|
||||||
|
{
|
||||||
|
auto node = new Vector;
|
||||||
|
expect(TokenType.vector);
|
||||||
|
expect(TokenType.lParen);
|
||||||
|
node.type = parseType();
|
||||||
|
expect(TokenType.rParen);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a VersionCondition
|
* Parses a VersionCondition
|
||||||
*
|
*
|
||||||
|
@ -5027,7 +5102,74 @@ q{(int a, ...)
|
||||||
TokenType.xor)();
|
TokenType.xor)();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool currentIsMemberFunctionAttribute() const
|
private:
|
||||||
|
|
||||||
|
bool isAssociativeArrayLiteral()
|
||||||
|
{
|
||||||
|
auto i = index;
|
||||||
|
scope(exit) index = i;
|
||||||
|
if (!currentIs(TokenType.lBracket))
|
||||||
|
return false;
|
||||||
|
advance();
|
||||||
|
while (moreTokens()) with (TokenType) switch (current().type)
|
||||||
|
{
|
||||||
|
case lBrace: skipBraceContent(); break;
|
||||||
|
case lParen: skipParenContent(); break;
|
||||||
|
case lBracket: skipBracketContent(); break;
|
||||||
|
case rBracket: return false;
|
||||||
|
case colon: return true;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isStatement() const
|
||||||
|
{
|
||||||
|
// TODO: Not complete
|
||||||
|
with (TokenType) switch (current().type)
|
||||||
|
{
|
||||||
|
case lBrace:
|
||||||
|
case if_:
|
||||||
|
case while_:
|
||||||
|
case do_:
|
||||||
|
case for_:
|
||||||
|
case foreach_:
|
||||||
|
case foreach_reverse_:
|
||||||
|
case switch_:
|
||||||
|
case continue_:
|
||||||
|
case break_:
|
||||||
|
case return_:
|
||||||
|
case goto_:
|
||||||
|
case with_:
|
||||||
|
case try_:
|
||||||
|
case throw_:
|
||||||
|
case asm_:
|
||||||
|
case default_:
|
||||||
|
case case_:
|
||||||
|
case new_:
|
||||||
|
mixin (SPECIAL_CASE_RANGE);
|
||||||
|
mixin (LITERAL_CASE_RANGE);
|
||||||
|
case true_:
|
||||||
|
case false_:
|
||||||
|
return true;
|
||||||
|
case extern_:
|
||||||
|
case union_:
|
||||||
|
case class_:
|
||||||
|
case interface_:
|
||||||
|
case function_:
|
||||||
|
case delegate_:
|
||||||
|
case typedef_:
|
||||||
|
case typeof_:
|
||||||
|
case invariant_:
|
||||||
|
case alias_:
|
||||||
|
mixin (BASIC_TYPE_CASE_RANGE);
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool currentIsMemberFunctionAttribute() const
|
||||||
{
|
{
|
||||||
switch (current.type)
|
switch (current.type)
|
||||||
{
|
{
|
||||||
|
@ -5044,7 +5186,7 @@ q{(int a, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Left parseLeftAssocBinaryExpression(alias Left, alias Right, Operators ...)
|
Left parseLeftAssocBinaryExpression(alias Left, alias Right, Operators ...)
|
||||||
(Right r = null)
|
(Right r = null)
|
||||||
{
|
{
|
||||||
auto node = new Left;
|
auto node = new Left;
|
||||||
|
@ -5063,7 +5205,7 @@ q{(int a, ...)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListType parseCommaSeparatedRule(alias ListType, alias ItemType)()
|
ListType parseCommaSeparatedRule(alias ListType, alias ItemType)()
|
||||||
{
|
{
|
||||||
auto node = new ListType;
|
auto node = new ListType;
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -5081,12 +5223,15 @@ q{(int a, ...)
|
||||||
{
|
{
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
++errorCount;
|
++errorCount;
|
||||||
if (errorFunction is null)
|
if (!suppressMessages)
|
||||||
stderr.writefln("%s(%d:%d): %s", fileName, tokens[index].line,
|
{
|
||||||
tokens[index].column, message);
|
if (errorFunction is null)
|
||||||
else
|
stderr.writefln("%s(%d:%d): %s", fileName, tokens[index].line,
|
||||||
errorFunction(fileName, tokens[index].line, tokens[index].column,
|
tokens[index].column, message);
|
||||||
message);
|
else
|
||||||
|
errorFunction(fileName, tokens[index].line, tokens[index].column,
|
||||||
|
message);
|
||||||
|
}
|
||||||
while (moreTokens())
|
while (moreTokens())
|
||||||
{
|
{
|
||||||
if (currentIsOneOf(TokenType.semicolon, TokenType.rBrace))
|
if (currentIsOneOf(TokenType.semicolon, TokenType.rBrace))
|
||||||
|
@ -5257,6 +5402,18 @@ q{(int a, ...)
|
||||||
return index + 1 < tokens.length;
|
return index + 1 < tokens.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t setBookmark()
|
||||||
|
{
|
||||||
|
suppressMessages = true;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToBookmark(size_t i)
|
||||||
|
{
|
||||||
|
suppressMessages = false;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
|
||||||
version (unittest) static void doNothingErrorFunction(string fileName,
|
version (unittest) static void doNothingErrorFunction(string fileName,
|
||||||
int line, int column, string message) {}
|
int line, int column, string message) {}
|
||||||
|
|
||||||
|
@ -5277,4 +5434,8 @@ q{(int a, ...)
|
||||||
size_t index;
|
size_t index;
|
||||||
string fileName;
|
string fileName;
|
||||||
void function(string, int, int, string) errorFunction;
|
void function(string, int, int, string) errorFunction;
|
||||||
|
immutable string BASIC_TYPE_CASE_RANGE = q{case bool_: .. case wchar_:};
|
||||||
|
immutable string LITERAL_CASE_RANGE = q{case doubleLiteral: .. case wstringLiteral:};
|
||||||
|
immutable string SPECIAL_CASE_RANGE = q{case specialDate: .. case specialPrettyFunction:};
|
||||||
|
bool suppressMessages;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ class TestVisitor : ASTVisitor
|
||||||
writeln("class ", classDeclaration.name.value, " on line ", classDeclaration.name.line);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
override void visit(ModuleDeclaration md)
|
override void visit(ModuleDeclaration md)
|
||||||
{
|
{
|
||||||
writeln("module declaration found");
|
writeln("module declaration found");
|
||||||
|
@ -58,7 +63,7 @@ void main(string[] args)
|
||||||
ubyte[] rawSource = f.rawRead(sourceBuffer);
|
ubyte[] rawSource = f.rawRead(sourceBuffer);
|
||||||
LexerConfig config;
|
LexerConfig config;
|
||||||
auto tokens = byToken(rawSource, config).array();
|
auto tokens = byToken(rawSource, config).array();
|
||||||
Module m = parseModule(tokens);
|
Module m = parseModule(tokens, args[1]);
|
||||||
ASTVisitor visitor = new TestVisitor;
|
ASTVisitor visitor = new TestVisitor;
|
||||||
visitor.visit(m);
|
visitor.visit(m);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue