-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpression.hpp
127 lines (91 loc) · 3.69 KB
/
expression.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*! \file expression.hpp
Defines the Expression type and assiciated functions.
*/
#ifndef EXPRESSION_HPP
#define EXPRESSION_HPP
#include <string>
#include <vector>
#include <map>
#include<iterator>
#include<utility>
#include <iomanip>
//#include <sstream>
#include "token.hpp"
#include "atom.hpp"
#include "message_queue.h"
// forward declare Environment
class Environment;
/*! \class Expression
\brief An expression is a tree of Atoms.
An expression is an atom called the head followed by a (possibly empty)
list of expressions called the tail.
*/
class Expression {
public:
typedef std::vector<Expression>::const_iterator ConstIteratorType;
/// Default construct and Expression, whose type in NoneType
Expression();
/*! Construct an Expression with given Atom as head an empty tail
\param atom the atom to make the head
*/
Expression(const Atom & a);
/// deep-copy construct an expression (recursive)
Expression(const Expression & a);
/// deep-copy assign an expression (recursive)
Expression & operator=(const Expression & a);
/// return a reference to the head Atom
Atom & head();
/// return a const-reference to the head Atom
const Atom & head() const;
/// append Atom to tail of the expression
void append(const Atom & a);
void addToTail(const Expression & a);
bool isListEmpty() const noexcept;
int listLength() const noexcept;
/// return a pointer to the last expression in the tail, or nullptr
Expression * tail();
/// return a const-iterator to the beginning of tail
ConstIteratorType tailConstBegin() const noexcept;
/// return a const-iterator to the tail end
ConstIteratorType tailConstEnd() const noexcept;
/// convienience member to determine if head atom is a number
bool isHeadNumber() const noexcept;
/// convienience member to determine if head atom is a symbol
bool isHeadSymbol() const noexcept;
/// Evaluate expression using a post-order traversal (recursive)
Expression eval(Environment & env);
/// equality comparison for two expressions (recursive)
bool operator==(const Expression & exp) const noexcept;
// returns the corresponding property of expression
std::pair<std::string, Expression> get_property(std::string const & target);
void setProperty(std::string tag, Expression property);
private:
// the head of the expression
Atom m_head;
//Atom list_head;
// the tail list is expressed as a vector for access efficiency
// and cache coherence, at the cost of wasted memory.
std::vector<Expression> m_tail;
// the property list stores all the property and types of those properties
// inside the map
std::map <std::string, Expression > m_property;
// convenience typedef
typedef std::vector<Expression>::iterator IteratorType;
// internal helper methods
Expression handle_lookup(const Atom & head, const Environment & env);
Expression handle_define(Environment & env);
Expression handle_begin(Environment & env);
Expression handle_lambda(Environment & env);
Expression handle_apply(Environment & env);
Expression handle_map(Environment & env);
Expression handle_setProperty(Environment & env);
Expression handle_getProperty(Environment & env);
Expression handle_discretePlot(Environment & env);
Expression handle_continousPlot(Environment & env);
};
/// Render expression to output stream
std::ostream & operator<<(std::ostream & out, const Expression & exp);
/// inequality comparison for two expressions (recursive)
bool operator!=(const Expression & left, const Expression & right) noexcept;
Expression list(const std::vector<Expression> & args);
#endif