| author | |
| committer | |
| log | 00878a15d703a668970c7869276d33b21464714a |
| tree | d84e68f83d2b484e04494e3b36d76a6beb34e443 |
| parent | f25182f46dd672eb5b10533c67ed462a3e5df999 |
| signature |
5 files changed, 202 insertions(+), 192 deletions(-)
lib/std/zig/ast.zig+16-11| ... | ... | @@ -137,7 +137,6 @@ pub const Error = union(enum) { |
| 137 | 137 | ExpectedCallOrFnProto: ExpectedCallOrFnProto, |
| 138 | 138 | ExpectedSliceOrRBracket: ExpectedSliceOrRBracket, |
| 139 | 139 | ExtraAlignQualifier: ExtraAlignQualifier, |
| 140 | ExtraNullQualifier: ExtraNullQualifier, | |
| 141 | 140 | ExtraConstQualifier: ExtraConstQualifier, |
| 142 | 141 | ExtraVolatileQualifier: ExtraVolatileQualifier, |
| 143 | 142 | ExtraAllowZeroQualifier: ExtraAllowZeroQualifier, |
| ... | ... | @@ -185,7 +184,6 @@ pub const Error = union(enum) { |
| 185 | 184 | .ExpectedCallOrFnProto => |*x| return x.render(tokens, stream), |
| 186 | 185 | .ExpectedSliceOrRBracket => |*x| return x.render(tokens, stream), |
| 187 | 186 | .ExtraAlignQualifier => |*x| return x.render(tokens, stream), |
| 188 | .ExtraNullQualifier => |*x| return x.render(tokens, stream), | |
| 189 | 187 | .ExtraConstQualifier => |*x| return x.render(tokens, stream), |
| 190 | 188 | .ExtraVolatileQualifier => |*x| return x.render(tokens, stream), |
| 191 | 189 | .ExtraAllowZeroQualifier => |*x| return x.render(tokens, stream), |
| ... | ... | @@ -235,7 +233,6 @@ pub const Error = union(enum) { |
| 235 | 233 | .ExpectedCallOrFnProto => |x| return x.node.firstToken(), |
| 236 | 234 | .ExpectedSliceOrRBracket => |x| return x.token, |
| 237 | 235 | .ExtraAlignQualifier => |x| return x.token, |
| 238 | .ExtraNullQualifier => |x| return x.token, | |
| 239 | 236 | .ExtraConstQualifier => |x| return x.token, |
| 240 | 237 | .ExtraVolatileQualifier => |x| return x.token, |
| 241 | 238 | .ExtraAllowZeroQualifier => |x| return x.token, |
| ... | ... | @@ -296,7 +293,6 @@ pub const Error = union(enum) { |
| 296 | 293 | pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub"); |
| 297 | 294 | pub const UnattachedDocComment = SimpleError("Unattached documentation comment"); |
| 298 | 295 | pub const ExtraAlignQualifier = SimpleError("Extra align qualifier"); |
| 299 | pub const ExtraNullQualifier = SimpleError("Extra null qualifier"); | |
| 300 | 296 | pub const ExtraConstQualifier = SimpleError("Extra const qualifier"); |
| 301 | 297 | pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier"); |
| 302 | 298 | pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier"); |
| ... | ... | @@ -1535,7 +1531,7 @@ pub const Node = struct { |
| 1535 | 1531 | }; |
| 1536 | 1532 | |
| 1537 | 1533 | pub const PrefixOp = struct { |
| 1538 | base: Node, | |
| 1534 | base: Node = Node{ .id = .PrefixOp }, | |
| 1539 | 1535 | op_token: TokenIndex, |
| 1540 | 1536 | op: Op, |
| 1541 | 1537 | rhs: *Node, |
| ... | ... | @@ -1558,15 +1554,15 @@ pub const Node = struct { |
| 1558 | 1554 | |
| 1559 | 1555 | pub const ArrayInfo = struct { |
| 1560 | 1556 | len_expr: *Node, |
| 1561 | null_token: ?TokenIndex, | |
| 1557 | sentinel: ?*Node, | |
| 1562 | 1558 | }; |
| 1563 | 1559 | |
| 1564 | 1560 | pub const PtrInfo = struct { |
| 1565 | allowzero_token: ?TokenIndex, | |
| 1566 | align_info: ?Align, | |
| 1567 | const_token: ?TokenIndex, | |
| 1568 | volatile_token: ?TokenIndex, | |
| 1569 | null_token: ?TokenIndex, | |
| 1561 | allowzero_token: ?TokenIndex = null, | |
| 1562 | align_info: ?Align = null, | |
| 1563 | const_token: ?TokenIndex = null, | |
| 1564 | volatile_token: ?TokenIndex = null, | |
| 1565 | sentinel: ?*Node = null, | |
| 1570 | 1566 | |
| 1571 | 1567 | pub const Align = struct { |
| 1572 | 1568 | node: *Node, |
| ... | ... | @@ -1585,6 +1581,11 @@ pub const Node = struct { |
| 1585 | 1581 | switch (self.op) { |
| 1586 | 1582 | // TODO https://github.com/ziglang/zig/issues/1107 |
| 1587 | 1583 | Op.SliceType => |addr_of_info| { |
| 1584 | if (addr_of_info.sentinel) |sentinel| { | |
| 1585 | if (i < 1) return sentinel; | |
| 1586 | i -= 1; | |
| 1587 | } | |
| 1588 | ||
| 1588 | 1589 | if (addr_of_info.align_info) |align_info| { |
| 1589 | 1590 | if (i < 1) return align_info.node; |
| 1590 | 1591 | i -= 1; |
| ... | ... | @@ -1601,6 +1602,10 @@ pub const Node = struct { |
| 1601 | 1602 | Op.ArrayType => |array_info| { |
| 1602 | 1603 | if (i < 1) return array_info.len_expr; |
| 1603 | 1604 | i -= 1; |
| 1605 | if (array_info.sentinel) |sentinel| { | |
| 1606 | if (i < 1) return sentinel; | |
| 1607 | i -= 1; | |
| 1608 | } | |
| 1604 | 1609 | }, |
| 1605 | 1610 | |
| 1606 | 1611 | Op.AddressOf, |
lib/std/zig/parse.zig+127-109| ... | ... | @@ -2246,73 +2246,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 2246 | 2246 | return &node.base; |
| 2247 | 2247 | } |
| 2248 | 2248 | |
| 2249 | if (try parseArrayTypeStart(arena, it, tree)) |node| { | |
| 2250 | switch (node.cast(Node.PrefixOp).?.op) { | |
| 2251 | .ArrayType => {}, | |
| 2252 | .SliceType => |*slice_type| { | |
| 2253 | // Collect pointer qualifiers in any order, but disallow duplicates | |
| 2254 | while (true) { | |
| 2255 | if (eatToken(it, .Keyword_null)) |null_token| { | |
| 2256 | if (slice_type.null_token != null) { | |
| 2257 | try tree.errors.push(AstError{ | |
| 2258 | .ExtraNullQualifier = AstError.ExtraNullQualifier{ .token = it.index }, | |
| 2259 | }); | |
| 2260 | return error.ParseError; | |
| 2261 | } | |
| 2262 | slice_type.null_token = null_token; | |
| 2263 | continue; | |
| 2264 | } | |
| 2265 | if (try parseByteAlign(arena, it, tree)) |align_expr| { | |
| 2266 | if (slice_type.align_info != null) { | |
| 2267 | try tree.errors.push(AstError{ | |
| 2268 | .ExtraAlignQualifier = AstError.ExtraAlignQualifier{ .token = it.index }, | |
| 2269 | }); | |
| 2270 | return error.ParseError; | |
| 2271 | } | |
| 2272 | slice_type.align_info = Node.PrefixOp.PtrInfo.Align{ | |
| 2273 | .node = align_expr, | |
| 2274 | .bit_range = null, | |
| 2275 | }; | |
| 2276 | continue; | |
| 2277 | } | |
| 2278 | if (eatToken(it, .Keyword_const)) |const_token| { | |
| 2279 | if (slice_type.const_token != null) { | |
| 2280 | try tree.errors.push(AstError{ | |
| 2281 | .ExtraConstQualifier = AstError.ExtraConstQualifier{ .token = it.index }, | |
| 2282 | }); | |
| 2283 | return error.ParseError; | |
| 2284 | } | |
| 2285 | slice_type.const_token = const_token; | |
| 2286 | continue; | |
| 2287 | } | |
| 2288 | if (eatToken(it, .Keyword_volatile)) |volatile_token| { | |
| 2289 | if (slice_type.volatile_token != null) { | |
| 2290 | try tree.errors.push(AstError{ | |
| 2291 | .ExtraVolatileQualifier = AstError.ExtraVolatileQualifier{ .token = it.index }, | |
| 2292 | }); | |
| 2293 | return error.ParseError; | |
| 2294 | } | |
| 2295 | slice_type.volatile_token = volatile_token; | |
| 2296 | continue; | |
| 2297 | } | |
| 2298 | if (eatToken(it, .Keyword_allowzero)) |allowzero_token| { | |
| 2299 | if (slice_type.allowzero_token != null) { | |
| 2300 | try tree.errors.push(AstError{ | |
| 2301 | .ExtraAllowZeroQualifier = AstError.ExtraAllowZeroQualifier{ .token = it.index }, | |
| 2302 | }); | |
| 2303 | return error.ParseError; | |
| 2304 | } | |
| 2305 | slice_type.allowzero_token = allowzero_token; | |
| 2306 | continue; | |
| 2307 | } | |
| 2308 | break; | |
| 2309 | } | |
| 2310 | }, | |
| 2311 | else => unreachable, | |
| 2312 | } | |
| 2313 | return node; | |
| 2314 | } | |
| 2315 | ||
| 2316 | 2249 | if (try parsePtrTypeStart(arena, it, tree)) |node| { |
| 2317 | 2250 | // If the token encountered was **, there will be two nodes instead of one. |
| 2318 | 2251 | // The attributes should be applied to the rightmost operator. |
| ... | ... | @@ -2323,10 +2256,6 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 2323 | 2256 | &prefix_op.op.PtrType; |
| 2324 | 2257 | |
| 2325 | 2258 | while (true) { |
| 2326 | if (eatToken(it, .Keyword_null)) |null_token| { | |
| 2327 | ptr_info.null_token = null_token; | |
| 2328 | continue; | |
| 2329 | } | |
| 2330 | 2259 | if (eatToken(it, .Keyword_align)) |align_token| { |
| 2331 | 2260 | const lparen = try expectToken(it, tree, .LParen); |
| 2332 | 2261 | const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{ |
| ... | ... | @@ -2375,6 +2304,63 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 2375 | 2304 | return node; |
| 2376 | 2305 | } |
| 2377 | 2306 | |
| 2307 | if (try parseArrayTypeStart(arena, it, tree)) |node| { | |
| 2308 | switch (node.cast(Node.PrefixOp).?.op) { | |
| 2309 | .ArrayType => {}, | |
| 2310 | .SliceType => |*slice_type| { | |
| 2311 | // Collect pointer qualifiers in any order, but disallow duplicates | |
| 2312 | while (true) { | |
| 2313 | if (try parseByteAlign(arena, it, tree)) |align_expr| { | |
| 2314 | if (slice_type.align_info != null) { | |
| 2315 | try tree.errors.push(AstError{ | |
| 2316 | .ExtraAlignQualifier = AstError.ExtraAlignQualifier{ .token = it.index }, | |
| 2317 | }); | |
| 2318 | return error.ParseError; | |
| 2319 | } | |
| 2320 | slice_type.align_info = Node.PrefixOp.PtrInfo.Align{ | |
| 2321 | .node = align_expr, | |
| 2322 | .bit_range = null, | |
| 2323 | }; | |
| 2324 | continue; | |
| 2325 | } | |
| 2326 | if (eatToken(it, .Keyword_const)) |const_token| { | |
| 2327 | if (slice_type.const_token != null) { | |
| 2328 | try tree.errors.push(AstError{ | |
| 2329 | .ExtraConstQualifier = AstError.ExtraConstQualifier{ .token = it.index }, | |
| 2330 | }); | |
| 2331 | return error.ParseError; | |
| 2332 | } | |
| 2333 | slice_type.const_token = const_token; | |
| 2334 | continue; | |
| 2335 | } | |
| 2336 | if (eatToken(it, .Keyword_volatile)) |volatile_token| { | |
| 2337 | if (slice_type.volatile_token != null) { | |
| 2338 | try tree.errors.push(AstError{ | |
| 2339 | .ExtraVolatileQualifier = AstError.ExtraVolatileQualifier{ .token = it.index }, | |
| 2340 | }); | |
| 2341 | return error.ParseError; | |
| 2342 | } | |
| 2343 | slice_type.volatile_token = volatile_token; | |
| 2344 | continue; | |
| 2345 | } | |
| 2346 | if (eatToken(it, .Keyword_allowzero)) |allowzero_token| { | |
| 2347 | if (slice_type.allowzero_token != null) { | |
| 2348 | try tree.errors.push(AstError{ | |
| 2349 | .ExtraAllowZeroQualifier = AstError.ExtraAllowZeroQualifier{ .token = it.index }, | |
| 2350 | }); | |
| 2351 | return error.ParseError; | |
| 2352 | } | |
| 2353 | slice_type.allowzero_token = allowzero_token; | |
| 2354 | continue; | |
| 2355 | } | |
| 2356 | break; | |
| 2357 | } | |
| 2358 | }, | |
| 2359 | else => unreachable, | |
| 2360 | } | |
| 2361 | return node; | |
| 2362 | } | |
| 2363 | ||
| 2378 | 2364 | return null; |
| 2379 | 2365 | } |
| 2380 | 2366 | |
| ... | ... | @@ -2473,14 +2459,19 @@ const AnnotatedParamList = struct { |
| 2473 | 2459 | fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 2474 | 2460 | const lbracket = eatToken(it, .LBracket) orelse return null; |
| 2475 | 2461 | const expr = try parseExpr(arena, it, tree); |
| 2462 | const sentinel = if (eatToken(it, .Colon)) |_| | |
| 2463 | try expectNode(arena, it, tree, parseExpr, AstError{ | |
| 2464 | .ExpectedExpr = .{ .token = it.index }, | |
| 2465 | }) | |
| 2466 | else | |
| 2467 | null; | |
| 2476 | 2468 | const rbracket = try expectToken(it, tree, .RBracket); |
| 2477 | const null_token = eatToken(it, .Keyword_null); | |
| 2478 | 2469 | |
| 2479 | 2470 | const op = if (expr) |len_expr| |
| 2480 | 2471 | Node.PrefixOp.Op{ |
| 2481 | 2472 | .ArrayType = .{ |
| 2482 | 2473 | .len_expr = len_expr, |
| 2483 | .null_token = null_token, | |
| 2474 | .sentinel = sentinel, | |
| 2484 | 2475 | }, |
| 2485 | 2476 | } |
| 2486 | 2477 | else |
| ... | ... | @@ -2490,7 +2481,7 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No |
| 2490 | 2481 | .align_info = null, |
| 2491 | 2482 | .const_token = null, |
| 2492 | 2483 | .volatile_token = null, |
| 2493 | .null_token = null, | |
| 2484 | .sentinel = sentinel, | |
| 2494 | 2485 | }, |
| 2495 | 2486 | }; |
| 2496 | 2487 | |
| ... | ... | @@ -2510,49 +2501,76 @@ fn parseArrayTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No |
| 2510 | 2501 | /// / PTRUNKNOWN |
| 2511 | 2502 | /// / PTRC |
| 2512 | 2503 | fn parsePtrTypeStart(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 2513 | const token = eatAnnotatedToken(it, .Asterisk) orelse | |
| 2514 | eatAnnotatedToken(it, .AsteriskAsterisk) orelse | |
| 2515 | eatAnnotatedToken(it, .BracketStarBracket) orelse | |
| 2516 | eatAnnotatedToken(it, .BracketStarCBracket) orelse | |
| 2517 | return null; | |
| 2504 | if (eatToken(it, .Asterisk)) |asterisk| { | |
| 2505 | const sentinel = if (eatToken(it, .Colon)) |_| | |
| 2506 | try expectNode(arena, it, tree, parseExpr, AstError{ | |
| 2507 | .ExpectedExpr = .{ .token = it.index }, | |
| 2508 | }) | |
| 2509 | else | |
| 2510 | null; | |
| 2511 | const node = try arena.create(Node.PrefixOp); | |
| 2512 | node.* = .{ | |
| 2513 | .op_token = asterisk, | |
| 2514 | .op = .{ .PtrType = .{ .sentinel = sentinel } }, | |
| 2515 | .rhs = undefined, // set by caller | |
| 2516 | }; | |
| 2517 | return &node.base; | |
| 2518 | } | |
| 2518 | 2519 | |
| 2519 | const node = try arena.create(Node.PrefixOp); | |
| 2520 | node.* = Node.PrefixOp{ | |
| 2521 | .base = Node{ .id = .PrefixOp }, | |
| 2522 | .op_token = token.index, | |
| 2523 | .op = Node.PrefixOp.Op{ | |
| 2524 | .PtrType = Node.PrefixOp.PtrInfo{ | |
| 2525 | .allowzero_token = null, | |
| 2526 | .align_info = null, | |
| 2527 | .const_token = null, | |
| 2528 | .volatile_token = null, | |
| 2529 | .null_token = null, | |
| 2530 | }, | |
| 2531 | }, | |
| 2532 | .rhs = undefined, // set by caller | |
| 2533 | }; | |
| 2520 | if (eatToken(it, .AsteriskAsterisk)) |double_asterisk| { | |
| 2521 | const node = try arena.create(Node.PrefixOp); | |
| 2522 | node.* = Node.PrefixOp{ | |
| 2523 | .op_token = double_asterisk, | |
| 2524 | .op = Node.PrefixOp.Op{ .PtrType = .{} }, | |
| 2525 | .rhs = undefined, // set by caller | |
| 2526 | }; | |
| 2534 | 2527 | |
| 2535 | // Special case for **, which is its own token | |
| 2536 | if (token.ptr.id == .AsteriskAsterisk) { | |
| 2528 | // Special case for **, which is its own token | |
| 2537 | 2529 | const child = try arena.create(Node.PrefixOp); |
| 2538 | 2530 | child.* = Node.PrefixOp{ |
| 2539 | .base = Node{ .id = .PrefixOp }, | |
| 2540 | .op_token = token.index, | |
| 2541 | .op = Node.PrefixOp.Op{ | |
| 2542 | .PtrType = Node.PrefixOp.PtrInfo{ | |
| 2543 | .allowzero_token = null, | |
| 2544 | .align_info = null, | |
| 2545 | .const_token = null, | |
| 2546 | .volatile_token = null, | |
| 2547 | .null_token = null, | |
| 2548 | }, | |
| 2549 | }, | |
| 2531 | .op_token = double_asterisk, | |
| 2532 | .op = Node.PrefixOp.Op{ .PtrType = .{} }, | |
| 2550 | 2533 | .rhs = undefined, // set by caller |
| 2551 | 2534 | }; |
| 2552 | 2535 | node.rhs = &child.base; |
| 2553 | } | |
| 2554 | 2536 | |
| 2555 | return &node.base; | |
| 2537 | return &node.base; | |
| 2538 | } | |
| 2539 | if (eatToken(it, .LBracket)) |lbracket| { | |
| 2540 | const asterisk = eatToken(it, .Asterisk) orelse { | |
| 2541 | putBackToken(it, lbracket); | |
| 2542 | return null; | |
| 2543 | }; | |
| 2544 | if (eatToken(it, .Identifier)) |ident| { | |
| 2545 | if (!std.mem.eql(u8, tree.tokenSlice(ident), "c")) { | |
| 2546 | putBackToken(it, ident); | |
| 2547 | } else { | |
| 2548 | _ = try expectToken(it, tree, .RBracket); | |
| 2549 | const node = try arena.create(Node.PrefixOp); | |
| 2550 | node.* = .{ | |
| 2551 | .op_token = ident, | |
| 2552 | .op = .{ .PtrType = .{} }, | |
| 2553 | .rhs = undefined, // set by caller | |
| 2554 | }; | |
| 2555 | return &node.base; | |
| 2556 | } | |
| 2557 | } | |
| 2558 | const sentinel = if (eatToken(it, .Colon)) |_| | |
| 2559 | try expectNode(arena, it, tree, parseExpr, AstError{ | |
| 2560 | .ExpectedExpr = .{ .token = it.index }, | |
| 2561 | }) | |
| 2562 | else | |
| 2563 | null; | |
| 2564 | _ = try expectToken(it, tree, .RBracket); | |
| 2565 | const node = try arena.create(Node.PrefixOp); | |
| 2566 | node.* = .{ | |
| 2567 | .op_token = lbracket, | |
| 2568 | .op = .{ .PtrType = .{ .sentinel = sentinel } }, | |
| 2569 | .rhs = undefined, // set by caller | |
| 2570 | }; | |
| 2571 | return &node.base; | |
| 2572 | } | |
| 2573 | return null; | |
| 2556 | 2574 | } |
| 2557 | 2575 | |
| 2558 | 2576 | /// ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE |
lib/std/zig/render.zig+29-11| ... | ... | @@ -418,13 +418,26 @@ fn renderExpression( |
| 418 | 418 | |
| 419 | 419 | switch (prefix_op_node.op) { |
| 420 | 420 | ast.Node.PrefixOp.Op.PtrType => |ptr_info| { |
| 421 | const star_offset = switch (tree.tokens.at(prefix_op_node.op_token).id) { | |
| 422 | Token.Id.AsteriskAsterisk => @as(usize, 1), | |
| 423 | else => @as(usize, 0), | |
| 424 | }; | |
| 425 | try renderTokenOffset(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None, star_offset); // * | |
| 426 | if (ptr_info.null_token) |null_token| { | |
| 427 | try renderToken(tree, stream, null_token, indent, start_col, Space.Space); // null | |
| 421 | const op_tok_id = tree.tokens.at(prefix_op_node.op_token).id; | |
| 422 | switch (op_tok_id) { | |
| 423 | .Asterisk, .AsteriskAsterisk => try stream.writeByte('*'), | |
| 424 | .Identifier => try stream.write("[*c]"), | |
| 425 | .LBracket => try stream.write("[*"), | |
| 426 | else => unreachable, | |
| 427 | } | |
| 428 | if (ptr_info.sentinel) |sentinel| { | |
| 429 | const colon_token = tree.prevToken(sentinel.firstToken()); | |
| 430 | try renderToken(tree, stream, colon_token, indent, start_col, Space.None); // : | |
| 431 | const sentinel_space = switch (op_tok_id) { | |
| 432 | .LBracket => Space.None, | |
| 433 | else => Space.Space, | |
| 434 | }; | |
| 435 | try renderExpression(allocator, stream, tree, indent, start_col, sentinel, sentinel_space); | |
| 436 | } | |
| 437 | switch (op_tok_id) { | |
| 438 | .Asterisk, .AsteriskAsterisk, .Identifier => {}, | |
| 439 | .LBracket => try stream.writeByte(']'), | |
| 440 | else => unreachable, | |
| 428 | 441 | } |
| 429 | 442 | if (ptr_info.allowzero_token) |allowzero_token| { |
| 430 | 443 | try renderToken(tree, stream, allowzero_token, indent, start_col, Space.Space); // allowzero |
| ... | ... | @@ -504,7 +517,10 @@ fn renderExpression( |
| 504 | 517 | |
| 505 | 518 | ast.Node.PrefixOp.Op.ArrayType => |array_info| { |
| 506 | 519 | const lbracket = prefix_op_node.op_token; |
| 507 | const rbracket = tree.nextToken(array_info.len_expr.lastToken()); | |
| 520 | const rbracket = tree.nextToken(if (array_info.sentinel) |sentinel| | |
| 521 | sentinel.lastToken() | |
| 522 | else | |
| 523 | array_info.len_expr.lastToken()); | |
| 508 | 524 | |
| 509 | 525 | try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [ |
| 510 | 526 | |
| ... | ... | @@ -519,10 +535,12 @@ fn renderExpression( |
| 519 | 535 | if (ends_with_comment or starts_with_comment) { |
| 520 | 536 | try stream.writeByteNTimes(' ', indent); |
| 521 | 537 | } |
| 522 | try renderToken(tree, stream, rbracket, indent, start_col, Space.None); // ] | |
| 523 | if (array_info.null_token) |null_token| { | |
| 524 | try renderToken(tree, stream, null_token, indent, start_col, Space.Space); // null | |
| 538 | if (array_info.sentinel) |sentinel| { | |
| 539 | const colon_token = tree.prevToken(sentinel.firstToken()); | |
| 540 | try renderToken(tree, stream, colon_token, indent, start_col, Space.None); // : | |
| 541 | try renderExpression(allocator, stream, tree, indent, start_col, sentinel, Space.None); | |
| 525 | 542 | } |
| 543 | try renderToken(tree, stream, rbracket, indent, start_col, Space.None); // ] | |
| 526 | 544 | }, |
| 527 | 545 | ast.Node.PrefixOp.Op.BitNot, |
| 528 | 546 | ast.Node.PrefixOp.Op.BoolNot, |
lib/std/zig/tokenizer.zig+10-52| ... | ... | @@ -143,8 +143,6 @@ pub const Token = struct { |
| 143 | 143 | LineComment, |
| 144 | 144 | DocComment, |
| 145 | 145 | ContainerDocComment, |
| 146 | BracketStarBracket, | |
| 147 | BracketStarCBracket, | |
| 148 | 146 | ShebangLine, |
| 149 | 147 | Keyword_align, |
| 150 | 148 | Keyword_allowzero, |
| ... | ... | @@ -269,8 +267,6 @@ pub const Token = struct { |
| 269 | 267 | .AngleBracketAngleBracketRight => ">>", |
| 270 | 268 | .AngleBracketAngleBracketRightEqual => ">>=", |
| 271 | 269 | .Tilde => "~", |
| 272 | .BracketStarBracket => "[*]", | |
| 273 | .BracketStarCBracket => "[*c]", | |
| 274 | 270 | .Keyword_align => "align", |
| 275 | 271 | .Keyword_allowzero => "allowzero", |
| 276 | 272 | .Keyword_and => "and", |
| ... | ... | @@ -400,9 +396,6 @@ pub const Tokenizer = struct { |
| 400 | 396 | Period, |
| 401 | 397 | Period2, |
| 402 | 398 | SawAtSign, |
| 403 | LBracket, | |
| 404 | LBracketStar, | |
| 405 | LBracketStarC, | |
| 406 | 399 | }; |
| 407 | 400 | |
| 408 | 401 | pub fn next(self: *Tokenizer) Token { |
| ... | ... | @@ -460,7 +453,9 @@ pub const Tokenizer = struct { |
| 460 | 453 | break; |
| 461 | 454 | }, |
| 462 | 455 | '[' => { |
| 463 | state = State.LBracket; | |
| 456 | result.id = .LBracket; | |
| 457 | self.index += 1; | |
| 458 | break; | |
| 464 | 459 | }, |
| 465 | 460 | ']' => { |
| 466 | 461 | result.id = Token.Id.RBracket; |
| ... | ... | @@ -564,43 +559,6 @@ pub const Tokenizer = struct { |
| 564 | 559 | }, |
| 565 | 560 | }, |
| 566 | 561 | |
| 567 | State.LBracket => switch (c) { | |
| 568 | '*' => { | |
| 569 | state = State.LBracketStar; | |
| 570 | }, | |
| 571 | else => { | |
| 572 | result.id = Token.Id.LBracket; | |
| 573 | break; | |
| 574 | }, | |
| 575 | }, | |
| 576 | ||
| 577 | State.LBracketStar => switch (c) { | |
| 578 | 'c' => { | |
| 579 | state = State.LBracketStarC; | |
| 580 | }, | |
| 581 | ']' => { | |
| 582 | result.id = Token.Id.BracketStarBracket; | |
| 583 | self.index += 1; | |
| 584 | break; | |
| 585 | }, | |
| 586 | else => { | |
| 587 | result.id = Token.Id.Invalid; | |
| 588 | break; | |
| 589 | }, | |
| 590 | }, | |
| 591 | ||
| 592 | State.LBracketStarC => switch (c) { | |
| 593 | ']' => { | |
| 594 | result.id = Token.Id.BracketStarCBracket; | |
| 595 | self.index += 1; | |
| 596 | break; | |
| 597 | }, | |
| 598 | else => { | |
| 599 | result.id = Token.Id.Invalid; | |
| 600 | break; | |
| 601 | }, | |
| 602 | }, | |
| 603 | ||
| 604 | 562 | State.Ampersand => switch (c) { |
| 605 | 563 | '&' => { |
| 606 | 564 | result.id = Token.Id.Invalid_ampersands; |
| ... | ... | @@ -1227,8 +1185,6 @@ pub const Tokenizer = struct { |
| 1227 | 1185 | State.CharLiteralEnd, |
| 1228 | 1186 | State.CharLiteralUnicode, |
| 1229 | 1187 | State.StringLiteralBackslash, |
| 1230 | State.LBracketStar, | |
| 1231 | State.LBracketStarC, | |
| 1232 | 1188 | => { |
| 1233 | 1189 | result.id = Token.Id.Invalid; |
| 1234 | 1190 | }, |
| ... | ... | @@ -1245,9 +1201,6 @@ pub const Tokenizer = struct { |
| 1245 | 1201 | State.Slash => { |
| 1246 | 1202 | result.id = Token.Id.Slash; |
| 1247 | 1203 | }, |
| 1248 | State.LBracket => { | |
| 1249 | result.id = Token.Id.LBracket; | |
| 1250 | }, | |
| 1251 | 1204 | State.Zero => { |
| 1252 | 1205 | result.id = Token.Id.IntegerLiteral; |
| 1253 | 1206 | }, |
| ... | ... | @@ -1368,9 +1321,14 @@ test "tokenizer - unknown length pointer and then c pointer" { |
| 1368 | 1321 | \\[*]u8 |
| 1369 | 1322 | \\[*c]u8 |
| 1370 | 1323 | , [_]Token.Id{ |
| 1371 | Token.Id.BracketStarBracket, | |
| 1324 | Token.Id.LBracket, | |
| 1325 | Token.Id.Asterisk, | |
| 1326 | Token.Id.RBracket, | |
| 1327 | Token.Id.Identifier, | |
| 1328 | Token.Id.LBracket, | |
| 1329 | Token.Id.Asterisk, | |
| 1372 | 1330 | Token.Id.Identifier, |
| 1373 | Token.Id.BracketStarCBracket, | |
| 1331 | Token.Id.RBracket, | |
| 1374 | 1332 | Token.Id.Identifier, |
| 1375 | 1333 | }); |
| 1376 | 1334 | } |
src-self-hosted/translate_c.zig+20-9| ... | ... | @@ -1105,19 +1105,32 @@ fn transCreateNodePtrType( |
| 1105 | 1105 | is_const: bool, |
| 1106 | 1106 | is_volatile: bool, |
| 1107 | 1107 | op_tok_id: std.zig.Token.Id, |
| 1108 | bytes: []const u8, | |
| 1109 | 1108 | ) !*ast.Node.PrefixOp { |
| 1110 | 1109 | const node = try c.a().create(ast.Node.PrefixOp); |
| 1110 | const op_token = switch (op_tok_id) { | |
| 1111 | .LBracket => blk: { | |
| 1112 | const lbracket = try appendToken(c, .LBracket, "["); | |
| 1113 | _ = try appendToken(c, .Asterisk, "*"); | |
| 1114 | _ = try appendToken(c, .RBracket, "]"); | |
| 1115 | break :blk lbracket; | |
| 1116 | }, | |
| 1117 | .Identifier => blk: { | |
| 1118 | _ = try appendToken(c, .LBracket, "["); | |
| 1119 | _ = try appendToken(c, .Asterisk, "*"); | |
| 1120 | const c_ident = try appendToken(c, .Identifier, "c"); | |
| 1121 | _ = try appendToken(c, .RBracket, "]"); | |
| 1122 | break :blk c_ident; | |
| 1123 | }, | |
| 1124 | .Asterisk => try appendToken(c, .Asterisk, "*"), | |
| 1125 | else => unreachable, | |
| 1126 | }; | |
| 1111 | 1127 | node.* = ast.Node.PrefixOp{ |
| 1112 | 1128 | .base = ast.Node{ .id = .PrefixOp }, |
| 1113 | .op_token = try appendToken(c, op_tok_id, bytes), | |
| 1129 | .op_token = op_token, | |
| 1114 | 1130 | .op = ast.Node.PrefixOp.Op{ |
| 1115 | .PtrType = ast.Node.PrefixOp.PtrInfo{ | |
| 1116 | .allowzero_token = null, | |
| 1117 | .align_info = null, | |
| 1131 | .PtrType = .{ | |
| 1118 | 1132 | .const_token = if (is_const) try appendToken(c, .Keyword_const, "const") else null, |
| 1119 | 1133 | .volatile_token = if (is_volatile) try appendToken(c, .Keyword_volatile, "volatile") else null, |
| 1120 | .null_token = null, | |
| 1121 | 1134 | }, |
| 1122 | 1135 | }, |
| 1123 | 1136 | .rhs = undefined, // translate and set afterward |
| ... | ... | @@ -1226,7 +1239,6 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1226 | 1239 | ZigClangQualType_isConstQualified(child_qt), |
| 1227 | 1240 | ZigClangQualType_isVolatileQualified(child_qt), |
| 1228 | 1241 | .Asterisk, |
| 1229 | "*", | |
| 1230 | 1242 | ); |
| 1231 | 1243 | optional_node.rhs = &pointer_node.base; |
| 1232 | 1244 | pointer_node.rhs = try transQualType(rp, child_qt, source_loc); |
| ... | ... | @@ -1236,8 +1248,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour |
| 1236 | 1248 | rp.c, |
| 1237 | 1249 | ZigClangQualType_isConstQualified(child_qt), |
| 1238 | 1250 | ZigClangQualType_isVolatileQualified(child_qt), |
| 1239 | .BracketStarCBracket, | |
| 1240 | "[*c]", | |
| 1251 | .Identifier, | |
| 1241 | 1252 | ); |
| 1242 | 1253 | pointer_node.rhs = try transQualType(rp, child_qt, source_loc); |
| 1243 | 1254 | return &pointer_node.base; |