authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-07 20:15:57+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-07 20:15:57+02:00
logdbc045706809e7135fdb55ebd7c4a7383f40bf0f
treee670539427ec6732a32b37f3e004bc9988d3d6bb
parent4184d4c66a26ba10fbc78cc21f2c73db8f0cfcb2
signature Commit is signed but in an unrecognized format.

std-c declaration parsing


2 files changed, 170 insertions(+), 82 deletions(-)

lib/std/c/ast.zig+45-13
......@@ -51,9 +51,14 @@ pub const Error = union(enum) {
5151 ExpectedEnumField: SingleTokenError("expected enum field, found '{}'"),
5252 ExpectedType: SingleTokenError("expected enum field, found '{}'"),
5353 InvalidTypeSpecifier: InvalidTypeSpecifier,
54 InvalidStorageClass: SingleTokenError("invalid storage class, found '{}'"),
55 InvalidDeclarator: SimpleError("invalid declarator"),
5456 DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"),
5557 DuplicateSpecifier: SingleTokenError("duplicate declaration specifier '{}'"),
5658 MustUseKwToRefer: MustUseKwToRefer,
59 FnSpecOnNonFn: SingleTokenError("function specifier '{}' on non function"),
60 NothingDeclared: SimpleError("declaration doesn't declare anything"),
61 QualifierIgnored: SingleTokenError("qualifier '{}' ignored"),
5762
5863 pub fn render(self: *const Error, tree: *Tree, stream: var) !void {
5964 switch (self.*) {
......@@ -68,9 +73,14 @@ pub const Error = union(enum) {
6873 .ExpectedEnumField => |*x| return x.render(tree, stream),
6974 .ExpectedType => |*x| return x.render(tree, stream),
7075 .InvalidTypeSpecifier => |*x| return x.render(tree, stream),
76 .InvalidStorageClass => |*x| return x.render(tree, stream),
77 .InvalidDeclarator => |*x| return x.render(tree, stream),
7178 .DuplicateQualifier => |*x| return x.render(tree, stream),
7279 .DuplicateSpecifier => |*x| return x.render(tree, stream),
7380 .MustUseKwToRefer => |*x| return x.render(tree, stream),
81 .FnSpecOnNonFn => |*x| return x.render(tree, stream),
82 .NothingDeclared => |*x| return x.render(tree, stream),
83 .QualifierIgnored => |*x| return x.render(tree, stream),
7484 }
7585 }
7686
......@@ -87,9 +97,14 @@ pub const Error = union(enum) {
8797 .ExpectedEnumField => |x| return x.token,
8898 .ExpectedType => |*x| return x.token,
8999 .InvalidTypeSpecifier => |x| return x.token,
100 .InvalidStorageClass => |x| return x.token,
101 .InvalidDeclarator => |x| return x.token,
90102 .DuplicateQualifier => |x| return x.token,
91103 .DuplicateSpecifier => |x| return x.token,
92104 .MustUseKwToRefer => |*x| return x.name,
105 .FnSpecOnNonFn => |*x| return x.name,
106 .NothingDeclared => |*x| return x.name,
107 .QualifierIgnored => |*x| return x.name,
93108 }
94109 }
95110
......@@ -125,7 +140,7 @@ pub const Error = union(enum) {
125140 name: TokenIndex,
126141
127142 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)});
143 return stream.print("must use '{}' tag to refer to type '{}'", .{ tree.slice(kw), tree.slice(name) });
129144 }
130145 };
131146
......@@ -139,6 +154,18 @@ pub const Error = union(enum) {
139154 }
140155 };
141156 }
157
158 fn SimpleError(comptime msg: []const u8) type {
159 return struct {
160 const ThisError = @This();
161
162 token: TokenIndex,
163
164 pub fn render(self: *const ThisError, tokens: *Tree.TokenList, stream: var) !void {
165 return stream.write(msg);
166 }
167 };
168 }
142169};
143170
144171pub const Type = struct {
......@@ -194,9 +221,11 @@ pub const Node = struct {
194221 CompoundStmt,
195222 IfStmt,
196223 StaticAssert,
197 Fn,
224 Declarator,
225 Pointer,
226 FnDecl,
198227 Typedef,
199 Var,
228 VarDecl,
200229 };
201230
202231 pub const Root = struct {
......@@ -457,7 +486,7 @@ pub const Node = struct {
457486
458487 pub const Declarator = struct {
459488 base: Node = Node{ .id = .Declarator },
460 pointer: *Pointer,
489 pointer: ?*Pointer,
461490 prefix: union(enum) {
462491 None,
463492 Identifer: TokenIndex,
......@@ -482,7 +511,7 @@ pub const Node = struct {
482511 };
483512
484513 pub const Array = struct {
485 rbracket: TokenIndex,
514 lbracket: TokenIndex,
486515 inner: union(enum) {
487516 Inferred,
488517 Unspecified: TokenIndex,
......@@ -490,7 +519,7 @@ pub const Node = struct {
490519 asterisk: ?TokenIndex,
491520 static: ?TokenIndex,
492521 qual: TypeQual,
493 expr: *Expr,
522 // expr: *Expr,
494523 },
495524 },
496525 rbracket: TokenIndex,
......@@ -514,10 +543,10 @@ pub const Node = struct {
514543 },
515544 };
516545
517 pub const Fn = struct {
518 base: Node = Node{ .id = .Fn },
546 pub const FnDecl = struct {
547 base: Node = Node{ .id = .FnDecl },
519548 decl_spec: DeclSpec,
520 declarator: *Node,
549 declarator: *Declarator,
521550 old_decls: OldDeclList,
522551 body: ?*CompoundStmt,
523552
......@@ -528,20 +557,23 @@ pub const Node = struct {
528557 base: Node = Node{ .id = .Typedef },
529558 decl_spec: DeclSpec,
530559 declarators: DeclaratorList,
560 semicolon: TokenIndex,
531561
532562 pub const DeclaratorList = Root.DeclList;
533563 };
534564
535 pub const Var = struct {
536 base: Node = Node{ .id = .Var },
565 pub const VarDecl = struct {
566 base: Node = Node{ .id = .VarDecl },
537567 decl_spec: DeclSpec,
538568 initializers: Initializers,
569 semicolon: TokenIndex,
539570
540 pub const Initializers = std.SegmentedList(*Initialized, 2);
571 pub const Initializers = Root.DeclList;
541572 };
542573
543574 pub const Initialized = struct {
544 declarator: *Node,
575 base: Node = Node{ .id = Initialized },
576 declarator: *Declarator,
545577 eq: TokenIndex,
546578 init: Initializer,
547579 };
lib/std/c/parse.zig+125-69
......@@ -105,6 +105,10 @@ const Parser = struct {
105105 return null;
106106 }
107107
108 fn declareSymbol(parser: *Parser, decl_spec: *Node.DeclSpec, dr: *Node.Declarator) Error!void {
109 return; // TODO
110 }
111
108112 /// Root <- ExternalDeclaration* eof
109113 fn root(parser: *Parser) Allocator.Error!*Node.Root {
110114 const node = try parser.arena.create(Node.Root);
......@@ -140,77 +144,127 @@ const Parser = struct {
140144
141145 fn declarationExtra(parser: *Parser, local: bool) !?*Node {
142146 if (try parser.staticAssert()) |decl| return decl;
147 const begin = parser.it.index + 1;
143148 var ds = Node.DeclSpec{};
144149 const got_ds = try parser.declSpec(&ds);
145150 if (local and !got_ds) {
146151 // not a declaration
147152 return null;
148153 }
149 var dr = try parser.declarator();
150 // TODO disallow auto and register
151 const next_tok = parser.it.peek().?;
152 if (next_tok.id == .Eof and !got_ds and dr == null) {
153 return null;
154 }
155 switch (next_tok.id) {
156 .Semicolon,
157 .Equal,
158 .Comma,
159 .Eof,
160 => {
161 while (dr != null) {
162 if (parser.eatToken(.Equal)) |tok| {
163 // TODO typedef
164 // dr.?.init = try parser.expect(initializer, .{
165 // .ExpectedInitializer = .{ .token = parser.it.index },
166 // });
167 }
168 if (parser.eatToken(.Comma) != null) break;
169 dr = (try parser.declarator()) orelse return parser.err(.{
154 switch (ds.storage_class) {
155 .Auto, .Register => |tok| return parser.err(.{
156 .InvalidStorageClass = .{ .token = tok },
157 }),
158 .Typedef => {
159 const node = try parser.arena.create(Node.Typedef);
160 node.* = .{
161 .decl_spec = ds,
162 .declarators = Node.Typedef.DeclaratorList.init(parser.arena),
163 .semicolon = undefined,
164 };
165 while (true) {
166 const dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{
170167 .ExpectedDeclarator = .{ .token = parser.it.index },
171 });
172 // .push(dr);
168 }));
169 try parser.declareSymbol(&ds, dr);
170 try node.declarators.push(&dr.base);
171 if (parser.eatToken(.Comma)) |_| {} else break;
173172 }
174 const semicolon = try parser.expectToken(.Semicolon);
175
176 // TODO VarDecl, TypeDecl, TypeDef
177 return null;
173 return &node.base;
178174 },
179 else => {
180 if (dr == null)
181 return parser.err(.{
182 .ExpectedDeclarator = .{ .token = parser.it.index },
183 });
184 var old_decls = Node.FnDef.OldDeclList.init(parser.arena);
185 while (true) {
186 var old_ds = Node.DeclSpec{};
187 if (!(try parser.declSpec(&old_ds))) {
188 // not old decl
189 break;
190 }
191 var old_dr = (try parser.declarator());
192 // if (old_dr == null)
193 // try parser.err(.{
194 // .NoParamName = .{ .token = parser.it.index },
195 // });
196 // try old_decls.push(decl);
197 }
198 const body = (try parser.compoundStmt()) orelse return parser.err(.{
175 else => {},
176 }
177 var first_dr = try parser.declarator(.Must);
178 if (first_dr != null and declaratorIsFunction(first_dr.?)) {
179 const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
180 try parser.declareSymbol(&ds, dr);
181 var old_decls = Node.FnDecl.OldDeclList.init(parser.arena);
182 const body = if (parser.eatToken(.Semicolon)) |_|
183 null
184 else blk: {
185 // TODO first_dr.is_old
186 // while (true) {
187 // var old_ds = Node.DeclSpec{};
188 // if (!(try parser.declSpec(&old_ds))) {
189 // // not old decl
190 // break;
191 // }
192 // var old_dr = (try parser.declarator(.Must));
193 // // if (old_dr == null)
194 // // try parser.err(.{
195 // // .NoParamName = .{ .token = parser.it.index },
196 // // });
197 // // try old_decls.push(decl);
198 // }
199 const body_node = (try parser.compoundStmt()) orelse return parser.err(.{
199200 .ExpectedFnBody = .{ .token = parser.it.index },
200201 });
202 break :blk @fieldParentPtr(Node.CompoundStmt, "base", body_node);
203 };
201204
202 const node = try parser.arena.create(Node.FnDef);
203 node.* = .{
204 .decl_spec = ds,
205 .declarator = dr orelse return null,
206 .old_decls = old_decls,
207 .body = @fieldParentPtr(Node.CompoundStmt, "base", body),
205 const node = try parser.arena.create(Node.FnDecl);
206 node.* = .{
207 .decl_spec = ds,
208 .declarator = dr,
209 .old_decls = old_decls,
210 .body = body,
211 };
212 return &node.base;
213 } else {
214 switch (ds.fn_spec) {
215 .Inline, .Noreturn => |tok| return parser.err(.{
216 .FnSpecOnNonFn = .{ .token = tok },
217 }),
218 else => {},
219 }
220 // TODO threadlocal without static or extern on local variable
221 const node = try parser.arena.create(Node.VarDecl);
222 node.* = .{
223 .decl_spec = ds,
224 .initializers = Node.VarDecl.Initializers.init(parser.arena),
225 .semicolon = undefined,
226 };
227 if (first_dr == null) {
228 node.semicolon = try parser.expectToken(.Semicolon);
229 const ok = switch (ds.type_spec.spec) {
230 .Enum => |e| e.name != null,
231 .Record => |r| r.name != null,
232 else => false,
208233 };
234 const q = ds.type_spec.qual;
235 if (!ok)
236 try parser.warn(.{
237 .NothingDeclared = .{ .token = begin },
238 })
239 else if (q.@"const" orelse q.atomic orelse q.@"volatile" orelse q.restrict) |tok|
240 try parser.warn(.{
241 .QualifierIgnored = .{ .token = tok },
242 });
209243 return &node.base;
210 },
244 }
245 var dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
246 while (true) {
247 try parser.declareSymbol(&ds, dr);
248 if (parser.eatToken(.Equal)) |tok| {
249 try node.initializers.push((try parser.initializer(dr)) orelse return parser.err(.{
250 .ExpectedInitializer = .{ .token = parser.it.index },
251 }));
252 } else
253 try node.initializers.push(&dr.base);
254 if (parser.eatToken(.Comma) != null) break;
255 dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{
256 .ExpectedDeclarator = .{ .token = parser.it.index },
257 }));
258 }
259 node.semicolon = try parser.expectToken(.Semicolon);
260 return &node.base;
211261 }
212262 }
213263
264 fn declaratorIsFunction(dr: *Node) bool {
265 return false; // TODO
266 }
267
214268 /// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
215269 fn staticAssert(parser: *Parser) !?*Node {
216270 const tok = parser.eatToken(.Keyword_static_assert) orelse return null;
......@@ -733,7 +787,7 @@ const Parser = struct {
733787 fn recordDeclarator(parser: *Parser) !*Node {}
734788
735789 /// Pointer <- ASTERISK TypeQual* Pointer?
736 fn pointer(parser: *Parser) Error!?*Node {
790 fn pointer(parser: *Parser) Error!?*Node.Pointer {
737791 const asterisk = parser.eatToken(.Asterisk) orelse return null;
738792 const node = try parser.arena.create(Node.Pointer);
739793 node.* = .{
......@@ -743,7 +797,7 @@ const Parser = struct {
743797 };
744798 while (try parser.typeQual(&node.qual)) {}
745799 node.pointer = try parser.pointer();
746 return &node.base;
800 return node;
747801 }
748802
749803 const Named = enum {
......@@ -772,7 +826,7 @@ const Parser = struct {
772826 node.* = .{
773827 .pointer = ptr,
774828 .prefix = .{
775 .Comples = .{
829 .Complex = .{
776830 .lparen = lparen,
777831 .inner = inner,
778832 .rparen = try parser.expectToken(.RParen),
......@@ -785,7 +839,7 @@ const Parser = struct {
785839 node = try parser.arena.create(Node.Declarator);
786840 node.* = .{
787841 .pointer = ptr,
788 .prefix = .{ .Simple = tok },
842 .prefix = .{ .Identifer = tok },
789843 .suffix = .None,
790844 };
791845 } else if (named == .Must) {
......@@ -793,7 +847,9 @@ const Parser = struct {
793847 .ExpectedToken = .{ .token = parser.it.index, .expected_id = .Identifier },
794848 });
795849 } else {
796 return ptr;
850 if (ptr) |some|
851 return &some.base;
852 return null;
797853 }
798854 } else {
799855 node = try parser.arena.create(Node.Declarator);
......@@ -808,16 +864,16 @@ const Parser = struct {
808864 node.suffix = .{
809865 .Fn = .{
810866 .lparen = lparen,
811 .params = .Node.Declarator.Params.init(parser.arena),
867 .params = Node.Declarator.Params.init(parser.arena),
812868 .rparen = undefined,
813869 },
814870 };
815 try parser.ParamDecl(node);
871 try parser.paramDecl(node);
816872 node.suffix.Fn.rparen = try parser.expectToken(.RParen);
817873 } else {
818 while (parser.arrayDeclarator()) |arr| {
874 while (try parser.arrayDeclarator()) |arr| {
819875 if (node.suffix == .None)
820 node.suffix = .{ .Array = .Node.Declarator.Arrays.init(parser.arena) };
876 node.suffix = .{ .Array = Node.Declarator.Arrays.init(parser.arena) };
821877 try node.suffix.Array.push(arr);
822878 }
823879 }
......@@ -825,7 +881,7 @@ const Parser = struct {
825881 return parser.err(.{
826882 .InvalidDeclarator = .{ .token = tok },
827883 });
828 return node;
884 return &node.base;
829885 }
830886
831887 /// ArrayDeclarator
......@@ -834,11 +890,11 @@ const Parser = struct {
834890 /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
835891 /// / TypeQual+ AssignmentExpr?
836892 /// / AssignmentExpr
837 fn arrayDeclarator(parser: *Parser, dr: *Node.Declarator) !?*Node.Array {
893 fn arrayDeclarator(parser: *Parser) !?*Node.Array {
838894 const lbracket = parser.eatToken(.LBracket) orelse return null;
839895 const arr = try parser.arena.create(Node.Array);
840896 arr.* = .{
841 .lbracket = lbarcket,
897 .lbracket = lbracket,
842898 .inner = .Inferred,
843899 .rbracket = undefined,
844900 };
......@@ -856,12 +912,12 @@ const Parser = struct {
856912 fn paramDecl(parser: *Parser, dr: *Node.Declarator) !void {
857913 var old_style = false;
858914 while (true) {
859 var ds = Node.DeclSpec;
915 var ds = Node.DeclSpec{};
860916 if (try parser.declSpec(&ds)) {
861917 //TODO
862 } else if (parser.eatToken(.Identifier)) {
918 } else if (parser.eatToken(.Identifier)) |tok| {
863919 old_style = true;
864 } else if (parser.eatToken(.Ellipsis)) {
920 } else if (parser.eatToken(.Ellipsis)) |tok| {
865921 // TODO
866922 }
867923 }