37
38:- module(json,
39 [ json_read/2, 40 json_read/3, 41 atom_json_term/3, 42 json_write/2, 43 json_write/3, 44 is_json_term/1, 45 is_json_term/2, 46 47 json_read_dict/2, 48 json_read_dict/3, 49 json_write_dict/2, 50 json_write_dict/3, 51 atom_json_dict/3 52 ]). 53:- use_module(library(record)). 54:- use_module(library(memfile)). 55:- use_module(library(error)). 56:- use_module(library(option)). 57:- use_module(library(lists)). 58
59:- use_foreign_library(foreign(json)). 60
61:- multifile
62 json_write_hook/4, 63 json_dict_pairs/2. 64
65:- predicate_options(json_read/3, 3,
66 [ null(ground),
67 true(ground),
68 false(ground),
69 value_string_as(oneof([atom,string]))
70 ]). 71:- predicate_options(json_write/3, 3,
72 [ indent(nonneg),
73 step(positive_integer),
74 tab(positive_integer),
75 width(nonneg),
76 null(ground),
77 true(ground),
78 false(ground),
79 serialize_unknown(boolean)
80 ]). 81:- predicate_options(json_read_dict/3, 3,
82 [ tag(atom),
83 default_tag(atom),
84 pass_to(json_read/3, 3)
85 ]). 86:- predicate_options(json_write_dict/3, 3,
87 [ tag(atom),
88 pass_to(json_write/3, 3)
89 ]). 90:- predicate_options(is_json_term/2, 2,
91 [ null(ground),
92 true(ground),
93 false(ground)
94 ]). 95:- predicate_options(atom_json_term/3, 3,
96 [ as(oneof([atom,string,codes])),
97 pass_to(json_read/3, 3),
98 pass_to(json_write/3, 3)
99 ]). 100
122
123:- record json_options(
124 null:ground = @(null),
125 true:ground = @(true),
126 false:ground = @(false),
127 end_of_file:ground = error,
128 value_string_as:oneof([atom,string]) = atom,
129 tag:atom = '',
130 default_tag:atom). 131
132default_json_dict_options(
133 json_options(null, true, false, error, string, '', _)).
134
135
136 139
148
149atom_json_term(Atom, Term, Options) :-
150 ground(Atom),
151 !,
152 setup_call_cleanup(
153 ( atom_to_memory_file(Atom, MF),
154 open_memory_file(MF, read, In, [free_on_close(true)])
155 ),
156 json_read(In, Term, Options),
157 close(In)).
158atom_json_term(Result, Term, Options) :-
159 select_option(as(Type), Options, Options1, atom),
160 ( type_term(Type, Result, Out)
161 -> true
162 ; must_be(oneof([atom,string,codes,chars]), Type)
163 ),
164 with_output_to(Out,
165 json_write(current_output, Term, Options1)).
166
167type_term(atom, Result, atom(Result)).
168type_term(string, Result, string(Result)).
169type_term(codes, Result, codes(Result)).
170type_term(chars, Result, chars(Result)).
171
172
173 176
249
250json_read(Stream, Term) :-
251 default_json_options(Options),
252 ( json_value_top(Stream, Term, Options)
253 -> true
254 ; syntax_error(illegal_json, Stream)
255 ).
256json_read(Stream, Term, Options) :-
257 make_json_options(Options, OptionTerm, _RestOptions),
258 ( json_value_top(Stream, Term, OptionTerm)
259 -> true
260 ; syntax_error(illegal_json, Stream)
261 ).
262
263json_value_top(Stream, Term, Options) :-
264 stream_property(Stream, type(binary)),
265 !,
266 setup_call_cleanup(
267 set_stream(Stream, encoding(utf8)),
268 json_value_top_(Stream, Term, Options),
269 set_stream(Stream, type(binary))).
270json_value_top(Stream, Term, Options) :-
271 json_value_top_(Stream, Term, Options).
272
273json_value_top_(Stream, Term, Options) :-
274 get_code(Stream, C0),
275 ws(C0, Stream, C1),
276 ( C1 == -1
277 -> json_options_end_of_file(Options, Action),
278 ( Action == error
279 -> syntax_error(unexpected_end_of_file, Stream)
280 ; Term = Action
281 )
282 ; json_term_top(C1, Stream, Term, Options)
283 ).
284
285json_value(Stream, Term, Next, Options) :-
286 get_code(Stream, C0),
287 ws(C0, Stream, C1),
288 ( C1 == -1
289 -> syntax_error(unexpected_end_of_file, Stream)
290 ; json_term(C1, Stream, Term, Next, Options)
291 ).
292
293json_term(C0, Stream, JSON, Next, Options) :-
294 json_term_top(C0, Stream, JSON, Options),
295 get_code(Stream, Next).
296
297json_term_top(0'{, Stream, json(Pairs), Options) :-
298 !,
299 ws(Stream, C),
300 json_pairs(C, Stream, Pairs, Options).
301json_term_top(0'[, Stream, Array, Options) :-
302 !,
303 ws(Stream, C),
304 json_array(C, Stream, Array, Options).
305json_term_top(0'", Stream, String, Options) :-
306 !,
307 get_code(Stream, C1),
308 json_string_codes(C1, Stream, Codes),
309 json_options_value_string_as(Options, Type),
310 codes_to_type(Type, Codes, String).
311json_term_top(0'-, Stream, Number, _Options) :-
312 !,
313 json_read_number(Stream, 0'-, Number).
314json_term_top(D, Stream, Number, _Options) :-
315 between(0'0, 0'9, D),
316 !,
317 json_read_number(Stream, D, Number).
318json_term_top(C, Stream, Constant, Options) :-
319 json_read_constant(C, Stream, ID),
320 json_constant(ID, Constant, Options).
321
322json_pairs(0'}, _, [], _) :- !.
323json_pairs(C0, Stream, [Pair|Tail], Options) :-
324 json_pair(C0, Stream, Pair, C, Options),
325 ws(C, Stream, Next),
326 ( Next == 0',
327 -> ws(Stream, C2),
328 json_pairs(C2, Stream, Tail, Options)
329 ; Next == 0'}
330 -> Tail = []
331 ; syntax_error(illegal_object, Stream)
332 ).
333
334json_pair(C0, Stream, Name=Value, Next, Options) :-
335 json_string_as_atom(C0, Stream, Name),
336 ws(Stream, C),
337 C == 0':,
338 json_value(Stream, Value, Next, Options).
339
340
341json_array(0'], _, [], _) :- !.
342json_array(C0, Stream, [Value|Tail], Options) :-
343 json_term(C0, Stream, Value, C, Options),
344 ws(C, Stream, Next),
345 ( Next == 0',
346 -> ws(Stream, C1),
347 json_array(C1, Stream, Tail, Options)
348 ; Next == 0']
349 -> Tail = []
350 ; syntax_error(illegal_array, Stream)
351 ).
352
353codes_to_type(atom, Codes, Atom) :-
354 atom_codes(Atom, Codes).
355codes_to_type(string, Codes, Atom) :-
356 string_codes(Atom, Codes).
357codes_to_type(codes, Codes, Codes).
358
359json_string_as_atom(0'", Stream, Atom) :-
360 get_code(Stream, C1),
361 json_string_codes(C1, Stream, Codes),
362 atom_codes(Atom, Codes).
363
364json_string_codes(0'", _, []) :- !.
365json_string_codes(0'\\, Stream, [H|T]) :-
366 !,
367 get_code(Stream, C0),
368 ( escape(C0, Stream, H)
369 -> true
370 ; syntax_error(illegal_string_escape, Stream)
371 ),
372 get_code(Stream, C1),
373 json_string_codes(C1, Stream, T).
374json_string_codes(-1, Stream, _) :-
375 !,
376 syntax_error(eof_in_string, Stream).
377json_string_codes(C, Stream, [C|T]) :-
378 get_code(Stream, C1),
379 json_string_codes(C1, Stream, T).
380
381escape(0'", _, 0'") :- !.
382escape(0'\\, _, 0'\\) :- !.
383escape(0'/, _, 0'/) :- !.
384escape(0'b, _, 0'\b) :- !.
385escape(0'f, _, 0'\f) :- !.
386escape(0'n, _, 0'\n) :- !.
387escape(0'r, _, 0'\r) :- !.
388escape(0't, _, 0'\t) :- !.
389escape(0'u, Stream, C) :-
390 !,
391 get_code(Stream, C1),
392 get_code(Stream, C2),
393 get_code(Stream, C3),
394 get_code(Stream, C4),
395 code_type(C1, xdigit(D1)),
396 code_type(C2, xdigit(D2)),
397 code_type(C3, xdigit(D3)),
398 code_type(C4, xdigit(D4)),
399 C is D1<<12+D2<<8+D3<<4+D4.
400
401json_read_constant(0't, Stream, true) :-
402 !,
403 must_see(`rue`, Stream, true).
404json_read_constant(0'f, Stream, false) :-
405 !,
406 must_see(`alse`, Stream, false).
407json_read_constant(0'n, Stream, null) :-
408 !,
409 must_see(`ull`, Stream, null).
410
411must_see([], _Stream, _).
412must_see([H|T], Stream, Name) :-
413 get_code(Stream, C),
414 ( C == H
415 -> true
416 ; syntax_error(json_expected(Name), Stream)
417 ),
418 must_see(T, Stream, Name).
419
420json_constant(true, Constant, Options) :-
421 !,
422 json_options_true(Options, Constant).
423json_constant(false, Constant, Options) :-
424 !,
425 json_options_false(Options, Constant).
426json_constant(null, Constant, Options) :-
427 !,
428 json_options_null(Options, Constant).
429
435
436ws(Stream, Next) :-
437 get_code(Stream, C0),
438 json_skip_ws(Stream, C0, Next).
439
440ws(C0, Stream, Next) :-
441 json_skip_ws(Stream, C0, Next).
442
443syntax_error(Message, Stream) :-
444 stream_error_context(Stream, Context),
445 throw(error(syntax_error(json(Message)), Context)).
446
447stream_error_context(Stream, stream(Stream, Line, LinePos, CharNo)) :-
448 stream_pair(Stream, Read, _),
449 character_count(Read, CharNo),
450 line_position(Read, LinePos),
451 line_count(Read, Line).
452
453
454 457
462
464
470
472
539
556
561
562:- record json_write_state(indent:nonneg = 0,
563 step:positive_integer = 2,
564 tab:positive_integer = 8,
565 width:nonneg = 72,
566 serialize_unknown:boolean = false
567 ). 568
569json_write(Stream, Term) :-
570 json_write(Stream, Term, []).
571json_write(Stream, Term, Options) :-
572 make_json_write_state(Options, State, Options1),
573 make_json_options(Options1, OptionTerm, _RestOptions),
574 json_write_term(Term, Stream, State, OptionTerm).
575
576json_write_term(Var, _, _, _) :-
577 var(Var),
578 !,
579 instantiation_error(Var).
580json_write_term(json(Pairs), Stream, State, Options) :-
581 !,
582 json_write_object(Pairs, Stream, State, Options).
583json_write_term(Dict, Stream, State, Options) :-
584 is_dict(Dict, Tag),
585 !,
586 json_pairs(Dict, Pairs0),
587 ( nonvar(Tag),
588 json_options_tag(Options, Name),
589 Name \== ''
590 -> Pairs = [Name-Tag|Pairs0]
591 ; Pairs = Pairs0
592 ),
593 json_write_object(Pairs, Stream, State, Options).
594json_write_term(List, Stream, State, Options) :-
595 is_list(List),
596 !,
597 space_if_not_at_left_margin(Stream, State),
598 write(Stream, '['),
599 ( json_write_state_width(State, Width),
600 ( Width == 0
601 -> true
602 ; json_write_state_indent(State, Indent),
603 json_print_length(List, Options, Width, Indent, _)
604 )
605 -> set_width_of_json_write_state(0, State, State2),
606 write_array_hor(List, Stream, State2, Options),
607 write(Stream, ']')
608 ; step_indent(State, State2),
609 write_array_ver(List, Stream, State2, Options),
610 indent(Stream, State),
611 write(Stream, ']')
612 ).
613
614json_write_term(Term, Stream, State, Options) :-
615 json_write_hook(Term, Stream, State, Options),
616 !.
617json_write_term(Number, Stream, _State, _Options) :-
618 number(Number),
619 !,
620 ( float(Number)
621 -> write(Stream, Number)
622 ; integer(Number)
623 -> write(Stream, Number)
624 ; Float is float(Number) 625 -> write(Stream, Float)
626 ).
627json_write_term(True, Stream, _State, Options) :-
628 json_options_true(Options, True),
629 !,
630 write(Stream, true).
631json_write_term(False, Stream, _State, Options) :-
632 json_options_false(Options, False),
633 !,
634 write(Stream, false).
635json_write_term(Null, Stream, _State, Options) :-
636 json_options_null(Options, Null),
637 !,
638 write(Stream, null).
639json_write_term(#(Text), Stream, _State, _Options) :-
640 !,
641 ( ( atom(Text)
642 ; string(Text)
643 )
644 -> json_write_string(Stream, Text)
645 ; term_string(Text, String),
646 json_write_string(Stream, String)
647 ).
648json_write_term(String, Stream, _State, _Options) :-
649 atom(String),
650 !,
651 json_write_string(Stream, String).
652json_write_term(String, Stream, _State, _Options) :-
653 string(String),
654 !,
655 json_write_string(Stream, String).
656json_write_term(AnyTerm, Stream, State, _Options) :-
657 ( json_write_state_serialize_unknown(State, true)
658 -> term_string(AnyTerm, String),
659 json_write_string(Stream, String)
660 ; type_error(json_term, AnyTerm)
661 ).
662
663json_pairs(Dict, Pairs) :-
664 json_dict_pairs(Dict, Pairs),
665 !.
666json_pairs(Dict, Pairs) :-
667 dict_pairs(Dict, _, Pairs).
668
669json_write_object(Pairs, Stream, State, Options) :-
670 space_if_not_at_left_margin(Stream, State),
671 write(Stream, '{'),
672 ( json_write_state_width(State, Width),
673 ( Width == 0
674 -> true
675 ; json_write_state_indent(State, Indent),
676 json_print_length(json(Pairs), Options, Width, Indent, _)
677 )
678 -> set_width_of_json_write_state(0, State, State2),
679 write_pairs_hor(Pairs, Stream, State2, Options),
680 write(Stream, '}')
681 ; step_indent(State, State2),
682 write_pairs_ver(Pairs, Stream, State2, Options),
683 indent(Stream, State),
684 write(Stream, '}')
685 ).
686
687
688write_pairs_hor([], _, _, _).
689write_pairs_hor([H|T], Stream, State, Options) :-
690 json_pair(H, Name, Value),
691 json_write_string(Stream, Name),
692 write(Stream, ':'),
693 json_write_term(Value, Stream, State, Options),
694 ( T == []
695 -> true
696 ; write(Stream, ', '),
697 write_pairs_hor(T, Stream, State, Options)
698 ).
699
700write_pairs_ver([], _, _, _).
701write_pairs_ver([H|T], Stream, State, Options) :-
702 indent(Stream, State),
703 json_pair(H, Name, Value),
704 json_write_string(Stream, Name),
705 write(Stream, ':'),
706 json_write_term(Value, Stream, State, Options),
707 ( T == []
708 -> true
709 ; write(Stream, ','),
710 write_pairs_ver(T, Stream, State, Options)
711 ).
712
713
714json_pair(Var, _, _) :-
715 var(Var),
716 !,
717 instantiation_error(Var).
718json_pair(Name=Value, Name, Value) :- !.
719json_pair(Name-Value, Name, Value) :- !.
720json_pair(NameValue, Name, Value) :-
721 compound(NameValue),
722 NameValue =.. [Name, Value],
723 !.
724json_pair(Pair, _, _) :-
725 type_error(json_pair, Pair).
726
727
728write_array_hor([], _, _, _).
729write_array_hor([H|T], Stream, State, Options) :-
730 json_write_term(H, Stream, State, Options),
731 ( T == []
732 -> write(Stream, ' ')
733 ; write(Stream, ', '),
734 write_array_hor(T, Stream, State, Options)
735 ).
736
737write_array_ver([], _, _, _).
738write_array_ver([H|T], Stream, State, Options) :-
739 indent(Stream, State),
740 json_write_term(H, Stream, State, Options),
741 ( T == []
742 -> true
743 ; write(Stream, ','),
744 write_array_ver(T, Stream, State, Options)
745 ).
746
747
748indent(Stream, State) :-
749 json_write_state_indent(State, Indent),
750 json_write_state_tab(State, Tab),
751 json_write_indent(Stream, Indent, Tab).
752
753step_indent(State0, State) :-
754 json_write_state_indent(State0, Indent),
755 json_write_state_step(State0, Step),
756 NewIndent is Indent+Step,
757 set_indent_of_json_write_state(NewIndent, State0, State).
758
759space_if_not_at_left_margin(Stream, State) :-
760 stream_pair(Stream, _, Write),
761 line_position(Write, LinePos),
762 ( LinePos == 0
763 ; json_write_state_indent(State, LinePos)
764 ),
765 !.
766space_if_not_at_left_margin(Stream, _) :-
767 put_char(Stream, ' ').
768
769
776
777json_print_length(Var, _, _, _, _) :-
778 var(Var),
779 !,
780 instantiation_error(Var).
781json_print_length(json(Pairs), Options, Max, Len0, Len) :-
782 !,
783 Len1 is Len0 + 2,
784 Len1 =< Max,
785 must_be(list, Pairs),
786 pairs_print_length(Pairs, Options, Max, Len1, Len).
787json_print_length(Dict, Options, Max, Len0, Len) :-
788 is_dict(Dict),
789 !,
790 dict_pairs(Dict, _Tag, Pairs),
791 Len1 is Len0 + 2,
792 Len1 =< Max,
793 pairs_print_length(Pairs, Options, Max, Len1, Len).
794json_print_length(Array, Options, Max, Len0, Len) :-
795 is_list(Array),
796 !,
797 Len1 is Len0 + 2,
798 Len1 =< Max,
799 array_print_length(Array, Options, Max, Len1, Len).
800json_print_length(Null, Options, Max, Len0, Len) :-
801 json_options_null(Options, Null),
802 !,
803 Len is Len0 + 4,
804 Len =< Max.
805json_print_length(False, Options, Max, Len0, Len) :-
806 json_options_false(Options, False),
807 !,
808 Len is Len0 + 5,
809 Len =< Max.
810json_print_length(True, Options, Max, Len0, Len) :-
811 json_options_true(Options, True),
812 !,
813 Len is Len0 + 4,
814 Len =< Max.
815json_print_length(Number, _Options, Max, Len0, Len) :-
816 number(Number),
817 !,
818 write_length(Number, AL, []),
819 Len is Len0 + AL,
820 Len =< Max.
821json_print_length(@(Id), _Options, Max, Len0, Len) :-
822 atom(Id),
823 !,
824 atom_length(Id, IdLen),
825 Len is Len0+IdLen,
826 Len =< Max.
827json_print_length(String, _Options, Max, Len0, Len) :-
828 string_len(String, Len0, Len),
829 !,
830 Len =< Max.
831json_print_length(AnyTerm, _Options, Max, Len0, Len) :-
832 write_length(AnyTerm, AL, []), 833 Len is Len0 + AL+2,
834 Len =< Max.
835
836pairs_print_length([], _, _, Len, Len).
837pairs_print_length([H|T], Options, Max, Len0, Len) :-
838 pair_len(H, Options, Max, Len0, Len1),
839 ( T == []
840 -> Len = Len1
841 ; Len2 is Len1 + 2,
842 Len2 =< Max,
843 pairs_print_length(T, Options, Max, Len2, Len)
844 ).
845
846pair_len(Pair, Options, Max, Len0, Len) :-
847 compound(Pair),
848 pair_nv(Pair, Name, Value),
849 !,
850 string_len(Name, Len0, Len1),
851 Len2 is Len1+2,
852 Len2 =< Max,
853 json_print_length(Value, Options, Max, Len2, Len).
854pair_len(Pair, _Options, _Max, _Len0, _Len) :-
855 type_error(pair, Pair).
856
857pair_nv(Name=Value, Name, Value) :- !.
858pair_nv(Name-Value, Name, Value) :- !.
859pair_nv(Term, Name, Value) :-
860 compound_name_arguments(Term, Name, [Value]).
861
862array_print_length([], _, _, Len, Len).
863array_print_length([H|T], Options, Max, Len0, Len) :-
864 json_print_length(H, Options, Max, Len0, Len1),
865 ( T == []
866 -> Len = Len1
867 ; Len2 is Len1+2,
868 Len2 =< Max,
869 array_print_length(T, Options, Max, Len2, Len)
870 ).
871
872string_len(String, Len0, Len) :-
873 atom(String),
874 !,
875 atom_length(String, AL),
876 Len is Len0 + AL + 2.
877string_len(String, Len0, Len) :-
878 string(String),
879 !,
880 string_length(String, AL),
881 Len is Len0 + AL + 2.
882
883
884 887
894
895is_json_term(Term) :-
896 default_json_options(Options),
897 is_json_term2(Options, Term).
898
899is_json_term(Term, Options) :-
900 make_json_options(Options, OptionTerm, _RestOptions),
901 is_json_term2(OptionTerm, Term).
902
903is_json_term2(_, Var) :-
904 var(Var), !, fail.
905is_json_term2(Options, json(Pairs)) :-
906 !,
907 is_list(Pairs),
908 maplist(is_json_pair(Options), Pairs).
909is_json_term2(Options, List) :-
910 is_list(List),
911 !,
912 maplist(is_json_term2(Options), List).
913is_json_term2(_, Primitive) :-
914 atomic(Primitive),
915 !. 916is_json_term2(Options, True) :-
917 json_options_true(Options, True).
918is_json_term2(Options, False) :-
919 json_options_false(Options, False).
920is_json_term2(Options, Null) :-
921 json_options_null(Options, Null).
922
923is_json_pair(_, Var) :-
924 var(Var), !, fail.
925is_json_pair(Options, Name=Value) :-
926 atom(Name),
927 is_json_term2(Options, Value).
928
929 932
971
972json_read_dict(Stream, Dict) :-
973 json_read_dict(Stream, Dict, []).
974
975json_read_dict(Stream, Dict, Options) :-
976 make_json_dict_options(Options, OptionTerm, _RestOptions),
977 ( json_value_top(Stream, Term, OptionTerm)
978 -> true
979 ; syntax_error(illegal_json, Stream)
980 ),
981 term_to_dict(Term, Dict, OptionTerm).
982
983term_to_dict(json(Pairs), Dict, Options) :-
984 !,
985 ( json_options_tag(Options, TagName),
986 Tag \== '',
987 select(TagName = Tag0, Pairs, NVPairs),
988 to_atom(Tag0, Tag)
989 -> json_dict_pairs(NVPairs, DictPairs, Options)
990 ; json_options_default_tag(Options, DefTag),
991 ( var(DefTag)
992 -> true
993 ; Tag = DefTag
994 ),
995 json_dict_pairs(Pairs, DictPairs, Options)
996 ),
997 dict_create(Dict, Tag, DictPairs).
998term_to_dict(Value0, Value, _Options) :-
999 atomic(Value0), Value0 \== [],
1000 !,
1001 Value = Value0.
1002term_to_dict(List0, List, Options) :-
1003 is_list(List0),
1004 !,
1005 terms_to_dicts(List0, List, Options).
1006term_to_dict(Special, Special, Options) :-
1007 ( json_options_true(Options, Special)
1008 ; json_options_false(Options, Special)
1009 ; json_options_null(Options, Special)
1010 ; json_options_end_of_file(Options, Special)
1011 ),
1012 !.
1013
1014json_dict_pairs([], [], _).
1015json_dict_pairs([Name=Value0|T0], [Name=Value|T], Options) :-
1016 term_to_dict(Value0, Value, Options),
1017 json_dict_pairs(T0, T, Options).
1018
1019terms_to_dicts([], [], _).
1020terms_to_dicts([Value0|T0], [Value|T], Options) :-
1021 term_to_dict(Value0, Value, Options),
1022 terms_to_dicts(T0, T, Options).
1023
1024to_atom(Tag, Atom) :-
1025 string(Tag),
1026 !,
1027 atom_string(Atom, Tag).
1028to_atom(Atom, Atom) :-
1029 atom(Atom).
1030
1037
1038json_write_dict(Stream, Dict) :-
1039 json_write_dict(Stream, Dict, []).
1040
1041json_write_dict(Stream, Dict, Options) :-
1042 make_json_write_state(Options, State, Options1),
1043 make_json_dict_options(Options1, OptionTerm, _RestOptions),
1044 json_write_term(Dict, Stream, State, OptionTerm).
1045
1046
1047make_json_dict_options(Options, Record, RestOptions) :-
1048 default_json_dict_options(Record0),
1049 set_json_options_fields(Options, Record0, Record, RestOptions).
1050
1061
1062atom_json_dict(Atom, Term, Options) :-
1063 ground(Atom),
1064 !,
1065 setup_call_cleanup(
1066 open_string(Atom, In),
1067 json_read_dict(In, Term, Options),
1068 close(In)).
1069atom_json_dict(Result, Term, Options) :-
1070 select_option(as(Type), Options, Options1, atom),
1071 ( type_term(Type, Result, Out)
1072 -> true
1073 ; must_be(oneof([atom,string,codes]), Type)
1074 ),
1075 with_output_to(Out,
1076 json_write_dict(current_output, Term, Options1)).
1077
1078
1079 1082
1083:- multifile
1084 prolog:error_message/3. 1085
1086prolog:error_message(syntax_error(json(Id))) -->
1087 [ 'JSON syntax error: ' ],
1088 json_syntax_error(Id).
1089
1090json_syntax_error(illegal_comment) -->
1091 [ 'Illegal comment' ].
1092json_syntax_error(illegal_string_escape) -->
1093 [ 'Illegal escape sequence in string' ]