forked from cparse/cparse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.cpp
159 lines (126 loc) · 4.21 KB
/
functions.cpp
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
#include <string>
#include "./shunting-yard.h"
#include "./functions.h"
#include "./shunting-yard-exceptions.h"
using cparse::packToken;
using cparse::Function;
using cparse::TokenList;
using cparse::TokenMap;
using cparse::CppFunction;
/* * * * * class Function * * * * */
packToken Function::call(packToken _this, const Function* func,
TokenList* args, TokenMap scope) {
// Build the local namespace:
TokenMap kwargs;
TokenMap local = scope.getChild();
args_t arg_names = func->args();
TokenList_t::iterator args_it = args->list().begin();
args_t::const_iterator names_it = arg_names.begin();
/* * * * * Parse positional arguments: * * * * */
while (args_it != args->list().end() && names_it != arg_names.end()) {
// If the positional argument list is over:
if ((*args_it)->type == STUPLE) break;
// Else add it to the local namespace:
local[*names_it] = *args_it;
++args_it;
++names_it;
}
/* * * * * Parse extra positional arguments: * * * * */
TokenList arglist;
for (; args_it != args->list().end(); ++args_it) {
// If there is a keyword argument:
if ((*args_it)->type == STUPLE) break;
// Else add it to arglist:
arglist.list().push_back(*args_it);
}
/* * * * * Parse keyword arguments: * * * * */
for (; args_it != args->list().end(); ++args_it) {
packToken& arg = *args_it;
if (arg->type != STUPLE) {
throw syntax_error("Positional argument follows keyword argument");
}
STuple* st = static_cast<STuple*>(arg.token());
if (st->list().size() != 2) {
throw syntax_error("Keyword tuples must have exactly 2 items!");
}
if (st->list()[0]->type != STR) {
throw syntax_error("Keyword first argument should be of type string!");
}
// Save it:
std::string key = st->list()[0].asString();
packToken& value = st->list()[1];
kwargs[key] = value;
}
/* * * * * Set missing positional arguments: * * * * */
for (; names_it != arg_names.end(); ++names_it) {
// If not set by a keyword argument:
auto kw_it = kwargs.map().find(*names_it);
if (kw_it == kwargs.map().end()) {
local[*names_it] = packToken::None();
} else {
local[*names_it] = kw_it->second;
kwargs.map().erase(kw_it);
}
}
/* * * * * Set built-in variables: * * * * */
local["this"] = _this;
local["args"] = arglist;
local["kwargs"] = kwargs;
return func->exec(local);
}
/* * * * * class CppFunction * * * * */
CppFunction::CppFunction() {
this->_name = "";
this->isStdFunc = false;
this->func = NULL;
}
CppFunction::CppFunction(packToken (*func)(TokenMap), const args_t args,
std::string name)
: func(func), _args(args) {
this->_name = name;
this->isStdFunc = false;
}
CppFunction::CppFunction(packToken (*func)(TokenMap), unsigned int nargs,
const char** args, std::string name)
: func(func) {
this->_name = name;
this->isStdFunc = false;
// Add all strings to args list:
for (uint32_t i = 0; i < nargs; ++i) {
this->_args.push_back(args[i]);
}
}
// Build a function with no named args:
CppFunction::CppFunction(packToken (*func)(TokenMap), std::string name)
: func(func) {
this->_name = name;
this->isStdFunc = false;
}
CppFunction::CppFunction(std::function<packToken(TokenMap)> func, const args_t args,
std::string name)
: stdFunc(func), _args(args) {
this->_name = name;
this->isStdFunc = true;
}
CppFunction::CppFunction(const args_t args, std::function<packToken(TokenMap)> func,
std::string name)
: stdFunc(func), _args(args) {
this->_name = name;
this->isStdFunc = true;
}
CppFunction::CppFunction(std::function<packToken(TokenMap)> func, unsigned int nargs,
const char** args, std::string name)
: stdFunc(func) {
this->_name = name;
this->isStdFunc = true;
// Add all strings to args list:
for (uint32_t i = 0; i < nargs; ++i) {
this->_args.push_back(args[i]);
}
}
// Build a function with no named args:
CppFunction::CppFunction(std::function<packToken(TokenMap)> func, std::string name)
: stdFunc(func) {
this->_name = name;
this->isStdFunc = true;
}