Commit aea46dcd7e
Changed files (3)
src-self-hosted
test
src-self-hosted/c_tokenizer.zig
@@ -31,6 +31,8 @@ pub const CToken = struct {
LBrace,
RBrace,
Pipe,
+ QuestionMark,
+ Colon,
};
pub const NumLitSuffix = enum {
@@ -365,6 +367,14 @@ fn next(chars: [*:0]const u8, i: *usize) !CToken {
result.id = .Pipe;
state = .Done;
},
+ '?' => {
+ result.id = .QuestionMark;
+ state = .Done;
+ },
+ ':' => {
+ result.id = .Colon;
+ state = .Done;
+ },
else => return error.TokenizingFailed,
}
},
src-self-hosted/translate_c.zig
@@ -4545,6 +4545,18 @@ fn parseCSuffixOpExpr(rp: RestorePoint, it: *ctok.TokenList.Iterator, source_loc
call_node.rtoken = try appendToken(rp.c, .RParen, ")");
node = &call_node.base;
},
+ .QuestionMark => {
+ // must come immediately after expr
+ _ = try appendToken(rp.c, .RParen, ")");
+ const if_node = try transCreateNodeIf(rp.c);
+ if_node.condition = node;
+ if_node.body = try parseCPrimaryExpr(rp, it, source_loc, scope);
+ if (it.next().?.id != .Colon)
+ return error.ParseError;
+ if_node.@"else" = try transCreateNodeElse(rp.c);
+ if_node.@"else".?.body = try parseCPrimaryExpr(rp, it, source_loc, scope);
+ node = &if_node.base;
+ },
else => {
_ = it.prev();
return node;
test/translate_c.zig
@@ -2192,6 +2192,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
+ cases.add_2("macro conditional operator",
+ \\#define FOO a ? b : c
+ , &[_][]const u8{
+ \\pub const FOO = if (a) b else c;
+ });
+
/////////////// Cases for only stage1 because stage2 behavior is better ////////////////
cases.addC("Parameterless function prototypes",
\\void foo() {}