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/util.hpp"
19
20#include <sstream>
21#include <stdexcept>
22
23#include "sexp/io.hpp"
24
25namespace sexp {
26
27bool
28is_list(Value const& sx)
29{
30 if (sx.is_nil())
31 {
32 return true;
33 }
34 else if (sx.is_cons())
35 {
36 return is_list(sx.get_cdr());
37 }
38 else
39 {
40 return false;
41 }
42}
43
44int
45list_length(Value const& sx)
46{
47 if (sx.is_nil())
48 {
49 return 0;
50 }
51 else if (sx.is_cons())
52 {
53 return 1 + list_length(sx.get_cdr());
54 }
55 else
56 {
57 // silently ignoring malformed list content
58 return 0;
59 }
60}
61
62Value const&
63list_ref(Value const& sx, int index)
64{
65 if (index == 0)
66 {
67 return sx.get_car();
68 }
69 else
70 {
71 return list_ref(sx.get_cdr(), index - 1);
72 }
73}
74
75Value const&
76assoc_ref(Value const& sx, std::string const& key)
77{
78 if (sx.is_nil())
79 {
80 return Value::nil_ref();
81 }
82 else if (sx.is_cons())
83 {
84 Value const& pair = sx.get_car();
85 if (pair.is_cons() &&
86 pair.get_car().is_symbol() &&
87 pair.get_car().as_string() == key)
88 {
89 return pair.get_cdr();
90 }
91 else
92 {
93 return assoc_ref(sx.get_cdr(), key);
94 }
95 }
96 else
97 {
98 std::ostringstream msg;
99 msg << "malformed input to sexp::assoc_ref(): sx:\"" << sx << "\" key:\"" << key << "\"";
100 throw std::runtime_error(msg.str());
101 }
102}
103
104} // namespace sexp
105
106/* EOF */
107