From d5d52af26ec3d3e6a171564112978a7d8c96aba4 Mon Sep 17 00:00:00 2001 From: Vexu Date: Mon, 6 Jan 2020 00:06:33 +0200 Subject: [PATCH] std-c parse pointer --- lib/std/c/ast.zig | 84 ++++++++++++++++++++++++++++++++++++++++++--- lib/std/c/parse.zig | 21 ++++++++---- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/lib/std/c/ast.zig b/lib/std/c/ast.zig index 8801bbfc48..5d34d26fe2 100644 --- a/lib/std/c/ast.zig +++ b/lib/std/c/ast.zig @@ -126,7 +126,9 @@ pub const Node = struct { CompoundStmt, IfStmt, StaticAssert, - FnDef, + Fn, + Typedef, + Var, }; pub const Root = struct { @@ -274,13 +276,85 @@ pub const Node = struct { semicolon: TokenIndex, }; - pub const FnDef = struct { - base: Node = Node{ .id = .FnDef }, + pub const Declarator = struct { + pointer: *Pointer, + identifier: ?TokenIndex, + kind: union(enum) { + Simple, + Complex: struct { + lparen: TokenIndex, + inner: *Declarator, + rparen: TokenIndex, + }, + Fn: ParamList, + Array: ArrayList, + }, + + pub const ArrayList = std.SegmentedList(*Array, 2); + pub const ParamList = std.SegmentedList(*Param, 4); + }; + + pub const Array = union(enum) { + Unspecified, + Variable: TokenIndex, + Known: *Expr, + }; + + pub const Pointer = struct { + asterisk: TokenIndex, + qual: TypeQual, + pointer: ?*Pointer, + }; + + pub const Param = struct { + kind: union(enum) { + Variable, + Old: TokenIndex, + Normal: struct { + decl_spec: *DeclSpec, + declarator: *Declarator, + }, + }, + }; + + pub const Fn = struct { + base: Node = Node{ .id = .Fn }, decl_spec: DeclSpec, - declarator: *Node, + declarator: *Declarator, old_decls: OldDeclList, - body: *CompoundStmt, + body: ?*CompoundStmt, pub const OldDeclList = SegmentedList(*Node, 0); }; + + pub const Typedef = struct { + base: Node = Node{ .id = .Typedef }, + decl_spec: DeclSpec, + declarators: DeclaratorList, + + pub const DeclaratorList = std.SegmentedList(*Declarator, 2); + }; + + pub const Var = struct { + base: Node = Node{ .id = .Var }, + decl_spec: DeclSpec, + initializers: Initializers, + + pub const Initializers = std.SegmentedList(*Initialized, 2); + }; + + pub const Initialized = struct { + declarator: *Declarator, + eq: TokenIndex, + init: Initializer, + }; + + pub const Initializer = union(enum) { + list: struct { + initializers: InitializerList, + rbrace: TokenIndex, + }, + expr: *Expr, + pub const InitializerList = std.SegmentedList(*Initializer, 4); + }; }; diff --git a/lib/std/c/parse.zig b/lib/std/c/parse.zig index 37e9814f7e..0925d65d8f 100644 --- a/lib/std/c/parse.zig +++ b/lib/std/c/parse.zig @@ -588,12 +588,19 @@ const Parser = struct { /// RecordDeclarator <- Declarator? (COLON ConstExpr)? fn recordDeclarator(parser: *Parser) !*Node {} - /// Declarator <- Pointer? DirectDeclarator - fn declarator(parser: *Parser) !*Node {} - /// Pointer <- ASTERISK TypeQual* Pointer? - fn pointer(parser: *Parser) !*Node {} - + fn pointer(parser: *Parser) !?*Node.Pointer { + const asterisk = parser.eatToken(.Asterisk) orelse return null; + const node = try parser.arena.create(Node.Pointer); + node.* = .{ + .asterisk = asterisk, + .qual = .{}, + .pointer = null, + }; + while (try parser.typeQual(&node.qual)) {} + node.pointer = try parser.pointer(); + return node; + } /// DirectDeclarator /// <- IDENTIFIER /// / LPAREN Declarator RPAREN @@ -687,7 +694,7 @@ const Parser = struct { /// PrimaryExpr /// <- IDENTIFIER - /// / INTEGERLITERAL / FLITERAL / STRINGLITERAL / CHARLITERAL + /// / INTEGERLITERAL / FLOATLITERAL / STRINGLITERAL / CHARLITERAL /// / LPAREN Expr RPAREN /// / Keyword_generic LPAREN AssignmentExpr (COMMA Generic)+ RPAREN fn primaryExpr(parser: *Parser) !*Node {} @@ -714,7 +721,7 @@ const Parser = struct { fn initializer(parser: *Parser) !*Node {} /// Designator - /// <- LBRACKET Initializers RBRACKET + /// <- LBRACKET ConstExpr RBRACKET /// / PERIOD IDENTIFIER fn designator(parser: *Parser) !*Node {}