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
|
#include "modcontext.h"
#include "module.h"
#include "expression.h"
#include "function.h"
#include "printutils.h"
#include "builtin.h"
#include <boost/foreach.hpp>
ModuleContext::ModuleContext(const Context *parent, const EvalContext *evalctx)
: Context(parent), functions_p(NULL), modules_p(NULL), evalctx(evalctx)
{
}
ModuleContext::~ModuleContext()
{
}
void ModuleContext::initializeModule(const class Module &module)
{
this->setVariables(module.definition_arguments, evalctx);
// FIXME: Don't access module members directly
this->functions_p = &module.scope.functions;
this->modules_p = &module.scope.modules;
BOOST_FOREACH(const Assignment &ass, module.scope.assignments) {
this->set_variable(ass.first, ass.second->evaluate(this));
}
}
/*!
Only used to initialize builtins for the top-level root context
*/
void ModuleContext::registerBuiltin()
{
const LocalScope &scope = Builtins::instance()->getGlobalScope();
// FIXME: Don't access module members directly
this->functions_p = &scope.functions;
this->modules_p = &scope.modules;
BOOST_FOREACH(const Assignment &ass, scope.assignments) {
this->set_variable(ass.first, ass.second->evaluate(this));
}
this->set_constant("PI",Value(M_PI));
}
const AbstractFunction *ModuleContext::findLocalFunction(const std::string &name) const
{
if (this->functions_p && this->functions_p->find(name) != this->functions_p->end()) {
return this->functions_p->find(name)->second;
}
return NULL;
}
const AbstractModule *ModuleContext::findLocalModule(const std::string &name) const
{
if (this->modules_p && this->modules_p->find(name) != this->modules_p->end()) {
AbstractModule *m = this->modules_p->find(name)->second;
std::string replacement = Builtins::instance()->isDeprecated(name);
if (!replacement.empty()) {
PRINTB("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", name % replacement);
}
return m;
}
return NULL;
}
Value ModuleContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const
{
const AbstractFunction *foundf = findLocalFunction(name);
if (foundf) return foundf->evaluate(this, evalctx);
return Context::evaluate_function(name, evalctx);
}
AbstractNode *ModuleContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
{
const AbstractModule *foundm = this->findLocalModule(inst.name());
if (foundm) return foundm->instantiate(this, &inst, evalctx);
return Context::instantiate_module(inst, evalctx);
}
#ifdef DEBUG
void ModuleContext::dump(const AbstractModule *mod, const ModuleInstantiation *inst)
{
if (inst)
PRINTB("ModuleContext %p (%p) for %s inst (%p) ", this % this->parent % inst->name() % inst);
else
PRINTB("ModuleContext: %p (%p)", this % this->parent);
PRINTB(" document path: %s", this->document_path);
if (mod) {
const Module *m = dynamic_cast<const Module*>(mod);
if (m) {
PRINT(" module args:");
BOOST_FOREACH(const Assignment &arg, m->definition_arguments) {
PRINTB(" %s = %s", arg.first % variables[arg.first]);
}
}
}
typedef std::pair<std::string, Value> ValueMapType;
PRINT(" vars:");
BOOST_FOREACH(const ValueMapType &v, constants) {
PRINTB(" %s = %s", v.first % v.second);
}
BOOST_FOREACH(const ValueMapType &v, variables) {
PRINTB(" %s = %s", v.first % v.second);
}
BOOST_FOREACH(const ValueMapType &v, config_variables) {
PRINTB(" %s = %s", v.first % v.second);
}
}
#endif
FileContext::FileContext(const class FileModule &module, const Context *parent)
: usedlibs(module.usedlibs), ModuleContext(parent)
{
if (!module.modulePath().empty()) this->document_path = module.modulePath();
}
Value FileContext::evaluate_function(const std::string &name, const EvalContext *evalctx) const
{
const AbstractFunction *foundf = findLocalFunction(name);
if (foundf) return foundf->evaluate(this, evalctx);
BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) {
if (m.second->scope.functions.find(name) != m.second->scope.functions.end()) {
FileContext ctx(*m.second, this->parent);
ctx.initializeModule(*m.second);
// FIXME: Set document path
#if 0 && DEBUG
PRINTB("New lib Context for %s func:", name);
ctx.dump(NULL, NULL);
#endif
return m.second->scope.functions[name]->evaluate(&ctx, evalctx);
}
}
return ModuleContext::evaluate_function(name, evalctx);
}
AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, const EvalContext *evalctx) const
{
const AbstractModule *foundm = this->findLocalModule(inst.name());
if (foundm) return foundm->instantiate(this, &inst, evalctx);
BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) {
assert(m.second);
if (m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) {
FileContext ctx(*m.second, this->parent);
ctx.initializeModule(*m.second);
// FIXME: Set document path
#if 0 && DEBUG
PRINT("New file Context:");
ctx.dump(NULL, &inst);
#endif
return m.second->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx);
}
}
return ModuleContext::instantiate_module(inst, evalctx);
}
|