| ... | @@ -69,6 +69,7 @@ enum TransScopeId { | ... | @@ -69,6 +69,7 @@ enum TransScopeId { |
| 69 | TransScopeIdVar, | 69 | TransScopeIdVar, |
| 70 | TransScopeIdBlock, | 70 | TransScopeIdBlock, |
| 71 | TransScopeIdRoot, | 71 | TransScopeIdRoot, |
| | 72 | TransScopeIdWhile, |
| 72 | }; | 73 | }; |
| 73 | | 74 | |
| 74 | struct TransScope { | 75 | struct TransScope { |
| ... | @@ -79,6 +80,8 @@ struct TransScope { | ... | @@ -79,6 +80,8 @@ struct TransScope { |
| 79 | struct TransScopeSwitch { | 80 | struct TransScopeSwitch { |
| 80 | TransScope base; | 81 | TransScope base; |
| 81 | AstNode *switch_node; | 82 | AstNode *switch_node; |
| | 83 | uint32_t case_index; |
| | 84 | bool found_default; |
| 82 | }; | 85 | }; |
| 83 | | 86 | |
| 84 | struct TransScopeVar { | 87 | struct TransScopeVar { |
| ... | @@ -96,12 +99,19 @@ struct TransScopeRoot { | ... | @@ -96,12 +99,19 @@ struct TransScopeRoot { |
| 96 | TransScope base; | 99 | TransScope base; |
| 97 | }; | 100 | }; |
| 98 | | 101 | |
| | 102 | struct TransScopeWhile { |
| | 103 | TransScope base; |
| | 104 | AstNode *node; |
| | 105 | }; |
| | 106 | |
| 99 | static TransScopeRoot *trans_scope_root_create(Context *c); | 107 | static TransScopeRoot *trans_scope_root_create(Context *c); |
| | 108 | static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope); |
| 100 | static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope); | 109 | static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope); |
| 101 | static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name); | 110 | static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name); |
| 102 | //static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope); | 111 | static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope); |
| 103 | | 112 | |
| 104 | static TransScopeBlock *trans_scope_block_find(TransScope *scope); | 113 | static TransScopeBlock *trans_scope_block_find(TransScope *scope); |
| | 114 | static TransScopeSwitch *trans_scope_switch_find(TransScope *scope); |
| 105 | | 115 | |
| 106 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl); | 116 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl); |
| 107 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); | 117 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| ... | @@ -238,6 +248,12 @@ static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_vol | ... | @@ -238,6 +248,12 @@ static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_vol |
| 238 | return node; | 248 | return node; |
| 239 | } | 249 | } |
| 240 | | 250 | |
| | 251 | static AstNode *trans_create_node_bool(Context *c, bool value) { |
| | 252 | AstNode *bool_node = trans_create_node(c, NodeTypeBoolLiteral); |
| | 253 | bool_node->data.bool_literal.value = value; |
| | 254 | return bool_node; |
| | 255 | } |
| | 256 | |
| 241 | static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) { | 257 | static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) { |
| 242 | AstNode *node = trans_create_node(c, NodeTypeStringLiteral); | 258 | AstNode *node = trans_create_node(c, NodeTypeStringLiteral); |
| 243 | node->data.string_literal.buf = buf; | 259 | node->data.string_literal.buf = buf; |
| ... | @@ -965,22 +981,30 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s | ... | @@ -965,22 +981,30 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s |
| 965 | return trans_type(c, qt.getTypePtr(), source_loc); | 981 | return trans_type(c, qt.getTypePtr(), source_loc); |
| 966 | } | 982 | } |
| 967 | | 983 | |
| 968 | static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const CompoundStmt *stmt, | 984 | static int trans_compound_stmt_inline(Context *c, TransScope *scope, const CompoundStmt *stmt, |
| 969 | TransScope **out_node_scope) | 985 | AstNode *block_node, TransScope **out_node_scope) |
| 970 | { | 986 | { |
| 971 | TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope); | 987 | assert(block_node->type == NodeTypeBlock); |
| 972 | scope = &child_scope_block->base; | | |
| 973 | for (CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { | 988 | for (CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { |
| 974 | AstNode *child_node; | 989 | AstNode *child_node; |
| 975 | scope = trans_stmt(c, scope, *it, &child_node); | 990 | scope = trans_stmt(c, scope, *it, &child_node); |
| 976 | if (scope == nullptr) | 991 | if (scope == nullptr) |
| 977 | return nullptr; | 992 | return ErrorUnexpected; |
| 978 | if (child_node != nullptr) | 993 | if (child_node != nullptr) |
| 979 | child_scope_block->node->data.block.statements.append(child_node); | 994 | block_node->data.block.statements.append(child_node); |
| 980 | } | 995 | } |
| 981 | if (out_node_scope != nullptr) { | 996 | if (out_node_scope != nullptr) { |
| 982 | *out_node_scope = &child_scope_block->base; | 997 | *out_node_scope = scope; |
| 983 | } | 998 | } |
| | 999 | return ErrorNone; |
| | 1000 | } |
| | 1001 | |
| | 1002 | static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const CompoundStmt *stmt, |
| | 1003 | TransScope **out_node_scope) |
| | 1004 | { |
| | 1005 | TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope); |
| | 1006 | if (trans_compound_stmt_inline(c, &child_scope_block->base, stmt, child_scope_block->node, out_node_scope)) |
| | 1007 | return nullptr; |
| 984 | return child_scope_block->node; | 1008 | return child_scope_block->node; |
| 985 | } | 1009 | } |
| 986 | | 1010 | |
| ... | @@ -2081,17 +2105,18 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt | ... | @@ -2081,17 +2105,18 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt |
| 2081 | } | 2105 | } |
| 2082 | | 2106 | |
| 2083 | static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) { | 2107 | static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) { |
| 2084 | AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); | 2108 | TransScopeWhile *while_scope = trans_scope_while_create(c, scope); |
| 2085 | | 2109 | |
| 2086 | while_node->data.while_expr.condition = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue); | 2110 | while_scope->node->data.while_expr.condition = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue); |
| 2087 | if (while_node->data.while_expr.condition == nullptr) | 2111 | if (while_scope->node->data.while_expr.condition == nullptr) |
| 2088 | return nullptr; | 2112 | return nullptr; |
| 2089 | | 2113 | |
| 2090 | TransScope *body_scope = trans_stmt(c, scope, stmt->getBody(), &while_node->data.while_expr.body); | 2114 | TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(), |
| | 2115 | &while_scope->node->data.while_expr.body); |
| 2091 | if (body_scope == nullptr) | 2116 | if (body_scope == nullptr) |
| 2092 | return nullptr; | 2117 | return nullptr; |
| 2093 | | 2118 | |
| 2094 | return while_node; | 2119 | return while_scope->node; |
| 2095 | } | 2120 | } |
| 2096 | | 2121 | |
| 2097 | static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *stmt) { | 2122 | static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *stmt) { |
| ... | @@ -2201,11 +2226,9 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop | ... | @@ -2201,11 +2226,9 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop |
| 2201 | } | 2226 | } |
| 2202 | | 2227 | |
| 2203 | static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt *stmt) { | 2228 | static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt *stmt) { |
| 2204 | AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); | 2229 | TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope); |
| 2205 | | 2230 | |
| 2206 | AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral); | 2231 | while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true); |
| 2207 | true_node->data.bool_literal.value = true; | | |
| 2208 | while_node->data.while_expr.condition = true_node; | | |
| 2209 | | 2232 | |
| 2210 | AstNode *body_node; | 2233 | AstNode *body_node; |
| 2211 | TransScope *child_scope; | 2234 | TransScope *child_scope; |
| ... | @@ -2222,7 +2245,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt | ... | @@ -2222,7 +2245,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt |
| 2222 | // zig: } | 2245 | // zig: } |
| 2223 | | 2246 | |
| 2224 | // We call the low level function so that we can set child_scope to the scope of the generated block. | 2247 | // We call the low level function so that we can set child_scope to the scope of the generated block. |
| 2225 | if (trans_stmt_extra(c, parent_scope, stmt->getBody(), ResultUsedNo, TransRValue, &body_node, | 2248 | if (trans_stmt_extra(c, &while_scope->base, stmt->getBody(), ResultUsedNo, TransRValue, &body_node, |
| 2226 | nullptr, &child_scope)) | 2249 | nullptr, &child_scope)) |
| 2227 | { | 2250 | { |
| 2228 | return nullptr; | 2251 | return nullptr; |
| ... | @@ -2237,7 +2260,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt | ... | @@ -2237,7 +2260,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt |
| 2237 | // zig: a; | 2260 | // zig: a; |
| 2238 | // zig: if (!cond) break; | 2261 | // zig: if (!cond) break; |
| 2239 | // zig: } | 2262 | // zig: } |
| 2240 | TransScopeBlock *child_block_scope = trans_scope_block_create(c, parent_scope); | 2263 | TransScopeBlock *child_block_scope = trans_scope_block_create(c, &while_scope->base); |
| 2241 | body_node = child_block_scope->node; | 2264 | body_node = child_block_scope->node; |
| 2242 | AstNode *child_statement; | 2265 | AstNode *child_statement; |
| 2243 | child_scope = trans_stmt(c, &child_block_scope->base, stmt->getBody(), &child_statement); | 2266 | child_scope = trans_stmt(c, &child_block_scope->base, stmt->getBody(), &child_statement); |
| ... | @@ -2254,89 +2277,206 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt | ... | @@ -2254,89 +2277,206 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt |
| 2254 | | 2277 | |
| 2255 | body_node->data.block.statements.append(terminator_node); | 2278 | body_node->data.block.statements.append(terminator_node); |
| 2256 | | 2279 | |
| 2257 | while_node->data.while_expr.body = body_node; | 2280 | while_scope->node->data.while_expr.body = body_node; |
| 2258 | | 2281 | |
| 2259 | return while_node; | 2282 | return while_scope->node; |
| 2260 | } | 2283 | } |
| 2261 | | 2284 | |
| 2262 | //static AstNode *trans_switch_stmt(Context *c, TransScope *scope, const SwitchStmt *stmt) { | 2285 | static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const SwitchStmt *stmt) { |
| 2263 | // AstNode *switch_block_node = trans_create_node(c, NodeTypeBlock); | 2286 | TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope); |
| 2264 | // AstNode *switch_node = trans_create_node(c, NodeTypeSwitchExpr); | 2287 | while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true); |
| 2265 | // const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt(); | 2288 | |
| 2266 | // if (var_decl_stmt != nullptr) { | 2289 | TransScopeBlock *block_scope = trans_scope_block_create(c, &while_scope->base); |
| 2267 | // AstNode *vars_node = trans_stmt(c, switch_block_node, var_decl_stmt); | 2290 | while_scope->node->data.while_expr.body = block_scope->node; |
| 2268 | // if (vars_node == nullptr) | 2291 | |
| 2269 | // return nullptr; | 2292 | TransScopeSwitch *switch_scope; |
| 2270 | // if (vars_node != nullptr) | 2293 | |
| 2271 | // switch_block_node->data.block.statements.append(vars_node); | 2294 | const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt(); |
| 2272 | // } | 2295 | if (var_decl_stmt == nullptr) { |
| 2273 | // switch_block_node->data.block.statements.append(switch_node); | 2296 | switch_scope = trans_scope_switch_create(c, &block_scope->base); |
| 2274 | // | 2297 | } else { |
| 2275 | // const Expr *cond_expr = stmt->getCond(); | 2298 | AstNode *vars_node; |
| 2276 | // assert(cond_expr != nullptr); | 2299 | TransScope *var_scope = trans_stmt(c, &block_scope->base, var_decl_stmt, &vars_node); |
| 2277 | // | 2300 | if (var_scope == nullptr) |
| 2278 | // AstNode *expr_node = trans_expr(c, ResultUsedYes, switch_block_node, cond_expr, TransRValue); | 2301 | return nullptr; |
| 2279 | // if (expr_node == nullptr) | 2302 | if (vars_node != nullptr) |
| 2280 | // return nullptr; | 2303 | block_scope->node->data.block.statements.append(vars_node); |
| 2281 | // switch_node->data.switch_expr.expr = expr_node; | 2304 | switch_scope = trans_scope_switch_create(c, var_scope); |
| 2282 | // | 2305 | } |
| 2283 | // AstNode *body_node = trans_stmt(c, switch_block_node, stmt->getBody()); | 2306 | block_scope->node->data.block.statements.append(switch_scope->switch_node); |
| 2284 | // if (body_node == nullptr) | 2307 | |
| 2285 | // return nullptr; | 2308 | const Expr *cond_expr = stmt->getCond(); |
| 2286 | // if (body_node != nullptr) | 2309 | assert(cond_expr != nullptr); |
| 2287 | // switch_block_node->data.block.statements.append(body_node); | 2310 | |
| 2288 | // | 2311 | AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue); |
| 2289 | // return switch_block_node; | 2312 | if (expr_node == nullptr) |
| 2290 | //} | 2313 | return nullptr; |
| | 2314 | switch_scope->switch_node->data.switch_expr.expr = expr_node; |
| | 2315 | |
| | 2316 | AstNode *body_node; |
| | 2317 | const Stmt *body_stmt = stmt->getBody(); |
| | 2318 | if (body_stmt->getStmtClass() == Stmt::CompoundStmtClass) { |
| | 2319 | if (trans_compound_stmt_inline(c, &switch_scope->base, (const CompoundStmt *)body_stmt, |
| | 2320 | block_scope->node, nullptr)) |
| | 2321 | { |
| | 2322 | return nullptr; |
| | 2323 | } |
| | 2324 | } else { |
| | 2325 | TransScope *body_scope = trans_stmt(c, &switch_scope->base, body_stmt, &body_node); |
| | 2326 | if (body_scope == nullptr) |
| | 2327 | return nullptr; |
| | 2328 | if (body_node != nullptr) |
| | 2329 | block_scope->node->data.block.statements.append(body_node); |
| | 2330 | } |
| | 2331 | |
| | 2332 | if (!switch_scope->found_default && !stmt->isAllEnumCasesCovered()) { |
| | 2333 | AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng); |
| | 2334 | prong_node->data.switch_prong.expr = trans_create_node(c, NodeTypeBreak); |
| | 2335 | switch_scope->switch_node->data.switch_expr.prongs.append(prong_node); |
| | 2336 | } |
| | 2337 | |
| | 2338 | // This is necessary if the last switch case "falls through" the end of the switch block |
| | 2339 | block_scope->node->data.block.statements.append(trans_create_node(c, NodeTypeBreak)); |
| | 2340 | |
| | 2341 | return while_scope->node; |
| | 2342 | } |
| | 2343 | |
| | 2344 | static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStmt *stmt, AstNode **out_node, |
| | 2345 | TransScope **out_scope) |
| | 2346 | { |
| | 2347 | *out_node = nullptr; |
| | 2348 | |
| | 2349 | if (stmt->getRHS() != nullptr) { |
| | 2350 | emit_warning(c, stmt->getLocStart(), "TODO support GNU switch case a ... b extension"); |
| | 2351 | return ErrorUnexpected; |
| | 2352 | } |
| | 2353 | |
| | 2354 | TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope); |
| | 2355 | assert(switch_scope != nullptr); |
| | 2356 | |
| | 2357 | Buf *label_name = buf_sprintf("case_%" PRIu32, switch_scope->case_index); |
| | 2358 | switch_scope->case_index += 1; |
| | 2359 | |
| | 2360 | { |
| | 2361 | // Add the prong |
| | 2362 | AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng); |
| | 2363 | AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, stmt->getLHS(), TransRValue); |
| | 2364 | if (item_node == nullptr) |
| | 2365 | return ErrorUnexpected; |
| | 2366 | prong_node->data.switch_prong.items.append(item_node); |
| | 2367 | |
| | 2368 | AstNode *goto_node = trans_create_node(c, NodeTypeGoto); |
| | 2369 | goto_node->data.goto_expr.name = label_name; |
| | 2370 | prong_node->data.switch_prong.expr = goto_node; |
| | 2371 | |
| | 2372 | switch_scope->switch_node->data.switch_expr.prongs.append(prong_node); |
| | 2373 | } |
| | 2374 | |
| | 2375 | AstNode *label_node = trans_create_node(c, NodeTypeLabel); |
| | 2376 | label_node->data.label.name = label_name; |
| | 2377 | |
| | 2378 | TransScopeBlock *scope_block = trans_scope_block_find(parent_scope); |
| | 2379 | scope_block->node->data.block.statements.append(label_node); |
| | 2380 | |
| | 2381 | AstNode *sub_stmt_node; |
| | 2382 | TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node); |
| | 2383 | if (new_scope == nullptr) |
| | 2384 | return ErrorUnexpected; |
| | 2385 | if (sub_stmt_node != nullptr) |
| | 2386 | scope_block->node->data.block.statements.append(sub_stmt_node); |
| | 2387 | |
| | 2388 | *out_scope = new_scope; |
| | 2389 | return ErrorNone; |
| | 2390 | } |
| | 2391 | |
| | 2392 | static int trans_switch_default(Context *c, TransScope *parent_scope, const DefaultStmt *stmt, AstNode **out_node, |
| | 2393 | TransScope **out_scope) |
| | 2394 | { |
| | 2395 | *out_node = nullptr; |
| | 2396 | |
| | 2397 | TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope); |
| | 2398 | assert(switch_scope != nullptr); |
| | 2399 | |
| | 2400 | Buf *label_name = buf_sprintf("default"); |
| | 2401 | |
| | 2402 | AstNode *label_node = trans_create_node(c, NodeTypeLabel); |
| | 2403 | label_node->data.label.name = label_name; |
| | 2404 | |
| | 2405 | { |
| | 2406 | // Add the prong |
| | 2407 | AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng); |
| | 2408 | |
| | 2409 | AstNode *goto_node = trans_create_node(c, NodeTypeGoto); |
| | 2410 | goto_node->data.goto_expr.name = label_name; |
| | 2411 | prong_node->data.switch_prong.expr = goto_node; |
| | 2412 | |
| | 2413 | switch_scope->switch_node->data.switch_expr.prongs.append(prong_node); |
| | 2414 | switch_scope->found_default = true; |
| | 2415 | } |
| | 2416 | |
| | 2417 | TransScopeBlock *scope_block = trans_scope_block_find(parent_scope); |
| | 2418 | scope_block->node->data.block.statements.append(label_node); |
| | 2419 | |
| | 2420 | AstNode *sub_stmt_node; |
| | 2421 | TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node); |
| | 2422 | if (new_scope == nullptr) |
| | 2423 | return ErrorUnexpected; |
| | 2424 | if (sub_stmt_node != nullptr) |
| | 2425 | scope_block->node->data.block.statements.append(sub_stmt_node); |
| | 2426 | |
| | 2427 | *out_scope = new_scope; |
| | 2428 | return ErrorNone; |
| | 2429 | } |
| 2291 | | 2430 | |
| 2292 | static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForStmt *stmt) { | 2431 | static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForStmt *stmt) { |
| 2293 | AstNode *loop_block_node; | 2432 | AstNode *loop_block_node; |
| 2294 | TransScope *inner_scope; | 2433 | TransScopeWhile *while_scope; |
| 2295 | AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); | 2434 | TransScope *cond_scope; |
| 2296 | const Stmt *init_stmt = stmt->getInit(); | 2435 | const Stmt *init_stmt = stmt->getInit(); |
| 2297 | if (init_stmt == nullptr) { | 2436 | if (init_stmt == nullptr) { |
| 2298 | loop_block_node = while_node; | 2437 | while_scope = trans_scope_while_create(c, parent_scope); |
| 2299 | inner_scope = parent_scope; | 2438 | loop_block_node = while_scope->node; |
| | 2439 | cond_scope = parent_scope; |
| 2300 | } else { | 2440 | } else { |
| 2301 | TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope); | 2441 | TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope); |
| 2302 | loop_block_node = child_scope->node; | 2442 | loop_block_node = child_scope->node; |
| 2303 | inner_scope = &child_scope->base; | | |
| 2304 | | 2443 | |
| 2305 | AstNode *vars_node; | 2444 | AstNode *vars_node; |
| 2306 | inner_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node); | 2445 | cond_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node); |
| 2307 | if (inner_scope == nullptr) | 2446 | if (cond_scope == nullptr) |
| 2308 | return nullptr; | 2447 | return nullptr; |
| 2309 | if (vars_node != nullptr) | 2448 | if (vars_node != nullptr) |
| 2310 | child_scope->node->data.block.statements.append(vars_node); | 2449 | child_scope->node->data.block.statements.append(vars_node); |
| 2311 | | 2450 | |
| 2312 | child_scope->node->data.block.statements.append(while_node); | 2451 | while_scope = trans_scope_while_create(c, cond_scope); |
| | 2452 | |
| | 2453 | child_scope->node->data.block.statements.append(while_scope->node); |
| 2313 | } | 2454 | } |
| 2314 | | 2455 | |
| 2315 | const Stmt *cond_stmt = stmt->getCond(); | 2456 | const Stmt *cond_stmt = stmt->getCond(); |
| 2316 | if (cond_stmt == nullptr) { | 2457 | if (cond_stmt == nullptr) { |
| 2317 | AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral); | 2458 | while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true); |
| 2318 | true_node->data.bool_literal.value = true; | | |
| 2319 | while_node->data.while_expr.condition = true_node; | | |
| 2320 | } else { | 2459 | } else { |
| 2321 | TransScope *cond_scope = trans_stmt(c, inner_scope, cond_stmt, &while_node->data.while_expr.condition); | 2460 | TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt, |
| 2322 | if (cond_scope == nullptr) | 2461 | &while_scope->node->data.while_expr.condition); |
| | 2462 | if (end_cond_scope == nullptr) |
| 2323 | return nullptr; | 2463 | return nullptr; |
| 2324 | } | 2464 | } |
| 2325 | | 2465 | |
| 2326 | const Stmt *inc_stmt = stmt->getInc(); | 2466 | const Stmt *inc_stmt = stmt->getInc(); |
| 2327 | if (inc_stmt != nullptr) { | 2467 | if (inc_stmt != nullptr) { |
| 2328 | AstNode *inc_node; | 2468 | AstNode *inc_node; |
| 2329 | TransScope *inc_scope = trans_stmt(c, inner_scope, inc_stmt, &inc_node); | 2469 | TransScope *inc_scope = trans_stmt(c, cond_scope, inc_stmt, &inc_node); |
| 2330 | if (inc_scope == nullptr) | 2470 | if (inc_scope == nullptr) |
| 2331 | return nullptr; | 2471 | return nullptr; |
| 2332 | while_node->data.while_expr.continue_expr = inc_node; | 2472 | while_scope->node->data.while_expr.continue_expr = inc_node; |
| 2333 | } | 2473 | } |
| 2334 | | 2474 | |
| 2335 | AstNode *child_statement; | 2475 | AstNode *body_statement; |
| 2336 | TransScope *body_scope = trans_stmt(c, inner_scope, stmt->getBody(), &child_statement); | 2476 | TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(), &body_statement); |
| 2337 | if (body_scope == nullptr) | 2477 | if (body_scope == nullptr) |
| 2338 | return nullptr; | 2478 | return nullptr; |
| 2339 | while_node->data.while_expr.body = child_statement; | 2479 | while_scope->node->data.while_expr.body = body_statement; |
| 2340 | | 2480 | |
| 2341 | return loop_block_node; | 2481 | return loop_block_node; |
| 2342 | } | 2482 | } |
| ... | @@ -2371,9 +2511,8 @@ static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_ | ... | @@ -2371,9 +2511,8 @@ static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_ |
| 2371 | if (result_node == nullptr) | 2511 | if (result_node == nullptr) |
| 2372 | return ErrorUnexpected; | 2512 | return ErrorUnexpected; |
| 2373 | *out_node = result_node; | 2513 | *out_node = result_node; |
| 2374 | if (out_scope != nullptr) { | 2514 | if (out_scope != nullptr) |
| 2375 | *out_scope = in_scope; | 2515 | *out_scope = in_scope; |
| 2376 | } | | |
| 2377 | return ErrorNone; | 2516 | return ErrorNone; |
| 2378 | } | 2517 | } |
| 2379 | | 2518 | |
| ... | @@ -2456,18 +2595,13 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt, | ... | @@ -2456,18 +2595,13 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt, |
| 2456 | case Stmt::ParenExprClass: | 2595 | case Stmt::ParenExprClass: |
| 2457 | return wrap_stmt(out_node, out_child_scope, scope, | 2596 | return wrap_stmt(out_node, out_child_scope, scope, |
| 2458 | trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue)); | 2597 | trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue)); |
| 2459 | // case Stmt::SwitchStmtClass: | | |
| 2460 | // return wrap_stmt(out_node, out_child_scope, scope, | | |
| 2461 | // trans_switch_stmt(c, scope, (const SwitchStmt *)stmt)); | | |
| 2462 | case Stmt::SwitchStmtClass: | 2598 | case Stmt::SwitchStmtClass: |
| 2463 | emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass"); | 2599 | return wrap_stmt(out_node, out_child_scope, scope, |
| 2464 | return ErrorUnexpected; | 2600 | trans_switch_stmt(c, scope, (const SwitchStmt *)stmt)); |
| 2465 | case Stmt::CaseStmtClass: | 2601 | case Stmt::CaseStmtClass: |
| 2466 | emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); | 2602 | return trans_switch_case(c, scope, (const CaseStmt *)stmt, out_node, out_child_scope); |
| 2467 | return ErrorUnexpected; | | |
| 2468 | case Stmt::DefaultStmtClass: | 2603 | case Stmt::DefaultStmtClass: |
| 2469 | emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass"); | 2604 | return trans_switch_default(c, scope, (const DefaultStmt *)stmt, out_node, out_child_scope); |
| 2470 | return ErrorUnexpected; | | |
| 2471 | case Stmt::NoStmtClass: | 2605 | case Stmt::NoStmtClass: |
| 2472 | emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass"); | 2606 | emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass"); |
| 2473 | return ErrorUnexpected; | 2607 | return ErrorUnexpected; |
| ... | @@ -2981,7 +3115,8 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope | ... | @@ -2981,7 +3115,8 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope |
| 2981 | TransLRValue lrval) | 3115 | TransLRValue lrval) |
| 2982 | { | 3116 | { |
| 2983 | AstNode *result_node; | 3117 | AstNode *result_node; |
| 2984 | if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, nullptr, nullptr)) { | 3118 | TransScope *result_scope; |
| | 3119 | if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, &result_scope, nullptr)) { |
| 2985 | return nullptr; | 3120 | return nullptr; |
| 2986 | } | 3121 | } |
| 2987 | return result_node; | 3122 | return result_node; |
| ... | @@ -3536,6 +3671,14 @@ static TransScopeRoot *trans_scope_root_create(Context *c) { | ... | @@ -3536,6 +3671,14 @@ static TransScopeRoot *trans_scope_root_create(Context *c) { |
| 3536 | return result; | 3671 | return result; |
| 3537 | } | 3672 | } |
| 3538 | | 3673 | |
| | 3674 | static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope) { |
| | 3675 | TransScopeWhile *result = allocate<TransScopeWhile>(1); |
| | 3676 | result->base.id = TransScopeIdWhile; |
| | 3677 | result->base.parent = parent_scope; |
| | 3678 | result->node = trans_create_node(c, NodeTypeWhileExpr); |
| | 3679 | return result; |
| | 3680 | } |
| | 3681 | |
| 3539 | static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) { | 3682 | static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) { |
| 3540 | TransScopeBlock *result = allocate<TransScopeBlock>(1); | 3683 | TransScopeBlock *result = allocate<TransScopeBlock>(1); |
| 3541 | result->base.id = TransScopeIdBlock; | 3684 | result->base.id = TransScopeIdBlock; |
| ... | @@ -3553,13 +3696,13 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop | ... | @@ -3553,13 +3696,13 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop |
| 3553 | return result; | 3696 | return result; |
| 3554 | } | 3697 | } |
| 3555 | | 3698 | |
| 3556 | //static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) { | 3699 | static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) { |
| 3557 | // TransScopeSwitch *result = allocate<TransScopeSwitch>(1); | 3700 | TransScopeSwitch *result = allocate<TransScopeSwitch>(1); |
| 3558 | // result->base.id = TransScopeIdSwitch; | 3701 | result->base.id = TransScopeIdSwitch; |
| 3559 | // result->base.parent = parent_scope; | 3702 | result->base.parent = parent_scope; |
| 3560 | // result->switch_node = trans_create_node(c, NodeTypeSwitchExpr); | 3703 | result->switch_node = trans_create_node(c, NodeTypeSwitchExpr); |
| 3561 | // return result; | 3704 | return result; |
| 3562 | //} | 3705 | } |
| 3563 | | 3706 | |
| 3564 | static TransScopeBlock *trans_scope_block_find(TransScope *scope) { | 3707 | static TransScopeBlock *trans_scope_block_find(TransScope *scope) { |
| 3565 | while (scope != nullptr) { | 3708 | while (scope != nullptr) { |
| ... | @@ -3571,6 +3714,16 @@ static TransScopeBlock *trans_scope_block_find(TransScope *scope) { | ... | @@ -3571,6 +3714,16 @@ static TransScopeBlock *trans_scope_block_find(TransScope *scope) { |
| 3571 | return nullptr; | 3714 | return nullptr; |
| 3572 | } | 3715 | } |
| 3573 | | 3716 | |
| | 3717 | static TransScopeSwitch *trans_scope_switch_find(TransScope *scope) { |
| | 3718 | while (scope != nullptr) { |
| | 3719 | if (scope->id == TransScopeIdSwitch) { |
| | 3720 | return (TransScopeSwitch *)scope; |
| | 3721 | } |
| | 3722 | scope = scope->parent; |
| | 3723 | } |
| | 3724 | return nullptr; |
| | 3725 | } |
| | 3726 | |
| 3574 | static void render_aliases(Context *c) { | 3727 | static void render_aliases(Context *c) { |
| 3575 | for (size_t i = 0; i < c->aliases.length; i += 1) { | 3728 | for (size_t i = 0; i < c->aliases.length; i += 1) { |
| 3576 | Alias *alias = &c->aliases.at(i); | 3729 | Alias *alias = &c->aliases.at(i); |