Fun 0.41.5
The programming language that makes you have fun!
Loading...
Searching...
No Matches
to_number.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
10/**
11 * @file to_number.c
12 * @brief Implements the OP_TO_NUMBER opcode for converting values to integers in the VM.
13 *
14 * This file handles the OP_TO_NUMBER instruction, which converts a value to an integer.
15 * The value is popped from the stack, and the result is pushed back.
16 *
17 * Behavior:
18 * - Pops the value from the stack.
19 * - Converts the value to an integer.
20 * - Pushes the result onto the stack.
21 *
22 * Error Handling:
23 * - Exits with an error if the conversion fails.
24 *
25 * Example:
26 * - Bytecode: OP_TO_NUMBER
27 * - Stack before: ["42"]
28 * - Stack after: [42]
29 */
30
32 Value v = pop_value(vm);
33 if (v.type == VAL_INT) {
34 push_value(vm, make_int(v.i));
36 } else if (v.type == VAL_FLOAT) {
37 double d = v.d;
38 if (d >= (double)INT64_MIN && d <= (double)INT64_MAX) {
39 int64_t ii = (int64_t)d;
40 if ((double)ii == d) {
41 push_value(vm, make_int(ii));
42 } else {
44 }
45 } else {
47 }
49 } else if (v.type == VAL_STRING) {
50 const char *s = v.s ? v.s : "";
51 const char *p = s;
52 while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
53 p++;
54 char *endp = NULL;
55 /* Try float first to support decimals and scientific notation */
56 double dval = strtod(p, &endp);
57 while (endp && (*endp == ' ' || *endp == '\t' || *endp == '\r' || *endp == '\n'))
58 endp++;
59 if (!endp || *endp != '\0') {
60 /* Fallback to integer-only parse */
61 endp = NULL;
62 long long parsed = strtoll(p, &endp, 10);
63 while (endp && (*endp == ' ' || *endp == '\t' || *endp == '\r' || *endp == '\n'))
64 endp++;
65 if (endp && *endp == '\0') {
66 push_value(vm, make_int((int64_t)parsed));
67 } else {
68 push_value(vm, make_int(0));
69 }
70 } else {
71 /* Preserve int when exact; else float */
72 if (dval >= (double)INT64_MIN && dval <= (double)INT64_MAX) {
73 int64_t ii = (int64_t)dval;
74 if ((double)ii == dval) {
75 push_value(vm, make_int(ii));
76 } else {
77 push_value(vm, make_float(dval));
78 }
79 } else {
80 push_value(vm, make_float(dval));
81 }
82 }
84 } else if (v.type == VAL_BOOL) {
85 push_value(vm, make_int(v.i ? 1 : 0));
87 } else {
90 }
91 break;
92}
@ OP_TO_NUMBER
Definition bytecode.h:93
Value v
Definition cast.c:22
dictionary * d
Definition get_bool.c:43
const char * p
Definition read_file.c:37
uint32_t s
Definition rol.c:31
Tagged union representing a Fun value.
Definition value.h:68
push_value(vm, make_int(0))
void free_value(Value v)
Free dynamic storage owned by a Value.
Definition value.c:517
Value make_float(double v)
Construct a Value representing a double-precision float.
Definition value.c:64
Value make_int(int64_t v)
Construct a Value representing a 64-bit integer.
Definition value.c:51
@ VAL_BOOL
Definition value.h:52
@ VAL_STRING
Definition value.h:53
@ VAL_INT
Definition value.h:51
@ VAL_FLOAT
Definition value.h:58
static Value pop_value(VM *vm)
Pop a Value from the VM operand stack.
Definition vm.c:580