-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathobject.h
More file actions
117 lines (106 loc) · 2.65 KB
/
object.h
File metadata and controls
117 lines (106 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#pragma once
#include <memory>
#include <string>
#include <error.h>
class Object : public std::enable_shared_from_this<Object> {
public:
virtual std::string GetString() {
return "";
}
virtual std::shared_ptr<Object> Do() {
return nullptr;
}
virtual ~Object() = default;
};
class Number : public Object {
public:
Number(int value) : value_(value) {
}
std::string GetString() override {
return std::to_string(value_);
}
int GetValue() const {
return value_;
};
private:
int value_;
};
class Symbol : public Object {
public:
Symbol(std::string str) : str_(str) {
}
std::string GetString() override {
return str_;
}
const std::string& GetName() const {
return str_;
};
private:
const std::string str_;
};
class Cell : public Object {
public:
Cell(std::shared_ptr<Object> first, std::shared_ptr<Object> second)
: first_(first), second_(second) {
}
std::shared_ptr<Object> GetFirst() const {
return first_;
};
std::shared_ptr<Object> GetSecond() const {
return second_;
};
std::string GetString() override {
if (!second_ && !first_) {
return "(())";
}
if (!second_) {
std::string answer;
answer += "(";
answer += first_->GetString();
answer += ")";
return answer;
}
if (!std::dynamic_pointer_cast<Cell>(second_)) {
std::string str;
str += "(";
str += first_->GetString();
str += " . ";
str += second_->GetString();
str += ")";
return str;
}
auto f = first_;
auto s = second_;
std::string ans;
ans += "(";
ans += f->GetString();
ans += " ";
while (s != nullptr) {
if (!std::dynamic_pointer_cast<Cell>(s)) {
ans += ". ";
ans += s->GetString();
ans += " ";
break;
} else {
f = std::dynamic_pointer_cast<Cell>(s)->GetFirst();
ans += f->GetString();
ans += " ";
s = std::dynamic_pointer_cast<Cell>(s)->GetSecond();
}
}
ans.pop_back();
ans += ")";
return ans;
}
private:
std::shared_ptr<Object> first_;
std::shared_ptr<Object> second_;
};
template <class T>
std::shared_ptr<T> As(const std::shared_ptr<Object>& obj) {
return std::dynamic_pointer_cast<T>(obj);
}
template <class T>
bool Is(const std::shared_ptr<Object>& obj) {
return As<T>(obj) != nullptr;
}