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 {...@@ -229,6 +229,9 @@ pub const Node = struct {
229 Label,229 Label,
230 CompoundStmt,230 CompoundStmt,
231 IfStmt,231 IfStmt,
232 WhileStmt,
233 DoStmt,
234 ForStmt,
232 StaticAssert,235 StaticAssert,
233 Declarator,236 Declarator,
234 Pointer,237 Pointer,
...@@ -438,7 +441,7 @@ pub const Node = struct {...@@ -438,7 +441,7 @@ pub const Node = struct {
438 pub const RecordDeclarator = struct {441 pub const RecordDeclarator = struct {
439 base: Node = Node{ .id = .RecordField },442 base: Node = Node{ .id = .RecordField },
440 declarator: *Declarator,443 declarator: *Declarator,
441 // bit_field_expr: ?*Expr,444 bit_field_expr: ?*Expr,
442 };445 };
443446
444 pub const TypeQual = struct {447 pub const TypeQual = struct {
...@@ -486,12 +489,41 @@ pub const Node = struct {...@@ -486,12 +489,41 @@ pub const Node = struct {
486 base: Node = Node{ .id = .IfStmt },489 base: Node = Node{ .id = .IfStmt },
487 @"if": TokenIndex,490 @"if": TokenIndex,
488 cond: *Node,491 cond: *Node,
492 body: *Node,
489 @"else": ?struct {493 @"else": ?struct {
490 tok: TokenIndex,494 tok: TokenIndex,
491 stmt: *Node,495 body: *Node,
492 },496 },
493 };497 };
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
495 pub const StaticAssert = struct {527 pub const StaticAssert = struct {
496 base: Node = Node{ .id = .StaticAssert },528 base: Node = Node{ .id = .StaticAssert },
497 assert: TokenIndex,529 assert: TokenIndex,
lib/std/c/parse.zig+69-4
...@@ -1119,23 +1119,88 @@ const Parser = struct {...@@ -1119,23 +1119,88 @@ const Parser = struct {
1119 .cond = (try parser.expr()) orelse return parser.err(.{1119 .cond = (try parser.expr()) orelse return parser.err(.{
1120 .ExpectedExpr = .{ .token = parser.it.index },1120 .ExpectedExpr = .{ .token = parser.it.index },
1121 }),1121 }),
1122 .body = undefined,
1122 .@"else" = null,1123 .@"else" = null,
1123 };1124 };
1124 _ = try parser.expectToken(.RParen);1125 _ = try parser.expectToken(.RParen);
1126 node.body = (try parser.stmt()) orelse return parser.err(.{
1127 .ExpectedStmt = .{ .token = parser.it.index },
1128 });
1125 if (parser.eatToken(.Keyword_else)) |else_tok| {1129 if (parser.eatToken(.Keyword_else)) |else_tok| {
1126 node.@"else" = .{1130 node.@"else" = .{
1127 .tok = else_tok,1131 .tok = else_tok,
1128 .stmt = (try parser.stmt()) orelse return parser.err(.{1132 .body = (try parser.stmt()) orelse return parser.err(.{
1129 .ExpectedStmt = .{ .token = parser.it.index },1133 .ExpectedStmt = .{ .token = parser.it.index },
1130 }),1134 }),
1131 };1135 };
1132 }1136 }
1133 return &node.base;1137 return &node.base;
1134 }1138 }
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 }
1135 // if (parser.eatToken(.Keyword_switch)) |tok| {}1203 // 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| {}
1139 // if (parser.eatToken(.Keyword_default)) |tok| {}1204 // if (parser.eatToken(.Keyword_default)) |tok| {}
1140 // if (parser.eatToken(.Keyword_case)) |tok| {}1205 // if (parser.eatToken(.Keyword_case)) |tok| {}
1141 if (parser.eatToken(.Keyword_goto)) |tok| {1206 if (parser.eatToken(.Keyword_goto)) |tok| {