function pointers and callbacks
This commit is contained in:
@@ -156,7 +156,7 @@ lower_compound_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instructi
|
||||
args[index] = lower_nested_expr(state, arg)
|
||||
}
|
||||
return append_instruction(state, ir.Instruction{
|
||||
op=.Aggregate, span=expr.span, type=expr.type, args=args,
|
||||
op=.Aggregate, span=expr.span, type=expr.type, args=args, integer=expr.integer,
|
||||
target=ir.INVALID_REF, a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
@@ -332,6 +332,19 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
})
|
||||
}
|
||||
_ = pop(&stack)
|
||||
case .Function:
|
||||
function := hir.as_function(expr.target)
|
||||
if function == hir.INVALID_FUNCTION || int(function) >= len(state.hir_module.functions) {
|
||||
last = append_recovery_value(state, expr.span, expr.type, expr.diagnostic)
|
||||
} else {
|
||||
last = append_instruction(state, ir.Instruction{
|
||||
op=.Function_Address, span=expr.span, type=expr.type,
|
||||
target=ir.function_ref(ir.Function_Id(function)),
|
||||
a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
}
|
||||
_ = pop(&stack)
|
||||
case .Widen, .C_Vararg_Promote, .Weaken_Pointer, .Weaken_Slice, .Decay_Array_Pointer:
|
||||
stack[frame_index].stage = 1
|
||||
append(&stack, Lower_Expr_Frame{expr=expr.left})
|
||||
@@ -343,7 +356,17 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
append(&stack, Lower_Expr_Frame{expr=expr.left})
|
||||
case .Call:
|
||||
function := hir.as_function(expr.target)
|
||||
if function == hir.INVALID_FUNCTION || int(function) >= len(state.hir_module.functions) {
|
||||
if function == hir.INVALID_FUNCTION {
|
||||
if expr.left == hir.INVALID_EXPR {
|
||||
last = append_recovery_value(state, expr.span, expr.type, expr.diagnostic)
|
||||
_ = pop(&stack)
|
||||
continue
|
||||
}
|
||||
stack[frame_index].stage = 6
|
||||
append(&stack, Lower_Expr_Frame{expr=expr.left})
|
||||
continue
|
||||
}
|
||||
if int(function) >= len(state.hir_module.functions) {
|
||||
last = append_recovery_value(state, expr.span, expr.type, expr.diagnostic)
|
||||
_ = pop(&stack)
|
||||
continue
|
||||
@@ -356,6 +379,15 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
}
|
||||
continue
|
||||
}
|
||||
if frame.stage == 6 {
|
||||
stack[frame_index].left = last
|
||||
stack[frame_index].args = make([]ir.Instruction_Id, len(expr.args), state.allocator)
|
||||
stack[frame_index].stage = 4
|
||||
if len(expr.args) > 0 {
|
||||
append(&stack, Lower_Expr_Frame{expr=expr.args[0]})
|
||||
}
|
||||
continue
|
||||
}
|
||||
if frame.stage == 5 {
|
||||
last = append_instruction(state, ir.Instruction{
|
||||
op=.Neg_Checked, span=expr.span, type=expr.type, target=ir.INVALID_REF,
|
||||
@@ -405,9 +437,14 @@ lower_expr :: proc(state: ^State, expr_id: hir.Expr_Id) -> ir.Instruction_Id {
|
||||
continue
|
||||
}
|
||||
}
|
||||
function := hir.as_function(expr.target)
|
||||
callee := frame.left
|
||||
if function != hir.INVALID_FUNCTION {
|
||||
callee = ir.INVALID_INSTRUCTION
|
||||
}
|
||||
last = append_instruction(state, ir.Instruction{
|
||||
op=.Call, span=expr.span, type=expr.type, target=ir.function_ref(ir.Function_Id(hir.as_function(expr.target))),
|
||||
a=ir.INVALID_INSTRUCTION, b=ir.INVALID_INSTRUCTION, args=stack[frame_index].args, diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
op=.Call, span=expr.span, type=expr.type, target=ir.function_ref(ir.Function_Id(function)),
|
||||
a=callee, b=ir.INVALID_INSTRUCTION, args=stack[frame_index].args, diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
stack[frame_index].args = nil
|
||||
_ = pop(&stack)
|
||||
|
||||
Reference in New Issue
Block a user