From: Jay Freeman (saurik) Date: Thu, 19 Nov 2009 00:37:29 +0000 (+0000) Subject: Started refactoring the identifier mechanism to sort on usage. X-Git-Tag: v0.9.432~147 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/e013809d7a06e37dcbf21c340febecda46ba0caf Started refactoring the identifier mechanism to sort on usage. --- diff --git a/Output.cpp b/Output.cpp index 26dc81f..552768b 100644 --- a/Output.cpp +++ b/Output.cpp @@ -293,6 +293,7 @@ void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const { void CYDeclaration::Output(CYOutput &out, CYFlags flags) const { out << *identifier_; + //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_; if (initialiser_ != NULL) { out << ' ' << '=' << ' '; initialiser_->Output(out, CYPA, CYRight(flags)); diff --git a/Parser.hpp b/Parser.hpp index 6bf18a7..73a605c 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -244,11 +244,13 @@ struct CYIdentifier : { CYIdentifier *replace_; size_t offset_; + size_t usage_; CYIdentifier(const char *word) : CYWord(word), replace_(NULL), - offset_(0) + offset_(0), + usage_(0) { } @@ -311,9 +313,15 @@ enum CYIdentifierFlags { typedef std::set CYCStringSet; typedef std::set CYIdentifierValueSet; -typedef std::vector CYIdentifierAddressVector; typedef std::map CYIdentifierAddressFlagsMap; +struct CYIdentifierUsage { + CYIdentifier *identifier_; + size_t usage_; +}; + +typedef std::vector CYIdentifierUsageVector; + struct CYScope { CYScope *parent_; CYIdentifierAddressFlagsMap internal_; @@ -339,7 +347,7 @@ struct CYProgram : CYThing { CYStatement *statements_; - CYIdentifierAddressVector rename_; + CYIdentifierUsageVector rename_; CYProgram(CYStatement *statements) : statements_(statements) diff --git a/Replace.cpp b/Replace.cpp index 0cfbfdc..b54bfe3 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -368,9 +368,11 @@ CYStatement *CYFunctionStatement::Replace(CYContext &context) { } CYIdentifier *CYIdentifier::Replace(CYContext &context) { - if (replace_ != NULL && replace_ != this) + if (replace_ == NULL) { + replace_ = context.scope_->Lookup(context, this); + ++replace_->usage_; + } else if (replace_ != this) return replace_->Replace(context); - replace_ = context.scope_->Lookup(context, this); return replace_; } @@ -461,6 +463,20 @@ CYExpression *CYPrefix::Replace(CYContext &context) { #define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ" //#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_" +namespace { + struct IdentifierUsageLess : + std::binary_function + { + _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const { + if (lhs->usage_ != rhs->usage_) + return lhs->usage_ > rhs->usage_; + return lhs < rhs; + } + }; + + typedef std::set IdentifierUsages; +} + void CYProgram::Replace(CYContext &context) { parent_ = context.scope_; CYProgram *program(context.program_); @@ -480,8 +496,14 @@ void CYProgram::Replace(CYContext &context) { for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i) external.insert((*i)->Word()); + IdentifierUsages usages; + + if (offset < rename_.size()) + for (CYIdentifier *i(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(rename_.begin()); i != rename_.end(); ++i, ++offset) { //std::cout << *i << ":" << (*i)->offset_ << std::endl; const char *name; @@ -510,7 +532,7 @@ void CYProgram::Replace(CYContext &context) { // 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); } } @@ -540,6 +562,7 @@ void CYScope::Merge(CYContext &context, CYIdentifier *identifier) { if ((*insert.first)->offset_ < identifier->offset_) (*insert.first)->offset_ = identifier->offset_; identifier->replace_ = *insert.first; + (*insert.first)->usage_ += identifier->usage_ + 1; } } @@ -547,11 +570,13 @@ namespace { struct IdentifierOffset { size_t offset_; CYIdentifierFlags flags_; + size_t usage_; CYIdentifier *identifier_; - IdentifierOffset(size_t offset, CYIdentifierFlags flags, CYIdentifier *identifier) : - offset_(offset), + IdentifierOffset(CYIdentifier *identifier, CYIdentifierFlags flags) : + offset_(identifier->offset_), flags_(flags), + usage_(identifier->usage_), identifier_(identifier) { } @@ -565,6 +590,8 @@ namespace { 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_; } }; @@ -578,10 +605,9 @@ void CYScope::Scope(CYContext &context, CYStatement *&statements) { 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) - offsets.insert(IdentifierOffset(i->first->offset_, i->second, i->first)); + offsets.insert(IdentifierOffset(i->first, i->second)); size_t offset(0); @@ -600,9 +626,10 @@ void CYScope::Scope(CYContext &context, CYStatement *&statements) { if (program->rename_.size() <= offset) program->rename_.resize(offset + 1); - CYIdentifier *&identifier(program->rename_[offset++]); - i->identifier_->SetNext(identifier); - identifier = i->identifier_; + CYIdentifierUsage &rename(program->rename_[offset++]); + i->identifier_->SetNext(rename.identifier_); + rename.identifier_ = i->identifier_; + rename.usage_ += i->identifier_->usage_ + 1; } if (last != NULL) {