From ad8f00687b144e9cccffb62ff031a767c01dce97 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 6 Mar 2014 09:12:20 +1100 Subject: [PATCH 1/7] Fix windows build script --- build.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.bat b/build.bat index 7802267..2cd4266 100644 --- a/build.bat +++ b/build.bat @@ -1 +1 @@ -dmd main.d stats.d imports.d highlighter.d ctags.d astprinter.d formatter.d outliner.d stdx/allocator.d stdx/lexer.d stdx/d/ast.d stdx/d/parser.d stdx/d/lexer.d analysis/.d analysis/base.d analysis/del.d analysis/enumarrayliteral.d analysis/fish.d analysis/numbers.d analysis/objectconst.d analysis/package.d analysis/pokemon.d analysis/range.d analysis/run.d analysis/style.d -ofdscanner.exe -O -release -noboundscheck -inline +dmd main.d stats.d imports.d highlighter.d ctags.d astprinter.d formatter.d outliner.d stdx/allocator.d stdx/lexer.d stdx/d/ast.d stdx/d/parser.d stdx/d/lexer.d analysis/base.d analysis/del.d analysis/enumarrayliteral.d analysis/fish.d analysis/numbers.d analysis/objectconst.d analysis/package.d analysis/pokemon.d analysis/range.d analysis/run.d analysis/style.d -ofdscanner.exe -O -release -noboundscheck -inline From b8093ec26946ca75abcc444bd26bd62a37dd4433 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 6 Mar 2014 09:47:30 +1100 Subject: [PATCH 2/7] Lex \x escape sequence --- stdx/d/lexer.d | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/stdx/d/lexer.d b/stdx/d/lexer.d index 31b15d7..fa3a638 100644 --- a/stdx/d/lexer.d +++ b/stdx/d/lexer.d @@ -1252,8 +1252,26 @@ public struct DLexer range.popFront(); break; case 'x': - // TODO range.popFront(); + foreach (i; 0 .. 2) + { + if (range.empty) + { + error("Error: 2 hex digits expected."); + return false; + } + switch (range.front) + { + case '0': .. case '9': + case 'a': .. case 'f': + case 'A': .. case 'F': + range.popFront(); + break; + default: + error("Error: 2 hex digits expected."); + return false; + } + } break; case '1': .. case '7': for (size_t i = 0; i < 3 && !range.empty && range.front >= '0' && range.front <= '7'; i++) @@ -1506,3 +1524,24 @@ unittest assert (tokens.map!"a.type"().equal([tok!"import", tok!"identifier", tok!".", tok!"identifier", tok!";"])); } + +/// Test \x char sequence +unittest +{ + auto toks = (string s) => byToken(cast(ubyte[])s); + + // valid + enum hex = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']; + auto source = ""; + foreach(h1; hex) + foreach(h2; hex) + source ~= "'\\x" ~ h1 ~ h2 ~ "'"; + assert(toks(source).filter!(t => t.type != tok!"characterLiteral").empty); + + // invalid + assert(toks(`'\x'`).messages[0] == DLexer.Message(1,4,"Error: 2 hex digits expected.",true)); + assert(toks(`'\x_'`).messages[0] == DLexer.Message(1,4,"Error: 2 hex digits expected.",true)); + assert(toks(`'\xA'`).messages[0] == DLexer.Message(1,5,"Error: 2 hex digits expected.",true)); + assert(toks(`'\xAY'`).messages[0] == DLexer.Message(1,5,"Error: 2 hex digits expected.",true)); + assert(toks(`'\xXX'`).messages[0] == DLexer.Message(1,4,"Error: 2 hex digits expected.",true)); +} From db71af8ddb5e39e2f11010354e6671c755844ad3 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 6 Mar 2014 10:29:29 +1100 Subject: [PATCH 3/7] Allow member func attrs after postblit --- stdx/d/ast.d | 1 + stdx/d/parser.d | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/stdx/d/ast.d b/stdx/d/ast.d index 636b516..03c1a82 100644 --- a/stdx/d/ast.d +++ b/stdx/d/ast.d @@ -1996,6 +1996,7 @@ public: mixin (visitIfNotNull!(functionBody)); } /** */ FunctionBody functionBody; + /** */ MemberFunctionAttribute[] memberFunctionAttributes; } /// diff --git a/stdx/d/parser.d b/stdx/d/parser.d index a95ec5a..0e384fc 100644 --- a/stdx/d/parser.d +++ b/stdx/d/parser.d @@ -4134,7 +4134,7 @@ q{(int a, ...) * Parses a Postblit * * $(GRAMMAR $(RULEDEF postblit): - * $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL 'this') $(LITERAL '$(RPAREN)') ($(RULE functionBody) | $(LITERAL ';')) + * $(LITERAL 'this') $(LITERAL '$(LPAREN)') $(LITERAL 'this') $(LITERAL '$(RPAREN)') $(RULE memberFunctionAttribute)* ($(RULE functionBody) | $(LITERAL ';')) * ;) */ Postblit parsePostblit() @@ -4144,6 +4144,8 @@ q{(int a, ...) expect(tok!"("); expect(tok!"this"); expect(tok!")"); + while (currentIsMemberFunctionAttribute()) + node.memberFunctionAttributes ~= parseMemberFunctionAttribute(); if (currentIs(tok!";")) advance(); else From 42556e6558cadb43f66e20c01fa31a43a1865789 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 6 Mar 2014 10:45:28 +1100 Subject: [PATCH 4/7] Distinguish between struct initializer and func literal call expression --- stdx/d/parser.d | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/stdx/d/parser.d b/stdx/d/parser.d index a95ec5a..10a0049 100644 --- a/stdx/d/parser.d +++ b/stdx/d/parser.d @@ -3875,7 +3875,13 @@ invariant() foo(); mixin(traceEnterAndExit!(__FUNCTION__)); auto node = allocate!NonVoidInitializer; if (currentIs(tok!"{")) - node.structInitializer = parseStructInitializer(); + { + auto b = peekPastBraces(); + if (b !is null && (b.type == tok!"(")) + node.assignExpression = parseAssignExpression(); + else + node.structInitializer = parseStructInitializer(); + } else if (currentIs(tok!"[")) { auto b = peekPastBrackets(); From 0873c7b6842dc04ac496b89c47c9c60b37dbaac1 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Thu, 6 Mar 2014 14:43:06 +1100 Subject: [PATCH 5/7] Hook manual memory management --- stdx/d/parser.d | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stdx/d/parser.d b/stdx/d/parser.d index 0e384fc..508b8e1 100644 --- a/stdx/d/parser.d +++ b/stdx/d/parser.d @@ -4144,8 +4144,10 @@ q{(int a, ...) expect(tok!"("); expect(tok!"this"); expect(tok!")"); + MemberFunctionAttribute[] memberFunctionAttributes; while (currentIsMemberFunctionAttribute()) - node.memberFunctionAttributes ~= parseMemberFunctionAttribute(); + memberFunctionAttributes ~= parseMemberFunctionAttribute(); + node.memberFunctionAttributes = ownArray(memberFunctionAttributes); if (currentIs(tok!";")) advance(); else From b3685f98497e557403ddfe6db7b84682ee0a5f72 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Fri, 7 Mar 2014 12:07:21 +1100 Subject: [PATCH 6/7] Allow for just identifier in class and interface decl --- stdx/d/parser.d | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/stdx/d/parser.d b/stdx/d/parser.d index 392d9e0..d247a7b 100644 --- a/stdx/d/parser.d +++ b/stdx/d/parser.d @@ -1309,7 +1309,7 @@ incorrect; * Parses a ClassDeclaration * * $(GRAMMAR $(RULEDEF classDeclaration): - * $(LITERAL 'class') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE baseClassList))? $(RULE structBody) + * $(LITERAL 'class') $(LITERAL Identifier) ($(LITERAL ';') | ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE baseClassList))? $(RULE structBody)) * ;) */ ClassDeclaration parseClassDeclaration() @@ -1322,6 +1322,11 @@ incorrect; node.name = *ident; node.comment = comment; comment = null; + if (currentIs(tok!";")) + { + advance(); + return node; + } if (currentIs(tok!"(")) { node.templateParameters = parseTemplateParameters(); @@ -3185,7 +3190,7 @@ import core.stdc.stdio, std.string : KeepTerminator; * Parses an InterfaceDeclaration * * $(GRAMMAR $(RULEDEF interfaceDeclaration): - * $(LITERAL 'interface') $(LITERAL Identifier) ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE baseClassList))? $(RULE structBody) + * $(LITERAL 'interface') $(LITERAL Identifier) ($(LITERAL ';') | ($(RULE templateParameters) $(RULE constraint)?)? ($(LITERAL ':') $(RULE baseClassList))? $(RULE structBody)) * ;) */ InterfaceDeclaration parseInterfaceDeclaration() @@ -3197,6 +3202,11 @@ import core.stdc.stdio, std.string : KeepTerminator; node.name = *ident; node.comment = comment; comment = null; + if (currentIs(tok!";")) + { + advance(); + return node; + } if (currentIs(tok!"(")) { node.templateParameters = parseTemplateParameters(); From 7d95f485544632b79921a0916efa926864444036 Mon Sep 17 00:00:00 2001 From: Callum Anderson Date: Sat, 8 Mar 2014 13:12:59 +1100 Subject: [PATCH 7/7] Attribute declarations can have attributes --- stdx/d/parser.d | 1 + 1 file changed, 1 insertion(+) diff --git a/stdx/d/parser.d b/stdx/d/parser.d index 392d9e0..47e874e 100644 --- a/stdx/d/parser.d +++ b/stdx/d/parser.d @@ -1731,6 +1731,7 @@ class ClassFour(A, B) if (someTest()) : Super {}}c; if (currentIs(tok!":")) { node.attributeDeclaration = parseAttributeDeclaration(attr); + node.attributes = ownArray(attributes); return node; } else