authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-08 00:00:14+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-08 00:00:14+02:00
loge21ea5bd9583e583c1691b05df682178f1bea10f
tree7d08bbba53b1987617d022d3406c50c80e4018aa
parent83b4163591982e66e7abeb2816706f0cd537633f
signaturelock-open Commit is signed but in an unrecognized format.

std-c parser loops


2 files changed, 103 insertions(+), 6 deletions(-)

lib/std/c/ast.zig+34-2
......@@ -229,6 +229,9 @@ pub const Node = struct {
229229 Label,
230230 CompoundStmt,
231231 IfStmt,
232 WhileStmt,
233 DoStmt,
234 ForStmt,
232235 StaticAssert,
233236 Declarator,
234237 Pointer,
......@@ -438,7 +441,7 @@ pub const Node = struct {
438441 pub const RecordDeclarator = struct {
439442 base: Node = Node{ .id = .RecordField },
440443 declarator: *Declarator,
441 // bit_field_expr: ?*Expr,
444 bit_field_expr: ?*Expr,
442445 };
443446
444447 pub const TypeQual = struct {
......@@ -486,12 +489,41 @@ pub const Node = struct {
486489 base: Node = Node{ .id = .IfStmt },
487490 @"if": TokenIndex,
488491 cond: *Node,
492 body: *Node,
489493 @"else": ?struct {
490494 tok: TokenIndex,
491 stmt: *Node,
495 body: *Node,
492496 },
493497 };
494498
499 pub const WhileStmt = struct {
500 base: Node = Node{ .id = .WhileStmt },
501 @"while": TokenIndex,
502 cond: *Expr,
503 rparen: TokenIndex,
504 body: *Node,
505 };
506
507 pub const DoStmt = struct {
508 base: Node = Node{ .id = .DoStmt },
509 do: TokenIndex,
510 body: *Node,
511 @"while": TokenIndex,
512 cond: *Expr,
513 semicolon: TokenIndex,
514 };
515
516 pub const ForStmt = struct {
517 base: Node = Node{ .id = .ForStmt },
518 @"for": TokenIndex,
519 init: ?*Node,
520 cond: ?*Expr,
521 semicolon: TokenIndex,
522 incr: ?*Expr,
523 rparen: TokenIndex,
524 body: *Node,
525 };
526
495527 pub const StaticAssert = struct {
496528 base: Node = Node{ .id = .StaticAssert },
497529 assert: TokenIndex,
lib/std/c/parse.zig+69-4
......@@ -1119,23 +1119,88 @@ const Parser = struct {
11191119 .cond = (try parser.expr()) orelse return parser.err(.{
11201120 .ExpectedExpr = .{ .token = parser.it.index },
11211121 }),
1122 .body = undefined,
11221123 .@"else" = null,
11231124 };
11241125 _ = try parser.expectToken(.RParen);
1126 node.body = (try parser.stmt()) orelse return parser.err(.{
1127 .ExpectedStmt = .{ .token = parser.it.index },
1128 });
11251129 if (parser.eatToken(.Keyword_else)) |else_tok| {
11261130 node.@"else" = .{
11271131 .tok = else_tok,
1128 .stmt = (try parser.stmt()) orelse return parser.err(.{
1132 .body = (try parser.stmt()) orelse return parser.err(.{
11291133 .ExpectedStmt = .{ .token = parser.it.index },
11301134 }),
11311135 };
11321136 }
11331137 return &node.base;
11341138 }
1139
1140 // TODO loop scope
1141 if (parser.eatToken(.Keyword_while)) |tok| {
1142 _ = try parser.expectToken(.LParen);
1143 const cond = (try parser.expr()) orelse return parser.err(.{
1144 .ExpectedExpr = .{ .token = parser.it.index },
1145 });
1146 const rparen = try parser.expectToken(.RParen);
1147 const node = try parser.arena.create(Node.WhileStmt);
1148 node.* = .{
1149 .@"while" = tok,
1150 .cond = cond,
1151 .rparen = rparen,
1152 .body = (try parser.stmt()) orelse return parser.err(.{
1153 .ExpectedStmt = .{ .token = parser.it.index },
1154 }),
1155 .semicolon = try parser.expectToken(.Semicolon),
1156 };
1157 return &node.base;
1158 }
1159 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);
1164 _ = try parser.expectToken(.LParen);
1165 const cond = (try parser.expr()) orelse return parser.err(.{
1166 .ExpectedExpr = .{ .token = parser.it.index },
1167 });
1168 _ = try parser.expectToken(.RParen);
1169 const node = try parser.arena.create(Node.DoStmt);
1170 node.* = .{
1171 .do = tok,
1172 .body = body,
1173 .cond = cond,
1174 .@"while" = @"while",
1175 .semicolon = try parser.expectToken(.Semicolon),
1176 };
1177 return &node.base;
1178 }
1179 if (parser.eatToken(.Keyword_for)) |tok| {
1180 _ = try parser.expectToken(.LParen);
1181 const init = if (try parser.declaration()) |decl| blk:{
1182 // TODO disallow storage class other than auto and register
1183 break :blk decl;
1184 } else try parser.exprStmt();
1185 const cond = try parser.expr();
1186 const semicolon = try parser.expectToken(.Semicolon);
1187 const incr = try parser.expr();
1188 const rparen = try parser.expectToken(.RParen);
1189 const node = try parser.arena.create(Node.ForStmt);
1190 node.* = .{
1191 .@"for" = tok,
1192 .init = init,
1193 .cond = cond,
1194 .semicolon = semicolon,
1195 .incr = incr,
1196 .rparen = rparen,
1197 .body = (try parser.stmt()) orelse return parser.err(.{
1198 .ExpectedStmt = .{ .token = parser.it.index },
1199 }),
1200 };
1201 return &node.base;
1202 }
11351203 // if (parser.eatToken(.Keyword_switch)) |tok| {}
1136 // if (parser.eatToken(.Keyword_while)) |tok| {}
1137 // if (parser.eatToken(.Keyword_do)) |tok| {}
1138 // if (parser.eatToken(.Keyword_for)) |tok| {}
11391204 // if (parser.eatToken(.Keyword_default)) |tok| {}
11401205 // if (parser.eatToken(.Keyword_case)) |tok| {}
11411206 if (parser.eatToken(.Keyword_goto)) |tok| {