private int print_core_case(string case_name) {
    PhpefRuntimeCore.Zval a;
    PhpefRuntimeCore.Zval b;
    bool use_concat = false;

    switch (case_name) {
    case "string_plus_int":
        a = PhpefRuntimeCore.Zval.from_string("5");
        b = PhpefRuntimeCore.Zval.from_int(4);
        break;
    case "int_plus_string":
        a = PhpefRuntimeCore.Zval.from_int(5);
        b = PhpefRuntimeCore.Zval.from_string("4");
        break;
    case "bool_plus_string":
        a = PhpefRuntimeCore.Zval.from_bool(true);
        b = PhpefRuntimeCore.Zval.from_string("4");
        break;
    case "string_concat_int":
        a = PhpefRuntimeCore.Zval.from_string("Welt");
        b = PhpefRuntimeCore.Zval.from_int(1);
        use_concat = true;
        break;
    case "bool_concat_string":
        a = PhpefRuntimeCore.Zval.from_bool(true);
        b = PhpefRuntimeCore.Zval.from_string("x");
        use_concat = true;
        break;
    default:
        stderr.printf("unknown core case: %s\n", case_name);
        return 2;
    }

    var result = use_concat ? a.concat(b) : a.add(b);
    stdout.printf("%s", result.to_php_string());
    return 0;
}

private string? php_code_for_case(string case_name) {
    switch (case_name) {
    case "string_plus_int":
        return "$a = \"5\"; $a = $a + 4; echo $a;";
    case "int_plus_string":
        return "$a = 5; $a = $a + \"4\"; echo $a;";
    case "bool_plus_string":
        return "$a = true; $a = $a + \"4\"; echo $a;";
    case "string_concat_int":
        return "$a = \"Welt\"; $a = $a . 1; echo $a;";
    case "bool_concat_string":
        return "$a = true; $a = $a . \"x\"; echo $a;";
    default:
        return null;
    }
}

private int print_php_case(string[] args, string case_name) {
    var code = php_code_for_case(case_name);
    if (code == null) {
        stderr.printf("unknown php case: %s\n", case_name);
        return 2;
    }

    PhpefRuntimeEmbed.engine_start(args);
    PhpefRuntimeEmbed.eval_code("phpef-runtime-embed-zval-retyping-ref", code);
    PhpefRuntimeEmbed.engine_stop();
    return 0;
}

public int main(string[] args) {
    if (args.length != 3) {
        stderr.printf("usage: %s core|php CASE\n", args[0]);
        return 2;
    }

    if (args[1] == "core") {
        return print_core_case(args[2]);
    }
    if (args[1] == "php") {
        return print_php_case(args, args[2]);
    }

    stderr.printf("unknown mode: %s\n", args[1]);
    return 2;
}
