authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-20 21:16:26-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-20 21:16:26-04:00
log0228f8c9fd848ec86aa188229ee82dfb0698ae0d
tree1418bb44201845c36d00f4b6a1de0eab9afb8e12
parentb1e04865cc2313886238e4361dcf2c849b9ecd7b

all parsec tests passing


2 files changed, 72 insertions(+), 33 deletions(-)

src/parsec.cpp+49-33
...@@ -49,6 +49,8 @@ struct Context {...@@ -49,6 +49,8 @@ struct Context {
4949
50 CodeGen *codegen;50 CodeGen *codegen;
51 ASTContext *ctx;51 ASTContext *ctx;
52
53 HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
52};54};
5355
54static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);56static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
...@@ -441,11 +443,16 @@ static bool c_is_float(Context *c, QualType qt) {...@@ -441,11 +443,16 @@ static bool c_is_float(Context *c, QualType qt) {
441 }443 }
442}444}
443445
444static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt);446enum TransLRValue {
447 TransLValue,
448 TransRValue,
449};
450
451static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrval);
445static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;452static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;
446453
447static AstNode *trans_expr(Context *c, bool result_used, AstNode *block, Expr *expr) {454static AstNode *trans_expr(Context *c, bool result_used, AstNode *block, Expr *expr, TransLRValue lrval) {
448 return trans_stmt(c, result_used, block, expr);455 return trans_stmt(c, result_used, block, expr, lrval);
449}456}
450457
451static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {458static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
...@@ -789,7 +796,7 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s...@@ -789,7 +796,7 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s
789static AstNode *trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {796static AstNode *trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
790 AstNode *child_block = trans_create_node(c, NodeTypeBlock);797 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
791 for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {798 for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
792 AstNode *child_node = trans_stmt(c, false, child_block, *it);799 AstNode *child_node = trans_stmt(c, false, child_block, *it, TransRValue);
793 if (child_node == nullptr)800 if (child_node == nullptr)
794 return nullptr;801 return nullptr;
795 if (child_node != skip_add_to_block_node)802 if (child_node != skip_add_to_block_node)
...@@ -805,7 +812,7 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt)...@@ -805,7 +812,7 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt)
805 return nullptr;812 return nullptr;
806 } else {813 } else {
807 AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);814 AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
808 return_node->data.return_expr.expr = trans_expr(c, true, block, value_expr);815 return_node->data.return_expr.expr = trans_expr(c, true, block, value_expr, TransRValue);
809 if (return_node->data.return_expr.expr == nullptr)816 if (return_node->data.return_expr.expr == nullptr)
810 return nullptr;817 return nullptr;
811 return return_node;818 return return_node;
...@@ -828,15 +835,15 @@ static AstNode *trans_conditional_operator(Context *c, bool result_used, AstNode...@@ -828,15 +835,15 @@ static AstNode *trans_conditional_operator(Context *c, bool result_used, AstNode
828 Expr *true_expr = stmt->getTrueExpr();835 Expr *true_expr = stmt->getTrueExpr();
829 Expr *false_expr = stmt->getFalseExpr();836 Expr *false_expr = stmt->getFalseExpr();
830837
831 node->data.if_bool_expr.condition = trans_expr(c, true, block, cond_expr);838 node->data.if_bool_expr.condition = trans_expr(c, true, block, cond_expr, TransRValue);
832 if (node->data.if_bool_expr.condition == nullptr)839 if (node->data.if_bool_expr.condition == nullptr)
833 return nullptr;840 return nullptr;
834841
835 node->data.if_bool_expr.then_block = trans_expr(c, result_used, block, true_expr);842 node->data.if_bool_expr.then_block = trans_expr(c, result_used, block, true_expr, TransRValue);
836 if (node->data.if_bool_expr.then_block == nullptr)843 if (node->data.if_bool_expr.then_block == nullptr)
837 return nullptr;844 return nullptr;
838845
839 node->data.if_bool_expr.else_node = trans_expr(c, result_used, block, false_expr);846 node->data.if_bool_expr.else_node = trans_expr(c, result_used, block, false_expr, TransRValue);
840 if (node->data.if_bool_expr.else_node == nullptr)847 if (node->data.if_bool_expr.else_node == nullptr)
841 return nullptr;848 return nullptr;
842849
...@@ -847,11 +854,11 @@ static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOp...@@ -847,11 +854,11 @@ static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOp
847 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);854 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
848 node->data.bin_op_expr.bin_op = bin_op;855 node->data.bin_op_expr.bin_op = bin_op;
849856
850 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs);857 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransRValue);
851 if (node->data.bin_op_expr.op1 == nullptr)858 if (node->data.bin_op_expr.op1 == nullptr)
852 return nullptr;859 return nullptr;
853860
854 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs);861 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);
855 if (node->data.bin_op_expr.op2 == nullptr)862 if (node->data.bin_op_expr.op2 == nullptr)
856 return nullptr;863 return nullptr;
857864
...@@ -992,7 +999,7 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast...@@ -992,7 +999,7 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
992 AstNode *child_block = trans_create_node(c, NodeTypeBlock);999 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
9931000
994 // const _ref = &lhs;1001 // const _ref = &lhs;
995 AstNode *lhs = trans_expr(c, true, child_block, stmt->getLHS());1002 AstNode *lhs = trans_expr(c, true, child_block, stmt->getLHS(), TransLValue);
996 if (lhs == nullptr) return nullptr;1003 if (lhs == nullptr) return nullptr;
997 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);1004 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
998 // TODO: avoid name collisions with generated variable names1005 // TODO: avoid name collisions with generated variable names
...@@ -1002,7 +1009,7 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast...@@ -1002,7 +1009,7 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
10021009
1003 // *_ref = result_type(operation_type(*_ref) >> u5(rhs));1010 // *_ref = result_type(operation_type(*_ref) >> u5(rhs));
10041011
1005 AstNode *rhs = trans_expr(c, true, child_block, stmt->getRHS());1012 AstNode *rhs = trans_expr(c, true, child_block, stmt->getRHS(), TransRValue);
1006 if (rhs == nullptr) return nullptr;1013 if (rhs == nullptr) return nullptr;
1007 const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();1014 const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
1008 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);1015 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
...@@ -1074,10 +1081,10 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast...@@ -1074,10 +1081,10 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
1074static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {1081static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
1075 switch (stmt->getCastKind()) {1082 switch (stmt->getCastKind()) {
1076 case CK_LValueToRValue:1083 case CK_LValueToRValue:
1077 return trans_expr(c, true, block, stmt->getSubExpr());1084 return trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);
1078 case CK_IntegralCast:1085 case CK_IntegralCast:
1079 {1086 {
1080 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr());1087 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);
1081 if (target_node == nullptr)1088 if (target_node == nullptr)
1082 return nullptr;1089 return nullptr;
1083 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);1090 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);
...@@ -1254,10 +1261,13 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas...@@ -1254,10 +1261,13 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas
1254 zig_unreachable();1261 zig_unreachable();
1255}1262}
12561263
1257static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {1264static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue lrval) {
1258 ValueDecl *value_decl = stmt->getDecl();1265 ValueDecl *value_decl = stmt->getDecl();
1259 const char *name = decl_name(value_decl);1266 Buf *symbol_name = buf_create_from_str(decl_name(value_decl));
1260 return trans_create_node_symbol_str(c, name);1267 if (lrval == TransLValue) {
1268 c->ptr_params.put(symbol_name, true);
1269 }
1270 return trans_create_node_symbol(c, symbol_name);
1261}1271}
12621272
1263static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {1273static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
...@@ -1290,7 +1300,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *...@@ -1290,7 +1300,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *
1290 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);1300 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
1291 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;1301 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
12921302
1293 node->data.prefix_op_expr.primary_expr = trans_expr(c, true, block, op_expr);1303 node->data.prefix_op_expr.primary_expr = trans_expr(c, true, block, op_expr, TransRValue);
1294 if (node->data.prefix_op_expr.primary_expr == nullptr)1304 if (node->data.prefix_op_expr.primary_expr == nullptr)
1295 return nullptr;1305 return nullptr;
12961306
...@@ -1300,7 +1310,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *...@@ -1300,7 +1310,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *
1300 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);1310 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1301 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);1311 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
13021312
1303 node->data.bin_op_expr.op2 = trans_expr(c, true, block, op_expr);1313 node->data.bin_op_expr.op2 = trans_expr(c, true, block, op_expr, TransRValue);
1304 if (node->data.bin_op_expr.op2 == nullptr)1314 if (node->data.bin_op_expr.op2 == nullptr)
1305 return nullptr;1315 return nullptr;
13061316
...@@ -1342,7 +1352,7 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st...@@ -1342,7 +1352,7 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
1342 QualType qual_type = var_decl->getTypeSourceInfo()->getType();1352 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
1343 AstNode *init_node = nullptr;1353 AstNode *init_node = nullptr;
1344 if (var_decl->hasInit()) {1354 if (var_decl->hasInit()) {
1345 init_node = trans_expr(c, true, block, var_decl->getInit());1355 init_node = trans_expr(c, true, block, var_decl->getInit(), TransRValue);
1346 if (init_node == nullptr)1356 if (init_node == nullptr)
1347 return nullptr;1357 return nullptr;
13481358
...@@ -1351,8 +1361,10 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st...@@ -1351,8 +1361,10 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
1351 if (type_node == nullptr)1361 if (type_node == nullptr)
1352 return nullptr;1362 return nullptr;
13531363
1364 Buf *symbol_name = buf_create_from_str(decl_name(var_decl));
1365
1354 AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),1366 AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),
1355 buf_create_from_str(decl_name(var_decl)), type_node, init_node);1367 symbol_name, type_node, init_node);
1356 block->data.block.statements.append(node);1368 block->data.block.statements.append(node);
1357 continue;1369 continue;
1358 }1370 }
...@@ -1583,18 +1595,18 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st...@@ -1583,18 +1595,18 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
1583static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {1595static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {
1584 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);1596 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
15851597
1586 while_node->data.while_expr.condition = trans_expr(c, true, block, stmt->getCond());1598 while_node->data.while_expr.condition = trans_expr(c, true, block, stmt->getCond(), TransRValue);
1587 if (while_node->data.while_expr.condition == nullptr)1599 if (while_node->data.while_expr.condition == nullptr)
1588 return nullptr;1600 return nullptr;
15891601
1590 while_node->data.while_expr.body = trans_stmt(c, false, block, stmt->getBody());1602 while_node->data.while_expr.body = trans_stmt(c, false, block, stmt->getBody(), TransRValue);
1591 if (while_node->data.while_expr.body == nullptr)1603 if (while_node->data.while_expr.body == nullptr)
1592 return nullptr;1604 return nullptr;
15931605
1594 return while_node;1606 return while_node;
1595}1607}
15961608
1597static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt) {1609static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) {
1598 Stmt::StmtClass sc = stmt->getStmtClass();1610 Stmt::StmtClass sc = stmt->getStmtClass();
1599 switch (sc) {1611 switch (sc) {
1600 case Stmt::ReturnStmtClass:1612 case Stmt::ReturnStmtClass:
...@@ -1612,7 +1624,7 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s...@@ -1612,7 +1624,7 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
1612 case Stmt::ImplicitCastExprClass:1624 case Stmt::ImplicitCastExprClass:
1613 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);1625 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
1614 case Stmt::DeclRefExprClass:1626 case Stmt::DeclRefExprClass:
1615 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt);1627 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt, lrvalue);
1616 case Stmt::UnaryOperatorClass:1628 case Stmt::UnaryOperatorClass:
1617 return trans_unary_operator(c, block, (UnaryOperator *)stmt);1629 return trans_unary_operator(c, block, (UnaryOperator *)stmt);
1618 case Stmt::DeclStmtClass:1630 case Stmt::DeclStmtClass:
...@@ -2230,9 +2242,9 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2230,9 +2242,9 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
2230 }2242 }
22312243
2232 // actual function definition with body2244 // actual function definition with body
22332245 c->ptr_params.clear();
2234 Stmt *body = fn_decl->getBody();2246 Stmt *body = fn_decl->getBody();
2235 AstNode *actual_body_node = trans_stmt(c, false, nullptr, body);2247 AstNode *actual_body_node = trans_stmt(c, false, nullptr, body, TransRValue);
2236 assert(actual_body_node != skip_add_to_block_node);2248 assert(actual_body_node != skip_add_to_block_node);
2237 if (actual_body_node == nullptr) {2249 if (actual_body_node == nullptr) {
2238 emit_warning(c, fn_decl->getLocation(), "unable to translate function");2250 emit_warning(c, fn_decl->getLocation(), "unable to translate function");
...@@ -2247,14 +2259,17 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2247,14 +2259,17 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
2247 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {2259 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
2248 AstNode *param_node = proto_node->data.fn_proto.params.at(i);2260 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
2249 Buf *good_name = param_node->data.param_decl.name;2261 Buf *good_name = param_node->data.param_decl.name;
2250 // TODO: avoid name collisions
2251 Buf *mangled_name = buf_sprintf("_arg_%s", buf_ptr(good_name));
2252 param_node->data.param_decl.name = mangled_name;
22532262
2254 // var c_name = _mangled_name;2263 if (c->ptr_params.maybe_get(good_name) != nullptr) {
2255 AstNode *parameter_init = trans_create_node_var_decl_local(c, false, good_name, nullptr, trans_create_node_symbol(c, mangled_name));2264 // TODO: avoid name collisions
2265 Buf *mangled_name = buf_sprintf("_arg_%s", buf_ptr(good_name));
2266 param_node->data.param_decl.name = mangled_name;
22562267
2257 body_node_with_param_inits->data.block.statements.append(parameter_init);2268 // var c_name = _mangled_name;
2269 AstNode *parameter_init = trans_create_node_var_decl_local(c, false, good_name, nullptr, trans_create_node_symbol(c, mangled_name));
2270
2271 body_node_with_param_inits->data.block.statements.append(parameter_init);
2272 }
2258 }2273 }
22592274
2260 for (size_t i = 0; i < actual_body_node->data.block.statements.length; i += 1) {2275 for (size_t i = 0; i < actual_body_node->data.block.statements.length; i += 1) {
...@@ -2875,6 +2890,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch...@@ -2875,6 +2890,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
2875 c->visib_mod = VisibModPub;2890 c->visib_mod = VisibModPub;
2876 c->decl_table.init(8);2891 c->decl_table.init(8);
2877 c->macro_table.init(8);2892 c->macro_table.init(8);
2893 c->ptr_params.init(8);
2878 c->codegen = codegen;2894 c->codegen = codegen;
2879 c->source_node = source_node;2895 c->source_node = source_node;
28802896
test/parsec.zig+23
...@@ -314,4 +314,27 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -314,4 +314,27 @@ pub fn addCases(cases: &tests.ParseCContext) {
314 ,314 ,
315 \\pub const LUA_GLOBALSINDEX = -10002;315 \\pub const LUA_GLOBALSINDEX = -10002;
316 );316 );
317
318 cases.add("sift right assign",
319 \\int log2(unsigned a) {
320 \\ int i = 0;
321 \\ while (a > 0) {
322 \\ a >>= 100;
323 \\ //i++;
324 \\ }
325 \\ return i;
326 \\}
327 ,
328 \\export fn log2(_arg_a: c_uint) -> c_int {
329 \\ var a = _arg_a;
330 \\ var i: c_int = 0;
331 \\ while (a > c_uint(0)) {
332 \\ {
333 \\ const _ref = &a;
334 \\ *_ref = c_uint(c_uint(*_ref) >> @import("std").math.Log2Int(c_uint)(100));
335 \\ };
336 \\ };
337 \\ return i;
338 \\}
339 );
317}340}