35
36:- if(current_predicate(is_dict/1)). 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
54:- else. 55
56:- module(json,
57 [ json_read/2, 58 json_read/3, 59 atom_json_term/3, 60 json_write/2, 61 json_write/3, 62 is_json_term/1, 63 is_json_term/2
64 ]). 65
66:- endif. 67
68:- use_module(library(record)). 69:- use_module(library(memfile)). 70:- use_module(library(error)). 71:- use_module(library(option)). 72
73:- use_foreign_library(foreign(json)). 74
75:- predicate_options(json_read/3, 3,
76 [ null(ground),
77 true(ground),
78 false(ground),
79 value_string_as(oneof([atom,string]))
80 ]). 81:- predicate_options(json_write/3, 3,
82 [ indent(nonneg),
83 step(positive_integer),
84 tab(positive_integer),
85 width(nonneg),
86 null(ground),
87 true(ground),
88 false(ground),
89 serialize_unknown(boolean)
90 ]). 91:- predicate_options(json_read_dict/3, 3,
92 [ tag(atom),
93 pass_to(json_read/3, 3)
94 ]). 95:- predicate_options(json_write_dict/3, 3,
96 [ tag(atom),
97 pass_to(json_write/3, 3)
98 ]). 99:- predicate_options(is_json_term/2, 2,
100 [ null(ground),
101 true(ground),
102 false(ground)
103 ]). 104:- predicate_options(atom_json_term/3, 3,
105 [ as(oneof([atom,string,codes])),
106 pass_to(json_read/3, 3),
107 pass_to(json_write/3, 3)
108 ]). 109
131
132:- record json_options(null:ground = @(null),
133 true:ground = @(true),
134 false:ground = @(false),
135 value_string_as:oneof([atom,string]) = atom,
136 tag:atom = ''). 137
138default_json_dict_options(
139 json_options(null, true, false, string, '')).
140
141
142 145
154
155atom_json_term(Atom, Term, Options) :-
156 ground(Atom),
157 !,
158 setup_call_cleanup(
159 ( atom_to_memory_file(Atom, MF),
160 open_memory_file(MF, read, In, [free_on_close(true)])
161 ),
162 json_read(In, Term, Options),
163 close(In)).
164atom_json_term(Result, Term, Options) :-
165 select_option(as(Type), Options, Options1, atom),
166 ( type_term(Type, Result, Out)
167 -> true
168 ; must_be(oneof([atom,string,codes,chars]), Type)
169 ),
170 with_output_to(Out,
171 json_write(current_output, Term, Options1)).
172
173type_term(atom, Result, atom(Result)).
174type_term(string, Result, string(Result)).
175type_term(codes, Result, codes(Result)).
176type_term(chars, Result, chars(Result)).
177
178
179 182
245
246json_read(Stream, Term) :-
247 default_json_options(Options),
248 ( json_value(Stream, Term, _, Options)
249 -> true
250 ; syntax_error(illegal_json, Stream)
251 ).
252json_read(Stream, Term, Options) :-
253 make_json_options(Options, OptionTerm, _RestOptions),
254 ( json_value(Stream, Term, _, OptionTerm)
255 -> true
256 ; syntax_error(illegal_json, Stream)
257 ).
258
259json_value(Stream, Term, Next, Options) :-
260 get_code(Stream, C0),
261 ws(C0, Stream, C1),
262 ( C1 == -1
263 -> syntax_error(unexpected_end_of_file, Stream)
264 ; json_term(C1, Stream, Term, Next, Options)
265 ).
266
267json_term(0'{, Stream, json(Pairs), Next, Options) :-
268 !,
269 ws(Stream, C),
270 json_pairs(C, Stream, Pairs, Options),
271 get_code(Stream, Next).
272json_term(0'[, Stream, Array, Next, Options) :-
273 !,
274 ws(Stream, C),
275 json_array(C, Stream, Array, Options),
276 get_code(Stream, Next).
277json_term(0'", Stream, String, Next, Options) :-
278 !,
279 get_code(Stream, C1),
280 json_string_codes(C1, Stream, Codes),
281 json_options_value_string_as(Options, Type),
282 codes_to_type(Type, Codes, String),
283 get_code(Stream, Next).
284json_term(0'-, Stream, Number, Next, _Options) :-
285 !,
286 json_number_codes(Stream, Codes, Next),
287 number_codes(Number, [0'-|Codes]).
288json_term(D, Stream, Number, Next, _Options) :-
289 between(0'0, 0'9, D),
290 !,
291 json_number_codes(Stream, Codes, Next),
292 number_codes(Number, [D|Codes]).
293json_term(C, Stream, Constant, Next, Options) :-
294 get_code(Stream, C1),
295 json_identifier_codes(C1, Stream, Codes, Next),
296 atom_codes(ID, [C|Codes]),
297 json_constant(ID, Constant, Options).
298
299json_pairs(0'}, _, [], _) :- !.
300json_pairs(C0, Stream, [Pair|Tail], Options) :-
301 json_pair(C0, Stream, Pair, C, Options),
302 ws(C, Stream, Next),
303 ( Next == 0',
304 -> ws(Stream, C2),
305 json_pairs(C2, Stream, Tail, Options)
306 ; Next == 0'}
307 -> Tail = []
308 ; syntax_error(illegal_object, Stream)
309 ).
310
311json_pair(C0, Stream, Name=Value, Next, Options) :-
312 json_string_as_atom(C0, Stream, Name),
313 ws(Stream, C),
314 C == 0':,
315 json_value(Stream, Value, Next, Options).
316
317
318json_array(0'], _, [], _) :- !.
319json_array(C0, Stream, [Value|Tail], Options) :-
320 json_term(C0, Stream, Value, C, Options),
321 ws(C, Stream, Next),
322 ( Next == 0',
323 -> ws(Stream, C1),
324 json_array(C1, Stream, Tail, Options)
325 ; Next == 0']
326 -> Tail = []
327 ; syntax_error(illegal_array, Stream)
328 ).
329
330codes_to_type(atom, Codes, Atom) :-
331 atom_codes(Atom, Codes).
332codes_to_type(string, Codes, Atom) :-
333 string_codes(Atom, Codes).
334codes_to_type(codes, Codes, Codes).
335
336json_string_as_atom(0'", Stream, Atom) :-
337 get_code(Stream, C1),
338 json_string_codes(C1, Stream, Codes),
339 atom_codes(Atom, Codes).
340
341json_string_codes(0'", _, []) :- !.
342json_string_codes(0'\\, Stream, [H|T]) :-
343 !,
344 get_code(Stream, C0),
345 ( escape(C0, Stream, H)
346 -> true
347 ; syntax_error(illegal_string_escape, Stream)
348 ),
349 get_code(Stream, C1),
350 json_string_codes(C1, Stream, T).
351json_string_codes(-1, Stream, _) :-
352 !,
353 syntax_error(eof_in_string, Stream).
354json_string_codes(C, Stream, [C|T]) :-
355 get_code(Stream, C1),
356 json_string_codes(C1, Stream, T).
357
358escape(0'", _, 0'") :- !.
359escape(0'\\, _, 0'\\) :- !.
360escape(0'/, _, 0'/) :- !.
361escape(0'b, _, 0'\b) :- !.
362escape(0'f, _, 0'\f) :- !.
363escape(0'n, _, 0'\n) :- !.
364escape(0'r, _, 0'\r) :- !.
365escape(0't, _, 0'\t) :- !.
366escape(0'u, Stream, C) :-
367 !,
368 get_code(Stream, C1),
369 get_code(Stream, C2),
370 get_code(Stream, C3),
371 get_code(Stream, C4),
372 code_type(C1, xdigit(D1)),
373 code_type(C2, xdigit(D2)),
374 code_type(C3, xdigit(D3)),
375 code_type(C4, xdigit(D4)),
376 C is D1<<12+D2<<8+D3<<4+D4.
377
378json_number_codes(Stream, Codes, Next) :-
379 get_code(Stream, C1),
380 json_number_codes(C1, Stream, Codes, Next).
381
382json_number_codes(C1, Stream, [C1|Codes], Next) :-
383 number_code(C1),
384 !,
385 get_code(Stream, C2),
386 json_number_codes(C2, Stream, Codes, Next).
387json_number_codes(C, _, [], C).
388
389number_code(C) :-
390 between(0'0, 0'9, C),
391 !.
392number_code(0'.).
393number_code(0'-).
394number_code(0'+).
395number_code(0'e).
396number_code(0'E).
397
398json_identifier_codes(C1, Stream, [C1|T], Next) :-
399 between(0'a, 0'z, C1),
400 !,
401 get_code(Stream, C2),
402 json_identifier_codes(C2, Stream, T, Next).
403json_identifier_codes(C, _, [], C).
404
405
406json_constant(true, Constant, Options) :-
407 !,
408 json_options_true(Options, Constant).
409json_constant(false, Constant, Options) :-
410 !,
411 json_options_false(Options, Constant).
412json_constant(null, Constant, Options) :-
413 !,
414 json_options_null(Options, Constant).
415
421
422ws(Stream, Next) :-
423 get_code(Stream, C0),
424 ws(C0, Stream, Next).
425
426ws(C0, Stream, C) :-
427 ws(C0),
428 !,
429 get_code(Stream, C1),
430 ws(C1, Stream, C).
431ws(0'/, Stream, C) :-
432 !,
433 get_code(Stream, Cmt1),
434 !,
435 expect(Cmt1, 0'/, Stream),
436 skip(Stream, 0'\n),
437 get_code(Stream, C0),
438 ws(C0, Stream, C).
439ws(C, _, C).
440
441ws(0' ).
442ws(0'\t).
443ws(0'\n).
444ws(0'\r).
445
446expect(C, C, _) :- !.
447expect(_, 0'/, Stream) :-
448 !,
449 syntax_error(illegal_comment, Stream).
450
451syntax_error(Message, Stream) :-
452 stream_error_context(Stream, Context),
453 throw(error(syntax_error(json(Message)), Context)).
454
455stream_error_context(Stream, stream(Stream, Line, LinePos, CharNo)) :-
456 stream_pair(Stream, Read, _),
457 character_count(Read, CharNo),
458 line_position(Read, LinePos),
459 line_count(Read, Line).
460
461
462 465
470
472
478
480
535
536:- record json_write_state(indent:nonneg = 0,
537 step:positive_integer = 2,
538 tab:positive_integer = 8,
539 width:nonneg = 72,
540 serialize_unknown:boolean = false
541 ). 542
543json_write(Stream, Term) :-
544 json_write(Stream, Term, []).
545json_write(Stream, Term, Options) :-
546 make_json_write_state(Options, State, Options1),
547 make_json_options(Options1, OptionTerm, _RestOptions),
548 json_write_term(Term, Stream, State, OptionTerm).
549
550json_write_term(Var, _, _, _) :-
551 var(Var),
552 !,
553 instantiation_error(Var).
554json_write_term(json(Pairs), Stream, State, Options) :-
555 !,
556 json_write_object(Pairs, Stream, State, Options).
557:- if(current_predicate(is_dict/1)). 558json_write_term(Dict, Stream, State, Options) :-
559 is_dict(Dict),
560 !,
561 dict_pairs(Dict, Tag, Pairs0),
562 ( nonvar(Tag),
563 json_options_tag(Options, Name),
564 Name \== ''
565 -> Pairs = [Name-Tag|Pairs0]
566 ; Pairs = Pairs0
567 ),
568 json_write_object(Pairs, Stream, State, Options).
569:- endif. 570json_write_term(List, Stream, State, Options) :-
571 is_list(List),
572 !,
573 space_if_not_at_left_margin(Stream, State),
574 write(Stream, '['),
575 ( json_write_state_width(State, Width),
576 ( Width == 0
577 -> true
578 ; json_write_state_indent(State, Indent),
579 json_print_length(List, Options, Width, Indent, _)
580 )
581 -> set_width_of_json_write_state(0, State, State2),
582 write_array_hor(List, Stream, State2, Options),
583 write(Stream, ']')
584 ; step_indent(State, State2),
585 write_array_ver(List, Stream, State2, Options),
586 indent(Stream, State),
587 write(Stream, ']')
588 ).
589json_write_term(Number, Stream, _State, _Options) :-
590 number(Number),
591 !,
592 write(Stream, Number).
593json_write_term(True, Stream, _State, Options) :-
594 json_options_true(Options, True),
595 !,
596 write(Stream, true).
597json_write_term(False, Stream, _State, Options) :-
598 json_options_false(Options, False),
599 !,
600 write(Stream, false).
601json_write_term(Null, Stream, _State, Options) :-
602 json_options_null(Options, Null),
603 !,
604 write(Stream, null).
605json_write_term(#(Text), Stream, _State, _Options) :-
606 !,
607 ( ( atom(Text)
608 ; string(Text)
609 )
610 -> json_write_string(Stream, Text)
611 ; term_string(Text, String),
612 json_write_string(Stream, String)
613 ).
614json_write_term(String, Stream, _State, _Options) :-
615 atom(String),
616 !,
617 json_write_string(Stream, String).
618json_write_term(String, Stream, _State, _Options) :-
619 string(String),
620 !,
621 json_write_string(Stream, String).
622json_write_term(AnyTerm, Stream, State, _Options) :-
623 ( json_write_state_serialize_unknown(State, true)
624 -> term_string(AnyTerm, String),
625 json_write_string(Stream, String)
626 ; type_error(json_term, AnyTerm)
627 ).
628
629json_write_object(Pairs, Stream, State, Options) :-
630 space_if_not_at_left_margin(Stream, State),
631 write(Stream, '{'),
632 ( json_write_state_width(State, Width),
633 ( Width == 0
634 -> true
635 ; json_write_state_indent(State, Indent),
636 json_print_length(json(Pairs), Options, Width, Indent, _)
637 )
638 -> set_width_of_json_write_state(0, State, State2),
639 write_pairs_hor(Pairs, Stream, State2, Options),
640 write(Stream, '}')
641 ; step_indent(State, State2),
642 write_pairs_ver(Pairs, Stream, State2, Options),
643 indent(Stream, State),
644 write(Stream, '}')
645 ).
646
647
648write_pairs_hor([], _, _, _).
649write_pairs_hor([H|T], Stream, State, Options) :-
650 json_pair(H, Name, Value),
651 json_write_string(Stream, Name),
652 write(Stream, ':'),
653 json_write_term(Value, Stream, State, Options),
654 ( T == []
655 -> true
656 ; write(Stream, ', '),
657 write_pairs_hor(T, Stream, State, Options)
658 ).
659
660write_pairs_ver([], _, _, _).
661write_pairs_ver([H|T], Stream, State, Options) :-
662 indent(Stream, State),
663 json_pair(H, Name, Value),
664 json_write_string(Stream, Name),
665 write(Stream, ':'),
666 json_write_term(Value, Stream, State, Options),
667 ( T == []
668 -> true
669 ; write(Stream, ','),
670 write_pairs_ver(T, Stream, State, Options)
671 ).
672
673
674json_pair(Var, _, _) :-
675 var(Var),
676 !,
677 instantiation_error(Var).
678json_pair(Name=Value, Name, Value) :- !.
679json_pair(Name-Value, Name, Value) :- !.
680json_pair(NameValue, Name, Value) :-
681 compound(NameValue),
682 NameValue =.. [Name, Value],
683 !.
684json_pair(Pair, _, _) :-
685 type_error(json_pair, Pair).
686
687
688write_array_hor([], _, _, _).
689write_array_hor([H|T], Stream, State, Options) :-
690 json_write_term(H, Stream, State, Options),
691 ( T == []
692 -> write(Stream, ' ')
693 ; write(Stream, ', '),
694 write_array_hor(T, Stream, State, Options)
695 ).
696
697write_array_ver([], _, _, _).
698write_array_ver([H|T], Stream, State, Options) :-
699 indent(Stream, State),
700 json_write_term(H, Stream, State, Options),
701 ( T == []
702 -> true
703 ; write(Stream, ','),
704 write_array_ver(T, Stream, State, Options)
705 ).
706
707
708indent(Stream, State) :-
709 json_write_state_indent(State, Indent),
710 json_write_state_tab(State, Tab),
711 json_write_indent(Stream, Indent, Tab).
712
713step_indent(State0, State) :-
714 json_write_state_indent(State0, Indent),
715 json_write_state_step(State0, Step),
716 NewIndent is Indent+Step,
717 set_indent_of_json_write_state(NewIndent, State0, State).
718
719space_if_not_at_left_margin(Stream, State) :-
720 stream_pair(Stream, _, Write),
721 line_position(Write, LinePos),
722 ( LinePos == 0
723 ; json_write_state_indent(State, LinePos)
724 ),
725 !.
726space_if_not_at_left_margin(Stream, _) :-
727 put_char(Stream, ' ').
728
729
736
737json_print_length(Var, _, _, _, _) :-
738 var(Var),
739 !,
740 instantiation_error(Var).
741json_print_length(json(Pairs), Options, Max, Len0, Len) :-
742 !,
743 Len1 is Len0 + 2,
744 Len1 =< Max,
745 must_be(list, Pairs),
746 pairs_print_length(Pairs, Options, Max, Len1, Len).
747:- if(current_predicate(is_dict/1)). 748json_print_length(Dict, Options, Max, Len0, Len) :-
749 is_dict(Dict),
750 !,
751 dict_pairs(Dict, _Tag, Pairs),
752 Len1 is Len0 + 2,
753 Len1 =< Max,
754 pairs_print_length(Pairs, Options, Max, Len1, Len).
755:- endif. 756json_print_length(Array, Options, Max, Len0, Len) :-
757 is_list(Array),
758 !,
759 Len1 is Len0 + 2,
760 Len1 =< Max,
761 array_print_length(Array, Options, Max, Len1, Len).
762json_print_length(Null, Options, Max, Len0, Len) :-
763 json_options_null(Options, Null),
764 !,
765 Len is Len0 + 4,
766 Len =< Max.
767json_print_length(False, Options, Max, Len0, Len) :-
768 json_options_false(Options, False),
769 !,
770 Len is Len0 + 5,
771 Len =< Max.
772json_print_length(True, Options, Max, Len0, Len) :-
773 json_options_true(Options, True),
774 !,
775 Len is Len0 + 4,
776 Len =< Max.
777json_print_length(Number, _Options, Max, Len0, Len) :-
778 number(Number),
779 !,
780 write_length(Number, AL, []),
781 Len is Len0 + AL,
782 Len =< Max.
783json_print_length(@(Id), _Options, Max, Len0, Len) :-
784 atom(Id),
785 !,
786 atom_length(Id, IdLen),
787 Len is Len0+IdLen,
788 Len =< Max.
789json_print_length(String, _Options, Max, Len0, Len) :-
790 string_len(String, Len0, Len),
791 !,
792 Len =< Max.
793json_print_length(AnyTerm, _Options, Max, Len0, Len) :-
794 write_length(AnyTerm, AL, []), 795 Len is Len0 + AL+2,
796 Len =< Max.
797
798pairs_print_length([], _, _, Len, Len).
799pairs_print_length([H|T], Options, Max, Len0, Len) :-
800 pair_len(H, Options, Max, Len0, Len1),
801 ( T == []
802 -> Len = Len1
803 ; Len2 is Len1 + 2,
804 Len2 =< Max,
805 pairs_print_length(T, Options, Max, Len2, Len)
806 ).
807
808pair_len(Pair, Options, Max, Len0, Len) :-
809 compound(Pair),
810 pair_nv(Pair, Name, Value),
811 !,
812 string_len(Name, Len0, Len1),
813 Len2 is Len1+2,
814 Len2 =< Max,
815 json_print_length(Value, Options, Max, Len2, Len).
816pair_len(Pair, _Options, _Max, _Len0, _Len) :-
817 type_error(pair, Pair).
818
819pair_nv(Name=Value, Name, Value) :- !.
820pair_nv(Name-Value, Name, Value) :- !.
821pair_nv(Term, Name, Value) :-
822 compound_name_arguments(Term, Name, [Value]).
823
824array_print_length([], _, _, Len, Len).
825array_print_length([H|T], Options, Max, Len0, Len) :-
826 json_print_length(H, Options, Max, Len0, Len1),
827 ( T == []
828 -> Len = Len1
829 ; Len2 is Len1+2,
830 Len2 =< Max,
831 array_print_length(T, Options, Max, Len2, Len)
832 ).
833
834string_len(String, Len0, Len) :-
835 atom(String),
836 !,
837 atom_length(String, AL),
838 Len is Len0 + AL + 2.
839string_len(String, Len0, Len) :-
840 string(String),
841 !,
842 string_length(String, AL),
843 Len is Len0 + AL + 2.
844
845
846 849
856
857is_json_term(Term) :-
858 default_json_options(Options),
859 is_json_term2(Options, Term).
860
861is_json_term(Term, Options) :-
862 make_json_options(Options, OptionTerm, _RestOptions),
863 is_json_term2(OptionTerm, Term).
864
865is_json_term2(_, Var) :-
866 var(Var), !, fail.
867is_json_term2(Options, json(Pairs)) :-
868 !,
869 is_list(Pairs),
870 maplist(is_json_pair(Options), Pairs).
871is_json_term2(Options, List) :-
872 is_list(List),
873 !,
874 maplist(is_json_term2(Options), List).
875is_json_term2(_, Primitive) :-
876 atomic(Primitive),
877 !. 878is_json_term2(Options, True) :-
879 json_options_true(Options, True).
880is_json_term2(Options, False) :-
881 json_options_false(Options, False).
882is_json_term2(Options, Null) :-
883 json_options_null(Options, Null).
884
885is_json_pair(_, Var) :-
886 var(Var), !, fail.
887is_json_pair(Options, Name=Value) :-
888 atom(Name),
889 is_json_term2(Options, Value).
890
891:- if(current_predicate(is_dict/1)). 892
893 896
930
931json_read_dict(Stream, Dict) :-
932 json_read_dict(Stream, Dict, []).
933
934json_read_dict(Stream, Dict, Options) :-
935 make_json_dict_options(Options, OptionTerm, _RestOptions),
936 ( json_value(Stream, Term, _, OptionTerm)
937 -> true
938 ; syntax_error(illegal_json, Stream)
939 ),
940 term_to_dict(Term, Dict, OptionTerm).
941
942term_to_dict(json(Pairs), Dict, Options) :-
943 !,
944 ( json_options_tag(Options, TagName),
945 Tag \== '',
946 select(TagName = Tag0, Pairs, NVPairs),
947 to_atom(Tag0, Tag)
948 -> json_dict_pairs(NVPairs, DictPairs, Options)
949 ; json_dict_pairs(Pairs, DictPairs, Options)
950 ),
951 dict_create(Dict, Tag, DictPairs).
952term_to_dict(Value0, Value, _Options) :-
953 atomic(Value0), Value0 \== [],
954 !,
955 Value = Value0.
956term_to_dict(List0, List, Options) :-
957 assertion(is_list(List0)),
958 terms_to_dicts(List0, List, Options).
959
960json_dict_pairs([], [], _).
961json_dict_pairs([Name=Value0|T0], [Name=Value|T], Options) :-
962 term_to_dict(Value0, Value, Options),
963 json_dict_pairs(T0, T, Options).
964
965terms_to_dicts([], [], _).
966terms_to_dicts([Value0|T0], [Value|T], Options) :-
967 term_to_dict(Value0, Value, Options),
968 terms_to_dicts(T0, T, Options).
969
970to_atom(Tag, Atom) :-
971 string(Tag),
972 !,
973 atom_string(Atom, Tag).
974to_atom(Atom, Atom) :-
975 atom(Atom).
976
983
984json_write_dict(Stream, Dict) :-
985 json_write_dict(Stream, Dict, []).
986
987json_write_dict(Stream, Dict, Options) :-
988 make_json_write_state(Options, State, Options1),
989 make_json_dict_options(Options1, OptionTerm, _RestOptions),
990 json_write_term(Dict, Stream, State, OptionTerm).
991
992
993make_json_dict_options(Options, Record, RestOptions) :-
994 default_json_dict_options(Record0),
995 set_json_options_fields(Options, Record0, Record, RestOptions).
996
1007
1008atom_json_dict(Atom, Term, Options) :-
1009 ground(Atom),
1010 !,
1011 setup_call_cleanup(
1012 ( text_memfile(Atom, MF),
1013 open_memory_file(MF, read, In, [free_on_close(true)])
1014 ),
1015 json_read_dict(In, Term, Options),
1016 close(In)).
1017atom_json_dict(Result, Term, Options) :-
1018 select_option(as(Type), Options, Options1, atom),
1019 ( type_term(Type, Result, Out)
1020 -> true
1021 ; must_be(oneof([atom,string,codes]), Type)
1022 ),
1023 with_output_to(Out,
1024 json_write_dict(current_output, Term, Options1)).
1025
1026text_memfile(Atom, MF) :-
1027 atom(Atom),
1028 !,
1029 atom_to_memory_file(Atom, MF).
1030text_memfile(String, MF) :-
1031 string(String),
1032 !,
1033 new_memory_file(MF),
1034 insert_memory_file(MF, 0, String).
1035
1036:- endif. 1037
1038 1041
1042:- multifile
1043 prolog:error_message/3. 1044
1045prolog:error_message(syntax_error(json(Id))) -->
1046 [ 'JSON syntax error: ' ],
1047 json_syntax_error(Id).
1048
1049json_syntax_error(illegal_comment) -->
1050 [ 'Illegal comment' ].
1051json_syntax_error(illegal_string_escape) -->
1052 [ 'Illegal escape sequence in string' ]