authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-07 19:05:46+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-07 19:05:46+02:00
log4184d4c66a26ba10fbc78cc21f2c73db8f0cfcb2
treece96a5cbe63f8bd86ab1cfeb3892e1fea44005d0
parentdf12c1328eb9c2af006dfd9e5cf69046ad6fc235
signature Commit is signed but in an unrecognized format.

std-c parser record and enum specifiers


2 files changed, 151 insertions(+), 31 deletions(-)

lib/std/c/ast.zig+36-16
......@@ -48,9 +48,12 @@ pub const Error = union(enum) {
4848 ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),
4949 ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"),
5050 ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"),
51 ExpectedEnumField: SingleTokenError("expected enum field, found '{}'"),
52 ExpectedType: SingleTokenError("expected enum field, found '{}'"),
5153 InvalidTypeSpecifier: InvalidTypeSpecifier,
5254 DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
5355 DuplicateSpecifier: SingleTokenError("duplicate declaration specifier '{}'"),
56 MustUseKwToRefer: MustUseKwToRefer,
5457
5558 pub fn render(self: *const Error, tree: *Tree, stream: var) !void {
5659 switch (self.*) {
......@@ -62,9 +65,12 @@ pub const Error = union(enum) {
6265 .ExpectedDeclarator => |*x| return x.render(tree, stream),
6366 .ExpectedFnBody => |*x| return x.render(tree, stream),
6467 .ExpectedInitializer => |*x| return x.render(tree, stream),
68 .ExpectedEnumField => |*x| return x.render(tree, stream),
69 .ExpectedType => |*x| return x.render(tree, stream),
6570 .InvalidTypeSpecifier => |*x| return x.render(tree, stream),
6671 .DuplicateQualifier => |*x| return x.render(tree, stream),
6772 .DuplicateSpecifier => |*x| return x.render(tree, stream),
73 .MustUseKwToRefer => |*x| return x.render(tree, stream),
6874 }
6975 }
7076
......@@ -78,9 +84,12 @@ pub const Error = union(enum) {
7884 .ExpectedDeclarator => |x| return x.token,
7985 .ExpectedFnBody => |x| return x.token,
8086 .ExpectedInitializer => |x| return x.token,
87 .ExpectedEnumField => |x| return x.token,
88 .ExpectedType => |*x| return x.token,
8189 .InvalidTypeSpecifier => |x| return x.token,
8290 .DuplicateQualifier => |x| return x.token,
8391 .DuplicateSpecifier => |x| return x.token,
92 .MustUseKwToRefer => |*x| return x.name,
8493 }
8594 }
8695
......@@ -111,6 +120,15 @@ pub const Error = union(enum) {
111120 }
112121 };
113122
123 pub const MustUseKwToRefer = struct {
124 kw: TokenIndex,
125 name: TokenIndex,
126
127 pub fn render(self: *const ExpectedToken, tree: *Tree, stream: var) !void {
128 return stream.print("must use '{}' tag to refer to type '{}'", .{tree.slice(kw), tree.slice(name)});
129 }
130 };
131
114132 fn SingleTokenError(comptime msg: []const u8) type {
115133 return struct {
116134 token: TokenIndex,
......@@ -125,14 +143,13 @@ pub const Error = union(enum) {
125143
126144pub const Type = struct {
127145 pub const TypeList = std.SegmentedList(*Type, 4);
128 @"const": bool,
129 atomic: bool,
130 @"volatile": bool,
131 restrict: bool,
146 @"const": bool = false,
147 atomic: bool = false,
148 @"volatile": bool = false,
149 restrict: bool = false,
132150
133151 id: union(enum) {
134152 Int: struct {
135 quals: Qualifiers,
136153 id: Id,
137154 is_signed: bool,
138155
......@@ -145,7 +162,6 @@ pub const Type = struct {
145162 };
146163 },
147164 Float: struct {
148 quals: Qualifiers,
149165 id: Id,
150166
151167 pub const Id = enum {
......@@ -154,10 +170,7 @@ pub const Type = struct {
154170 LongDouble,
155171 };
156172 },
157 Pointer: struct {
158 quals: Qualifiers,
159 child_type: *Type,
160 },
173 Pointer: *Type,
161174 Function: struct {
162175 return_type: *Type,
163176 param_types: TypeList,
......@@ -173,6 +186,8 @@ pub const Node = struct {
173186
174187 pub const Id = enum {
175188 Root,
189 EnumField,
190 RecordField,
176191 JumpStmt,
177192 ExprStmt,
178193 Label,
......@@ -350,15 +365,16 @@ pub const Node = struct {
350365 };
351366
352367 pub const EnumField = struct {
353 base: Node = Node{ .id = EnumField },
368 base: Node = Node{ .id = .EnumField },
354369 name: TokenIndex,
355370 value: ?*Node,
356371 };
357372
358373 pub const RecordType = struct {
359 kind: union(enum) {
360 Struct: TokenIndex,
361 Union: TokenIndex,
374 tok: TokenIndex,
375 kind: enum {
376 Struct,
377 Union,
362378 },
363379 name: ?TokenIndex,
364380 body: ?struct {
......@@ -373,8 +389,12 @@ pub const Node = struct {
373389 };
374390
375391 pub const RecordField = struct {
376 base: Node = Node{ .id = RecordField },
377 // TODO
392 base: Node = Node{ .id = .RecordField },
393 type_spec: TypeSpec,
394 declarators: DeclaratorList,
395 semicolon: TokenIndex,
396
397 pub const DeclaratorList = Root.DeclList;
378398 };
379399
380400 pub const TypeQual = struct {
lib/std/c/parse.zig+115-15
......@@ -94,12 +94,11 @@ const Parser = struct {
9494 }
9595
9696 fn getSymbol(parser: *Parser, tok: TokenIndex) ?*Type {
97 const token = parser.it.list.at(tok);
98 const name = parser.tree.slice(token);
97 const name = parser.tree.slice(tok);
9998 const syms = parser.symbols.toSliceConst();
10099 var i = syms.len;
101100 while (i > 0) : (i -= 1) {
102 if (mem.eql(u8, name, syms[i].name)) {
101 if (std.mem.eql(u8, name, syms[i].name)) {
103102 return syms[i].ty;
104103 }
105104 }
......@@ -492,31 +491,29 @@ const Parser = struct {
492491 } else if (parser.eatToken(.Keyword_enum)) |tok| {
493492 if (type_spec.spec != .None)
494493 break :blk;
495 type_spec.Enum = try parser.enumSpec(tok);
494 type_spec.spec.Enum = try parser.enumSpec(tok);
496495 return true;
497496 } else if (parser.eatToken(.Keyword_union) orelse parser.eatToken(.Keyword_struct)) |tok| {
498497 if (type_spec.spec != .None)
499498 break :blk;
500 type_spec.Record = try parser.recordSpec();
499 type_spec.spec.Record = try parser.recordSpec(tok);
501500 return true;
502501 } else if (parser.eatToken(.Identifier)) |tok| {
503502 const ty = parser.getSymbol(tok) orelse {
504503 parser.putBackToken(tok);
505504 return false;
506505 };
507 switch (ty) {
506 switch (ty.id) {
508507 .Enum => |e| {
509508 return parser.err(.{
510 .MustUseKwToRefer = .{ .kw = e.identifier, .sym = tok },
509 .MustUseKwToRefer = .{ .kw = e.tok, .name = tok },
511510 });
512511 },
513512 .Record => |r| {
514513 return parser.err(.{
515514 .MustUseKwToRefer = .{
516 .kw = switch (r.kind) {
517 .Struct, .Union => |kw| kw,
518 },
519 .sym = tok,
515 .kw = r.tok,
516 .name = tok,
520517 },
521518 });
522519 },
......@@ -613,18 +610,121 @@ const Parser = struct {
613610 }
614611
615612 /// EnumSpec <- Keyword_enum IDENTIFIER? (LBRACE EnumField RBRACE)?
616 fn enumSpecifier(parser: *Parser) !*Node {}
613 fn enumSpec(parser: *Parser, tok: TokenIndex) !*Node.EnumType {
614 const node = try parser.arena.create(Node.EnumType);
615 const name = parser.eatToken(.Identifier);
616 node.* = .{
617 .tok = tok,
618 .name = name,
619 .body = null,
620 };
621 const ty = try parser.arena.create(Type);
622 ty.* = .{
623 .id = .{
624 .Enum = node,
625 },
626 };
627 if (name) |some|
628 try parser.symbols.append(.{
629 .name = parser.tree.slice(some),
630 .ty = ty,
631 });
632 if (parser.eatToken(.LBrace)) |lbrace| {
633 var fields = Node.EnumType.FieldList.init(parser.arena);
634 try fields.push((try parser.enumField()) orelse return parser.err(.{
635 .ExpectedEnumField = .{ .token = parser.it.index },
636 }));
637 while (parser.eatToken(.Comma)) |_| {
638 try fields.push((try parser.enumField()) orelse break);
639 }
640 node.body = .{
641 .lbrace = lbrace,
642 .fields = fields,
643 .rbrace = try parser.expectToken(.RBrace),
644 };
645 }
646 return node;
647 }
617648
618649 /// EnumField <- IDENTIFIER (EQUAL ConstExpr)? (COMMA EnumField) COMMA?
619 fn enumField(parser: *Parser) !*Node {}
650 fn enumField(parser: *Parser) !?*Node {
651 const name = parser.eatToken(.Identifier) orelse return null;
652 const node = try parser.arena.create(Node.EnumField);
653 node.* = .{
654 .name = name,
655 .value = null,
656 };
657 if (parser.eatToken(.Equal)) |eq| {
658 node.value = try parser.constExpr();
659 }
660 return &node.base;
661 }
620662
621663 /// RecordSpec <- (Keyword_struct / Keyword_union) IDENTIFIER? (LBRACE RecordField+ RBRACE)?
622 fn recordSpecifier(parser: *Parser) !*Node {}
664 fn recordSpec(parser: *Parser, tok: TokenIndex) !*Node.RecordType {
665 const node = try parser.arena.create(Node.RecordType);
666 const name = parser.eatToken(.Identifier);
667 const is_struct = parser.tree.slice(tok)[0] == 's';
668 node.* = .{
669 .tok = tok,
670 .kind = if (is_struct) .Struct else .Union,
671 .name = name,
672 .body = null,
673 };
674 const ty = try parser.arena.create(Type);
675 ty.* = .{
676 .id = .{
677 .Record = node,
678 },
679 };
680 if (name) |some|
681 try parser.symbols.append(.{
682 .name = parser.tree.slice(some),
683 .ty = ty,
684 });
685 if (parser.eatToken(.LBrace)) |lbrace| {
686 var fields = Node.RecordType.FieldList.init(parser.arena);
687 while (true) {
688 if (parser.eatToken(.RBrace)) |rbrace| {
689 node.body = .{
690 .lbrace = lbrace,
691 .fields = fields,
692 .rbrace = rbrace,
693 };
694 break;
695 }
696 try fields.push(try parser.recordField());
697 }
698 }
699 return node;
700 }
623701
624702 /// RecordField
625703 /// <- TypeSpec* (RecordDeclarator (COMMA RecordDeclarator))? SEMICOLON
626704 /// \ StaticAssert
627 fn recordField(parser: *Parser) !*Node {}
705 fn recordField(parser: *Parser) Error!*Node {
706 if (try parser.staticAssert()) |decl| return decl;
707 var got = false;
708 var type_spec = Node.TypeSpec{};
709 while (try parser.typeSpec(&type_spec)) got = true;
710 if (!got)
711 return parser.err(.{
712 .ExpectedType = .{ .token = parser.it.index },
713 });
714 const node = try parser.arena.create(Node.RecordField);
715 node.* = .{
716 .type_spec = type_spec,
717 .declarators = Node.RecordField.DeclaratorList.init(parser.arena),
718 .semicolon = undefined,
719 };
720 while (true) {
721 try node.declarators.push(try parser.recordDeclarator());
722 if (parser.eatToken(.Comma)) |_| {} else break;
723 }
724
725 node.semicolon = try parser.expectToken(.Semicolon);
726 return &node.base;
727 }
628728
629729 /// TypeName <- TypeSpec* AbstractDeclarator?
630730 fn typeName(parser: *Parser) !*Node {