authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-09-20 23:45:46-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-09-20 23:45:53-07:00
logd7775e3dca054003acaf500fcf018f9cf582b78d
treef1f6985fac00592cb8b382b00c22bc2c1390fe73
parentbe37b03f4c841ea4e309008885e1831fa86ff085

chain assignment


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

src/parsec.cpp+44-15
......@@ -942,19 +942,52 @@ static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOp
942942 return node;
943943}
944944
945static AstNode *trans_create_assign(Context *c, AstNode *block, Expr *lhs, Expr *rhs) {
946 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
947 node->data.bin_op_expr.bin_op = BinOpTypeAssign;
945static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block, Expr *lhs, Expr *rhs) {
946 if (!result_used) {
947 // common case
948 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
949 node->data.bin_op_expr.bin_op = BinOpTypeAssign;
948950
949 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransLValue);
950 if (node->data.bin_op_expr.op1 == nullptr)
951 return nullptr;
951 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransLValue);
952 if (node->data.bin_op_expr.op1 == nullptr)
953 return nullptr;
952954
953 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);
954 if (node->data.bin_op_expr.op2 == nullptr)
955 return nullptr;
955 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);
956 if (node->data.bin_op_expr.op2 == nullptr)
957 return nullptr;
956958
957 return node;
959 return node;
960 } else {
961 // worst case
962 // c: lhs = rhs
963 // zig: {
964 // zig: const _tmp = rhs;
965 // zig: lhs = _tmp;
966 // zig: _tmp
967 // zig: }
968
969 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
970
971 // const _tmp = rhs;
972 AstNode *rhs_node = trans_expr(c, true, child_block, rhs, TransRValue);
973 if (rhs_node == nullptr) return nullptr;
974 // TODO: avoid name collisions with generated variable names
975 Buf* tmp_var_name = buf_create_from_str("_tmp");
976 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, rhs_node);
977 child_block->data.block.statements.append(tmp_var_decl);
978
979 // lhs = _tmp;
980 AstNode *lhs_node = trans_expr(c, true, child_block, lhs, TransLValue);
981 if (lhs_node == nullptr) return nullptr;
982 child_block->data.block.statements.append(
983 trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,
984 trans_create_node_symbol(c, tmp_var_name)));
985
986 // _tmp
987 child_block->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
988
989 return child_block;
990 }
958991}
959992
960993static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *block, BinaryOperator *stmt) {
......@@ -1037,11 +1070,7 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
10371070 // TODO: int vs bool
10381071 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
10391072 case BO_Assign:
1040 if (result_used) {
1041 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Assign with result_used");
1042 return nullptr;
1043 }
1044 return trans_create_assign(c, block, stmt->getLHS(), stmt->getRHS());
1073 return trans_create_assign(c, result_used, block, stmt->getLHS(), stmt->getRHS());
10451074 case BO_MulAssign:
10461075 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_MulAssign");
10471076 return nullptr;
test/parsec.zig+17
......@@ -466,6 +466,23 @@ pub fn addCases(cases: &tests.ParseCContext) {
466466 \\}
467467 );
468468
469 cases.add("chaining assign",
470 \\void max(int a) {
471 \\ int b, c;
472 \\ c = b = a;
473 \\}
474 ,
475 \\export fn max(a: c_int) {
476 \\ var b: c_int;
477 \\ var c: c_int;
478 \\ c = {
479 \\ const _tmp = a;
480 \\ b = _tmp;
481 \\ _tmp;
482 \\ };
483 \\}
484 );
485
469486 cases.add("shift right assign with a fixed size type",
470487 \\#include <stdint.h>
471488 \\int log2(uint32_t a) {