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...@@ -942,19 +942,52 @@ static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOp
942 return node;942 return node;
943}943}
944944
945static AstNode *trans_create_assign(Context *c, AstNode *block, Expr *lhs, Expr *rhs) {945static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block, Expr *lhs, Expr *rhs) {
946 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);946 if (!result_used) {
947 node->data.bin_op_expr.bin_op = BinOpTypeAssign;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);951 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransLValue);
950 if (node->data.bin_op_expr.op1 == nullptr)952 if (node->data.bin_op_expr.op1 == nullptr)
951 return nullptr;953 return nullptr;
952954
953 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);955 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);
954 if (node->data.bin_op_expr.op2 == nullptr)956 if (node->data.bin_op_expr.op2 == nullptr)
955 return 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 }
958}991}
959992
960static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *block, BinaryOperator *stmt) {993static 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...@@ -1037,11 +1070,7 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
1037 // TODO: int vs bool1070 // TODO: int vs bool
1038 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());1071 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1039 case BO_Assign:1072 case BO_Assign:
1040 if (result_used) {1073 return trans_create_assign(c, result_used, block, stmt->getLHS(), stmt->getRHS());
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());
1045 case BO_MulAssign:1074 case BO_MulAssign:
1046 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_MulAssign");1075 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_MulAssign");
1047 return nullptr;1076 return nullptr;
test/parsec.zig+17
...@@ -466,6 +466,23 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -466,6 +466,23 @@ pub fn addCases(cases: &tests.ParseCContext) {
466 \\}466 \\}
467 );467 );
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
469 cases.add("shift right assign with a fixed size type",486 cases.add("shift right assign with a fixed size type",
470 \\#include <stdint.h>487 \\#include <stdint.h>
471 \\int log2(uint32_t a) {488 \\int log2(uint32_t a) {