-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalue.hpp
189 lines (148 loc) · 4.41 KB
/
value.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#ifndef YS2_VALUE_HPP
#define YS2_VALUE_HPP
#include <string>
#include <iostream>
#include <vector>
#include <gmp.h>
#include <gmpxx.h>
#include <algorithm>
#include <memory>
#include <cstddef>
#include <unordered_map>
typedef decltype(nullptr) nullptr_t;
/*
* - could contain any reperesentable value
* - union + enum system to preserve memory
* TODO: convert this to use std::variant for better performance
*
*/
#include "extend.hpp"
#include "object.hpp"
#include "lambda.hpp"
// Variant data type
class Value {
public:
// what kind of data is contained
enum vtype {
EMT = 0, // empty - value of nothing
// no value, equivalent to undefined
DEC, // float - double
// double value
STR, // string - collection of chars
// string
REF, // reference - reference to memory address of a Value
// shared_ptr
IMR, // immuteable reference - reference to memory that isn't allowed to be changed (change this object)
// identical to REF in every other way
MAC, // macro - framed block of code
// string
INT, // integer
// gnu multiple precision int
ARR, // array - collection of Values
// vector of values
OBJ, // object/dict - fancy dict
// will receive dedicated class eventually
LAM, // lambda - fancy function
// will receive dedicated class eventually
DEF, // defined term - gets evaluated as soon as it's put onto stack
// def ptr
NSP, // namespace collection of labeled def's
// typedef in namespace_def.hpp
/* could be added in future:
CHR ? character - prolly not bc international == confusion
BLN ? boolean - prolly not, truthy values are fine
RXP ? reg exp - prolly not, could be added through lang extension
*/
} type { EMT };
// actual data contained here
union {
double dec;
mpz_class* mp_int;
std::string* str;
std::vector<std::shared_ptr<Value>>* arr;
Object* obj;
Lambda* lam;
Namespace* ns;
Def* def;
// Used to manage reference counting and method binding
struct {
std::shared_ptr<Value>* ref;
std::shared_ptr<Value>* related;
};
};
Value();
Value(const vtype);
Value(const vtype, const std::string);
Value(const char*);
Value(const std::string&);
Value(const double);
Value(std::shared_ptr<Value>);
Value(const vtype t, const std::shared_ptr<Value>&);
Value(mpz_class);
Value(const std::vector<std::shared_ptr<Value>>&);
Value(const nullptr_t&);
Value(const Def&);
Value(const Namespace&);
Value(const Lambda& lam);
Value(const Object& obj);
// double ref
Value(const std::shared_ptr<Value>& ref, const std::shared_ptr<Value>& related);
// prevent memory leaks when changing the value
// TODO: add object destructor
void erase();
~Value(){
erase();
}
// set self to given value
Value& set(const Value& v) {
erase();
return set_noerase(v);
}
// set self to given value
Value& set_noerase(const Value& v);
// copy
Value(const Value& v) {
set_noerase(v);
//std::cout <<"copy\n";
}
Value& operator=(const Value& v)
{ set(v); return *this;}
std::string depict(); // represent value
std::string toString(); // stringify value
// gets a value from a ref, if it's a lambda then it adds an if
bool deferValue(Value& ret, std::vector<std::shared_ptr<Value>*>& pastPtrs);
bool deferValue(Value& ret) {
std::vector<std::shared_ptr<Value>*> ptrs; // recycle vector to save memory
return deferValue(ret, ptrs);
}
// get the value that a reference points to
const Value* defer(std::vector<std::shared_ptr<Value>*>& pastPtrs);
const Value* defer(bool& imr, std::vector<std::shared_ptr<Value>*>& pastPtrs);
const Value* defer(){
std::vector<std::shared_ptr<Value>*> ptrs;
return defer(ptrs);
}
const Value* defer(bool& imr) {
std::vector<std::shared_ptr<Value>*> ptrs;
return defer(imr, ptrs);
}
// get muteable value
// stops at immuteable references
Value* deferMuteable(std::vector<std::shared_ptr<Value>*>& pastPtrs);
Value* deferMuteable() { // this is to make it so we can use references to prevent copies
std::vector<std::shared_ptr<Value>*> ptrs;
return deferMuteable(ptrs);
}
Value* deferChange();
//
std::shared_ptr<Value> lastRef(std::vector<std::shared_ptr<Value>*>& pastPtrs);
std::shared_ptr<Value> lastRef() {
std::vector<std::shared_ptr<Value>*> ptrs;
return lastRef(ptrs);
}
const char* typeName();
static const char* typeName(vtype value_type);
bool truthy();
bool operator==(Value& v);
};
#endif //YS2_VALUE_HPP