1 #include "../minilang.h"
2 #include "../ml_macros.h"
3 #include "../ml_cbor.h"
4 #include <gc/gc.h>
5 #include <string.h>
6 #include "../ml_object.h"
7 
8 #include "minicbor/minicbor.h"
9 
ml_cbor_write(ml_value_t * Value,void * Data,ml_cbor_write_fn WriteFn)10 ml_value_t *ml_cbor_write(ml_value_t *Value, void *Data, ml_cbor_write_fn WriteFn) {
11 	typeof(ml_cbor_write) *function = ml_typed_fn_get(Value->Type, ml_cbor_write);
12 	if (function) {
13 		return function(Value, Data, WriteFn);
14 	} else {
15 		return ml_error("CBORError", "No method to encode %s to CBOR", ml_typeof(Value)->Name);
16 	}
17 }
18 
ml_cbor_size_fn(size_t * Total,unsigned char * Bytes,int Size)19 static void ml_cbor_size_fn(size_t *Total, unsigned char *Bytes, int Size) {
20 	*Total += Size;
21 }
22 
ml_cbor_bytes_fn(unsigned char ** End,unsigned char * Bytes,int Size)23 static void ml_cbor_bytes_fn(unsigned char **End, unsigned char *Bytes, int Size) {
24 	memcpy(*End, Bytes, Size);
25 	*End += Size;
26 }
27 
ml_to_cbor(ml_value_t * Value)28 ml_cbor_t ml_to_cbor(ml_value_t *Value) {
29 	size_t Size = 0;
30 	ml_value_t *Error = ml_cbor_write(Value, &Size, (void *)ml_cbor_size_fn);
31 	if (Error) return (ml_cbor_t){{Error}, 0};
32 	unsigned char *Bytes = GC_MALLOC_ATOMIC(Size), *End = Bytes;
33 	ml_cbor_write(Value, &End, (void *)ml_cbor_bytes_fn);
34 	return (ml_cbor_t){{Bytes}, Size};
35 }
36 
37 typedef struct block_t {
38 	struct block_t *Prev;
39 	const void *Data;
40 	int Size;
41 } block_t;
42 
43 typedef struct collection_t {
44 	struct collection_t *Prev;
45 	struct tag_t *Tags;
46 	ml_value_t *Key;
47 	ml_value_t *Collection;
48 	block_t *Blocks;
49 	int Remaining;
50 } collection_t;
51 
52 typedef struct tag_t {
53 	struct tag_t *Prev;
54 	ml_tag_t Handler;
55 	void *Data;
56 } tag_t;
57 
58 typedef struct ml_cbor_reader_t {
59 	collection_t *Collection;
60 	tag_t *Tags;
61 	ml_value_t *Value;
62 	ml_tag_t (*TagFn)(uint64_t Tag, void *Data, void **TagData);
63 	void *TagFnData;
64 	minicbor_reader_t Reader[1];
65 } ml_cbor_reader_t;
66 
ml_cbor_reader_new(void * TagFnData,ml_tag_t (* TagFn)(uint64_t,void *,void **))67 ml_cbor_reader_t *ml_cbor_reader_new(void *TagFnData, ml_tag_t (*TagFn)(uint64_t, void *, void **)) {
68 	ml_cbor_reader_t *Reader = new(ml_cbor_reader_t);
69 	Reader->TagFnData = TagFnData;
70 	Reader->TagFn = TagFn;
71 	ml_cbor_reader_init(Reader->Reader);
72 	Reader->Reader->UserData = Reader;
73 	return Reader;
74 }
75 
ml_cbor_reader_read(ml_cbor_reader_t * Reader,unsigned char * Bytes,int Size)76 void ml_cbor_reader_read(ml_cbor_reader_t *Reader, unsigned char *Bytes, int Size) {
77 	ml_cbor_read(Reader->Reader, Bytes, Size);
78 }
79 
ml_cbor_reader_get(ml_cbor_reader_t * Reader)80 ml_value_t *ml_cbor_reader_get(ml_cbor_reader_t *Reader) {
81 	if (!Reader->Value) return ml_error("CBORError", "CBOR not completely read");
82 	return Reader->Value;
83 }
84 
ml_cbor_reader_extra(ml_cbor_reader_t * Reader)85 int ml_cbor_reader_extra(ml_cbor_reader_t *Reader) {
86 	return ml_cbor_reader_remaining(Reader->Reader);
87 }
88 
89 static ml_value_t IsByteString[1];
90 static ml_value_t IsString[1];
91 static ml_value_t IsList[1];
92 
value_handler(ml_cbor_reader_t * Reader,ml_value_t * Value)93 static void value_handler(ml_cbor_reader_t *Reader, ml_value_t *Value) {
94 	for (tag_t *Tag = Reader->Tags; Tag; Tag = Tag->Prev) {
95 		if (!ml_is_error(Value)) Value = Tag->Handler(Tag->Data, Value);
96 	}
97 	Reader->Tags = 0;
98 	collection_t *Collection = Reader->Collection;
99 	if (!Collection) {
100 		Reader->Value = Value;
101 		ml_cbor_reader_finish(Reader->Reader);
102 	} else if (Collection->Key == IsList) {
103 		ml_list_append(Collection->Collection, Value);
104 		if (Collection->Remaining && --Collection->Remaining == 0) {
105 			Reader->Collection = Collection->Prev;
106 			Reader->Tags = Collection->Tags;
107 			value_handler(Reader, Collection->Collection);
108 		}
109 	} else if (Collection->Key) {
110 		ml_map_insert(Collection->Collection, Collection->Key, Value);
111 		if (Collection->Remaining && --Collection->Remaining == 0) {
112 			Reader->Collection = Collection->Prev;
113 			Reader->Tags = Collection->Tags;
114 			value_handler(Reader, Collection->Collection);
115 		} else {
116 			Collection->Key = 0;
117 		}
118 	} else {
119 		Collection->Key = Value;
120 	}
121 }
122 
ml_cbor_read_positive_fn(ml_cbor_reader_t * Reader,uint64_t Value)123 void ml_cbor_read_positive_fn(ml_cbor_reader_t *Reader, uint64_t Value) {
124 	value_handler(Reader, ml_integer(Value));
125 }
126 
ml_cbor_read_negative_fn(ml_cbor_reader_t * Reader,uint64_t Value)127 void ml_cbor_read_negative_fn(ml_cbor_reader_t *Reader, uint64_t Value) {
128 	if (Value <= 0x7FFFFFFFL) {
129 		value_handler(Reader, ml_integer(~(uint32_t)Value));
130 	} else {
131 		value_handler(Reader, ml_integer(Value));
132 		// TODO: Implement large numbers somehow
133 		// mpz_t Temp;
134 		// mpz_init_set_ui(Temp, (uint32_t)(Value >> 32));
135 		// mpz_mul_2exp(Temp, Temp, 32);
136 		// mpz_add_ui(Temp, Temp, (uint32_t)Value);
137 		// mpz_com(Temp, Temp);
138 		// value_handler(Reader, Std$Integer$new_big(Temp));
139 	}
140 }
141 
ml_cbor_read_bytes_fn(ml_cbor_reader_t * Reader,int Size)142 void ml_cbor_read_bytes_fn(ml_cbor_reader_t *Reader, int Size) {
143 	if (Size) {
144 		collection_t *Collection = new(collection_t);
145 		Collection->Prev = Reader->Collection;
146 		Collection->Tags = Reader->Tags;
147 		Reader->Tags = 0;
148 		Collection->Key = IsByteString;
149 		Collection->Remaining = 0;
150 		Collection->Blocks = 0;
151 		Reader->Collection = Collection;
152 	} else {
153 		value_handler(Reader, ml_cstring(""));
154 	}
155 }
156 
ml_cbor_read_bytes_piece_fn(ml_cbor_reader_t * Reader,const void * Bytes,int Size,int Final)157 void ml_cbor_read_bytes_piece_fn(ml_cbor_reader_t *Reader, const void *Bytes, int Size, int Final) {
158 	collection_t *Collection = Reader->Collection;
159 	if (Final) {
160 		Reader->Collection = Collection->Prev;
161 		Reader->Tags = Collection->Tags;
162 		int Total = Collection->Remaining + Size;
163 		char *Buffer = GC_MALLOC_ATOMIC(Total);
164 		Buffer += Collection->Remaining;
165 		memcpy(Buffer, Bytes, Size);
166 		for (block_t *B = Collection->Blocks; B; B = B->Prev) {
167 			Buffer -= B->Size;
168 			memcpy(Buffer, B->Data, B->Size);
169 		}
170 		value_handler(Reader, ml_string(Buffer, Total));
171 	} else {
172 		block_t *Block = new(block_t);
173 		Block->Prev = Collection->Blocks;
174 		Block->Data = Bytes;
175 		Block->Size = Size;
176 		Collection->Blocks = Block;
177 		Collection->Remaining += Size;
178 	}
179 }
180 
ml_cbor_read_string_fn(ml_cbor_reader_t * Reader,int Size)181 void ml_cbor_read_string_fn(ml_cbor_reader_t *Reader, int Size) {
182 	if (Size) {
183 		collection_t *Collection = new(collection_t);
184 		Collection->Prev = Reader->Collection;
185 		Collection->Tags = Reader->Tags;
186 		Reader->Tags = 0;
187 		Collection->Key = IsString;
188 		Collection->Remaining = 0;
189 		Collection->Blocks = 0;
190 		Reader->Collection = Collection;
191 	} else {
192 		value_handler(Reader, ml_cstring(""));
193 	}
194 }
195 
ml_cbor_read_string_piece_fn(ml_cbor_reader_t * Reader,const void * Bytes,int Size,int Final)196 void ml_cbor_read_string_piece_fn(ml_cbor_reader_t *Reader, const void *Bytes, int Size, int Final) {
197 	collection_t *Collection = Reader->Collection;
198 	if (Final) {
199 		Reader->Collection = Collection->Prev;
200 		Reader->Tags = Collection->Tags;
201 		int Total = Collection->Remaining + Size;
202 		char *Buffer = GC_MALLOC_ATOMIC(Total);
203 		Buffer += Collection->Remaining;
204 		memcpy(Buffer, Bytes, Size);
205 		for (block_t *B = Collection->Blocks; B; B = B->Prev) {
206 			Buffer -= B->Size;
207 			memcpy(Buffer, B->Data, B->Size);
208 		}
209 		value_handler(Reader, ml_string(Buffer, Total));
210 	} else {
211 		block_t *Block = new(block_t);
212 		Block->Prev = Collection->Blocks;
213 		Block->Data = Bytes;
214 		Block->Size = Size;
215 		Collection->Blocks = Block;
216 		Collection->Remaining += Size;
217 	}
218 }
219 
ml_cbor_read_array_fn(ml_cbor_reader_t * Reader,int Size)220 void ml_cbor_read_array_fn(ml_cbor_reader_t *Reader, int Size) {
221 	if (Size) {
222 		collection_t *Collection = new(collection_t);
223 		Collection->Prev = Reader->Collection;
224 		Collection->Tags = Reader->Tags;
225 		Reader->Tags = 0;
226 		Collection->Remaining = Size;
227 		Collection->Key = IsList;
228 		Collection->Collection = ml_list();
229 		Reader->Collection = Collection;
230 	} else {
231 		value_handler(Reader, ml_list());
232 	}
233 }
234 
ml_cbor_read_map_fn(ml_cbor_reader_t * Reader,int Size)235 void ml_cbor_read_map_fn(ml_cbor_reader_t *Reader, int Size) {
236 	if (Size > 0) {
237 		collection_t *Collection = new(collection_t);
238 		Collection->Prev = Reader->Collection;
239 		Collection->Tags = Reader->Tags;
240 		Reader->Tags = 0;
241 		Collection->Remaining = Size;
242 		Collection->Key = 0;
243 		Collection->Collection = ml_map();
244 		Reader->Collection = Collection;
245 	} else {
246 		value_handler(Reader, ml_map());
247 	}
248 }
249 
ml_cbor_read_tag_fn(ml_cbor_reader_t * Reader,uint64_t Tag)250 void ml_cbor_read_tag_fn(ml_cbor_reader_t *Reader, uint64_t Tag) {
251 	void *Data;
252 	ml_tag_t Handler = Reader->TagFn(Tag, Reader->TagFnData, &Data);
253 	if (Handler) {
254 		tag_t *Tag = new(tag_t);
255 		Tag->Prev = Reader->Tags;
256 		Tag->Handler = Handler;
257 		Tag->Data = Data;
258 		Reader->Tags = Tag;
259 	}
260 }
261 
ml_cbor_read_float_fn(ml_cbor_reader_t * Reader,double Value)262 void ml_cbor_read_float_fn(ml_cbor_reader_t *Reader, double Value) {
263 	value_handler(Reader, ml_real(Value));
264 }
265 
ml_cbor_read_simple_fn(ml_cbor_reader_t * Reader,int Value)266 void ml_cbor_read_simple_fn(ml_cbor_reader_t *Reader, int Value) {
267 	switch (Value) {
268 	case CBOR_SIMPLE_FALSE:
269 		value_handler(Reader, (ml_value_t *)MLFalse);
270 		break;
271 	case CBOR_SIMPLE_TRUE:
272 		value_handler(Reader, (ml_value_t *)MLTrue);
273 		break;
274 	case CBOR_SIMPLE_NULL:
275 		value_handler(Reader, MLNil);
276 		break;
277 	default:
278 		value_handler(Reader, MLNil);
279 		break;
280 	}
281 }
282 
ml_cbor_read_break_fn(ml_cbor_reader_t * Reader)283 void ml_cbor_read_break_fn(ml_cbor_reader_t *Reader) {
284 	collection_t *Collection = Reader->Collection;
285 	Reader->Collection = Collection->Prev;
286 	Reader->Tags = Collection->Tags;
287 	value_handler(Reader, Collection->Collection);
288 }
289 
ml_cbor_read_error_fn(ml_cbor_reader_t * Reader,int Position,const char * Message)290 void ml_cbor_read_error_fn(ml_cbor_reader_t *Reader, int Position, const char *Message) {
291 	value_handler(Reader, ml_error("CBORError", "Read error: %s at %d", Message, Position));
292 }
293 
ml_value_fn(ml_value_t * Callback,ml_value_t * Value)294 static ml_value_t *ml_value_fn(ml_value_t *Callback, ml_value_t *Value) {
295 	return ml_simple_inline(Callback, 1, Value);
296 }
297 
ml_value_tag_fn(uint64_t Tag,ml_value_t * Callback,void ** Data)298 static ml_tag_t ml_value_tag_fn(uint64_t Tag, ml_value_t *Callback, void **Data) {
299 	Data[0] = ml_simple_inline(Callback, 1, ml_integer(Tag));
300 	return (ml_tag_t)ml_value_fn;
301 }
302 
303 ml_value_t *CborDefaultTags;
304 
ML_FUNCTION(DefaultTagFn)305 ML_FUNCTION(DefaultTagFn) {
306 	return ml_map_search(CborDefaultTags, Args[0]);
307 }
308 
ml_from_cbor(ml_cbor_t Cbor,void * TagFnData,ml_tag_t (* TagFn)(uint64_t,void *,void **))309 ml_value_t *ml_from_cbor(ml_cbor_t Cbor, void *TagFnData, ml_tag_t (*TagFn)(uint64_t, void *, void **)) {
310 	ml_cbor_reader_t Reader[1];
311 	Reader->TagFnData = TagFnData ?: DefaultTagFn;
312 	Reader->TagFn = TagFn ?: (void *)ml_value_tag_fn;
313 	ml_cbor_reader_init(Reader->Reader);
314 	Reader->Reader->UserData = Reader;
315 	Reader->Collection = 0;
316 	Reader->Tags = 0;
317 	Reader->Value = 0;
318 	ml_cbor_read(Reader->Reader, Cbor.Data, Cbor.Length);
319 	int Extra = ml_cbor_reader_extra(Reader);
320 	if (Extra) return ml_error("CBORError", "Extra bytes after decoding: %d", Extra);
321 	return ml_cbor_reader_get(Reader);
322 }
323 
ml_from_cbor_extra(ml_cbor_t Cbor,void * TagFnData,ml_tag_t (* TagFn)(uint64_t,void *,void **))324 ml_cbor_result_t ml_from_cbor_extra(ml_cbor_t Cbor, void *TagFnData, ml_tag_t (*TagFn)(uint64_t, void *, void **)) {
325 	ml_cbor_reader_t Reader[1];
326 	Reader->TagFnData = TagFnData ?: DefaultTagFn;
327 	Reader->TagFn = TagFn ?: (void *)ml_value_tag_fn;
328 	ml_cbor_reader_init(Reader->Reader);
329 	Reader->Reader->UserData = Reader;
330 	Reader->Collection = 0;
331 	Reader->Tags = 0;
332 	Reader->Value = 0;
333 	ml_cbor_read(Reader->Reader, Cbor.Data, Cbor.Length);
334 	return (ml_cbor_result_t){ml_cbor_reader_get(Reader), ml_cbor_reader_extra(Reader)};
335 }
336 
ml_to_cbor_fn(void * Data,int Count,ml_value_t ** Args)337 static ml_value_t *ml_to_cbor_fn(void *Data, int Count, ml_value_t **Args) {
338 	ml_cbor_t Cbor = ml_to_cbor(Args[0]);
339 	if (Cbor.Data) return ml_string(Cbor.Data, Cbor.Length);
340 	return ml_error("CborError", "Error encoding to cbor");
341 }
342 
ml_from_cbor_fn(void * Data,int Count,ml_value_t ** Args)343 static ml_value_t *ml_from_cbor_fn(void *Data, int Count, ml_value_t **Args) {
344 	ML_CHECK_ARG_COUNT(1);
345 	ML_CHECK_ARG_TYPE(0, MLStringT);
346 	ml_cbor_t Cbor = {{ml_string_value(Args[0])}, ml_string_length(Args[0])};
347 	return ml_from_cbor(Cbor, Count > 1 ? Args[1] : (ml_value_t *)DefaultTagFn, (void *)ml_value_tag_fn);
348 }
349 
ML_TYPED_FN(ml_cbor_write,MLIntegerT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)350 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLIntegerT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
351 	//printf("%s()\n", __func__);
352 	int64_t Value = ml_integer_value_fast(Arg);
353 	if (Value < 0) {
354 		ml_cbor_write_negative(Data, WriteFn, ~Value);
355 	} else {
356 		ml_cbor_write_positive(Data, WriteFn, Value);
357 	}
358 	return NULL;
359 }
360 
ML_TYPED_FN(ml_cbor_write,MLStringT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)361 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLStringT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
362 	//printf("%s()\n", __func__);
363 	ml_cbor_write_string(Data, WriteFn, ml_string_length(Arg));
364 	WriteFn(Data, (const unsigned char *)ml_string_value(Arg), ml_string_length(Arg));
365 	return NULL;
366 }
367 
ML_TYPED_FN(ml_cbor_write,MLListT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)368 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLListT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
369 	ml_cbor_write_array(Data, WriteFn, ml_list_length(Arg));
370 	ML_LIST_FOREACH(Arg, Node) {
371 		ml_value_t *Error = ml_cbor_write(Node->Value, Data, WriteFn);
372 		if (Error) return Error;
373 	}
374 	return NULL;
375 }
376 
ML_TYPED_FN(ml_cbor_write,MLMapT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)377 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLMapT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
378 	ml_cbor_write_map(Data, WriteFn, ml_map_size(Arg));
379 	ML_MAP_FOREACH(Arg, Node) {
380 		ml_value_t *Error = ml_cbor_write(Node->Key, Data, WriteFn);
381 		if (Error) return Error;
382 		Error = ml_cbor_write(Node->Value, Data, WriteFn);
383 		if (Error) return Error;
384 	}
385 	return NULL;
386 }
387 
ML_TYPED_FN(ml_cbor_write,MLDoubleT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)388 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLDoubleT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
389 	ml_cbor_write_float8(Data, WriteFn, ml_double_value_fast(Arg));
390 	return NULL;
391 }
392 
ML_TYPED_FN(ml_cbor_write,MLNilT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)393 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLNilT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
394 	ml_cbor_write_simple(Data, WriteFn, CBOR_SIMPLE_NULL);
395 	return NULL;
396 }
397 
ML_TYPED_FN(ml_cbor_write,MLBooleanT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)398 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLBooleanT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
399 	ml_cbor_write_simple(Data, WriteFn, ml_boolean_value(Arg) ? CBOR_SIMPLE_TRUE : CBOR_SIMPLE_FALSE);
400 	return NULL;
401 }
402 
ML_TYPED_FN(ml_cbor_write,MLMethodT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)403 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLMethodT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
404 	const char *Name = ml_method_name(Arg);
405 	ml_cbor_write_tag(Data, WriteFn, 26); // TODO: Change this to a proper tag
406 	ml_cbor_write_string(Data, WriteFn, strlen(Name));
407 	WriteFn(Data, (void *)Name, strlen(Name));
408 	return NULL;
409 }
410 
ML_TYPED_FN(ml_cbor_write,MLObjectT,ml_value_t * Arg,void * Data,ml_cbor_write_fn WriteFn)411 static ml_value_t *ML_TYPED_FN(ml_cbor_write, MLObjectT, ml_value_t *Arg, void *Data, ml_cbor_write_fn WriteFn) {
412 	ml_cbor_write_tag(Data, WriteFn, 27);
413 	int Size = ml_object_size(Arg);
414 	ml_cbor_write_array(Data, WriteFn, 1 + Size);
415 	const char *Name = ml_typeof(Arg)->Name;
416 	ml_cbor_write_string(Data, WriteFn, strlen(Name));
417 	WriteFn(Data, (void *)Name, strlen(Name));
418 	for (int I = 0; I < Size; ++I) {
419 		ml_value_t *Error = ml_cbor_write(ml_object_field(Arg, I), Data, WriteFn);
420 		if (Error) return Error;
421 	}
422 	return NULL;
423 }
424 
ml_cbor_read_method(void * Data,int Count,ml_value_t ** Args)425 ml_value_t *ml_cbor_read_method(void *Data, int Count, ml_value_t **Args) {
426 	ML_CHECK_ARG_TYPE(0, MLStringT);
427 	return ml_method(ml_string_value(Args[0]));
428 }
429 
430 ml_value_t *CborObjects;
431 
ml_cbor_read_object(void * Data,int Count,ml_value_t ** Args)432 ml_value_t *ml_cbor_read_object(void *Data, int Count, ml_value_t **Args) {
433 	ML_CHECK_ARG_COUNT(1);
434 	ML_CHECK_ARG_TYPE(0, MLListT);
435 	ml_list_iter_t Iter[1];
436 	ml_list_iter_forward(Args[0], Iter);
437 	if (!ml_list_iter_valid(Iter)) return ml_error("CBORError", "Object tag requires type name");
438 	ml_value_t *TypeName = Iter->Value;
439 	if (ml_typeof(TypeName) != MLStringT) return ml_error("CBORError", "Object tag requires type name");
440 	ml_value_t *Constructor = ml_map_search(CborObjects, TypeName);
441 	if (Constructor == MLNil) return ml_error("CBORError", "Object %s not found", ml_string_value(TypeName));
442 	int Count2 = ml_list_length(Args[0]) - 1;
443 	ml_value_t **Args2 = anew(ml_value_t *, Count2);
444 	for (int I = 0; I < Count2; ++I) {
445 		ml_list_iter_next(Iter);
446 		Args2[I] = Iter->Value;
447 	}
448 	return ml_simple_call(Constructor, Count2, Args2);
449 }
450 
ml_library_entry(ml_value_t * Module,ml_getter_t GlobalGet,void * Globals)451 void ml_library_entry(ml_value_t *Module, ml_getter_t GlobalGet, void *Globals) {
452 	CborDefaultTags = ml_map();
453 	CborObjects = ml_map();
454 	ml_map_insert(CborDefaultTags, ml_integer(26), ml_cfunction(NULL, ml_cbor_read_method)); // TODO: Change this to a proper tag
455 	ml_map_insert(CborDefaultTags, ml_integer(27), ml_cfunction(NULL, ml_cbor_read_object));
456 #ifdef ML_CBOR_BYTECODE
457 	ml_map_insert(CborDefaultTags, ml_integer(36), ml_cfunction(NULL, ml_cbor_read_closure));
458 #endif
459 #include "ml_cbor_init.c"
460 	ml_module_export(Module, "encode", ml_cfunction(NULL, ml_to_cbor_fn));
461 	ml_module_export(Module, "decode", ml_cfunction(NULL, ml_from_cbor_fn));
462 	ml_module_export(Module, "Default", CborDefaultTags);
463 }
464