if (outer)
Inject(context);
- parent_ = context.scope_;
- context.scope_ = this;
+ CYScope scope;
+ scope.parent_ = context.scope_;
+ context.scope_ = &scope;
if (!outer && name_ != NULL)
Inject(context);
parameters_->Replace(context);
code_.Replace(context);
- context.scope_ = parent_;
- Scope(context, code_.statements_);
+ context.scope_ = scope.parent_;
+ scope.Scope(context, code_.statements_);
}
CYExpression *CYFunctionExpression::Replace(CYContext &context) {
}
CYIdentifier *CYIdentifier::Replace(CYContext &context) {
- if (replace_ == NULL)
- replace_ = context.scope_->Lookup(context, this);
+ if (replace_ != NULL && replace_ != this)
+ return replace_->Replace(context);
+ replace_ = context.scope_->Lookup(context, this);
return replace_;
}
return this;
}
+// XXX: this is evil evil black magic. don't ask, don't tell... don't believe!
#define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ"
+//#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"
+
+namespace {
+ struct IdentifierUsageLess :
+ std::binary_function<CYIdentifier *, CYIdentifier *, bool>
+ {
+ _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
+ if (lhs->usage_ != rhs->usage_)
+ return lhs->usage_ > rhs->usage_;
+ return lhs < rhs;
+ }
+ };
-void CYProgram::Replace(CYContext &context) {
- parent_ = context.scope_;
- CYProgram *program(context.program_);
-
- context.scope_ = this;
- context.program_ = this;
+ typedef std::set<CYIdentifier *, IdentifierUsageLess> IdentifierUsages;
+}
+void CYProgram::Replace(CYContext &context) {
+ CYScope scope;
+ scope.parent_ = context.scope_;
+ context.scope_ = &scope;
statements_ = statements_->ReplaceAll(context);
-
- context.scope_ = parent_;
- context.program_ = program;
- Scope(context, statements_);
+ context.scope_ = scope.parent_;
+ scope.Scope(context, statements_);
size_t offset(0);
CYCStringSet external;
- for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
+ for (CYIdentifierValueSet::const_iterator i(scope.identifiers_.begin()); i != scope.identifiers_.end(); ++i)
external.insert((*i)->Word());
+ IdentifierUsages usages;
+
+ if (offset < context.rename_.size())
+ for (CYIdentifier *i(context.rename_[offset].identifier_); i != NULL; i = i->next_)
+ usages.insert(i);
+
// 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) {
+ for (CYIdentifierUsageVector::const_iterator i(context.rename_.begin()); i != context.rename_.end(); ++i, ++offset) {
+ //std::cout << *i << ":" << (*i)->offset_ << std::endl;
+
const char *name;
if (context.options_.verbose_)
// XXX: at some point, this could become a keyword
}
- for (CYIdentifier *identifier(*i); identifier != NULL; identifier = identifier->next_)
+ for (CYIdentifier *identifier(i->identifier_); identifier != NULL; identifier = identifier->next_)
identifier->Set(name);
}
}
}
void CYScope::Merge(CYContext &context, CYIdentifier *identifier) {
- std::pair<CYIdentifierAddressSet::iterator, bool> insert(identifiers_.insert(identifier));
+ std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers_.insert(identifier));
if (!insert.second) {
if ((*insert.first)->offset_ < identifier->offset_)
(*insert.first)->offset_ = identifier->offset_;
identifier->replace_ = *insert.first;
+ (*insert.first)->usage_ += identifier->usage_ + 1;
}
}
+namespace {
+ struct IdentifierOffset {
+ size_t offset_;
+ CYIdentifierFlags flags_;
+ size_t usage_;
+ CYIdentifier *identifier_;
+
+ IdentifierOffset(CYIdentifier *identifier, CYIdentifierFlags flags) :
+ offset_(identifier->offset_),
+ flags_(flags),
+ usage_(identifier->usage_),
+ identifier_(identifier)
+ {
+ }
+ };
+
+ struct IdentifierOffsetLess :
+ std::binary_function<const IdentifierOffset &, const IdentifierOffset &, bool>
+ {
+ _finline bool operator ()(const IdentifierOffset &lhs, const IdentifierOffset &rhs) const {
+ if (lhs.offset_ != rhs.offset_)
+ return lhs.offset_ < rhs.offset_;
+ if (lhs.flags_ != rhs.flags_)
+ return lhs.flags_ < rhs.flags_;
+ /*if (lhs.usage_ != rhs.usage_)
+ return lhs.usage_ < rhs.usage_;*/
+ return lhs.identifier_ < rhs.identifier_;
+ }
+ };
+
+ typedef std::set<IdentifierOffset, IdentifierOffsetLess> IdentifierOffsets;
+}
+
void CYScope::Scope(CYContext &context, CYStatement *&statements) {
+ if (parent_ == NULL)
+ return;
+
CYDeclarations *last(NULL), *curr(NULL);
- CYProgram *program(context.program_);
- typedef std::multimap<size_t, CYIdentifier *> IdentifierOffsetMap;
- IdentifierOffsetMap offsetted;
+ IdentifierOffsets offsets;
- // 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)
- offsetted.insert(IdentifierOffsetMap::value_type(i->first->offset_, i->first));
- if (i->second == CYIdentifierVariable) {
- CYDeclarations *next($ CYDeclarations($ CYDeclaration(i->first)));
+ for (CYIdentifierAddressFlagsMap::const_iterator i(internal_.begin()); i != internal_.end(); ++i)
+ if (i->second != CYIdentifierMagic)
+ offsets.insert(IdentifierOffset(i->first, i->second));
+
+ size_t offset(0);
+
+ for (IdentifierOffsets::const_iterator i(offsets.begin()); i != offsets.end(); ++i) {
+ if (i->flags_ == CYIdentifierVariable) {
+ CYDeclarations *next($ CYDeclarations($ CYDeclaration(i->identifier_)));
if (last == NULL)
last = next;
if (curr != NULL)
curr->SetNext(next);
curr = next;
}
- }
- size_t offset(0);
+ if (offset < i->offset_)
+ offset = i->offset_;
+ if (context.rename_.size() <= offset)
+ context.rename_.resize(offset + 1);
- 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;
+ CYIdentifierUsage &rename(context.rename_[offset++]);
+ i->identifier_->SetNext(rename.identifier_);
+ rename.identifier_ = i->identifier_;
+ rename.usage_ += i->identifier_->usage_ + 1;
}
if (last != NULL) {
for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
if (internal_.find(*i) == internal_.end()) {
+ //std::cout << *i << '=' << offset << std::endl;
if ((*i)->offset_ < offset)
(*i)->offset_ = offset;
parent_->Merge(context, *i);