@@ -200,6 +200,73 @@ Value value_tns_slice(Value v, const int64_t* starts, const int64_t* ends, size_
200200 return out ;
201201}
202202
203+ // Map implementation
204+ Value value_map_new (void ) {
205+ Value v ; v .type = VAL_MAP ;
206+ Map * m = malloc (sizeof (Map ));
207+ if (!m ) { fprintf (stderr , "Out of memory\n" ); exit (1 ); }
208+ m -> items = NULL ;
209+ m -> count = 0 ;
210+ m -> capacity = 0 ;
211+ v .as .map = m ;
212+ return v ;
213+ }
214+
215+ static int map_find_index (Map * m , Value key ) {
216+ for (size_t i = 0 ; i < m -> count ; i ++ ) {
217+ MapEntry * e = & m -> items [i ];
218+ if (e -> key .type == key .type ) {
219+ if (key .type == VAL_INT && e -> key .as .i == key .as .i ) return (int )i ;
220+ if (key .type == VAL_STR && e -> key .as .s && key .as .s && strcmp (e -> key .as .s , key .as .s ) == 0 ) return (int )i ;
221+ if (key .type == VAL_FLT && e -> key .as .f == key .as .f ) return (int )i ;
222+ }
223+ }
224+ return -1 ;
225+ }
226+
227+ void value_map_set (Value * mapval , Value key , Value val ) {
228+ if (!mapval || mapval -> type != VAL_MAP ) return ;
229+ Map * m = mapval -> as .map ;
230+ int idx = map_find_index (m , key );
231+ if (idx >= 0 ) {
232+ // replace
233+ value_free (m -> items [idx ].value );
234+ m -> items [idx ].value = value_copy (val );
235+ return ;
236+ }
237+ if (m -> count + 1 > m -> capacity ) {
238+ size_t newc = m -> capacity == 0 ? 8 : m -> capacity * 2 ;
239+ m -> items = realloc (m -> items , sizeof (MapEntry ) * newc );
240+ if (!m -> items ) { fprintf (stderr , "Out of memory\n" ); exit (1 ); }
241+ m -> capacity = newc ;
242+ }
243+ m -> items [m -> count ].key = value_copy (key );
244+ m -> items [m -> count ].value = value_copy (val );
245+ m -> count ++ ;
246+ }
247+
248+ Value value_map_get (Value mapval , Value key , int * found ) {
249+ Value out = value_null ();
250+ if (!mapval .as .map ) { if (found ) * found = 0 ; return out ; }
251+ Map * m = mapval .as .map ;
252+ int idx = map_find_index (m , key );
253+ if (idx < 0 ) { if (found ) * found = 0 ; return out ; }
254+ if (found ) * found = 1 ;
255+ return value_copy (m -> items [idx ].value );
256+ }
257+
258+ void value_map_delete (Value * mapval , Value key ) {
259+ if (!mapval || mapval -> type != VAL_MAP ) return ;
260+ Map * m = mapval -> as .map ;
261+ int idx = map_find_index (m , key );
262+ if (idx < 0 ) return ;
263+ value_free (m -> items [idx ].key );
264+ value_free (m -> items [idx ].value );
265+ // compact
266+ for (size_t i = (size_t )idx ; i + 1 < m -> count ; i ++ ) m -> items [i ] = m -> items [i + 1 ];
267+ m -> count -- ;
268+ }
269+
203270Value value_copy (Value v ) {
204271 Value out = v ;
205272 if (v .type == VAL_STR && v .as .s ) {
@@ -216,6 +283,18 @@ Value value_copy(Value v) {
216283 t2 -> data = malloc (sizeof (Value ) * t2 -> length );
217284 for (size_t i = 0 ; i < t2 -> length ; i ++ ) t2 -> data [i ] = value_copy (t -> data [i ]);
218285 out .as .tns = t2 ;
286+ } else if (v .type == VAL_MAP && v .as .map ) {
287+ Map * m = v .as .map ;
288+ Map * m2 = malloc (sizeof (Map ));
289+ if (!m2 ) { fprintf (stderr , "Out of memory\n" ); exit (1 ); }
290+ m2 -> count = m -> count ;
291+ m2 -> capacity = m -> count ;
292+ m2 -> items = malloc (sizeof (MapEntry ) * (m2 -> capacity ? m2 -> capacity : 1 ));
293+ for (size_t i = 0 ; i < m -> count ; i ++ ) {
294+ m2 -> items [i ].key = value_copy (m -> items [i ].key );
295+ m2 -> items [i ].value = value_copy (m -> items [i ].value );
296+ }
297+ out .as .map = m2 ;
219298 }
220299 return out ;
221300}
@@ -233,12 +312,24 @@ void value_free(Value v) {
233312 if (t -> strides ) free (t -> strides );
234313 free (t );
235314 }
315+ else if (v .type == VAL_MAP && v .as .map ) {
316+ Map * m = v .as .map ;
317+ if (m -> items ) {
318+ for (size_t i = 0 ; i < m -> count ; i ++ ) {
319+ value_free (m -> items [i ].key );
320+ value_free (m -> items [i ].value );
321+ }
322+ free (m -> items );
323+ }
324+ free (m );
325+ }
236326}
237327
238328const char * value_type_name (Value v ) {
239329 switch (v .type ) {
240330 case VAL_INT : return "INT" ;
241331 case VAL_FLT : return "FLT" ;
332+ case VAL_MAP : return "MAP" ;
242333 case VAL_TNS : return "TNS" ;
243334 case VAL_STR : return "STR" ;
244335 case VAL_FUNC : return "FUNC" ;
0 commit comments