static void exit_params(void) { if (SCOPE > PARAM) exit_scope(); exit_scope(); }
void CCodeGenerator::operator()(Block* expr) { enter_scope(); for (Expression::Ptr s = expr->children(); s; s = s->next()) { loc(s); s(this); } exit_scope(); }
void CCodeGenerator::operator()(Function* feature) { // Emit a function, or extern declaration if the function is native. String::Ptr id = feature->name(); op_ = Operand(); if (feature->is_virtual()) { return; } function_ = feature; loc(feature); line(); func_sig(feature); if (feature->is_native()) { out_ << ";\n"; function_ = 0; return; } out_ << " {\n"; indent_ += 4; enter_scope(); // Set up the 'self' variable with the constructor, if necessary; this // allocates memory for the object using calloc. if (feature->is_constructor()) { ctor_preamble(class_); } // If this is main(), then emit the code to load constants. String::Ptr name = feature->name(); Feature::Ptr parent = feature->parent(); if (name->string() == "main" && parent->name()->string() == "Boot") { assert(!"check for entry point instead of this hack"); constants(); } // Load constants //assert("Load constants" && 0); Block::Ptr block = feature->block(); block(this); if (feature->type()->is_void() || feature->is_constructor()) { func_return(); } exit_scope(); indent_ -= 4; function_ = 0; out_ << "}\n\n"; }
/** * Evaluate a Compound Expression defined in the current scope given its name * and parameters. After all the bookkeeping is done, enter a new scope, bind * the signature to the parameters, evaluate, and exit. */ std::shared_ptr<const List> Context::evaluate(const std::string& name, const std::vector<std::vector<double>>& data, const std::vector<std::vector<std::string>>& content) { auto scope = stack.begin(); std::map<Signature, std::shared_ptr<const Expression>>::const_iterator pair; while (scope != stack.end()) { for (auto prefix = scope->use.begin(); prefix != scope->use.end(); ++prefix) { pair = scope->symbols.begin(); while (pair != scope->symbols.end()) { std::string qualified = prefix->empty() ? name : *prefix + "::" + name; if (pair->first.matches(qualified, data, content)) goto found; ++pair; } } ++scope; } { std::ostringstream message; message << "Warning: No match for template \"" << name; for (auto i = data.begin(); i != data.end(); ++i) message << '(' << i->size() << ')'; for (auto i = content.begin(); i != content.end(); ++i) message << '{' << i->size() << '}'; message << "\"."; // throw std::runtime_error(message.str()); std::cerr << message.str() << '\n'; return std::shared_ptr<const List>(new List(0, 0)); } found: enter_scope(); pair->first.bind(*this, data, content); std::shared_ptr<const List> result(pair->second->evaluate(*this)); exit_scope(); return result; }