mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 15:13:08 +00:00
std-c parser loops
This commit is contained in:
parent
83b4163591
commit
e21ea5bd95
@ -229,6 +229,9 @@ pub const Node = struct {
|
||||
Label,
|
||||
CompoundStmt,
|
||||
IfStmt,
|
||||
WhileStmt,
|
||||
DoStmt,
|
||||
ForStmt,
|
||||
StaticAssert,
|
||||
Declarator,
|
||||
Pointer,
|
||||
@ -438,7 +441,7 @@ pub const Node = struct {
|
||||
pub const RecordDeclarator = struct {
|
||||
base: Node = Node{ .id = .RecordField },
|
||||
declarator: *Declarator,
|
||||
// bit_field_expr: ?*Expr,
|
||||
bit_field_expr: ?*Expr,
|
||||
};
|
||||
|
||||
pub const TypeQual = struct {
|
||||
@ -486,12 +489,41 @@ pub const Node = struct {
|
||||
base: Node = Node{ .id = .IfStmt },
|
||||
@"if": TokenIndex,
|
||||
cond: *Node,
|
||||
body: *Node,
|
||||
@"else": ?struct {
|
||||
tok: TokenIndex,
|
||||
stmt: *Node,
|
||||
body: *Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const WhileStmt = struct {
|
||||
base: Node = Node{ .id = .WhileStmt },
|
||||
@"while": TokenIndex,
|
||||
cond: *Expr,
|
||||
rparen: TokenIndex,
|
||||
body: *Node,
|
||||
};
|
||||
|
||||
pub const DoStmt = struct {
|
||||
base: Node = Node{ .id = .DoStmt },
|
||||
do: TokenIndex,
|
||||
body: *Node,
|
||||
@"while": TokenIndex,
|
||||
cond: *Expr,
|
||||
semicolon: TokenIndex,
|
||||
};
|
||||
|
||||
pub const ForStmt = struct {
|
||||
base: Node = Node{ .id = .ForStmt },
|
||||
@"for": TokenIndex,
|
||||
init: ?*Node,
|
||||
cond: ?*Expr,
|
||||
semicolon: TokenIndex,
|
||||
incr: ?*Expr,
|
||||
rparen: TokenIndex,
|
||||
body: *Node,
|
||||
};
|
||||
|
||||
pub const StaticAssert = struct {
|
||||
base: Node = Node{ .id = .StaticAssert },
|
||||
assert: TokenIndex,
|
||||
|
||||
@ -1119,23 +1119,88 @@ const Parser = struct {
|
||||
.cond = (try parser.expr()) orelse return parser.err(.{
|
||||
.ExpectedExpr = .{ .token = parser.it.index },
|
||||
}),
|
||||
.body = undefined,
|
||||
.@"else" = null,
|
||||
};
|
||||
_ = try parser.expectToken(.RParen);
|
||||
node.body = (try parser.stmt()) orelse return parser.err(.{
|
||||
.ExpectedStmt = .{ .token = parser.it.index },
|
||||
});
|
||||
if (parser.eatToken(.Keyword_else)) |else_tok| {
|
||||
node.@"else" = .{
|
||||
.tok = else_tok,
|
||||
.stmt = (try parser.stmt()) orelse return parser.err(.{
|
||||
.body = (try parser.stmt()) orelse return parser.err(.{
|
||||
.ExpectedStmt = .{ .token = parser.it.index },
|
||||
}),
|
||||
};
|
||||
}
|
||||
return &node.base;
|
||||
}
|
||||
|
||||
// TODO loop scope
|
||||
if (parser.eatToken(.Keyword_while)) |tok| {
|
||||
_ = try parser.expectToken(.LParen);
|
||||
const cond = (try parser.expr()) orelse return parser.err(.{
|
||||
.ExpectedExpr = .{ .token = parser.it.index },
|
||||
});
|
||||
const rparen = try parser.expectToken(.RParen);
|
||||
const node = try parser.arena.create(Node.WhileStmt);
|
||||
node.* = .{
|
||||
.@"while" = tok,
|
||||
.cond = cond,
|
||||
.rparen = rparen,
|
||||
.body = (try parser.stmt()) orelse return parser.err(.{
|
||||
.ExpectedStmt = .{ .token = parser.it.index },
|
||||
}),
|
||||
.semicolon = try parser.expectToken(.Semicolon),
|
||||
};
|
||||
return &node.base;
|
||||
}
|
||||
if (parser.eatToken(.Keyword_do)) |tok| {
|
||||
const body = (try parser.stmt()) orelse return parser.err(.{
|
||||
.ExpectedStmt = .{ .token = parser.it.index },
|
||||
});
|
||||
const @"while" = try parser.expectToken(.Keyword_while);
|
||||
_ = try parser.expectToken(.LParen);
|
||||
const cond = (try parser.expr()) orelse return parser.err(.{
|
||||
.ExpectedExpr = .{ .token = parser.it.index },
|
||||
});
|
||||
_ = try parser.expectToken(.RParen);
|
||||
const node = try parser.arena.create(Node.DoStmt);
|
||||
node.* = .{
|
||||
.do = tok,
|
||||
.body = body,
|
||||
.cond = cond,
|
||||
.@"while" = @"while",
|
||||
.semicolon = try parser.expectToken(.Semicolon),
|
||||
};
|
||||
return &node.base;
|
||||
}
|
||||
if (parser.eatToken(.Keyword_for)) |tok| {
|
||||
_ = try parser.expectToken(.LParen);
|
||||
const init = if (try parser.declaration()) |decl| blk:{
|
||||
// TODO disallow storage class other than auto and register
|
||||
break :blk decl;
|
||||
} else try parser.exprStmt();
|
||||
const cond = try parser.expr();
|
||||
const semicolon = try parser.expectToken(.Semicolon);
|
||||
const incr = try parser.expr();
|
||||
const rparen = try parser.expectToken(.RParen);
|
||||
const node = try parser.arena.create(Node.ForStmt);
|
||||
node.* = .{
|
||||
.@"for" = tok,
|
||||
.init = init,
|
||||
.cond = cond,
|
||||
.semicolon = semicolon,
|
||||
.incr = incr,
|
||||
.rparen = rparen,
|
||||
.body = (try parser.stmt()) orelse return parser.err(.{
|
||||
.ExpectedStmt = .{ .token = parser.it.index },
|
||||
}),
|
||||
};
|
||||
return &node.base;
|
||||
}
|
||||
// if (parser.eatToken(.Keyword_switch)) |tok| {}
|
||||
// if (parser.eatToken(.Keyword_while)) |tok| {}
|
||||
// if (parser.eatToken(.Keyword_do)) |tok| {}
|
||||
// if (parser.eatToken(.Keyword_for)) |tok| {}
|
||||
// if (parser.eatToken(.Keyword_default)) |tok| {}
|
||||
// if (parser.eatToken(.Keyword_case)) |tok| {}
|
||||
if (parser.eatToken(.Keyword_goto)) |tok| {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user