authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-11 21:46:36+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-11 21:48:12+02:00
log4c0776b2a5a8a92e770fe0b08a15e06671000cb6
tree5a3fbe1bf0cee6f05e5804e3c192f36fe4ff0614
parente21ea5bd9583e583c1691b05df682178f1bea10f
signaturelock-open Commit is signed but in an unrecognized format.

std-c parse switch


2 files changed, 94 insertions(+), 54 deletions(-)

lib/std/c/ast.zig+22-13
......@@ -48,7 +48,6 @@ pub const Error = union(enum) {
4848 InvalidToken: SingleTokenError("invalid token '{}'"),
4949 ExpectedToken: ExpectedToken,
5050 ExpectedExpr: SingleTokenError("expected expression, found '{}'"),
51 ExpectedStmt: SingleTokenError("expected statement, found '{}'"),
5251 ExpectedTypeName: SingleTokenError("expected type name, found '{}'"),
5352 ExpectedFnBody: SingleTokenError("expected function body, found '{}'"),
5453 ExpectedDeclarator: SingleTokenError("expected declarator, found '{}'"),
......@@ -70,7 +69,6 @@ pub const Error = union(enum) {
7069 .InvalidToken => |*x| return x.render(tree, stream),
7170 .ExpectedToken => |*x| return x.render(tree, stream),
7271 .ExpectedExpr => |*x| return x.render(tree, stream),
73 .ExpectedStmt => |*x| return x.render(tree, stream),
7472 .ExpectedTypeName => |*x| return x.render(tree, stream),
7573 .ExpectedDeclarator => |*x| return x.render(tree, stream),
7674 .ExpectedFnBody => |*x| return x.render(tree, stream),
......@@ -94,7 +92,6 @@ pub const Error = union(enum) {
9492 .InvalidToken => |x| return x.token,
9593 .ExpectedToken => |x| return x.token,
9694 .ExpectedExpr => |x| return x.token,
97 .ExpectedStmt => |x| return x.token,
9895 .ExpectedTypeName => |x| return x.token,
9996 .ExpectedDeclarator => |x| return x.token,
10097 .ExpectedFnBody => |x| return x.token,
......@@ -226,9 +223,10 @@ pub const Node = struct {
226223 RecordField,
227224 JumpStmt,
228225 ExprStmt,
229 Label,
226 LabeledStmt,
230227 CompoundStmt,
231228 IfStmt,
229 SwitchStmt,
232230 WhileStmt,
233231 DoStmt,
234232 ForStmt,
......@@ -454,26 +452,29 @@ pub const Node = struct {
454452 pub const JumpStmt = struct {
455453 base: Node = Node{ .id = .JumpStmt },
456454 ltoken: TokenIndex,
457 kind: Kind,
458 semicolon: TokenIndex,
459
460 pub const Kind = union(enum) {
455 kind: union(enum) {
461456 Break,
462457 Continue,
463458 Return: ?*Node,
464459 Goto: TokenIndex,
465 };
460 },
461 semicolon: TokenIndex,
466462 };
467463
468464 pub const ExprStmt = struct {
469465 base: Node = Node{ .id = .ExprStmt },
470 expr: ?*Node,
466 expr: ?*Expr,
471467 semicolon: TokenIndex,
472468 };
473469
474 pub const Label = struct {
475 base: Node = Node{ .id = .Label },
476 identifier: TokenIndex,
470 pub const LabeledStmt = struct {
471 base: Node = Node{ .id = .LabeledStmt },
472 kind: union(enum) {
473 Label: TokenIndex,
474 Case: TokenIndex,
475 Default: TokenIndex,
476 },
477 stmt: *Node,
477478 };
478479
479480 pub const CompoundStmt = struct {
......@@ -496,6 +497,14 @@ pub const Node = struct {
496497 },
497498 };
498499
500 pub const SwitchStmt = struct {
501 base: Node = Node{ .id = .SwitchStmt },
502 @"switch": TokenIndex,
503 expr: *Expr,
504 rparen: TokenIndex,
505 stmt: *Node,
506 };
507
499508 pub const WhileStmt = struct {
500509 base: Node = Node{ .id = .WhileStmt },
501510 @"while": TokenIndex,
lib/std/c/parse.zig+72-41
......@@ -104,7 +104,14 @@ const Parser = struct {
104104 ty: *Type,
105105 };
106106
107 fn pushScope(parser: *Parser) usize {
107 const ScopeKind = enum {
108 Block,
109 Loop,
110 Root,
111 Switch,
112 };
113
114 fn pushScope(parser: *Parser, kind: ScopeKind) usize {
108115 return parser.symbols.len;
109116 }
110117
......@@ -130,6 +137,8 @@ const Parser = struct {
130137
131138 /// Root <- ExternalDeclaration* eof
132139 fn root(parser: *Parser) Allocator.Error!*Node.Root {
140 const scope = parser.pushScope(.Root);
141 defer parser.popScope(scope);
133142 const node = try parser.arena.create(Node.Root);
134143 node.* = .{
135144 .decls = Node.Root.DeclList.init(parser.arena),
......@@ -779,7 +788,7 @@ const Parser = struct {
779788 .ty = ty,
780789 });
781790 if (parser.eatToken(.LBrace)) |lbrace| {
782 const scope = parser.pushScope();
791 const scope = parser.pushScope(.Block);
783792 defer parser.popScope(scope);
784793 var fields = Node.RecordType.FieldList.init(parser.arena);
785794 while (true) {
......@@ -1079,18 +1088,22 @@ const Parser = struct {
10791088
10801089 /// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
10811090 fn compoundStmt(parser: *Parser) Error!?*Node {
1082 const scope = parser.pushScope();
1083 defer parser.popScope(scope);
10841091 const lbrace = parser.eatToken(.LBrace) orelse return null;
1092 const scope = parser.pushScope(.Block);
1093 defer parser.popScope(scope);
10851094 const body_node = try parser.arena.create(Node.CompoundStmt);
10861095 body_node.* = .{
10871096 .lbrace = lbrace,
10881097 .statements = Node.CompoundStmt.StmtList.init(parser.arena),
10891098 .rbrace = undefined,
10901099 };
1091 while ((try parser.declaration()) orelse (try parser.stmt())) |node|
1092 try body_node.statements.push(node);
1093 body_node.rbrace = try parser.expectToken(.RBrace);
1100 while (true) {
1101 if (parser.eatToken(.RBRACE)) |rbrace| {
1102 body_node.rbrace = rbrace;
1103 break;
1104 }
1105 try body_node.statements.push((try parser.declaration()) orelse (try parser.stmt()));
1106 }
10941107 return &body_node.base;
10951108 }
10961109
......@@ -1109,7 +1122,7 @@ const Parser = struct {
11091122 /// / Keyword_return Expr? SEMICOLON
11101123 /// / IDENTIFIER COLON Stmt
11111124 /// / ExprStmt
1112 fn stmt(parser: *Parser) Error!?*Node {
1125 fn stmt(parser: *Parser) Error!*Node {
11131126 if (try parser.compoundStmt()) |node| return node;
11141127 if (parser.eatToken(.Keyword_if)) |tok| {
11151128 const node = try parser.arena.create(Node.IfStmt);
......@@ -1123,22 +1136,18 @@ const Parser = struct {
11231136 .@"else" = null,
11241137 };
11251138 _ = try parser.expectToken(.RParen);
1126 node.body = (try parser.stmt()) orelse return parser.err(.{
1127 .ExpectedStmt = .{ .token = parser.it.index },
1128 });
1139 node.body = try parser.stmt();
11291140 if (parser.eatToken(.Keyword_else)) |else_tok| {
11301141 node.@"else" = .{
11311142 .tok = else_tok,
1132 .body = (try parser.stmt()) orelse return parser.err(.{
1133 .ExpectedStmt = .{ .token = parser.it.index },
1134 }),
1143 .body = try parser.stmt(),
11351144 };
11361145 }
11371146 return &node.base;
11381147 }
1139
1140 // TODO loop scope
11411148 if (parser.eatToken(.Keyword_while)) |tok| {
1149 const scope = parser.pushScope(.Loop);
1150 defer parser.popScope(scope);
11421151 _ = try parser.expectToken(.LParen);
11431152 const cond = (try parser.expr()) orelse return parser.err(.{
11441153 .ExpectedExpr = .{ .token = parser.it.index },
......@@ -1149,18 +1158,15 @@ const Parser = struct {
11491158 .@"while" = tok,
11501159 .cond = cond,
11511160 .rparen = rparen,
1152 .body = (try parser.stmt()) orelse return parser.err(.{
1153 .ExpectedStmt = .{ .token = parser.it.index },
1154 }),
1161 .body = try parser.stmt(),
11551162 .semicolon = try parser.expectToken(.Semicolon),
11561163 };
11571164 return &node.base;
11581165 }
11591166 if (parser.eatToken(.Keyword_do)) |tok| {
1160 const body = (try parser.stmt()) orelse return parser.err(.{
1161 .ExpectedStmt = .{ .token = parser.it.index },
1162 });
1163 const @"while" = try parser.expectToken(.Keyword_while);
1167 const scope = parser.pushScope(.Loop);
1168 defer parser.popScope(scope);
1169 const body = try parser.stmt();
11641170 _ = try parser.expectToken(.LParen);
11651171 const cond = (try parser.expr()) orelse return parser.err(.{
11661172 .ExpectedExpr = .{ .token = parser.it.index },
......@@ -1177,6 +1183,8 @@ const Parser = struct {
11771183 return &node.base;
11781184 }
11791185 if (parser.eatToken(.Keyword_for)) |tok| {
1186 const scope = parser.pushScope(.Loop);
1187 defer parser.popScope(scope);
11801188 _ = try parser.expectToken(.LParen);
11811189 const init = if (try parser.declaration()) |decl| blk:{
11821190 // TODO disallow storage class other than auto and register
......@@ -1194,15 +1202,43 @@ const Parser = struct {
11941202 .semicolon = semicolon,
11951203 .incr = incr,
11961204 .rparen = rparen,
1197 .body = (try parser.stmt()) orelse return parser.err(.{
1198 .ExpectedStmt = .{ .token = parser.it.index },
1199 }),
1205 .body = try parser.stmt(),
1206 };
1207 return &node.base;
1208 }
1209 if (parser.eatToken(.Keyword_switch)) |tok| {
1210 const scope = parser.pushScope(.Switch);
1211 defer parser.popScope(scope);
1212 _ = try parser.expectToken(.LParen);
1213 const switch_expr = try parser.exprStmt();
1214 const rparen = try parser.expectToken(.RParen);
1215 const node = try parser.arena.create(Node.SwitchStmt);
1216 node.* = .{
1217 .@"switch" = tok,
1218 .expr = switch_expr,
1219 .rparen = rparen,
1220 .body = try parser.stmt(),
1221 };
1222 return &node.base;
1223 }
1224 if (parser.eatToken(.Keyword_default)) |tok| {
1225 _ = try parser.expectToken(.Colon);
1226 const node = try parser.arena.create(Node.LabeledStmt);
1227 node.* = .{
1228 .kind = .{.Default = tok },
1229 .stmt = try parser.stmt(),
1230 };
1231 return &node.base;
1232 }
1233 if (parser.eatToken(.Keyword_case)) |tok| {
1234 _ = try parser.expectToken(.Colon);
1235 const node = try parser.arena.create(Node.LabeledStmt);
1236 node.* = .{
1237 .kind = .{.Case = tok },
1238 .stmt = try parser.stmt(),
12001239 };
12011240 return &node.base;
12021241 }
1203 // if (parser.eatToken(.Keyword_switch)) |tok| {}
1204 // if (parser.eatToken(.Keyword_default)) |tok| {}
1205 // if (parser.eatToken(.Keyword_case)) |tok| {}
12061242 if (parser.eatToken(.Keyword_goto)) |tok| {
12071243 const node = try parser.arena.create(Node.JumpStmt);
12081244 node.* = .{
......@@ -1241,29 +1277,24 @@ const Parser = struct {
12411277 }
12421278 if (parser.eatToken(.Identifier)) |tok| {
12431279 if (parser.eatToken(.Colon)) |_| {
1244 const node = try parser.arena.create(Node.Label);
1280 const node = try parser.arena.create(Node.LabeledStmt);
12451281 node.* = .{
1246 .identifier = tok,
1282 .kind = .{.Label = tok },
1283 .stmt = try parser.stmt(),
12471284 };
12481285 return &node.base;
12491286 }
12501287 parser.putBackToken(tok);
12511288 }
1252 if (try parser.exprStmt()) |node| return node;
1253 return null;
1289 return parser.exprStmt();
12541290 }
12551291
12561292 /// ExprStmt <- Expr? SEMICOLON
1257 fn exprStmt(parser: *Parser) !?*Node {
1293 fn exprStmt(parser: *Parser) !*Node {
12581294 const node = try parser.arena.create(Node.ExprStmt);
1259 const expr_node = try parser.expr();
1260 const semicolon = if (expr_node != null)
1261 try parser.expectToken(.Semicolon)
1262 else
1263 parser.eatToken(.Semicolon) orelse return null;
12641295 node.* = .{
1265 .expr = expr_node,
1266 .semicolon = semicolon,
1296 .expr = try parser.expr(),
1297 .semicolon = try parser.expectToken(.Semicolon),
12671298 };
12681299 return &node.base;
12691300 }