Fun 0.41.5
The programming language that makes you have fun!
Loading...
Searching...
No Matches
json.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 json.c
12 * @brief JSON extension helpers and VM opcode cases (conditional build).
13 *
14 * Provides conversions between json-c objects and the Fun Value type and
15 * supplies VM opcode case implementations when FUN_WITH_JSON is enabled.
16 * This unit may be included or compiled conditionally based on build flags.
17 */
18
19/* json-c helpers and VM opcode cases (included from vm.c) */
20
21#ifdef FUN_WITH_JSON
22#include "value.h"
23#include "vm.h"
24
25#include <json-c/json.h>
26#include <string.h>
27
28/* --- Conversion helpers between json-c and Fun Value --- */
29/**
30 * @brief Convert a json-c object into a Fun Value.
31 *
32 * Maps json-c primitive and compound types to the closest Fun Value
33 * representation.
34 * - null -> Nil
35 * - boolean -> Bool
36 * - number (int/double) -> Int/Float
37 * - string -> String
38 * - array -> Array (recursively converted)
39 * - object -> Map<string,any> (values recursively converted)
40 *
41 * @param j Pointer to a json_object; may be NULL.
42 * @return A Value representing the converted JSON data. Ownership of the
43 * returned Value belongs to the caller and must be freed with
44 * free_value() when no longer needed.
45 */
46static Value json_to_fun(json_object *j) {
47 if (!j) return make_nil();
48 enum json_type t = json_object_get_type(j);
49 switch (t) {
50 case json_type_null:
51 return make_nil();
52 case json_type_boolean:
53 return make_bool(json_object_get_boolean(j));
54 case json_type_double:
55 return make_float(json_object_get_double(j));
56 case json_type_int:
57 return make_int((int64_t)json_object_get_int64(j));
58 case json_type_string:
59 return make_string(json_object_get_string(j));
60 case json_type_array: {
61 size_t n = json_object_array_length(j);
62 if (n == 0) {
63 return make_array_from_values(NULL, 0);
64 }
65 Value *vals = (Value *)malloc(sizeof(Value) * n);
66 if (!vals) return make_array_from_values(NULL, 0);
67 for (size_t i = 0; i < n; ++i) {
68 json_object *item = json_object_array_get_idx(j, (int)i);
69 vals[i] = json_to_fun(item);
70 }
72 for (size_t i = 0; i < n; ++i)
73 free_value(vals[i]);
74 free(vals);
75 return arr;
76 }
77 case json_type_object: {
78 Value map = make_map_empty();
79 json_object_object_foreach(j, key, val) {
80 (void)map_set(&map, key, json_to_fun(val));
81 }
82 return map;
83 }
84 default:
85 return make_nil();
86 }
87}
88
89/**
90 * @brief Convert a Fun Value into a json-c object.
91 *
92 * Produces a newly-allocated json_object tree representing the supplied
93 * Value. Unsupported Fun types are stringified using a placeholder.
94 *
95 * @param v Pointer to the source Value. Must not be NULL.
96 * @return Newly created json_object* on success. The caller owns the
97 * returned object and must release it with json_object_put().
98 */
99static json_object *fun_to_json(const Value *v) {
100 switch (v->type) {
101 case VAL_NIL:
102 return json_object_new_null();
103 case VAL_BOOL:
104 return json_object_new_boolean(v->i ? 1 : 0);
105 case VAL_INT:
106 return json_object_new_int64(v->i);
107 case VAL_FLOAT:
108 return json_object_new_double(v->d);
109 case VAL_STRING:
110 return json_object_new_string(v->s ? v->s : "");
111 case VAL_ARRAY: {
112 json_object *arr = json_object_new_array();
113 int n = array_length(v);
114 for (int i = 0; i < n; ++i) {
115 Value item;
116 if (array_get_copy(v, i, &item)) {
117 json_object_array_add(arr, fun_to_json(&item));
118 free_value(item);
119 } else {
120 json_object_array_add(arr, json_object_new_null());
121 }
122 }
123 return arr;
124 }
125 case VAL_MAP: {
126 json_object *obj = json_object_new_object();
127 /* We don't have an iterator API; use keys() helper */
128 Value keys = map_keys_array(v);
129 int kn = array_length(&keys);
130 for (int i = 0; i < kn; ++i) {
131 Value k;
132 if (!array_get_copy(&keys, i, &k)) continue;
133 if (k.type == VAL_STRING && k.s) {
134 Value val;
135 if (map_get_copy(v, k.s, &val)) {
136 json_object_object_add(obj, k.s, fun_to_json(&val));
138 } else {
139 json_object_object_add(obj, k.s, json_object_new_null());
140 }
141 }
142 free_value(k);
143 }
144 free_value(keys);
145 return obj;
146 }
147 default:
148 /* Fallback: stringify unsupported types */
149 return json_object_new_string("<unsupported>");
150 }
151}
152#endif
Value v
Definition cast.c:22
int k
Definition cast.c:29
array_clear & arr
Definition clear.c:38
const char * key
Definition get_bool.c:40
int n
Definition insert.c:41
static json_object * fun_to_json(const Value *v)
Convert a Fun Value into a json-c object.
Definition json.c:99
static Value json_to_fun(json_object *j)
Convert a json-c object into a Fun Value.
Definition json.c:46
Value val
Definition load_local.c:36
Value * vals
Definition make_array.c:39
free(vals)
int map_set(Value *vm, const char *key, Value v)
Insert or replace a key in the map.
Definition map.c:79
Value make_map_empty(void)
Construct a new empty map Value.
Definition map.c:35
int map_get_copy(const Value *vm, const char *key, Value *out)
Look up a key and copy the stored value into out.
Definition map.c:112
Value map_keys_array(const Value *vm)
Return all map keys as an array of strings.
Definition map.c:147
long t
Definition sleep_ms.c:32
json_object * j
Definition stringify.c:37
Tagged union representing a Fun value.
Definition value.h:68
Value make_bool(int v)
Construct a boolean Value.
Definition value.c:79
Value make_nil(void)
Construct a nil Value.
Definition value.c:126
Value make_string(const char *s)
Construct a string Value by duplicating the given C string.
Definition value.c:95
int array_length(const Value *v)
Get the element count of an array Value.
Definition value.c:176
void free_value(Value v)
Free dynamic storage owned by a Value.
Definition value.c:517
int array_get_copy(const Value *v, int index, Value *out)
Copy an array element into out.
Definition value.c:192
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
Value make_array_from_values(const Value *vals, int count)
Create an array Value by copying items from an input span.
Definition value.c:142
Defines the Value type and associated functions for the Fun VM.
@ VAL_BOOL
Definition value.h:52
@ VAL_ARRAY
Definition value.h:55
@ VAL_MAP
Definition value.h:56
@ VAL_STRING
Definition value.h:53
@ VAL_NIL
Definition value.h:57
@ VAL_INT
Definition value.h:51
@ VAL_FLOAT
Definition value.h:58
Core virtual machine data structures and public VM API.