From de30438ed2efb909538f3177cced441b57eb1a5d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Nov 2019 16:15:12 -0500
Subject: stage1 parser code for anon container lit
---
src/parser.cpp | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/src/parser.cpp b/src/parser.cpp
index a1ece3ed10..484e145cfa 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -81,7 +81,7 @@ static AstNode *ast_parse_for_type_expr(ParseContext *pc);
static AstNode *ast_parse_while_type_expr(ParseContext *pc);
static AstNode *ast_parse_switch_expr(ParseContext *pc);
static AstNode *ast_parse_asm_expr(ParseContext *pc);
-static AstNode *ast_parse_enum_lit(ParseContext *pc);
+static AstNode *ast_parse_anon_lit(ParseContext *pc);
static AstNode *ast_parse_asm_output(ParseContext *pc);
static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);
static AstNode *ast_parse_asm_input(ParseContext *pc);
@@ -1600,9 +1600,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
if (container_decl != nullptr)
return container_decl;
- AstNode *enum_lit = ast_parse_enum_lit(pc);
- if (enum_lit != nullptr)
- return enum_lit;
+ AstNode *anon_lit = ast_parse_anon_lit(pc);
+ if (anon_lit != nullptr)
+ return anon_lit;
AstNode *error_set_decl = ast_parse_error_set_decl(pc);
if (error_set_decl != nullptr)
@@ -1876,16 +1876,22 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {
return res;
}
-static AstNode *ast_parse_enum_lit(ParseContext *pc) {
+static AstNode *ast_parse_anon_lit(ParseContext *pc) {
Token *period = eat_token_if(pc, TokenIdDot);
if (period == nullptr)
return nullptr;
- Token *identifier = expect_token(pc, TokenIdSymbol);
- AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);
- res->data.enum_literal.period = period;
- res->data.enum_literal.identifier = identifier;
- return res;
+ // anon enum literal
+ Token *identifier = eat_token_if(pc, TokenIdSymbol);
+ if (identifier != nullptr) {
+ AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);
+ res->data.enum_literal.period = period;
+ res->data.enum_literal.identifier = identifier;
+ return res;
+ }
+
+ // anon container literal
+ return ast_parse_init_list(pc);
}
// AsmOutput <- COLON AsmOutputList AsmInput?
--
cgit v1.2.3
From e509d21f39af726da3c6001b0c20f2c765be07a5 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Fri, 15 Nov 2019 14:12:14 +0200
Subject: implemented container doc comments in stage 1
---
src/all_types.hpp | 1 +
src/parser.cpp | 23 ++++++++++++++++++++++-
src/tokenizer.cpp | 32 ++++++++++++++++++++++++++++++++
src/tokenizer.hpp | 1 +
4 files changed, 56 insertions(+), 1 deletion(-)
(limited to 'src/parser.cpp')
diff --git a/src/all_types.hpp b/src/all_types.hpp
index a1e9d76be7..c4178cb130 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -968,6 +968,7 @@ struct AstNodeContainerDecl {
AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
ZigList fields;
ZigList decls;
+ Buf doc_comments;
ContainerKind kind;
ContainerLayout layout;
diff --git a/src/parser.cpp b/src/parser.cpp
index 484e145cfa..eef832e32c 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -493,6 +493,7 @@ static AstNode *ast_parse_root(ParseContext *pc) {
node->data.container_decl.layout = ContainerLayoutAuto;
node->data.container_decl.kind = ContainerKindStruct;
node->data.container_decl.is_root = true;
+ node->data.container_decl.doc_comments = members.doc_comments;
return node;
}
@@ -514,6 +515,21 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
return first_doc_token;
}
+static void ast_parse_container_doc_comments(ParseContext *pc, Buf *buf) {
+ if (buf_len(buf) != 0 && peek_token(pc)->id == TokenIdContainerDocComment) {
+ buf_append_char(buf, '\n');
+ }
+ Token *doc_token = nullptr;
+ while ((doc_token = eat_token_if(pc, TokenIdContainerDocComment))) {
+ if (buf->list.length == 0) {
+ buf_resize(buf, 0);
+ }
+ // chops off '//!' but leaves '\n'
+ buf_append_mem(buf, buf_ptr(pc->buf) + doc_token->start_pos + 3,
+ doc_token->end_pos - doc_token->start_pos - 3);
+ }
+}
+
// ContainerMembers
// <- TestDecl ContainerMembers
// / TopLevelComptime ContainerMembers
@@ -523,7 +539,11 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
// /
static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
AstNodeContainerDecl res = {};
+ Buf tld_doc_comment_buf = BUF_INIT;
+ buf_resize(&tld_doc_comment_buf, 0);
for (;;) {
+ ast_parse_container_doc_comments(pc, &tld_doc_comment_buf);
+
AstNode *test_decl = ast_parse_test_decl(pc);
if (test_decl != nullptr) {
res.decls.append(test_decl);
@@ -566,7 +586,7 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
break;
}
-
+ res.doc_comments = tld_doc_comment_buf;
return res;
}
@@ -2797,6 +2817,7 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
res->data.container_decl.fields = members.fields;
res->data.container_decl.decls = members.decls;
+ res->data.container_decl.doc_comments = members.doc_comments;
return res;
}
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 8b301f85ac..7ece5ff3fe 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -198,6 +198,7 @@ enum TokenizeState {
TokenizeStateSawSlash,
TokenizeStateSawSlash2,
TokenizeStateSawSlash3,
+ TokenizeStateSawSlashBang,
TokenizeStateSawBackslash,
TokenizeStateSawPercent,
TokenizeStateSawPlus,
@@ -209,6 +210,7 @@ enum TokenizeState {
TokenizeStateSawBar,
TokenizeStateSawBarBar,
TokenizeStateDocComment,
+ TokenizeStateContainerDocComment,
TokenizeStateLineComment,
TokenizeStateLineString,
TokenizeStateLineStringEnd,
@@ -938,6 +940,9 @@ void tokenize(Buf *buf, Tokenization *out) {
case '/':
t.state = TokenizeStateSawSlash3;
break;
+ case '!':
+ t.state = TokenizeStateSawSlashBang;
+ break;
case '\n':
cancel_token(&t);
t.state = TokenizeStateStart;
@@ -965,6 +970,19 @@ void tokenize(Buf *buf, Tokenization *out) {
break;
}
break;
+ case TokenizeStateSawSlashBang:
+ switch (c) {
+ case '\n':
+ set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
+ end_token(&t);
+ t.state = TokenizeStateStart;
+ break;
+ default:
+ set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
+ t.state = TokenizeStateContainerDocComment;
+ break;
+ }
+ break;
case TokenizeStateSawBackslash:
switch (c) {
case '\\':
@@ -1055,6 +1073,17 @@ void tokenize(Buf *buf, Tokenization *out) {
break;
}
break;
+ case TokenizeStateContainerDocComment:
+ switch (c) {
+ case '\n':
+ end_token(&t);
+ t.state = TokenizeStateStart;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ break;
case TokenizeStateSymbolFirstC:
switch (c) {
case '"':
@@ -1545,6 +1574,7 @@ void tokenize(Buf *buf, Tokenization *out) {
case TokenizeStateSawBarBar:
case TokenizeStateLBracket:
case TokenizeStateDocComment:
+ case TokenizeStateContainerDocComment:
end_token(&t);
break;
case TokenizeStateSawDotDot:
@@ -1559,6 +1589,7 @@ void tokenize(Buf *buf, Tokenization *out) {
case TokenizeStateLineComment:
case TokenizeStateSawSlash2:
case TokenizeStateSawSlash3:
+ case TokenizeStateSawSlashBang:
break;
}
if (t.state != TokenizeStateError) {
@@ -1606,6 +1637,7 @@ const char * token_name(TokenId id) {
case TokenIdDash: return "-";
case TokenIdDivEq: return "/=";
case TokenIdDocComment: return "DocComment";
+ case TokenIdContainerDocComment: return "ContainerDocComment";
case TokenIdDot: return ".";
case TokenIdDotStar: return ".*";
case TokenIdEllipsis2: return "..";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index ee336123bb..149e58b6a7 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -43,6 +43,7 @@ enum TokenId {
TokenIdDash,
TokenIdDivEq,
TokenIdDocComment,
+ TokenIdContainerDocComment,
TokenIdDot,
TokenIdDotStar,
TokenIdEllipsis2,
--
cgit v1.2.3
From 977b6138817c4b09d6d1e47fa3562d9f9e0268a8 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Fri, 15 Nov 2019 15:03:28 +0200
Subject: add container doc comments to generated docs
---
lib/std/special/docs/index.html | 2 +-
lib/std/special/docs/main.js | 31 +++++++++++++++++++------------
lib/std/zig/ast.zig | 1 -
src/dump_analysis.cpp | 1 +
src/parser.cpp | 8 ++++++--
5 files changed, 27 insertions(+), 16 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/lib/std/special/docs/index.html b/lib/std/special/docs/index.html
index 81df8f30f1..b170ad4a14 100644
--- a/lib/std/special/docs/index.html
+++ b/lib/std/special/docs/index.html
@@ -484,7 +484,7 @@
doc comments.
-
+
Errors
diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js
index e0d6cdaf05..1812671227 100644
--- a/lib/std/special/docs/main.js
+++ b/lib/std/special/docs/main.js
@@ -20,7 +20,7 @@
var domListValues = document.getElementById("listValues");
var domFnProto = document.getElementById("fnProto");
var domFnProtoCode = document.getElementById("fnProtoCode");
- var domFnDocs = document.getElementById("fnDocs");
+ var domTldDocs = document.getElementById("tldDocs");
var domSectFnErrors = document.getElementById("sectFnErrors");
var domListFnErrors = document.getElementById("listFnErrors");
var domTableFnErrors = document.getElementById("tableFnErrors");
@@ -34,7 +34,6 @@
var domListSearchResults = document.getElementById("listSearchResults");
var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
var domSectInfo = document.getElementById("sectInfo");
- var domListInfo = document.getElementById("listInfo");
var domTdTarget = document.getElementById("tdTarget");
var domTdZigVer = document.getElementById("tdZigVer");
var domHdrName = document.getElementById("hdrName");
@@ -102,7 +101,7 @@
function render() {
domStatus.classList.add("hidden");
domFnProto.classList.add("hidden");
- domFnDocs.classList.add("hidden");
+ domTldDocs.classList.add("hidden");
domSectPkgs.classList.add("hidden");
domSectTypes.classList.add("hidden");
domSectNamespaces.classList.add("hidden");
@@ -190,11 +189,11 @@
var docs = zigAnalysis.astNodes[decl.src].docs;
if (docs != null) {
- domFnDocs.innerHTML = markdown(docs);
+ domTldDocs.innerHTML = markdown(docs);
} else {
- domFnDocs.innerHTML = '
There are no doc comments for this declaration.
';
+ domTldDocs.innerHTML = '
There are no doc comments for this declaration.
';
}
- domFnDocs.classList.remove("hidden");
+ domTldDocs.classList.remove("hidden");
}
function typeIsErrSet(typeIndex) {
@@ -274,8 +273,8 @@
docsSource = protoSrcNode.docs;
}
if (docsSource != null) {
- domFnDocs.innerHTML = markdown(docsSource);
- domFnDocs.classList.remove("hidden");
+ domTldDocs.innerHTML = markdown(docsSource);
+ domTldDocs.classList.remove("hidden");
}
domFnProto.classList.remove("hidden");
}
@@ -893,8 +892,8 @@
var docs = zigAnalysis.astNodes[decl.src].docs;
if (docs != null) {
- domFnDocs.innerHTML = markdown(docs);
- domFnDocs.classList.remove("hidden");
+ domTldDocs.innerHTML = markdown(docs);
+ domTldDocs.classList.remove("hidden");
}
domFnProto.classList.remove("hidden");
@@ -906,8 +905,8 @@
var docs = zigAnalysis.astNodes[decl.src].docs;
if (docs != null) {
- domFnDocs.innerHTML = markdown(docs);
- domFnDocs.classList.remove("hidden");
+ domTldDocs.innerHTML = markdown(docs);
+ domTldDocs.classList.remove("hidden");
}
domFnProto.classList.remove("hidden");
@@ -957,6 +956,14 @@
varsList.sort(byNameProperty);
valsList.sort(byNameProperty);
+ if (container.src != null) {
+ var docs = zigAnalysis.astNodes[container.src].docs;
+ if (docs != null) {
+ domTldDocs.innerHTML = markdown(docs);
+ domTldDocs.classList.remove("hidden");
+ }
+ }
+
if (typesList.length !== 0) {
resizeDomList(domListTypes, typesList.length, '
');
for (var i = 0; i < typesList.length; i += 1) {
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 65fbc51606..0a7bfe2f56 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -2253,7 +2253,6 @@ pub const Node = struct {
test "iterate" {
var root = Node.Root{
.base = Node{ .id = Node.Id.Root },
- .doc_comments = null,
.decls = Node.Root.DeclList.init(std.debug.global_allocator),
.eof_token = 0,
};
diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp
index b5fd38e266..98bbcc6a42 100644
--- a/src/dump_analysis.cpp
+++ b/src/dump_analysis.cpp
@@ -1088,6 +1088,7 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
break;
case NodeTypeContainerDecl:
field_nodes = &node->data.container_decl.fields;
+ doc_comments_buf = &node->data.container_decl.doc_comments;
break;
default:
break;
diff --git a/src/parser.cpp b/src/parser.cpp
index eef832e32c..04dccb0d2a 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -493,7 +493,9 @@ static AstNode *ast_parse_root(ParseContext *pc) {
node->data.container_decl.layout = ContainerLayoutAuto;
node->data.container_decl.kind = ContainerKindStruct;
node->data.container_decl.is_root = true;
- node->data.container_decl.doc_comments = members.doc_comments;
+ if (buf_len(&members.doc_comments) != 0) {
+ node->data.container_decl.doc_comments = members.doc_comments;
+ }
return node;
}
@@ -2817,7 +2819,9 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
res->data.container_decl.fields = members.fields;
res->data.container_decl.decls = members.decls;
- res->data.container_decl.doc_comments = members.doc_comments;
+ if (buf_len(&members.doc_comments) != 0) {
+ res->data.container_decl.doc_comments = members.doc_comments;
+ }
return res;
}
--
cgit v1.2.3
From 6cddf9d7238a58b88064c3f3ce6e3948143598d8 Mon Sep 17 00:00:00 2001
From: Vexu <15308111+Vexu@users.noreply.github.com>
Date: Sun, 17 Nov 2019 17:07:48 +0200
Subject: properly parse anon literal in array
---
lib/std/zig/parse.zig | 6 +++++-
lib/std/zig/parser_test.zig | 10 ++++++++++
src/parser.cpp | 7 ++++++-
test/stage1/behavior/array.zig | 21 +++++++++++++++++++++
4 files changed, 42 insertions(+), 2 deletions(-)
(limited to 'src/parser.cpp')
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 6d5d4b5f2d..3ad82824ce 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -1630,7 +1630,11 @@ fn parseBlockLabel(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?TokenInd
/// FieldInit <- DOT IDENTIFIER EQUAL Expr
fn parseFieldInit(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const period_token = eatToken(it, .Period) orelse return null;
- const name_token = try expectToken(it, tree, .Identifier);
+ const name_token = eatToken(it, .Identifier) orelse {
+ // Because of anon literals `.{` is also valid.
+ putBackToken(it, period_token);
+ return null;
+ };
const eq_token = eatToken(it, .Equal) orelse {
// `.Name` may also be an enum literal, which is a later rule.
putBackToken(it, name_token);
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index cabbe823f6..6e5ef878d5 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1,3 +1,13 @@
+test "zig fmt: anon literal in array" {
+ try testCanonical(
+ \\var arr: [2]Foo = .{
+ \\ .{ .a = 2 },
+ \\ .{ .b = 3 },
+ \\};
+ \\
+ );
+}
+
test "zig fmt: anon struct literal syntax" {
try testCanonical(
\\const x = .{
diff --git a/src/parser.cpp b/src/parser.cpp
index 484e145cfa..65894bb833 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -2025,7 +2025,12 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {
if (first == nullptr)
return nullptr;
- Token *name = expect_token(pc, TokenIdSymbol);
+ Token *name = eat_token_if(pc, TokenIdSymbol);
+ if (name == nullptr) {
+ // Because of anon literals ".{" is also valid.
+ put_back_token(pc);
+ return nullptr;
+ }
if (eat_token_if(pc, TokenIdEq) == nullptr) {
// Because ".Name" can also be intepreted as an enum literal, we should put back
// those two tokens again so that the parser can try to parse them as the enum
diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig
index 0558a47fa4..3a9c9a7655 100644
--- a/test/stage1/behavior/array.zig
+++ b/test/stage1/behavior/array.zig
@@ -312,3 +312,24 @@ test "anonymous list literal syntax" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "anonymous literal in array" {
+ const S = struct {
+ const Foo = struct {
+ a: usize = 2,
+ b: usize = 4,
+ };
+ fn doTheTest() void {
+ var array: [2]Foo = .{
+ .{.a = 3},
+ .{.b = 3},
+ };
+ expect(array[0].a == 3);
+ expect(array[0].b == 4);
+ expect(array[1].a == 2);
+ expect(array[1].b == 3);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
--
cgit v1.2.3