authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-17 12:06:28+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-17 12:06:28+02:00
log0283ab8a1a27c9d3a7a6d88960418485a7125d1d
tree007a611cfef6d5224817e77a4475e86a033bc101
parentdaa22d42b0cdb8ccf04625ea921f3e71b647b68c
signature Commit is signed but in an unrecognized format.

translate-c-2 conditional operator


3 files changed, 56 insertions(+), 2 deletions(-)

src-self-hosted/clang.zig+4
...@@ -1055,3 +1055,7 @@ pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStm...@@ -1055,3 +1055,7 @@ pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStm
10551055
1056pub extern fn ZigClangAPFloat_toString(self: *const ZigClangAPFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8;1056pub extern fn ZigClangAPFloat_toString(self: *const ZigClangAPFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8;
1057pub extern fn ZigClangAPFloat_getValueAsApproximateDouble(*const ZigClangFloatingLiteral) f64;1057pub extern fn ZigClangAPFloat_getValueAsApproximateDouble(*const ZigClangFloatingLiteral) f64;
1058
1059pub extern fn ZigClangConditionalOperator_getCond(*const ZigClangConditionalOperator) *const ZigClangExpr;
1060pub extern fn ZigClangConditionalOperator_getTrueExpr(*const ZigClangConditionalOperator) *const ZigClangExpr;
1061pub extern fn ZigClangConditionalOperator_getFalseExpr(*const ZigClangConditionalOperator) *const ZigClangExpr;
src-self-hosted/translate_c.zig+40-2
...@@ -633,6 +633,7 @@ fn transStmt(...@@ -633,6 +633,7 @@ fn transStmt(
633 .BreakStmtClass => return transBreak(rp, scope),633 .BreakStmtClass => return transBreak(rp, scope),
634 .ForStmtClass => return transForLoop(rp, scope, @ptrCast(*const ZigClangForStmt, stmt)),634 .ForStmtClass => return transForLoop(rp, scope, @ptrCast(*const ZigClangForStmt, stmt)),
635 .FloatingLiteralClass => return transFloatingLiteral(rp, scope, @ptrCast(*const ZigClangFloatingLiteral, stmt), result_used),635 .FloatingLiteralClass => return transFloatingLiteral(rp, scope, @ptrCast(*const ZigClangFloatingLiteral, stmt), result_used),
636 .ConditionalOperatorClass => return transConditionalOperator(rp, scope, @ptrCast(*const ZigClangConditionalOperator, stmt), result_used),
636 else => {637 else => {
637 return revertAndWarn(638 return revertAndWarn(
638 rp,639 rp,
...@@ -1239,11 +1240,11 @@ fn transIfStmt(...@@ -1239,11 +1240,11 @@ fn transIfStmt(
1239 if_node.condition = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false);1240 if_node.condition = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false);
1240 _ = try appendToken(rp.c, .RParen, ")");1241 _ = try appendToken(rp.c, .RParen, ")");
12411242
1242 if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .used, .r_value);1243 if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value);
12431244
1244 if (ZigClangIfStmt_getElse(stmt)) |expr| {1245 if (ZigClangIfStmt_getElse(stmt)) |expr| {
1245 if_node.@"else" = try transCreateNodeElse(rp.c);1246 if_node.@"else" = try transCreateNodeElse(rp.c);
1246 if_node.@"else".?.body = try transStmt(rp, scope, expr, .used, .r_value);1247 if_node.@"else".?.body = try transStmt(rp, scope, expr, .unused, .r_value);
1247 }1248 }
1248 _ = try appendToken(rp.c, .Semicolon, ";");1249 _ = try appendToken(rp.c, .Semicolon, ";");
1249 return &if_node.base;1250 return &if_node.base;
...@@ -1429,6 +1430,43 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl...@@ -1429,6 +1430,43 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl
1429 return maybeSuppressResult(rp, scope, used, &node.base);1430 return maybeSuppressResult(rp, scope, used, &node.base);
1430}1431}
14311432
1433fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node {
1434 const gropued = scope.id == .Condition;
1435 const lparen = if (gropued) try appendToken(rp.c, .LParen, "(") else undefined;
1436 const if_node = try transCreateNodeIf(rp.c);
1437 var cond_scope = Scope.Condition{
1438 .base = .{
1439 .parent = scope,
1440 .id = .Condition,
1441 },
1442 };
1443
1444 const cond_expr = ZigClangConditionalOperator_getCond(stmt);
1445 const true_expr = ZigClangConditionalOperator_getTrueExpr(stmt);
1446 const false_expr = ZigClangConditionalOperator_getFalseExpr(stmt);
1447
1448 if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
1449 _ = try appendToken(rp.c, .RParen, ")");
1450
1451 if_node.body = try transExpr(rp, scope, true_expr, .used, .r_value);
1452
1453 if_node.@"else" = try transCreateNodeElse(rp.c);
1454 if_node.@"else".?.body = try transExpr(rp, scope, false_expr, .used, .r_value);
1455
1456 if (gropued) {
1457 const rparen = try appendToken(rp.c, .RParen, ")");
1458 const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
1459 grouped_expr.* = .{
1460 .lparen = lparen,
1461 .expr = &if_node.base,
1462 .rparen = rparen,
1463 };
1464 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
1465 } else {
1466 return maybeSuppressResult(rp, scope, used, &if_node.base);
1467 }
1468}
1469
1432fn maybeSuppressResult(1470fn maybeSuppressResult(
1433 rp: RestorePoint,1471 rp: RestorePoint,
1434 scope: *Scope,1472 scope: *Scope,
test/translate_c.zig+12
...@@ -837,6 +837,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -837,6 +837,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
837 \\pub export var d: f64 = @intToFloat(f64, 3);837 \\pub export var d: f64 = @intToFloat(f64, 3);
838 });838 });
839839
840 cases.add_2("conditional operator",
841 \\int bar(void) {
842 \\ if (2 ? 5 : 5 ? 4 : 6) 2;
843 \\ return 2 ? 5 : 5 ? 4 : 6;
844 \\}
845 , &[_][]const u8{
846 \\pub export fn bar() c_int {
847 \\ if ((if (2 != 0) 5 else (if (5 != 0) 4 else 6)) != 0) _ = 2;
848 \\ return if (2 != 0) 5 else if (5 != 0) 4 else 6;
849 \\}
850 });
851
840 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////852 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
841853
842 if (builtin.os != builtin.Os.windows) {854 if (builtin.os != builtin.Os.windows) {