| author | |
| committer | |
| log | 3ed6d7d24589aa295409880239833fdc8d6be9d6 |
| tree | dbc34e02bcde7e5f4cc2ba668d41ff7382629b03 |
| parent | d5d52af26ec3d3e6a171564112978a7d8c96aba4 |
| signature | Commit is signed but in an unrecognized format. |
2 files changed, 153 insertions(+), 37 deletions(-)
lib/std/c/ast.zig+37-16| ... | @@ -41,6 +41,7 @@ pub const Error = union(enum) { | ... | @@ -41,6 +41,7 @@ pub const Error = union(enum) { |
| 41 | ExpectedStmt: SingleTokenError("expected statement, found '{}'"), | 41 | ExpectedStmt: SingleTokenError("expected statement, found '{}'"), |
| 42 | ExpectedTypeName: SingleTokenError("expected type name, found '{}'"), | 42 | ExpectedTypeName: SingleTokenError("expected type name, found '{}'"), |
| 43 | ExpectedFnBody: SingleTokenError("expected function body, found '{}'"), | 43 | ExpectedFnBody: SingleTokenError("expected function body, found '{}'"), |
| 44 | ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"), | ||
| 44 | ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"), | 45 | ExpectedInitializer: SingleTokenError("expected initializer, found '{}'"), |
| 45 | InvalidTypeSpecifier: InvalidTypeSpecifier, | 46 | InvalidTypeSpecifier: InvalidTypeSpecifier, |
| 46 | DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"), | 47 | DuplicateQualifier: SingleTokenError("duplicate type qualifier '{}'"), |
| ... | @@ -55,6 +56,7 @@ pub const Error = union(enum) { | ... | @@ -55,6 +56,7 @@ pub const Error = union(enum) { |
| 55 | .ExpectedTypeName => |*x| return x.render(tokens, stream), | 56 | .ExpectedTypeName => |*x| return x.render(tokens, stream), |
| 56 | .ExpectedDeclarator => |*x| return x.render(tokens, stream), | 57 | .ExpectedDeclarator => |*x| return x.render(tokens, stream), |
| 57 | .ExpectedFnBody => |*x| return x.render(tokens, stream), | 58 | .ExpectedFnBody => |*x| return x.render(tokens, stream), |
| 59 | .ExpectedInitializer => |*x| return x.render(tokens, stream), | ||
| 58 | .InvalidTypeSpecifier => |*x| return x.render(tokens, stream), | 60 | .InvalidTypeSpecifier => |*x| return x.render(tokens, stream), |
| 59 | .DuplicateQualifier => |*x| return x.render(tokens, stream), | 61 | .DuplicateQualifier => |*x| return x.render(tokens, stream), |
| 60 | .DuplicateSpecifier => |*x| return x.render(tokens, stream), | 62 | .DuplicateSpecifier => |*x| return x.render(tokens, stream), |
| ... | @@ -70,6 +72,7 @@ pub const Error = union(enum) { | ... | @@ -70,6 +72,7 @@ pub const Error = union(enum) { |
| 70 | .ExpectedTypeName => |x| return x.token, | 72 | .ExpectedTypeName => |x| return x.token, |
| 71 | .ExpectedDeclarator => |x| return x.token, | 73 | .ExpectedDeclarator => |x| return x.token, |
| 72 | .ExpectedFnBody => |x| return x.token, | 74 | .ExpectedFnBody => |x| return x.token, |
| 75 | .ExpectedInitializer => |x| return x.token, | ||
| 73 | .InvalidTypeSpecifier => |x| return x.token, | 76 | .InvalidTypeSpecifier => |x| return x.token, |
| 74 | .DuplicateQualifier => |x| return x.token, | 77 | .DuplicateQualifier => |x| return x.token, |
| 75 | .DuplicateSpecifier => |x| return x.token, | 78 | .DuplicateSpecifier => |x| return x.token, |
| ... | @@ -277,30 +280,48 @@ pub const Node = struct { | ... | @@ -277,30 +280,48 @@ pub const Node = struct { |
| 277 | }; | 280 | }; |
| 278 | 281 | ||
| 279 | pub const Declarator = struct { | 282 | pub const Declarator = struct { |
| 283 | base: Node = Node{ .id = .Declarator }, | ||
| 280 | pointer: *Pointer, | 284 | pointer: *Pointer, |
| 281 | identifier: ?TokenIndex, | 285 | prefix: union(enum) { |
| 282 | kind: union(enum) { | 286 | None, |
| 283 | Simple, | 287 | Identifer: TokenIndex, |
| 284 | Complex: struct { | 288 | Complex: struct { |
| 285 | lparen: TokenIndex, | 289 | lparen: TokenIndex, |
| 286 | inner: *Declarator, | 290 | inner: *Node, |
| 287 | rparen: TokenIndex, | 291 | rparen: TokenIndex, |
| 288 | }, | 292 | }, |
| 289 | Fn: ParamList, | 293 | }, |
| 290 | Array: ArrayList, | 294 | suffix: union(enum) { |
| 295 | None, | ||
| 296 | Fn: struct { | ||
| 297 | lparen: TokenIndex, | ||
| 298 | params: Params, | ||
| 299 | rparen: TokenIndex, | ||
| 300 | }, | ||
| 301 | Array: Arrays, | ||
| 291 | }, | 302 | }, |
| 292 | 303 | ||
| 293 | pub const ArrayList = std.SegmentedList(*Array, 2); | 304 | pub const Arrays = std.SegmentedList(*Array, 2); |
| 294 | pub const ParamList = std.SegmentedList(*Param, 4); | 305 | pub const Params = std.SegmentedList(*Param, 4); |
| 295 | }; | 306 | }; |
| 296 | 307 | ||
| 297 | pub const Array = union(enum) { | 308 | pub const Array = struct { |
| 298 | Unspecified, | 309 | rbracket: TokenIndex, |
| 299 | Variable: TokenIndex, | 310 | inner: union(enum) { |
| 300 | Known: *Expr, | 311 | Inferred, |
| 312 | Unspecified: TokenIndex, | ||
| 313 | Variable: struct { | ||
| 314 | asterisk: ?TokenIndex, | ||
| 315 | static: ?TokenIndex, | ||
| 316 | qual: TypeQual, | ||
| 317 | expr: *Expr, | ||
| 318 | }, | ||
| 319 | }, | ||
| 320 | rbracket: TokenIndex, | ||
| 301 | }; | 321 | }; |
| 302 | 322 | ||
| 303 | pub const Pointer = struct { | 323 | pub const Pointer = struct { |
| 324 | base: Node = Node{ .id = .Pointer }, | ||
| 304 | asterisk: TokenIndex, | 325 | asterisk: TokenIndex, |
| 305 | qual: TypeQual, | 326 | qual: TypeQual, |
| 306 | pointer: ?*Pointer, | 327 | pointer: ?*Pointer, |
| ... | @@ -312,7 +333,7 @@ pub const Node = struct { | ... | @@ -312,7 +333,7 @@ pub const Node = struct { |
| 312 | Old: TokenIndex, | 333 | Old: TokenIndex, |
| 313 | Normal: struct { | 334 | Normal: struct { |
| 314 | decl_spec: *DeclSpec, | 335 | decl_spec: *DeclSpec, |
| 315 | declarator: *Declarator, | 336 | declarator: *Node, |
| 316 | }, | 337 | }, |
| 317 | }, | 338 | }, |
| 318 | }; | 339 | }; |
| ... | @@ -320,7 +341,7 @@ pub const Node = struct { | ... | @@ -320,7 +341,7 @@ pub const Node = struct { |
| 320 | pub const Fn = struct { | 341 | pub const Fn = struct { |
| 321 | base: Node = Node{ .id = .Fn }, | 342 | base: Node = Node{ .id = .Fn }, |
| 322 | decl_spec: DeclSpec, | 343 | decl_spec: DeclSpec, |
| 323 | declarator: *Declarator, | 344 | declarator: *Node, |
| 324 | old_decls: OldDeclList, | 345 | old_decls: OldDeclList, |
| 325 | body: ?*CompoundStmt, | 346 | body: ?*CompoundStmt, |
| 326 | 347 | ||
| ... | @@ -332,7 +353,7 @@ pub const Node = struct { | ... | @@ -332,7 +353,7 @@ pub const Node = struct { |
| 332 | decl_spec: DeclSpec, | 353 | decl_spec: DeclSpec, |
| 333 | declarators: DeclaratorList, | 354 | declarators: DeclaratorList, |
| 334 | 355 | ||
| 335 | pub const DeclaratorList = std.SegmentedList(*Declarator, 2); | 356 | pub const DeclaratorList = Root.DeclList; |
| 336 | }; | 357 | }; |
| 337 | 358 | ||
| 338 | pub const Var = struct { | 359 | pub const Var = struct { |
| ... | @@ -344,7 +365,7 @@ pub const Node = struct { | ... | @@ -344,7 +365,7 @@ pub const Node = struct { |
| 344 | }; | 365 | }; |
| 345 | 366 | ||
| 346 | pub const Initialized = struct { | 367 | pub const Initialized = struct { |
| 347 | declarator: *Declarator, | 368 | declarator: *Node, |
| 348 | eq: TokenIndex, | 369 | eq: TokenIndex, |
| 349 | init: Initializer, | 370 | init: Initializer, |
| 350 | }; | 371 | }; |
lib/std/c/parse.zig+116-21| ... | @@ -589,7 +589,7 @@ const Parser = struct { | ... | @@ -589,7 +589,7 @@ const Parser = struct { |
| 589 | fn recordDeclarator(parser: *Parser) !*Node {} | 589 | fn recordDeclarator(parser: *Parser) !*Node {} |
| 590 | 590 | ||
| 591 | /// Pointer <- ASTERISK TypeQual* Pointer? | 591 | /// Pointer <- ASTERISK TypeQual* Pointer? |
| 592 | fn pointer(parser: *Parser) !?*Node.Pointer { | 592 | fn pointer(parser: *Parser) Error!?*Node { |
| 593 | const asterisk = parser.eatToken(.Asterisk) orelse return null; | 593 | const asterisk = parser.eatToken(.Asterisk) orelse return null; |
| 594 | const node = try parser.arena.create(Node.Pointer); | 594 | const node = try parser.arena.create(Node.Pointer); |
| 595 | node.* = .{ | 595 | node.* = .{ |
| ... | @@ -599,34 +599,129 @@ const Parser = struct { | ... | @@ -599,34 +599,129 @@ const Parser = struct { |
| 599 | }; | 599 | }; |
| 600 | while (try parser.typeQual(&node.qual)) {} | 600 | while (try parser.typeQual(&node.qual)) {} |
| 601 | node.pointer = try parser.pointer(); | 601 | node.pointer = try parser.pointer(); |
| 602 | return node; | 602 | return &node.base; |
| 603 | } | 603 | } |
| 604 | /// DirectDeclarator | 604 | |
| 605 | /// <- IDENTIFIER | 605 | const Named = enum { |
| 606 | Must, | ||
| 607 | Allowed, | ||
| 608 | Forbidden, | ||
| 609 | }; | ||
| 610 | |||
| 611 | /// Declarator <- Pointer? DeclaratorSuffix | ||
| 612 | /// DeclaratorPrefix | ||
| 613 | /// <- IDENTIFIER // if named != .Forbidden | ||
| 606 | /// / LPAREN Declarator RPAREN | 614 | /// / LPAREN Declarator RPAREN |
| 607 | /// / DirectDeclarator LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET | 615 | /// / (none) // if named != .Must |
| 608 | /// / DirectDeclarator LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN | 616 | /// DeclaratorSuffix |
| 609 | fn directDeclarator(parser: *Parser) !*Node {} | 617 | /// <. DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)* |
| 618 | /// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN | ||
| 619 | fn declarator(parser: *Parser, named: Named) Error!?*Node { | ||
| 620 | const ptr = try parser.pointer(); | ||
| 621 | var node: *Node.Declarator = undefined; | ||
| 622 | // prefix | ||
| 623 | if (parser.eatToken(.LParen)) |lparen| { | ||
| 624 | const inner = (try parser.declarator(named)) orelse return parser.err(.{ | ||
| 625 | .ExpectedDeclarator = .{ .token = lparen + 1 }, | ||
| 626 | }); | ||
| 627 | node = try parser.arena.create(Node.Declarator); | ||
| 628 | node.* = .{ | ||
| 629 | .pointer = ptr, | ||
| 630 | .prefix = .{ | ||
| 631 | .Comples = .{ | ||
| 632 | .lparen = lparen, | ||
| 633 | .inner = inner, | ||
| 634 | .rparen = try parser.expectToken(.RParen), | ||
| 635 | }, | ||
| 636 | }, | ||
| 637 | .suffix = .None, | ||
| 638 | }; | ||
| 639 | } else if (named != .Forbidden) { | ||
| 640 | if (parser.eatToken(.Identifier)) |tok| { | ||
| 641 | node = try parser.arena.create(Node.Declarator); | ||
| 642 | node.* = .{ | ||
| 643 | .pointer = ptr, | ||
| 644 | .prefix = .{ .Simple = tok }, | ||
| 645 | .suffix = .None, | ||
| 646 | }; | ||
| 647 | } else if (named == .Must) { | ||
| 648 | return parser.err(.{ | ||
| 649 | .ExpectedToken = .{ .token = parser.it.index, .expected_id = .Identifier }, | ||
| 650 | }); | ||
| 651 | } else { | ||
| 652 | return ptr; | ||
| 653 | } | ||
| 654 | } else { | ||
| 655 | node = try parser.arena.create(Node.Declarator); | ||
| 656 | node.* = .{ | ||
| 657 | .pointer = ptr, | ||
| 658 | .prefix = .None, | ||
| 659 | .suffix = .None, | ||
| 660 | }; | ||
| 661 | } | ||
| 662 | // suffix | ||
| 663 | if (parser.eatToken(.LParen)) |lparen| { | ||
| 664 | node.suffix = .{ | ||
| 665 | .Fn = .{ | ||
| 666 | .lparen = lparen, | ||
| 667 | .params = .Node.Declarator.Params.init(parser.arena), | ||
| 668 | .rparen = undefined, | ||
| 669 | }, | ||
| 670 | }; | ||
| 671 | try parser.ParamDecl(node); | ||
| 672 | node.suffix.Fn.rparen = try parser.expectToken(.RParen); | ||
| 673 | } else { | ||
| 674 | while (parser.arrayDeclarator()) |arr| { | ||
| 675 | if (node.suffix == .None) | ||
| 676 | node.suffix = .{ .Array = .Node.Declarator.Arrays.init(parser.arena) }; | ||
| 677 | try node.suffix.Array.push(arr); | ||
| 678 | } | ||
| 679 | } | ||
| 680 | if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok| | ||
| 681 | return parser.err(.{ | ||
| 682 | .InvalidDeclarator = .{ .token = tok }, | ||
| 683 | }); | ||
| 684 | return node; | ||
| 685 | } | ||
| 610 | 686 | ||
| 611 | /// BracketDeclarator | 687 | /// ArrayDeclarator |
| 612 | /// <- Keyword_static TypeQual* AssignmentExpr | 688 | /// <- ASTERISK |
| 689 | /// / Keyword_static TypeQual* AssignmentExpr | ||
| 613 | /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr) | 690 | /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr) |
| 614 | /// / TypeQual+ AssignmentExpr? | 691 | /// / TypeQual+ AssignmentExpr? |
| 615 | /// / AssignmentExpr | 692 | /// / AssignmentExpr |
| 616 | fn bracketDeclarator(parser: *Parser) !*Node {} | 693 | fn arrayDeclarator(parser: *Parser, dr: *Node.Declarator) !?*Node.Array { |
| 694 | const lbracket = parser.eatToken(.LBracket) orelse return null; | ||
| 695 | const arr = try parser.arena.create(Node.Array); | ||
| 696 | arr.* = .{ | ||
| 697 | .lbracket = lbarcket, | ||
| 698 | .inner = .Inferred, | ||
| 699 | .rbracket = undefined, | ||
| 700 | }; | ||
| 701 | if (parser.eatToken(.Asterisk)) |tok| { | ||
| 702 | arr.inner = .{ .Unspecified = tok }; | ||
| 703 | } else { | ||
| 704 | // TODO | ||
| 705 | } | ||
| 706 | arr.rbracket = try parser.expectToken(.RBracket); | ||
| 707 | return arr; | ||
| 708 | } | ||
| 617 | 709 | ||
| 710 | /// Params <- ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)? | ||
| 618 | /// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator) | 711 | /// ParamDecl <- DeclSpec (Declarator / AbstractDeclarator) |
| 619 | fn paramDecl(parser: *Parser) !*Node {} | 712 | fn paramDecl(parser: *Parser, dr: *Node.Declarator) !void { |
| 620 | 713 | var old_style = false; | |
| 621 | /// AbstractDeclarator <- Pointer? DirectAbstractDeclarator? | 714 | while (true) { |
| 622 | fn abstractDeclarator(parser: *Parser) !*Node {} | 715 | var ds = Node.DeclSpec; |
| 623 | 716 | if (try parser.declSpec(&ds)) { | |
| 624 | /// DirectAbstractDeclarator | 717 | //TODO |
| 625 | /// <- IDENTIFIER | 718 | } else if (parser.eatToken(.Identifier)) { |
| 626 | /// / LPAREN DirectAbstractDeclarator RPAREN | 719 | old_style = true; |
| 627 | /// / DirectAbstractDeclarator? LBRACKET (ASTERISK / BracketDeclarator)? RBRACKET | 720 | } else if (parser.eatToken(.Ellipsis)) { |
| 628 | /// / DirectAbstractDeclarator? LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN | 721 | // TODO |
| 629 | fn directAbstractDeclarator(parser: *Parser) !*Node {} | 722 | } |
| 723 | } | ||
| 724 | } | ||
| 630 | 725 | ||
| 631 | /// Expr <- AssignmentExpr (COMMA Expr)* | 726 | /// Expr <- AssignmentExpr (COMMA Expr)* |
| 632 | fn expr(parser: *Parser) !*Node {} | 727 | fn expr(parser: *Parser) !*Node {} |