From 28daddae81f354da89f917528dab2e5d87bca829 Mon Sep 17 00:00:00 2001 From: Vexu Date: Tue, 14 Jan 2020 16:18:32 +0200 Subject: [PATCH] std-c todos and small fixes --- lib/std/c/ast.zig | 5 ++-- lib/std/c/parse.zig | 54 +++++++++++++++++++---------------------- lib/std/c/tokenizer.zig | 8 +++++- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/lib/std/c/ast.zig b/lib/std/c/ast.zig index 093ea4cc1..bb6eb54d2 100644 --- a/lib/std/c/ast.zig +++ b/lib/std/c/ast.zig @@ -221,6 +221,7 @@ pub const Node = struct { Root, EnumField, RecordField, + RecordDeclarator, JumpStmt, ExprStmt, LabeledStmt, @@ -437,8 +438,8 @@ pub const Node = struct { }; pub const RecordDeclarator = struct { - base: Node = Node{ .id = .RecordField }, - declarator: *Declarator, + base: Node = Node{ .id = .RecordDeclarator }, + declarator: ?*Declarator, bit_field_expr: ?*Expr, }; diff --git a/lib/std/c/parse.zig b/lib/std/c/parse.zig index 7473cf0ac..d3a96e9aa 100644 --- a/lib/std/c/parse.zig +++ b/lib/std/c/parse.zig @@ -13,8 +13,8 @@ const TokenIterator = ast.Tree.TokenList.Iterator; pub const Error = error{ParseError} || Allocator.Error; pub const Options = struct { - /// Keep simple macros unexpanded and add the definitions to the ast - retain_macros: bool = false, + // /// Keep simple macros unexpanded and add the definitions to the ast + // retain_macros: bool = false, /// Warning or error warn_as_err: union(enum) { @@ -204,12 +204,16 @@ const Parser = struct { } var first_dr = try parser.declarator(.Must); if (first_dr != null and declaratorIsFunction(first_dr.?)) { + // TODO typedeffed fn proto-only const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?); try parser.declareSymbol(ds.type_spec, dr); var old_decls = Node.FnDecl.OldDeclList.init(parser.arena); const body = if (parser.eatToken(.Semicolon)) |_| null else blk: { + if (local) { + // TODO nested function warning + } // TODO first_dr.is_old // while (true) { // var old_ds = Node.DeclSpec{}; @@ -387,13 +391,11 @@ const Parser = struct { /// / IDENTIFIER // typedef name /// / TypeQual fn typeSpec(parser: *Parser, type_spec: *Node.TypeSpec) !bool { - while (try parser.typeQual(&type_spec.qual)) {} blk: { if (parser.eatToken(.Keyword_void)) |tok| { if (type_spec.spec != .None) break :blk; type_spec.spec = .{ .Void = tok }; - return true; } else if (parser.eatToken(.Keyword_char)) |tok| { switch (type_spec.spec) { .None => { @@ -415,7 +417,6 @@ const Parser = struct { }, else => break :blk, } - return true; } else if (parser.eatToken(.Keyword_short)) |tok| { switch (type_spec.spec) { .None => { @@ -437,7 +438,6 @@ const Parser = struct { }, else => break :blk, } - return true; } else if (parser.eatToken(.Keyword_long)) |tok| { switch (type_spec.spec) { .None => { @@ -468,7 +468,6 @@ const Parser = struct { }, else => break :blk, } - return true; } else if (parser.eatToken(.Keyword_int)) |tok| { switch (type_spec.spec) { .None => { @@ -495,7 +494,6 @@ const Parser = struct { }, else => break :blk, } - return true; } else if (parser.eatToken(.Keyword_signed) orelse parser.eatToken(.Keyword_unsigned)) |tok| { switch (type_spec.spec) { .None => { @@ -527,7 +525,6 @@ const Parser = struct { }, else => break :blk, } - return true; } else if (parser.eatToken(.Keyword_float)) |tok| { if (type_spec.spec != .None) break :blk; @@ -536,7 +533,6 @@ const Parser = struct { .float = tok, }, }; - return true; } else if (parser.eatToken(.Keyword_double)) |tok| { if (type_spec.spec != .None) break :blk; @@ -545,7 +541,6 @@ const Parser = struct { .double = tok, }, }; - return true; } else if (parser.eatToken(.Keyword_complex)) |tok| { switch (type_spec.spec) { .None => { @@ -568,36 +563,34 @@ const Parser = struct { }, else => break :blk, } - return true; - } - if (parser.eatToken(.Keyword_bool)) |tok| { + } else if (parser.eatToken(.Keyword_bool)) |tok| { if (type_spec.spec != .None) break :blk; type_spec.spec = .{ .Bool = tok }; - return true; } else if (parser.eatToken(.Keyword_atomic)) |tok| { - if (type_spec.spec != .None) - break :blk; - _ = try parser.expectToken(.LParen); - const name = (try parser.typeName()) orelse return parser.err(.{ - .ExpectedTypeName = .{ .token = parser.it.index }, - }); - type_spec.spec.Atomic = .{ - .atomic = tok, - .typename = name, - .rparen = try parser.expectToken(.RParen), - }; - return true; + // might be _Atomic qualifier + if (parser.eatToken(.LParen)) |_| { + if (type_spec.spec != .None) + break :blk; + const name = (try parser.typeName()) orelse return parser.err(.{ + .ExpectedTypeName = .{ .token = parser.it.index }, + }); + type_spec.spec.Atomic = .{ + .atomic = tok, + .typename = name, + .rparen = try parser.expectToken(.RParen), + }; + } else { + parser.putBackToken(tok); + } } else if (parser.eatToken(.Keyword_enum)) |tok| { if (type_spec.spec != .None) break :blk; type_spec.spec.Enum = try parser.enumSpec(tok); - return true; } else if (parser.eatToken(.Keyword_union) orelse parser.eatToken(.Keyword_struct)) |tok| { if (type_spec.spec != .None) break :blk; type_spec.spec.Record = try parser.recordSpec(tok); - return true; } else if (parser.eatToken(.Identifier)) |tok| { const ty = parser.getSymbol(tok) orelse { parser.putBackToken(tok); @@ -637,6 +630,7 @@ const Parser = struct { parser.putBackToken(tok); return false; } + return parser.typeQual(&type_spec.qual); } return parser.err(.{ .InvalidTypeSpecifier = .{ @@ -874,6 +868,7 @@ const Parser = struct { var node: *Node.Declarator = undefined; var inner_fn = false; + // TODO sizof(int (int)) // prefix if (parser.eatToken(.LParen)) |lparen| { const inner = (try parser.declarator(named)) orelse return parser.err(.{ @@ -981,6 +976,7 @@ const Parser = struct { var ds = Node.DeclSpec{}; if (try parser.declSpec(&ds)) { //TODO + // TODO try parser.declareSymbol(ds.type_spec, dr); } else if (parser.eatToken(.Identifier)) |tok| { old_style = true; } else if (parser.eatToken(.Ellipsis)) |tok| { diff --git a/lib/std/c/tokenizer.zig b/lib/std/c/tokenizer.zig index fa76fb42a..7da2e1832 100644 --- a/lib/std/c/tokenizer.zig +++ b/lib/std/c/tokenizer.zig @@ -593,9 +593,15 @@ pub const Tokenizer = struct { '\\' => { state = .BackSlash; }, - else => { + '\t', '\x0B', '\x0C', ' ' => { result.start = self.index + 1; }, + else => { + // TODO handle invalid bytes better + result.id = .Invalid; + self.index += 1; + break; + }, }, .Cr => switch (c) { '\n' => {