authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-16 15:22:37+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-16 18:19:24+02:00
logd9527edfe0f017cd397de7ed947e47600092f929
tree9afbe4c73c3eaf232acea35c0104b9258a4bdaf9
parentfe0e8c87b762aba6eb5ff1fad8ad7d37404476f1
signature Commit is signed but in an unrecognized format.

translate-c-2 comma operator


2 files changed, 75 insertions(+), 15 deletions(-)

src-self-hosted/translate_c.zig+60-15
...@@ -47,7 +47,7 @@ const Scope = struct {...@@ -47,7 +47,7 @@ const Scope = struct {
47 Switch,47 Switch,
48 Block,48 Block,
49 Root,49 Root,
50 While,50 Condition,
51 FnDef,51 FnDef,
52 Ref,52 Ref,
53 };53 };
...@@ -65,9 +65,13 @@ const Scope = struct {...@@ -65,9 +65,13 @@ const Scope = struct {
65 base: Scope,65 base: Scope,
66 block_node: *ast.Node.Block,66 block_node: *ast.Node.Block,
67 variables: AliasList,67 variables: AliasList,
68 label: ?[]const u8,
6869
69 /// Don't forget to set rbrace token later70 /// Don't forget to set rbrace token later
70 fn init(c: *Context, parent: *Scope, block_node: *ast.Node.Block) !*Block {71 fn init(c: *Context, parent: *Scope, want_label: bool) !*Block {
72 // TODO removing `?[]const u8` here causes LLVM error
73 const label: ?[]const u8 = if (want_label) try std.fmt.allocPrint(c.a(), "blk_{}", .{c.getMangle()}) else null;
74 const block_node = try transCreateNodeBlock(c, label);
71 const block = try c.a().create(Block);75 const block = try c.a().create(Block);
72 block.* = .{76 block.* = .{
73 .base = .{77 .base = .{
...@@ -76,6 +80,7 @@ const Scope = struct {...@@ -76,6 +80,7 @@ const Scope = struct {
76 },80 },
77 .block_node = block_node,81 .block_node = block_node,
78 .variables = AliasList.init(c.a()),82 .variables = AliasList.init(c.a()),
83 .label = label,
79 };84 };
80 return block;85 return block;
81 }86 }
...@@ -120,7 +125,8 @@ const Scope = struct {...@@ -120,7 +125,8 @@ const Scope = struct {
120 }125 }
121 };126 };
122127
123 const While = struct {128 const Condition = struct {
129 expr: *ast.Node,
124 base: Scope,130 base: Scope,
125 };131 };
126132
...@@ -157,10 +163,19 @@ const Scope = struct {...@@ -157,10 +163,19 @@ const Scope = struct {
157 }163 }
158 };164 };
159165
160 fn findBlockScope(inner: *Scope) *Scope.Block {166 fn findBlockScope(inner: *Scope, c: *Context) !*Scope.Block {
161 var scope = inner;167 var scope = inner;
162 while (true) : (scope = scope.parent orelse unreachable) {168 while (true) {
163 if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope);169 switch (scope.id) {
170 .Root => unreachable,
171 .Block => return @fieldParentPtr(Block, "base", scope),
172 .Condition => {
173 const cond = @fieldParentPtr(Condition, "base", scope);
174 // comma operator used
175 return try Block.init(c, scope, true);
176 },
177 else => scope = inner,
178 }
164 }179 }
165 }180 }
166181
...@@ -751,7 +766,6 @@ fn transBinaryOperator(...@@ -751,7 +766,6 @@ fn transBinaryOperator(
751 .Or,766 .Or,
752 .LAnd,767 .LAnd,
753 .LOr,768 .LOr,
754 .Comma,
755 => return revertAndWarn(769 => return revertAndWarn(
756 rp,770 rp,
757 error.UnsupportedTranslation,771 error.UnsupportedTranslation,
...@@ -759,6 +773,23 @@ fn transBinaryOperator(...@@ -759,6 +773,23 @@ fn transBinaryOperator(
759 "TODO: handle more C binary operators: {}",773 "TODO: handle more C binary operators: {}",
760 .{op},774 .{op},
761 ),775 ),
776 .Comma => {
777 const block_scope = try scope.findBlockScope(rp.c);
778
779 const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);
780 try block_scope.block_node.statements.push(lhs);
781
782 const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
783 if (block_scope.base.parent == scope) {
784 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
785 _ = try appendToken(rp.c, .Semicolon, ";");
786 try block_scope.block_node.statements.push(&break_node.base);
787 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
788 return maybeSuppressResult(rp, scope, result_used, &block_scope.block_node.base);
789 } else {
790 return maybeSuppressResult(rp, scope, result_used, rhs);
791 }
792 },
762 .MulAssign,793 .MulAssign,
763 .DivAssign,794 .DivAssign,
764 .RemAssign,795 .RemAssign,
...@@ -790,11 +821,10 @@ fn transCompoundStmtInline(...@@ -790,11 +821,10 @@ fn transCompoundStmtInline(
790}821}
791822
792fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {823fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {
793 const block_node = try transCreateNodeBlock(rp.c, null);824 const block_scope = try Scope.Block.init(rp.c, scope, false);
794 const block_scope = try Scope.Block.init(rp.c, scope, block_node);825 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
795 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_node);826 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
796 block_node.rbrace = try appendToken(rp.c, .RBrace, "}");827 return &block_scope.block_node.base;
797 return &block_node.base;
798}828}
799829
800fn transCStyleCastExprClass(830fn transCStyleCastExprClass(
...@@ -818,7 +848,7 @@ fn transCStyleCastExprClass(...@@ -818,7 +848,7 @@ fn transCStyleCastExprClass(
818848
819fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!*ast.Node {849fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt) TransError!*ast.Node {
820 const c = rp.c;850 const c = rp.c;
821 const block_scope = scope.findBlockScope();851 const block_scope = try scope.findBlockScope(c);
822852
823 var it = ZigClangDeclStmt_decl_begin(stmt);853 var it = ZigClangDeclStmt_decl_begin(stmt);
824 const end_it = ZigClangDeclStmt_decl_end(stmt);854 const end_it = ZigClangDeclStmt_decl_end(stmt);
...@@ -927,7 +957,7 @@ fn transImplicitCastExpr(...@@ -927,7 +957,7 @@ fn transImplicitCastExpr(
927 return transExpr(rp, scope, sub_expr, .used, .r_value);957 return transExpr(rp, scope, sub_expr, .used, .r_value);
928 },958 },
929 .NullToPointer => {959 .NullToPointer => {
930 return transCreateNodeNullLiteral(rp.c);960 return try transCreateNodeNullLiteral(rp.c);
931 },961 },
932 else => |kind| return revertAndWarn(962 else => |kind| return revertAndWarn(
933 rp,963 rp,
...@@ -1185,7 +1215,7 @@ fn transImplicitValueInitExpr(...@@ -1185,7 +1215,7 @@ fn transImplicitValueInitExpr(
1185 .Builtin => blk: {1215 .Builtin => blk: {
1186 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);1216 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
1187 switch (ZigClangBuiltinType_getKind(builtin_ty)) {1217 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
1188 .Bool => return transCreateNodeBoolLiteral(rp.c, false),1218 .Bool => return try transCreateNodeBoolLiteral(rp.c, false),
1189 .Char_U,1219 .Char_U,
1190 .UChar,1220 .UChar,
1191 .Char_S,1221 .Char_S,
...@@ -2046,6 +2076,21 @@ fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block {...@@ -2046,6 +2076,21 @@ fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block {
2046 return block_node;2076 return block_node;
2047}2077}
20482078
2079fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression {
2080 const ltoken = try appendToken(c, .Keyword_break, "break");
2081 const label_node = if (label) |l| blk: {
2082 _ = try appendToken(c, .Colon, ":");
2083 break :blk try transCreateNodeIdentifier(c, l);
2084 } else null;
2085 const node = try c.a().create(ast.Node.ControlFlowExpression);
2086 node.* = ast.Node.ControlFlowExpression{
2087 .ltoken = ltoken,
2088 .kind = .{ .Break = label_node },
2089 .rhs = null,
2090 };
2091 return node;
2092}
2093
2049const RestorePoint = struct {2094const RestorePoint = struct {
2050 c: *Context,2095 c: *Context,
2051 token_index: ast.TokenIndex,2096 token_index: ast.TokenIndex,
test/translate_c.zig+15
...@@ -699,6 +699,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -699,6 +699,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
699 \\}699 \\}
700 });700 });
701701
702 cases.add_2("comma operator",
703 \\int foo(char c) {
704 \\ 2, 4;
705 \\ return 2, 4, 6;
706 \\}
707 , &[_][]const u8{
708 \\pub export fn foo(c: u8) c_int {
709 \\ _ = 2;
710 \\ _ = 4;
711 \\ _ = 2;
712 \\ _ = 4;
713 \\ return 6;
714 \\}
715 });
716
702 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////717 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
703718
704 if (builtin.os != builtin.Os.windows) {719 if (builtin.os != builtin.Os.windows) {