-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenvironment.hpp
More file actions
139 lines (109 loc) · 4.37 KB
/
environment.hpp
File metadata and controls
139 lines (109 loc) · 4.37 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*! \file environment.hpp
This file defines the module representing the environment.
The environment is the collection of all previously defined procedures, e.g.
the built-in ones, and previously defined symbols. The environment is used
by the interpreter to store and lookup the value of symbols and procedures as
needed.
*/
#ifndef ENVIRONMENT_HPP
#define ENVIRONMENT_HPP
// system includes
#include <map>
// module includes
#include "atom.hpp"
#include "expression.hpp"
#include <complex>
#include <vector>
#include <string>
/*! \typedef Procedure
\brief A Procedure is a C++ function pointer taking a vector of
Expressions as arguments and returning an Expression.
*/
typedef Expression (*Procedure)(const std::vector<Expression> & args);
/*! \class Environment
\brief A class representing the interpreter environment.
An instance of Environment allows the interpreter to track previously defined
procedures and definitions, either built-in or defined during execution.
To lookup a symbol use one of the member functions is_exp or is_proc, or if you
do not care about
what the symbol maps to is_known. Depending on the value these member functions
return you can obtain
the mapped-to value using get_exp or get_proc.
To add an symbol to expression mapping use the add_exp member function.
*/
class Environment {
public:
/*! Construct the default environment with built-in procedures and
* definitions. */
Environment();
// Copy constructor for Lambda
Environment(const Environment & env);
/*! Determine if a symbol is known to the environment.
\param sym the sumbol to lookup
\return true if the symbol has been defined in the environment
*/
bool is_known(const Atom &sym) const;
/*! Determine if a symbol has been defined as an expression.
\param sym the sumbol to lookup
\return true if the symbol has been defined in the environment as an
expression
*/
bool is_exp(const Atom &sym) const;
/*! Get the Expression the argument symbol maps to.
\param sym the symbol to lookup
\return the expression the symbol maps to or an Expression of NoneType
*/
Expression get_exp(const Atom &sym) const;
/*! Add a mapping from sym argument to the exp argument within the environment.
\param sym the symbol to add
\param exp the expression the symbol should map to
*/
void add_exp(const Atom &sym, const Expression &exp);
/*! Determine if a symbol has been defined as a procedure
\param sym the symbol to lookup
\return true if the symbol maps to a procedure
*/
bool is_proc(const Atom &sym) const;
/*! Determine if a symbol has been user-defined as a procedure
\param sym the symbol to lookup
\return true if the symbol maps to a procedure
*/
bool is_anon_proc(const Atom &sym) const;
/*! Get the Procedure the argument symbol maps to
\param sym the symbol to lookup
\return the procedure it maps to
Note: return the default procedure if argument is not a symbol
or does not map to a known procedure.
*/
Procedure get_proc(const Atom &sym) const;
/*! Reset the environment to its default state. */
void reset();
// equality comparison for two environments (recursive)
bool operator==(const Environment & env) const noexcept;
private:
// Environment is a mapping from symbols to expressions or procedures
enum EnvResultType { ExpressionType, ProcedureType };
struct EnvResult {
EnvResultType type;
Expression exp; // used when type is ExpressionType
Procedure proc; // used when type is ProcedureType
// constructors for use in container emplace
EnvResult(){};
EnvResult(EnvResultType t, Expression e) : type(t), exp(e){};
EnvResult(EnvResultType t, Procedure p) : type(t), proc(p){};
// equality comparison for two EnvResult objects (idk if necessary)
bool operator==(const EnvResult & right) const noexcept{
if(type != right.type) return false;
if(type == ExpressionType){return exp == right.exp;}
if(type == ProcedureType){return proc == right.proc;}
return false; // This line should never be reached
};
};
// the environment map
std::map<std::string, EnvResult> envmap;
// Flag to allow overwriting variables in a Lambda shadow Environment
bool isLambda;
};
/// inequality comparison for two environments (recursive)
bool operator!=(const Environment & left, const Environment & right) noexcept;
#endif