| ... | @@ -124,7 +124,7 @@ const Parser = struct { | ... | @@ -124,7 +124,7 @@ const Parser = struct { |
| 124 | return null; | 124 | return null; |
| 125 | } | 125 | } |
| 126 | | 126 | |
| 127 | fn declareSymbol(parser: *Parser, decl_spec: *Node.DeclSpec, dr: *Node.Declarator) Error!void { | 127 | fn declareSymbol(parser: *Parser, type_spec: Node.TypeSpec, dr: *Node.Declarator) Error!void { |
| 128 | return; // TODO | 128 | return; // TODO |
| 129 | } | 129 | } |
| 130 | | 130 | |
| ... | @@ -185,7 +185,7 @@ const Parser = struct { | ... | @@ -185,7 +185,7 @@ const Parser = struct { |
| 185 | const dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{ | 185 | const dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{ |
| 186 | .ExpectedDeclarator = .{ .token = parser.it.index }, | 186 | .ExpectedDeclarator = .{ .token = parser.it.index }, |
| 187 | })); | 187 | })); |
| 188 | try parser.declareSymbol(&ds, dr); | 188 | try parser.declareSymbol(ds.type_spec, dr); |
| 189 | try node.declarators.push(&dr.base); | 189 | try node.declarators.push(&dr.base); |
| 190 | if (parser.eatToken(.Comma)) |_| {} else break; | 190 | if (parser.eatToken(.Comma)) |_| {} else break; |
| 191 | } | 191 | } |
| ... | @@ -196,7 +196,7 @@ const Parser = struct { | ... | @@ -196,7 +196,7 @@ const Parser = struct { |
| 196 | var first_dr = try parser.declarator(.Must); | 196 | var first_dr = try parser.declarator(.Must); |
| 197 | if (first_dr != null and declaratorIsFunction(first_dr.?)) { | 197 | if (first_dr != null and declaratorIsFunction(first_dr.?)) { |
| 198 | const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?); | 198 | const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?); |
| 199 | try parser.declareSymbol(&ds, dr); | 199 | try parser.declareSymbol(ds.type_spec, dr); |
| 200 | var old_decls = Node.FnDecl.OldDeclList.init(parser.arena); | 200 | var old_decls = Node.FnDecl.OldDeclList.init(parser.arena); |
| 201 | const body = if (parser.eatToken(.Semicolon)) |_| | 201 | const body = if (parser.eatToken(.Semicolon)) |_| |
| 202 | null | 202 | null |
| ... | @@ -263,7 +263,7 @@ const Parser = struct { | ... | @@ -263,7 +263,7 @@ const Parser = struct { |
| 263 | } | 263 | } |
| 264 | var dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?); | 264 | var dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?); |
| 265 | while (true) { | 265 | while (true) { |
| 266 | try parser.declareSymbol(&ds, dr); | 266 | try parser.declareSymbol(ds.type_spec, dr); |
| 267 | if (parser.eatToken(.Equal)) |tok| { | 267 | if (parser.eatToken(.Equal)) |tok| { |
| 268 | try node.initializers.push((try parser.initializer(dr)) orelse return parser.err(.{ | 268 | try node.initializers.push((try parser.initializer(dr)) orelse return parser.err(.{ |
| 269 | .ExpectedInitializer = .{ .token = parser.it.index }, | 269 | .ExpectedInitializer = .{ .token = parser.it.index }, |
| ... | @@ -280,8 +280,27 @@ const Parser = struct { | ... | @@ -280,8 +280,27 @@ const Parser = struct { |
| 280 | } | 280 | } |
| 281 | } | 281 | } |
| 282 | | 282 | |
| 283 | fn declaratorIsFunction(dr: *Node) bool { | 283 | fn declaratorIsFunction(node: *Node) bool { |
| 284 | return false; // TODO | 284 | if (node.id != .Declarator) return false; |
| | 285 | assert(node.id == .Declarator); |
| | 286 | const dr = @fieldParentPtr(Node.Declarator, "base", node); |
| | 287 | if (dr.suffix != .Fn) return false; |
| | 288 | switch (dr.prefix) { |
| | 289 | .None, .Identifer => return true, |
| | 290 | .Complex => |inner| { |
| | 291 | var inner_node = inner.inner; |
| | 292 | while (true) { |
| | 293 | if (inner_node.id != .Declarator) return false; |
| | 294 | assert(inner_node.id == .Declarator); |
| | 295 | const inner_dr = @fieldParentPtr(Node.Declarator, "base", inner_node); |
| | 296 | if (inner_dr.pointer != null) return false; |
| | 297 | switch (inner_dr.prefix) { |
| | 298 | .None, .Identifer => return true, |
| | 299 | .Complex => |c| inner_node = c.inner, |
| | 300 | } |
| | 301 | } |
| | 302 | }, |
| | 303 | } |
| 285 | } | 304 | } |
| 286 | | 305 | |
| 287 | /// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON | 306 | /// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON |
| ... | @@ -292,12 +311,11 @@ const Parser = struct { | ... | @@ -292,12 +311,11 @@ const Parser = struct { |
| 292 | _ = try parser.expectToken(.Comma); | 311 | _ = try parser.expectToken(.Comma); |
| 293 | const str = try parser.expectToken(.StringLiteral); | 312 | const str = try parser.expectToken(.StringLiteral); |
| 294 | _ = try parser.expectToken(.RParen); | 313 | _ = try parser.expectToken(.RParen); |
| 295 | const semicolon = try parser.expectToken(.Semicolon); | | |
| 296 | const node = try parser.arena.create(Node.StaticAssert); | 314 | const node = try parser.arena.create(Node.StaticAssert); |
| 297 | node.* = .{ | 315 | node.* = .{ |
| 298 | .assert = tok, | 316 | .assert = tok, |
| 299 | .expr = const_expr, | 317 | .expr = const_expr, |
| 300 | .semicolon = semicolon, | 318 | .semicolon = try parser.expectToken(.Semicolon), |
| 301 | }; | 319 | }; |
| 302 | return &node.base; | 320 | return &node.base; |
| 303 | } | 321 | } |
| ... | @@ -761,6 +779,8 @@ const Parser = struct { | ... | @@ -761,6 +779,8 @@ const Parser = struct { |
| 761 | .ty = ty, | 779 | .ty = ty, |
| 762 | }); | 780 | }); |
| 763 | if (parser.eatToken(.LBrace)) |lbrace| { | 781 | if (parser.eatToken(.LBrace)) |lbrace| { |
| | 782 | const scope = parser.pushScope(); |
| | 783 | defer parser.popScope(scope); |
| 764 | var fields = Node.RecordType.FieldList.init(parser.arena); | 784 | var fields = Node.RecordType.FieldList.init(parser.arena); |
| 765 | while (true) { | 785 | while (true) { |
| 766 | if (parser.eatToken(.RBrace)) |rbrace| { | 786 | if (parser.eatToken(.RBrace)) |rbrace| { |
| ... | @@ -796,7 +816,9 @@ const Parser = struct { | ... | @@ -796,7 +816,9 @@ const Parser = struct { |
| 796 | .semicolon = undefined, | 816 | .semicolon = undefined, |
| 797 | }; | 817 | }; |
| 798 | while (true) { | 818 | while (true) { |
| 799 | try node.declarators.push(try parser.recordDeclarator()); | 819 | const rdr = try parser.recordDeclarator(); |
| | 820 | try parser.declareSymbol(type_spec, rdr.declarator); |
| | 821 | try node.declarators.push(&rdr.base); |
| 800 | if (parser.eatToken(.Comma)) |_| {} else break; | 822 | if (parser.eatToken(.Comma)) |_| {} else break; |
| 801 | } | 823 | } |
| 802 | | 824 | |
| ... | @@ -836,16 +858,19 @@ const Parser = struct { | ... | @@ -836,16 +858,19 @@ const Parser = struct { |
| 836 | /// / LPAREN Declarator RPAREN | 858 | /// / LPAREN Declarator RPAREN |
| 837 | /// / (none) // if named != .Must | 859 | /// / (none) // if named != .Must |
| 838 | /// DeclaratorSuffix | 860 | /// DeclaratorSuffix |
| 839 | /// <. DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)* | 861 | /// <- DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)* |
| 840 | /// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN | 862 | /// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN |
| 841 | fn declarator(parser: *Parser, named: Named) Error!?*Node { | 863 | fn declarator(parser: *Parser, named: Named) Error!?*Node { |
| 842 | const ptr = try parser.pointer(); | 864 | const ptr = try parser.pointer(); |
| 843 | var node: *Node.Declarator = undefined; | 865 | var node: *Node.Declarator = undefined; |
| | 866 | var inner_fn = false; |
| | 867 | |
| 844 | // prefix | 868 | // prefix |
| 845 | if (parser.eatToken(.LParen)) |lparen| { | 869 | if (parser.eatToken(.LParen)) |lparen| { |
| 846 | const inner = (try parser.declarator(named)) orelse return parser.err(.{ | 870 | const inner = (try parser.declarator(named)) orelse return parser.err(.{ |
| 847 | .ExpectedDeclarator = .{ .token = lparen + 1 }, | 871 | .ExpectedDeclarator = .{ .token = lparen + 1 }, |
| 848 | }); | 872 | }); |
| | 873 | inner_fn = declaratorIsFunction(inner); |
| 849 | node = try parser.arena.create(Node.Declarator); | 874 | node = try parser.arena.create(Node.Declarator); |
| 850 | node.* = .{ | 875 | node.* = .{ |
| 851 | .pointer = ptr, | 876 | .pointer = ptr, |
| ... | @@ -885,6 +910,10 @@ const Parser = struct { | ... | @@ -885,6 +910,10 @@ const Parser = struct { |
| 885 | } | 910 | } |
| 886 | // suffix | 911 | // suffix |
| 887 | if (parser.eatToken(.LParen)) |lparen| { | 912 | if (parser.eatToken(.LParen)) |lparen| { |
| | 913 | if (inner_fn) |
| | 914 | return parser.err(.{ |
| | 915 | .InvalidDeclarator = .{ .token = lparen }, |
| | 916 | }); |
| 888 | node.suffix = .{ | 917 | node.suffix = .{ |
| 889 | .Fn = .{ | 918 | .Fn = .{ |
| 890 | .lparen = lparen, | 919 | .lparen = lparen, |
| ... | @@ -894,11 +923,16 @@ const Parser = struct { | ... | @@ -894,11 +923,16 @@ const Parser = struct { |
| 894 | }; | 923 | }; |
| 895 | try parser.paramDecl(node); | 924 | try parser.paramDecl(node); |
| 896 | node.suffix.Fn.rparen = try parser.expectToken(.RParen); | 925 | node.suffix.Fn.rparen = try parser.expectToken(.RParen); |
| 897 | } else { | 926 | } else if (parser.eatToken(.LBracket)) |tok| { |
| 898 | while (try parser.arrayDeclarator()) |arr| { | 927 | if (inner_fn) |
| 899 | if (node.suffix == .None) | 928 | return parser.err(.{ |
| 900 | node.suffix = .{ .Array = Node.Declarator.Arrays.init(parser.arena) }; | 929 | .InvalidDeclarator = .{ .token = tok }, |
| 901 | try node.suffix.Array.push(arr); | 930 | }); |
| | 931 | node.suffix = .{ .Array = Node.Declarator.Arrays.init(parser.arena) }; |
| | 932 | var lbrace = tok; |
| | 933 | while (true) { |
| | 934 | try node.suffix.Array.push(try parser.arrayDeclarator(lbrace)); |
| | 935 | if (parser.eatToken(.LBracket)) |t| lbrace = t else break; |
| 902 | } | 936 | } |
| 903 | } | 937 | } |
| 904 | if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok| | 938 | if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok| |
| ... | @@ -914,8 +948,7 @@ const Parser = struct { | ... | @@ -914,8 +948,7 @@ const Parser = struct { |
| 914 | /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr) | 948 | /// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr) |
| 915 | /// / TypeQual+ AssignmentExpr? | 949 | /// / TypeQual+ AssignmentExpr? |
| 916 | /// / AssignmentExpr | 950 | /// / AssignmentExpr |
| 917 | fn arrayDeclarator(parser: *Parser) !?*Node.Array { | 951 | fn arrayDeclarator(parser: *Parser, lbracket: TokenIndex) !*Node.Array { |
| 918 | const lbracket = parser.eatToken(.LBracket) orelse return null; | | |
| 919 | const arr = try parser.arena.create(Node.Array); | 952 | const arr = try parser.arena.create(Node.Array); |
| 920 | arr.* = .{ | 953 | arr.* = .{ |
| 921 | .lbracket = lbracket, | 954 | .lbracket = lbracket, |
| ... | @@ -1046,6 +1079,8 @@ const Parser = struct { | ... | @@ -1046,6 +1079,8 @@ const Parser = struct { |
| 1046 | | 1079 | |
| 1047 | /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE | 1080 | /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE |
| 1048 | fn compoundStmt(parser: *Parser) Error!?*Node { | 1081 | fn compoundStmt(parser: *Parser) Error!?*Node { |
| | 1082 | const scope = parser.pushScope(); |
| | 1083 | defer parser.popScope(scope); |
| 1049 | const lbrace = parser.eatToken(.LBrace) orelse return null; | 1084 | const lbrace = parser.eatToken(.LBrace) orelse return null; |
| 1050 | const body_node = try parser.arena.create(Node.CompoundStmt); | 1085 | const body_node = try parser.arena.create(Node.CompoundStmt); |
| 1051 | body_node.* = .{ | 1086 | body_node.* = .{ |