/* }}} */
#include "Parser.hpp"
-#include "Context.hpp"
+#include "Replace.hpp"
#include <iomanip>
-#include "Replace.hpp"
-
CYExpression *CYAdd::Replace(CYContext &context) {
CYInfix::Replace(context);
}
CYExpression *CYDeclaration::Replace(CYContext &context) {
- CYIdentifier *identifier(identifier_->Replace(context));
- context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, CYIdentifierVariable));
- return $ CYVariable(identifier);
+ context.Replace(identifier_);
+ context.scope_->Declare(context, identifier_, CYIdentifierVariable);
+ return $ CYVariable(identifier_);
}
CYProperty *CYDeclarations::Property(CYContext &context) { $T(NULL)
}
void CYFunction::Inject(CYContext &context) {
- name_ = name_->Replace(context);
- context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(name_, CYIdentifierOther));
+ context.Replace(name_);
+ context.scope_->Declare(context, name_, CYIdentifierOther);
}
void CYFunction::Replace_(CYContext &context, bool outer) {
void CYFunctionParameter::Replace(CYContext &context) { $T()
name_ = name_->Replace(context);
- context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(name_, CYIdentifierArgument));
+ context.scope_->Declare(context, name_, CYIdentifierArgument);
next_->Replace(context);
}
}
CYIdentifier *CYIdentifier::Replace(CYContext &context) {
- if (replace_ != NULL)
- return replace_;
-
- CYIdentifierValueSet &identifiers(context.scope_->identifiers_);
- std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers.insert(this));
- if (!insert.second)
- return *insert.first;
-
- replace_ = this;
- return this;
+ if (replace_ == NULL)
+ replace_ = context.scope_->Lookup(context, this);
+ return replace_;
}
CYStatement *CYIf::Replace(CYContext &context) {
statements_ = statements_->ReplaceAll(context);
context.scope_ = parent_;
- Scope(context, statements_);
context.program_ = program;
+ Scope(context, statements_);
size_t offset(0);
+ CYCStringSet external;
+ for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
+ external.insert((*i)->Word());
+
// XXX: totalling the probable occurrences and sorting by them would improve the result
for (CYIdentifierAddressVector::const_iterator i(rename_.begin()); i != rename_.end(); ++i, ++offset) {
const char *name;
id[--position] = index == 0 ? '0' : index < 27 ? index - 1 + 'a' : index - 27 + 'A';
} while (local != 0);
- if (external_.find(id + position) != external_.end()) {
+ if (external.find(id + position) != external.end()) {
++offset;
goto id;
}
return this;
}
-void CYScope::Add(CYContext &context, CYIdentifierAddressVector &external) {
- for (CYIdentifierAddressVector::const_iterator i(external.begin()); i != external.end(); ++i) {
- std::pair<CYIdentifierAddressSet::iterator, bool> insert(identifiers_.insert(*i));
- if (!insert.second)
- (*i)->replace_ = *insert.first;
- }
+void CYScope::Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags) {
+ internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, flags));
}
-void CYScope::Scope(CYContext &context, CYStatement *&statements) {
- CYIdentifierAddressVector external;
+CYIdentifier *CYScope::Lookup(CYContext &context, CYIdentifier *identifier) {
+ std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers_.insert(identifier));
+ return *insert.first;
+}
- for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
- if (internal_.find(*i) == internal_.end())
- external.push_back(*i);
+void CYScope::Merge(CYContext &context, CYIdentifier *identifier) {
+ std::pair<CYIdentifierAddressSet::iterator, bool> insert(identifiers_.insert(identifier));
+ if (!insert.second) {
+ if ((*insert.first)->offset_ < identifier->offset_)
+ (*insert.first)->offset_ = identifier->offset_;
+ identifier->replace_ = *insert.first;
+ }
+}
+void CYScope::Scope(CYContext &context, CYStatement *&statements) {
CYDeclarations *last(NULL), *curr(NULL);
CYProgram *program(context.program_);
+ typedef std::multimap<size_t, CYIdentifier *> IdentifierOffsetMap;
+ IdentifierOffsetMap offsetted;
+
// XXX: we don't want to do this in order, we want to sort it by probable occurrence
for (CYIdentifierAddressFlagsMap::const_iterator i(internal_.begin()); i != internal_.end(); ++i) {
- if (program != NULL && i->second != CYIdentifierMagic) {
- if (program->rename_.size() <= offset_)
- program->rename_.resize(offset_ + 1);
- CYIdentifier *&identifier(program->rename_[offset_++]);
- i->first->SetNext(identifier);
- identifier = i->first;
- }
-
+ if (program != NULL && i->second != CYIdentifierMagic)
+ offsetted.insert(IdentifierOffsetMap::value_type(i->first->offset_, i->first));
if (i->second == CYIdentifierVariable) {
CYDeclarations *next($ CYDeclarations($ CYDeclaration(i->first)));
if (last == NULL)
}
}
+ size_t offset(0);
+
+ for (IdentifierOffsetMap::const_iterator i(offsetted.begin()); i != offsetted.end(); ++i) {
+ if (offset < i->first)
+ offset = i->first;
+ if (program->rename_.size() <= offset)
+ program->rename_.resize(offset + 1);
+ CYIdentifier *&identifier(program->rename_[offset++]);
+ i->second->SetNext(identifier);
+ identifier = i->second;
+ }
+
if (last != NULL) {
CYVar *var($ CYVar(last));
var->SetNext(statements);
statements = var;
}
- if (parent_ != NULL) {
- if (parent_->offset_ < offset_)
- parent_->offset_ = offset_;
- parent_->Add(context, external);
- } else if (program != NULL)
- for (CYIdentifierAddressVector::const_iterator i(external.begin()); i != external.end(); ++i)
- program->external_.insert((*i)->Word());
+ for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
+ if (internal_.find(*i) == internal_.end()) {
+ if ((*i)->offset_ < offset)
+ (*i)->offset_ = offset;
+ parent_->Merge(context, *i);
+ }
}
CYStatement *CYStatement::Collapse(CYContext &context) {