authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-18 23:52:42-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-18 23:52:42-05:00
log19037014e5a25eaac9564d22cc04cf12fb6ef98e
treeec7ec61515ddf48ab94585d054bb69c329febce3
parent31565efe9d6cde2e4909f986d50f8c46166d3311

IR: more maybe type support


4 files changed, 150 insertions(+), 86 deletions(-)

src/ast_render.cpp+55-35
...@@ -342,13 +342,23 @@ static void print_symbol(AstRender *ar, Buf *symbol) {...@@ -342,13 +342,23 @@ static void print_symbol(AstRender *ar, Buf *symbol) {
342 fprintf(ar->f, "@\"%s\"", buf_ptr(&escaped));342 fprintf(ar->f, "@\"%s\"", buf_ptr(&escaped));
343}343}
344344
345static void render_node(AstRender *ar, AstNode *node) {345static void render_node_extra(AstRender *ar, AstNode *node, bool grouped);
346
347static void render_node_grouped(AstRender *ar, AstNode *node) {
348 return render_node_extra(ar, node, true);
349}
350
351static void render_node_ungrouped(AstRender *ar, AstNode *node) {
352 return render_node_extra(ar, node, false);
353}
354
355static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
346 switch (node->type) {356 switch (node->type) {
347 case NodeTypeRoot:357 case NodeTypeRoot:
348 for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) {358 for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) {
349 AstNode *child = node->data.root.top_level_decls.at(i);359 AstNode *child = node->data.root.top_level_decls.at(i);
350 print_indent(ar);360 print_indent(ar);
351 render_node(ar, child);361 render_node_grouped(ar, child);
352362
353 if (child->type == NodeTypeUse ||363 if (child->type == NodeTypeUse ||
354 child->type == NodeTypeVariableDeclaration ||364 child->type == NodeTypeVariableDeclaration ||
...@@ -381,7 +391,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -381,7 +391,7 @@ static void render_node(AstRender *ar, AstNode *node) {
381 print_symbol(ar, param_decl->data.param_decl.name);391 print_symbol(ar, param_decl->data.param_decl.name);
382 fprintf(ar->f, ": ");392 fprintf(ar->f, ": ");
383 }393 }
384 render_node(ar, param_decl->data.param_decl.type);394 render_node_grouped(ar, param_decl->data.param_decl.type);
385395
386 if (arg_i + 1 < arg_count || is_var_args) {396 if (arg_i + 1 < arg_count || is_var_args) {
387 fprintf(ar->f, ", ");397 fprintf(ar->f, ", ");
...@@ -394,14 +404,14 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -394,14 +404,14 @@ static void render_node(AstRender *ar, AstNode *node) {
394404
395 AstNode *return_type_node = node->data.fn_proto.return_type;405 AstNode *return_type_node = node->data.fn_proto.return_type;
396 fprintf(ar->f, " -> ");406 fprintf(ar->f, " -> ");
397 render_node(ar, return_type_node);407 render_node_grouped(ar, return_type_node);
398 break;408 break;
399 }409 }
400 case NodeTypeFnDef:410 case NodeTypeFnDef:
401 {411 {
402 render_node(ar, node->data.fn_def.fn_proto);412 render_node_grouped(ar, node->data.fn_def.fn_proto);
403 fprintf(ar->f, " ");413 fprintf(ar->f, " ");
404 render_node(ar, node->data.fn_def.body);414 render_node_grouped(ar, node->data.fn_def.body);
405 break;415 break;
406 }416 }
407 case NodeTypeBlock:417 case NodeTypeBlock:
...@@ -414,7 +424,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -414,7 +424,7 @@ static void render_node(AstRender *ar, AstNode *node) {
414 for (size_t i = 0; i < node->data.block.statements.length; i += 1) {424 for (size_t i = 0; i < node->data.block.statements.length; i += 1) {
415 AstNode *statement = node->data.block.statements.at(i);425 AstNode *statement = node->data.block.statements.at(i);
416 print_indent(ar);426 print_indent(ar);
417 render_node(ar, statement);427 render_node_grouped(ar, statement);
418 if (i != node->data.block.statements.length - 1)428 if (i != node->data.block.statements.length - 1)
419 fprintf(ar->f, ";");429 fprintf(ar->f, ";");
420 fprintf(ar->f, "\n");430 fprintf(ar->f, "\n");
...@@ -427,14 +437,14 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -427,14 +437,14 @@ static void render_node(AstRender *ar, AstNode *node) {
427 {437 {
428 const char *return_str = return_string(node->data.return_expr.kind);438 const char *return_str = return_string(node->data.return_expr.kind);
429 fprintf(ar->f, "%s ", return_str);439 fprintf(ar->f, "%s ", return_str);
430 render_node(ar, node->data.return_expr.expr);440 render_node_grouped(ar, node->data.return_expr.expr);
431 break;441 break;
432 }442 }
433 case NodeTypeDefer:443 case NodeTypeDefer:
434 {444 {
435 const char *defer_str = defer_string(node->data.defer.kind);445 const char *defer_str = defer_string(node->data.defer.kind);
436 fprintf(ar->f, "%s ", defer_str);446 fprintf(ar->f, "%s ", defer_str);
437 render_node(ar, node->data.return_expr.expr);447 render_node_grouped(ar, node->data.return_expr.expr);
438 break;448 break;
439 }449 }
440 case NodeTypeVariableDeclaration:450 case NodeTypeVariableDeclaration:
...@@ -447,11 +457,11 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -447,11 +457,11 @@ static void render_node(AstRender *ar, AstNode *node) {
447457
448 if (node->data.variable_declaration.type) {458 if (node->data.variable_declaration.type) {
449 fprintf(ar->f, ": ");459 fprintf(ar->f, ": ");
450 render_node(ar, node->data.variable_declaration.type);460 render_node_grouped(ar, node->data.variable_declaration.type);
451 }461 }
452 if (node->data.variable_declaration.expr) {462 if (node->data.variable_declaration.expr) {
453 fprintf(ar->f, " = ");463 fprintf(ar->f, " = ");
454 render_node(ar, node->data.variable_declaration.expr);464 render_node_grouped(ar, node->data.variable_declaration.expr);
455 }465 }
456 break;466 break;
457 }467 }
...@@ -460,15 +470,15 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -460,15 +470,15 @@ static void render_node(AstRender *ar, AstNode *node) {
460 const char *pub_str = visib_mod_string(node->data.type_decl.top_level_decl.visib_mod);470 const char *pub_str = visib_mod_string(node->data.type_decl.top_level_decl.visib_mod);
461 const char *var_name = buf_ptr(node->data.type_decl.symbol);471 const char *var_name = buf_ptr(node->data.type_decl.symbol);
462 fprintf(ar->f, "%stype %s = ", pub_str, var_name);472 fprintf(ar->f, "%stype %s = ", pub_str, var_name);
463 render_node(ar, node->data.type_decl.child_type);473 render_node_grouped(ar, node->data.type_decl.child_type);
464 break;474 break;
465 }475 }
466 case NodeTypeBinOpExpr:476 case NodeTypeBinOpExpr:
467 fprintf(ar->f, "(");477 if (!grouped) fprintf(ar->f, "(");
468 render_node(ar, node->data.bin_op_expr.op1);478 render_node_ungrouped(ar, node->data.bin_op_expr.op1);
469 fprintf(ar->f, " %s ", bin_op_str(node->data.bin_op_expr.bin_op));479 fprintf(ar->f, " %s ", bin_op_str(node->data.bin_op_expr.bin_op));
470 render_node(ar, node->data.bin_op_expr.op2);480 render_node_ungrouped(ar, node->data.bin_op_expr.op2);
471 fprintf(ar->f, ")");481 if (!grouped) fprintf(ar->f, ")");
472 break;482 break;
473 case NodeTypeNumberLiteral:483 case NodeTypeNumberLiteral:
474 switch (node->data.number_literal.bignum->kind) {484 switch (node->data.number_literal.bignum->kind) {
...@@ -511,7 +521,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -511,7 +521,7 @@ static void render_node(AstRender *ar, AstNode *node) {
511 PrefixOp op = node->data.prefix_op_expr.prefix_op;521 PrefixOp op = node->data.prefix_op_expr.prefix_op;
512 fprintf(ar->f, "%s", prefix_op_str(op));522 fprintf(ar->f, "%s", prefix_op_str(op));
513523
514 render_node(ar, node->data.prefix_op_expr.primary_expr);524 render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);
515 break;525 break;
516 }526 }
517 case NodeTypeFnCallExpr:527 case NodeTypeFnCallExpr:
...@@ -520,7 +530,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -520,7 +530,7 @@ static void render_node(AstRender *ar, AstNode *node) {
520 } else {530 } else {
521 fprintf(ar->f, "(");531 fprintf(ar->f, "(");
522 }532 }
523 render_node(ar, node->data.fn_call_expr.fn_ref_expr);533 render_node_ungrouped(ar, node->data.fn_call_expr.fn_ref_expr);
524 if (!node->data.fn_call_expr.is_builtin) {534 if (!node->data.fn_call_expr.is_builtin) {
525 fprintf(ar->f, ")");535 fprintf(ar->f, ")");
526 }536 }
...@@ -530,21 +540,21 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -530,21 +540,21 @@ static void render_node(AstRender *ar, AstNode *node) {
530 if (i != 0) {540 if (i != 0) {
531 fprintf(ar->f, ", ");541 fprintf(ar->f, ", ");
532 }542 }
533 render_node(ar, param);543 render_node_grouped(ar, param);
534 }544 }
535 fprintf(ar->f, ")");545 fprintf(ar->f, ")");
536 break;546 break;
537 case NodeTypeArrayAccessExpr:547 case NodeTypeArrayAccessExpr:
538 render_node(ar, node->data.array_access_expr.array_ref_expr);548 render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
539 fprintf(ar->f, "[");549 fprintf(ar->f, "[");
540 render_node(ar, node->data.array_access_expr.subscript);550 render_node_grouped(ar, node->data.array_access_expr.subscript);
541 fprintf(ar->f, "]");551 fprintf(ar->f, "]");
542 break;552 break;
543 case NodeTypeFieldAccessExpr:553 case NodeTypeFieldAccessExpr:
544 {554 {
545 AstNode *lhs = node->data.field_access_expr.struct_expr;555 AstNode *lhs = node->data.field_access_expr.struct_expr;
546 Buf *rhs = node->data.field_access_expr.field_name;556 Buf *rhs = node->data.field_access_expr.field_name;
547 render_node(ar, lhs);557 render_node_ungrouped(ar, lhs);
548 fprintf(ar->f, ".");558 fprintf(ar->f, ".");
549 print_symbol(ar, rhs);559 print_symbol(ar, rhs);
550 break;560 break;
...@@ -565,7 +575,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -565,7 +575,7 @@ static void render_node(AstRender *ar, AstNode *node) {
565 print_indent(ar);575 print_indent(ar);
566 print_symbol(ar, field_node->data.struct_field.name);576 print_symbol(ar, field_node->data.struct_field.name);
567 fprintf(ar->f, ": ");577 fprintf(ar->f, ": ");
568 render_node(ar, field_node->data.struct_field.type);578 render_node_grouped(ar, field_node->data.struct_field.type);
569 fprintf(ar->f, ",\n");579 fprintf(ar->f, ",\n");
570 }580 }
571581
...@@ -574,9 +584,8 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -574,9 +584,8 @@ static void render_node(AstRender *ar, AstNode *node) {
574 break;584 break;
575 }585 }
576 case NodeTypeContainerInitExpr:586 case NodeTypeContainerInitExpr:
577 fprintf(ar->f, "(");587 render_node_ungrouped(ar, node->data.container_init_expr.type);
578 render_node(ar, node->data.container_init_expr.type);588 fprintf(ar->f, "{");
579 fprintf(ar->f, "){");
580 assert(node->data.container_init_expr.entries.length == 0);589 assert(node->data.container_init_expr.entries.length == 0);
581 fprintf(ar->f, "}");590 fprintf(ar->f, "}");
582 break;591 break;
...@@ -584,13 +593,13 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -584,13 +593,13 @@ static void render_node(AstRender *ar, AstNode *node) {
584 {593 {
585 fprintf(ar->f, "[");594 fprintf(ar->f, "[");
586 if (node->data.array_type.size) {595 if (node->data.array_type.size) {
587 render_node(ar, node->data.array_type.size);596 render_node_grouped(ar, node->data.array_type.size);
588 }597 }
589 fprintf(ar->f, "]");598 fprintf(ar->f, "]");
590 if (node->data.array_type.is_const) {599 if (node->data.array_type.is_const) {
591 fprintf(ar->f, "const ");600 fprintf(ar->f, "const ");
592 }601 }
593 render_node(ar, node->data.array_type.child_type);602 render_node_ungrouped(ar, node->data.array_type.child_type);
594 break;603 break;
595 }604 }
596 case NodeTypeErrorType:605 case NodeTypeErrorType:
...@@ -622,7 +631,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -622,7 +631,7 @@ static void render_node(AstRender *ar, AstNode *node) {
622 buf_ptr(asm_output->constraint));631 buf_ptr(asm_output->constraint));
623 if (asm_output->return_type) {632 if (asm_output->return_type) {
624 fprintf(ar->f, "-> ");633 fprintf(ar->f, "-> ");
625 render_node(ar, asm_output->return_type);634 render_node_grouped(ar, asm_output->return_type);
626 } else {635 } else {
627 fprintf(ar->f, "%s", buf_ptr(asm_output->variable_name));636 fprintf(ar->f, "%s", buf_ptr(asm_output->variable_name));
628 }637 }
...@@ -642,7 +651,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -642,7 +651,7 @@ static void render_node(AstRender *ar, AstNode *node) {
642 fprintf(ar->f, "[%s] \"%s\" (",651 fprintf(ar->f, "[%s] \"%s\" (",
643 buf_ptr(asm_input->asm_symbolic_name),652 buf_ptr(asm_input->asm_symbolic_name),
644 buf_ptr(asm_input->constraint));653 buf_ptr(asm_input->constraint));
645 render_node(ar, asm_input->expr);654 render_node_grouped(ar, asm_input->expr);
646 fprintf(ar->f, ")");655 fprintf(ar->f, ")");
647 }656 }
648 fprintf(ar->f, "\n");657 fprintf(ar->f, "\n");
...@@ -660,13 +669,13 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -660,13 +669,13 @@ static void render_node(AstRender *ar, AstNode *node) {
660 {669 {
661 const char *inline_str = node->data.while_expr.is_inline ? "inline " : "";670 const char *inline_str = node->data.while_expr.is_inline ? "inline " : "";
662 fprintf(ar->f, "%swhile (", inline_str);671 fprintf(ar->f, "%swhile (", inline_str);
663 render_node(ar, node->data.while_expr.condition);672 render_node_grouped(ar, node->data.while_expr.condition);
664 if (node->data.while_expr.continue_expr) {673 if (node->data.while_expr.continue_expr) {
665 fprintf(ar->f, "; ");674 fprintf(ar->f, "; ");
666 render_node(ar, node->data.while_expr.continue_expr);675 render_node_grouped(ar, node->data.while_expr.continue_expr);
667 }676 }
668 fprintf(ar->f, ") ");677 fprintf(ar->f, ") ");
669 render_node(ar, node->data.while_expr.body);678 render_node_grouped(ar, node->data.while_expr.body);
670 break;679 break;
671 }680 }
672 case NodeTypeThisLiteral:681 case NodeTypeThisLiteral:
...@@ -680,6 +689,18 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -680,6 +689,18 @@ static void render_node(AstRender *ar, AstNode *node) {
680 fprintf(ar->f, "%s", bool_str);689 fprintf(ar->f, "%s", bool_str);
681 break;690 break;
682 }691 }
692 case NodeTypeIfBoolExpr:
693 {
694 fprintf(ar->f, "if (");
695 render_node_grouped(ar, node->data.if_bool_expr.condition);
696 fprintf(ar->f, ") ");
697 render_node_grouped(ar, node->data.if_bool_expr.then_block);
698 if (node->data.if_bool_expr.else_node) {
699 fprintf(ar->f, "else ");
700 render_node_grouped(ar, node->data.if_bool_expr.else_node);
701 }
702 break;
703 }
683 case NodeTypeFnDecl:704 case NodeTypeFnDecl:
684 case NodeTypeParamDecl:705 case NodeTypeParamDecl:
685 case NodeTypeErrorValueDecl:706 case NodeTypeErrorValueDecl:
...@@ -690,7 +711,6 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -690,7 +711,6 @@ static void render_node(AstRender *ar, AstNode *node) {
690 case NodeTypeUse:711 case NodeTypeUse:
691 case NodeTypeNullLiteral:712 case NodeTypeNullLiteral:
692 case NodeTypeZeroesLiteral:713 case NodeTypeZeroesLiteral:
693 case NodeTypeIfBoolExpr:
694 case NodeTypeIfVarExpr:714 case NodeTypeIfVarExpr:
695 case NodeTypeForExpr:715 case NodeTypeForExpr:
696 case NodeTypeSwitchExpr:716 case NodeTypeSwitchExpr:
...@@ -711,5 +731,5 @@ void ast_render(FILE *f, AstNode *node, int indent_size) {...@@ -711,5 +731,5 @@ void ast_render(FILE *f, AstNode *node, int indent_size) {
711 ar.indent_size = indent_size;731 ar.indent_size = indent_size;
712 ar.indent = 0;732 ar.indent = 0;
713733
714 render_node(&ar, node);734 render_node_grouped(&ar, node);
715}735}
src/codegen.cpp+11-1
...@@ -3242,9 +3242,19 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -3242,9 +3242,19 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
3242 buf_appendf(out_buf, "%s%s *", const_str, buf_ptr(&child_buf));3242 buf_appendf(out_buf, "%s%s *", const_str, buf_ptr(&child_buf));
3243 break;3243 break;
3244 }3244 }
3245 case TypeTableEntryIdMaybe:
3246 {
3247 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
3248 if (child_type->id == TypeTableEntryIdPointer ||
3249 child_type->id == TypeTableEntryIdFn)
3250 {
3251 return get_c_type(g, child_type, out_buf);
3252 } else {
3253 zig_unreachable();
3254 }
3255 }
3245 case TypeTableEntryIdArray:3256 case TypeTableEntryIdArray:
3246 case TypeTableEntryIdStruct:3257 case TypeTableEntryIdStruct:
3247 case TypeTableEntryIdMaybe:
3248 case TypeTableEntryIdErrorUnion:3258 case TypeTableEntryIdErrorUnion:
3249 case TypeTableEntryIdPureError:3259 case TypeTableEntryIdPureError:
3250 case TypeTableEntryIdEnum:3260 case TypeTableEntryIdEnum:
src/ir.cpp+71-44
...@@ -3113,8 +3113,11 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -3113,8 +3113,11 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
3113 var->type = result_type;3113 var->type = result_type;
3114 assert(var->type);3114 assert(var->type);
31153115
3116 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];3116 if (var->mem_slot_index != SIZE_MAX) {
3117 *mem_slot = casted_init_value->static_value;3117 assert(var->mem_slot_index < ira->exec_context.mem_slot_count);
3118 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
3119 *mem_slot = casted_init_value->static_value;
3120 }
31183121
3119 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);3122 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
31203123
...@@ -3341,6 +3344,70 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp...@@ -3341,6 +3344,70 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp
3341 return child_type;3344 return child_type;
3342}3345}
33433346
3347static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
3348 IrInstruction *value = un_op_instruction->value->other;
3349 TypeTableEntry *type_entry = ir_resolve_type(ira, value);
3350 TypeTableEntry *canon_type = get_underlying_type(type_entry);
3351 switch (canon_type->id) {
3352 case TypeTableEntryIdInvalid:
3353 return ira->codegen->builtin_types.entry_invalid;
3354 case TypeTableEntryIdVar:
3355 case TypeTableEntryIdTypeDecl:
3356 zig_unreachable();
3357 case TypeTableEntryIdMetaType:
3358 case TypeTableEntryIdVoid:
3359 case TypeTableEntryIdBool:
3360 case TypeTableEntryIdInt:
3361 case TypeTableEntryIdFloat:
3362 case TypeTableEntryIdPointer:
3363 case TypeTableEntryIdArray:
3364 case TypeTableEntryIdStruct:
3365 case TypeTableEntryIdNumLitFloat:
3366 case TypeTableEntryIdNumLitInt:
3367 case TypeTableEntryIdUndefLit:
3368 case TypeTableEntryIdNullLit:
3369 case TypeTableEntryIdMaybe:
3370 case TypeTableEntryIdErrorUnion:
3371 case TypeTableEntryIdPureError:
3372 case TypeTableEntryIdEnum:
3373 case TypeTableEntryIdUnion:
3374 case TypeTableEntryIdFn:
3375 case TypeTableEntryIdNamespace:
3376 case TypeTableEntryIdBlock:
3377 case TypeTableEntryIdGenericFn:
3378 {
3379 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
3380 value->static_value.depends_on_compile_var);
3381 out_val->data.x_type = get_maybe_type(ira->codegen, type_entry);
3382 return ira->codegen->builtin_types.entry_type;
3383 }
3384 case TypeTableEntryIdUnreachable:
3385 add_node_error(ira->codegen, un_op_instruction->base.source_node,
3386 buf_sprintf("type '%s' not nullable", buf_ptr(&type_entry->name)));
3387 // TODO if it's a type decl, put an error note here pointing to the decl
3388 return ira->codegen->builtin_types.entry_invalid;
3389 }
3390 zig_unreachable();
3391}
3392
3393static TypeTableEntry *ir_analyze_unwrap_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
3394 IrInstruction *value = un_op_instruction->value->other;
3395 TypeTableEntry *type_entry = value->type_entry;
3396 if (type_entry->id == TypeTableEntryIdInvalid) {
3397 return type_entry;
3398 } else if (type_entry->id == TypeTableEntryIdMaybe) {
3399 if (value->static_value.special != ConstValSpecialRuntime) {
3400 zig_panic("TODO compile time eval unwrap maybe");
3401 }
3402 ir_build_un_op_from(&ira->new_irb, &un_op_instruction->base, IrUnOpUnwrapMaybe, value);
3403 return type_entry->data.maybe.child_type;
3404 } else {
3405 add_node_error(ira->codegen, un_op_instruction->base.source_node,
3406 buf_sprintf("expected maybe type, found '%s'", buf_ptr(&type_entry->name)));
3407 return ira->codegen->builtin_types.entry_invalid;
3408 }
3409}
3410
3344static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {3411static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) {
3345 IrUnOp op_id = un_op_instruction->op_id;3412 IrUnOp op_id = un_op_instruction->op_id;
3346 switch (op_id) {3413 switch (op_id) {
...@@ -3417,34 +3484,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio...@@ -3417,34 +3484,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio
3417 case IrUnOpDereference:3484 case IrUnOpDereference:
3418 return ir_analyze_dereference(ira, un_op_instruction);3485 return ir_analyze_dereference(ira, un_op_instruction);
3419 case IrUnOpMaybe:3486 case IrUnOpMaybe:
3420 zig_panic("TODO analyze PrefixOpMaybe");3487 return ir_analyze_maybe(ira, un_op_instruction);
3421 //{
3422 // TypeTableEntry *type_entry = analyze_expression(g, import, context, nullptr, *expr_node);
3423
3424 // if (type_entry->id == TypeTableEntryIdInvalid) {
3425 // return type_entry;
3426 // } else if (type_entry->id == TypeTableEntryIdMetaType) {
3427 // TypeTableEntry *meta_type = resolve_type(g, *expr_node);
3428 // if (meta_type->id == TypeTableEntryIdInvalid) {
3429 // return g->builtin_types.entry_invalid;
3430 // } else if (meta_type->id == TypeTableEntryIdUnreachable) {
3431 // add_node_error(g, node, buf_create_from_str("unable to wrap unreachable in maybe type"));
3432 // return g->builtin_types.entry_invalid;
3433 // } else {
3434 // return resolve_expr_const_val_as_type(g, node, get_maybe_type(g, meta_type), false);
3435 // }
3436 // } else if (type_entry->id == TypeTableEntryIdUnreachable) {
3437 // add_node_error(g, *expr_node, buf_sprintf("unable to wrap unreachable in maybe type"));
3438 // return g->builtin_types.entry_invalid;
3439 // } else {
3440 // ConstExprValue *target_const_val = &get_resolved_expr(*expr_node)->const_val;
3441 // TypeTableEntry *maybe_type = get_maybe_type(g, type_entry);
3442 // if (!target_const_val->ok) {
3443 // return maybe_type;
3444 // }
3445 // return resolve_expr_const_val_as_non_null(g, node, maybe_type, target_const_val);
3446 // }
3447 //}
3448 case IrUnOpError:3488 case IrUnOpError:
3449 return ir_analyze_unary_prefix_op_err(ira, un_op_instruction);3489 return ir_analyze_unary_prefix_op_err(ira, un_op_instruction);
3450 case IrUnOpUnwrapError:3490 case IrUnOpUnwrapError:
...@@ -3463,20 +3503,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio...@@ -3463,20 +3503,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio
3463 // }3503 // }
3464 //}3504 //}
3465 case IrUnOpUnwrapMaybe:3505 case IrUnOpUnwrapMaybe:
3466 zig_panic("TODO analyze PrefixOpUnwrapMaybe");3506 return ir_analyze_unwrap_maybe(ira, un_op_instruction);
3467 //{
3468 // TypeTableEntry *type_entry = analyze_expression(g, import, context, nullptr, *expr_node);
3469
3470 // if (type_entry->id == TypeTableEntryIdInvalid) {
3471 // return type_entry;
3472 // } else if (type_entry->id == TypeTableEntryIdMaybe) {
3473 // return type_entry->data.maybe.child_type;
3474 // } else {
3475 // add_node_error(g, *expr_node,
3476 // buf_sprintf("expected maybe type, got '%s'", buf_ptr(&type_entry->name)));
3477 // return g->builtin_types.entry_invalid;
3478 // }
3479 //}
3480 case IrUnOpErrorReturn:3507 case IrUnOpErrorReturn:
3481 zig_panic("TODO analyze IrUnOpErrorReturn");3508 zig_panic("TODO analyze IrUnOpErrorReturn");
3482 case IrUnOpMaybeReturn:3509 case IrUnOpMaybeReturn:
std/builtin.zig+13-6
...@@ -1,24 +1,31 @@...@@ -1,24 +1,31 @@
1// These functions are provided when not linking against libc because LLVM1// These functions are provided when not linking against libc because LLVM
2// sometimes generates code that calls them.2// sometimes generates code that calls them.
33
4// TODO dest should be nullable and return value should be nullable4export fn memset(dest: ?&u8, c: u8, n: usize) -> ?&u8 {
5export fn memset(dest: &u8, c: u8, n: usize) -> &u8 {
6 @setDebugSafety(this, false);5 @setDebugSafety(this, false);
76
7 if (n == 0)
8 return dest;
9
10 const d = ??dest;
8 var index: usize = 0;11 var index: usize = 0;
9 while (index != n; index += 1)12 while (index != n; index += 1)
10 dest[index] = c;13 d[index] = c;
1114
12 return dest;15 return dest;
13}16}
1417
15// TODO dest, source, and return value should be nullable18export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) -> ?&u8 {
16export fn memcpy(noalias dest: &u8, noalias src: &const u8, n: usize) -> &u8 {
17 @setDebugSafety(this, false);19 @setDebugSafety(this, false);
1820
21 if (n == 0)
22 return dest;
23
24 const d = ??dest;
25 const s = ??src;
19 var index: usize = 0;26 var index: usize = 0;
20 while (index != n; index += 1)27 while (index != n; index += 1)
21 dest[index] = src[index];28 d[index] = s[index];
2229
23 return dest;30 return dest;
24}31}