1// SExp - A S-Expression Parser for C++
2// Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3// 2015 Ingo Ruhnke <grumbel@gmail.com>
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18#include "sexp/io.hpp"
19
20#include <sstream>
21
22#include "float.hpp"
23
24namespace sexp {
25
26void escape_string(std::ostream& os, std::string const& text)
27{
28 os << '"';
29 for(size_t i = 0; i < text.size(); ++i)
30 {
31 if (text[i] == '"')
32 {
33 os << "\\\"";
34 }
35 else if (text[i] == '\\')
36 {
37 os << "\\\\";
38 }
39 else
40 {
41 os << text[i];
42 }
43 }
44 os << '"';
45}
46
47std::ostream& operator<<(std::ostream& os, Value const& sx)
48{
49 switch(sx.get_type())
50 {
51 case Value::Type::NIL:
52 os << "()";
53 break;
54
55 case Value::Type::CONS:
56 {
57 os << '(';
58 Value const* cur = &sx;
59 do
60 {
61 if (cur->get_type() != Value::Type::CONS)
62 {
63 os << ". " << *cur;
64 break;
65 }
66 else
67 {
68 os << cur->get_car();
69 cur = &cur->get_cdr();
70 if (*cur)
71 {
72 os << ' ';
73 }
74 }
75 }
76 while(*cur);
77 os << ')';
78 }
79 break;
80
81 case Value::Type::STRING:
82 escape_string(os, sx.as_string());
83 break;
84
85 case Value::Type::INTEGER:
86 os << sx.as_int();
87 break;
88
89 case Value::Type::REAL:
90 float2string(os, sx.as_float());
91 break;
92
93 case Value::Type::SYMBOL:
94 os << sx.as_string();
95 break;
96
97 case Value::Type::BOOLEAN:
98 os << (sx.as_bool() ? "#t" : "#f");
99 break;
100
101 case Value::Type::ARRAY:
102 {
103 os << "#(";
104 auto const& arr = sx.as_array();
105 for(size_t i = 0; i != arr.size(); ++i)
106 {
107 if (i != 0) { os << ' '; }
108 os << arr[i];
109 }
110 os << ")";
111 }
112 break;
113 }
114
115 return os;
116}
117
118} // namespace sexp
119
120/* EOF */
121