conditional optional unwrapping
This commit is contained in:
+26
-1
@@ -232,7 +232,8 @@ valid_value :: proc(
|
||||
}
|
||||
switch instructions[value_id].op {
|
||||
case .Param, .Const, .String, .Aggregate, .None, .Optional_Some,
|
||||
.Load_Global, .Function_Address, .Address_Of, .Load, .Slice, .Length, .Slice_Ptr, .Unwrap, .Orelse,
|
||||
.Load_Global, .Function_Address, .Address_Of, .Load, .Slice, .Length, .Slice_Ptr, .Unwrap,
|
||||
.Optional_Is_Some, .Optional_Value, .Orelse,
|
||||
.Widen, .C_Vararg_Promote, .Weaken_Pointer, .Weaken_Slice, .Decay_Array_Pointer,
|
||||
.Neg_Checked, .Add_Checked, .Pointer_Add, .Not, .Compare, .Call:
|
||||
return true
|
||||
@@ -928,6 +929,30 @@ emit_instruction_stream :: proc(
|
||||
} else {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = extractvalue %s %%v%d, 1\n", instruction_index, llvm_type(optional_type, &emitter.module.types), instruction.a)
|
||||
}
|
||||
case .Optional_Is_Some:
|
||||
optional_type := instructions[instruction.a].type if valid_instruction(instructions, instruction.a) else types.INVALID
|
||||
item, ok := types.node(&emitter.module.types, optional_type)
|
||||
if !ok || item.kind != .Optional {
|
||||
emit_recovery_value(emitter, instruction_index, instruction, "invalid optional presence test")
|
||||
continue
|
||||
}
|
||||
if types.is_pointer(item.child, &emitter.module.types) {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = icmp ne ptr %%v%d, null\n", instruction_index, instruction.a)
|
||||
} else {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = extractvalue %s %%v%d, 0\n", instruction_index, llvm_type(optional_type, &emitter.module.types), instruction.a)
|
||||
}
|
||||
case .Optional_Value:
|
||||
optional_type := instructions[instruction.a].type if valid_instruction(instructions, instruction.a) else types.INVALID
|
||||
item, ok := types.node(&emitter.module.types, optional_type)
|
||||
if !ok || item.kind != .Optional || !types.equal(item.child, instruction.type) {
|
||||
emit_recovery_value(emitter, instruction_index, instruction, "invalid optional value")
|
||||
continue
|
||||
}
|
||||
if types.is_pointer(item.child, &emitter.module.types) {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = select i1 true, ptr %%v%d, ptr null\n", instruction_index, instruction.a)
|
||||
} else {
|
||||
fmt.sbprintf(&emitter.builder, " %%v%d = extractvalue %s %%v%d, 1\n", instruction_index, llvm_type(optional_type, &emitter.module.types), instruction.a)
|
||||
}
|
||||
case .Orelse_Begin:
|
||||
optional_type := instructions[instruction.a].type if valid_instruction(instructions, instruction.a) else types.INVALID
|
||||
item, ok := types.node(&emitter.module.types, optional_type)
|
||||
|
||||
Reference in New Issue
Block a user