digraph {
    node[shape="point"]
    mid_var_1[width="0"]
    mid_var_2[width="0"]
    mid_var_3[width="0"]
    mid_var_4[width="0"]
    HELP_var_1 [label="integer_subtraction",shape="rectangle"]
    HELP_var_2 [label="integer_multiplication",shape="rectangle"]
    HELP_var_3 [label="integer_gt",shape="rectangle"]
    HELP_var_4 [label="factorial",shape="rectangle"]
    var_1 -> HELP_var_1 [style="dotted"]
    var_2 -> HELP_var_2 [style="dotted"]
    var_3 -> HELP_var_3 [style="dotted"]
    var_4 -> HELP_var_4 [style="dotted"]

    root -> globals [label="__globals"]
    globals -> mid_var_1 [arrowhead="none"]
    mid_var_1 -> var_1 [constraint="false"]
    mid_var_1 -> var_value_1
    var_value_1 -> signature_1 [label="value"]
    signature_1 -> body_1 [label="body"]
    signature_1 -> params_1 [label="params"]
    params_1 -> params_1_a [label="a"]
    params_1 -> params_1_b [label="b"]

    globals -> mid_var_2 [arrowhead="none"]
    mid_var_2 -> var_2 [constraint="false"]
    mid_var_2 -> var_value_2
    var_value_2 -> signature_2 [label="value"]
    signature_2 -> body_2 [label="body"]
    signature_2 -> params_2 [label="params"]
    params_2 -> params_2_a [label="a"]
    params_2 -> params_2_b [label="b"]

    globals -> mid_var_3 [arrowhead="none"]
    mid_var_3 -> var_3 [constraint="false"]
    mid_var_3 -> var_value_3
    var_value_3 -> signature_3 [label="value"]
    signature_3 -> body_3 [label="body"]
    signature_3 -> params_3 [label="params"]
    params_3 -> params_3_a [label="a"]
    params_3 -> params_3_b [label="b"]

    globals -> mid_var_4 [arrowhead="none"]
    mid_var_4 -> var_4 [constraint="false"]
    mid_var_4 -> var_value_4
    var_value_4 -> signature_4 [label="value"]
    signature_4 -> if_1 [label="body"]
    signature_4 -> params_4 [label="params"]
    params_4 -> params_4_a [label="n"]

    // The actual function begins here
    value_1 [shape="oval",label="1"]
    value_2 [shape="oval",label="1"]
    value_3 [shape="oval",label="1"]
    value_a [shape="oval",label="a"]
    value_b [shape="oval",label="b"]
    value_a2 [shape="oval",label="a"]
    value_b2 [shape="oval",label="b"]
    value_a3 [shape="oval",label="a"]
    value_b3 [shape="oval",label="b"]
    value_n [shape="oval",label="n"]
    value_n2 [shape="oval",label="n"]

    access_resolve_1 [shape="oval",label="ACCESS"]
    access_resolve_3 [shape="oval",label="ACCESS"]
    access_resolve_4 [shape="oval",label="ACCESS"]
    access_resolve_5 [shape="oval",label="ACCESS"]
    access_resolve_7 [shape="oval",label="ACCESS"]

    if_1 [shape="oval",label="IF"]
    call_1 [shape="oval",label="CALL"]
    call_2 [shape="oval",label="CALL"]
    call_3 [shape="oval",label="CALL"]
    call_4 [shape="oval",label="CALL"]
    resolve_1 [shape="oval",label="RESOLVE"]
    resolve_2 [shape="oval",label="RESOLVE"]
    resolve_3 [shape="oval",label="RESOLVE"]
    resolve_4 [shape="oval",label="RESOLVE"]
    resolve_5 [shape="oval",label="RESOLVE"]
    resolve_6 [shape="oval",label="RESOLVE"]
    resolve_10[label="RESOLVE",shape="oval"]
    access_1 [shape="oval",label="ACCESS"]
    access_2 [shape="oval",label="ACCESS"]
    access_3 [shape="oval",label="ACCESS"]
    return_1 [shape="oval",label="RETURN"]
    return_2 [shape="oval",label="RETURN"]
    const_1 [shape="oval",label="CONST"]
    const_2 [shape="oval",label="CONST"]
    const_3 [shape="oval",label="CONST"]

    if_1 -> call_1 [label="cond"]
    if_1 -> return_2 [label="then"]
    if_1 -> return_1 [label="else"]

    // Condition
    call_1 -> access_resolve_1 [label="func"]
    access_resolve_1 -> resolve_1 [label="var"]
    resolve_1 -> var_3 [label="var"]
    call_1 -> param_1a [label="params"]
    param_1a -> value_a [label="name"]
    param_1a -> access_1 [label="value"]
    access_1 -> resolve_2 [label="var"]
    resolve_2 -> params_4_a [label="var",constraint="false"]
    param_1a -> param_1b [label="next_param"]
    param_1b -> value_b [label="name"]
    param_1b -> const_1 [label="value"]
    const_1 -> value_1 [label="node"]
    call_1 -> param_1b [label="last_param"]

    // Else
    return_1 -> const_2 [label="value"]
    const_2 -> value_2 [label="node"]

    // Then
    return_2 -> call_2 [label="value"]
    call_2 -> access_resolve_3 [label="func"]
    access_resolve_3 -> resolve_3 [label="var"]
    resolve_3 -> var_2 [label="var"]
    call_2 -> param_2a [label="params"]
    call_2 -> param_2b [label="last_param"]
    param_2a -> value_a2 [label="name"]
    param_2a -> param_2b [label="next_param"]
    param_2a -> access_2 [label="value"]
    access_2 -> resolve_10 [label="var"]
    resolve_10 -> params_4_a [label="var"]
    param_2b -> value_b2 [label="name"]
    param_2b -> call_3 [label="value"]
    // call to self
    call_3 -> access_resolve_4 [label="func"]
    access_resolve_4 -> resolve_4 [label="var"]
    resolve_4 -> var_4 [label="var"]
    call_3 -> param_3a [label="params"]
    call_3 -> param_3a [label="last_param"]
    param_3a -> value_n [label="name"]
    param_3a -> call_4 [label="value"]
    // Subtraction
    call_4 -> access_resolve_5 [label="func"]
    access_resolve_5 -> resolve_5 [label="var"]
    resolve_5 -> var_1 [label="var"]
    call_4 -> param_4a [label="params"]
    param_4a -> value_a3 [label="name"]
    param_4a -> access_3 [label="value"]
    access_3 -> resolve_6 [label="var"]
    resolve_6 -> params_4_a [label="var"]
    param_4a -> param_4b [label="next_param"]
    param_4b -> value_b3 [label="name"]
    param_4b -> const_3 [label="value"]
    const_3 -> value_3 [label="node"]
    call_4 -> param_4b [label="last_param"]

    // Global initial IP
    const_4 [shape="oval",label="CONST"]
    value_4 [shape="oval",label="3"]
    resolve_7 [shape="oval",label="RESOLVE"]
    invoke_factorial [shape="oval",label="CALL"]

    globals -> invoke_factorial [label="__IP"]
    invoke_factorial -> access_resolve_7 [label="func"]
    access_resolve_7 -> resolve_7 [label="var"]
    resolve_7 -> var_4 [label="var"]
    invoke_factorial -> invoke_params [label="params"]
    invoke_factorial -> invoke_params [label="last_param"]
    invoke_params -> const_4 [label="value"]
    invoke_params -> value_n2 [label="name"]
    const_4 -> value_4 [label="node"]
}
