-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.hpp
109 lines (76 loc) · 2.9 KB
/
atom.hpp
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
/*! \file atom.hpp
Defines the Atom type and associated functions.
*/
#ifndef ATOM_HPP
#define ATOM_HPP
#include "token.hpp"
#include <complex>
/*! \class Atom
\brief A variant type that may be a Number or Symbol or the default type None.
This class provides value semantics.
*/
class Atom {
public:
/// Construct a default Atom of type None
Atom();
/// Construct an Atom of type Number with value
Atom(double value);
/// Construct an Atom of type complx Number with value
Atom(std::complex<double> value);
/// Construct an Atom of type Symbol named value
Atom(const std::string & value);
/// Construct an Atom directly from a Token
Atom(const Token & token);
/// Copy-construct an Atom
Atom(const Atom & x);
/// Assign an Atom
Atom & operator=(const Atom & x);
/// Atom destructor
~Atom();
/// predicate to determine if an Atom is of type None
bool isNone() const noexcept;
/// predicate to determine if an Atom is of type Number
bool isNumber() const noexcept;
/// predicate to determine if an Atom is of type Complex Number
bool isComplexNumber() const noexcept;
/// predicate to determine if an Atom is of type Symbol
bool isSymbol() const noexcept;
/// predicate to determine if an Atom is of type String Literal
bool isStringLiteral() const noexcept;
/// value of Atom as a number, return 0 if not a Number
double asNumber() const noexcept;
/// value of Atom as a complex number, return 0 if not a complex Number
std::complex<double> asComplexNumber() const noexcept;
/// value of Atom as a number, returns empty-string if not a Symbol
std::string asSymbol() const noexcept;
/// value of Atom as a number, returns empty-string if not a String Literal
std::string asStringLiteral() const noexcept;
/// equality comparison based on type and value
bool operator==(const Atom & right) const noexcept;
void setStringLiteral();
private:
// internal enum of known types
enum Type {NoneKind, NumberKind, SymbolKind, ComplexKind, StringKind};
// track the type
Type m_type;
// values for the known types. Note the use of a union requires care
// when setting non POD values (see setSymbol)
union {
double numberValue;
std::string stringValue;
std::complex<double> complexValue;
};
// helper to set type and value of Number
void setNumber(double value);
// helper to set type and value of Number
void setComplexNumber(std::complex<double> value);
// helper to set type and value of Symbol
void setSymbol(const std::string & value);
// helper to set type and value of string
void setString(const std::string & value);
};
/// inequality comparison for Atom
bool operator!=(const Atom &left, const Atom & right) noexcept;
/// output stream rendering
std::ostream & operator<<(std::ostream & out, const Atom & a);
#endif