}
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::Replace_(CYContext &context) {
+void CYFunction::Inject(CYContext &context) {
+ name_ = name_->Replace(context);
+ context.scope_->Declare(context, name_, CYIdentifierOther);
+}
+
+void CYFunction::Replace_(CYContext &context, bool outer) {
+ if (outer)
+ Inject(context);
+
parent_ = context.scope_;
context.scope_ = this;
+ if (!outer && name_ != NULL)
+ Inject(context);
+
parameters_->Replace(context);
code_.Replace(context);
}
CYExpression *CYFunctionExpression::Replace(CYContext &context) {
- Replace_(context);
+ Replace_(context, false);
return this;
}
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);
}
CYStatement *CYFunctionStatement::Replace(CYContext &context) {
- Replace_(context);
+ Replace_(context, true);
return this;
}
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) {
void CYProgram::Replace(CYContext &context) {
parent_ = context.scope_;
+ CYProgram *program(context.program_);
+
context.scope_ = this;
+ context.program_ = this;
+
statements_ = statements_->ReplaceAll(context);
+
context.scope_ = parent_;
+ context.program_ = program;
Scope(context, statements_);
+
+ size_t offset(0);
+
+ // 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;
+
+ if (context.options_.verbose_)
+ name = apr_psprintf(context.pool_, "$%"APR_SIZE_T_FMT"", offset);
+ else {
+ char id[8];
+ id[7] = '\0';
+
+ id:
+ unsigned position(7), local(offset + 1);
+
+ do {
+ unsigned index(local % 53);
+ local /= 53;
+ id[--position] = index == 0 ? '0' : index < 27 ? index - 1 + 'a' : index - 27 + 'A';
+ } while (local != 0);
+
+ if (external_.find(id + position) != external_.end()) {
+ ++offset;
+ goto id;
+ }
+
+ name = apr_pstrmemdup(context.pool_, id + position, 7 - position);
+ // XXX: at some point, this could become a keyword
+ }
+
+ for (CYIdentifier *identifier(*i); identifier != NULL; identifier = identifier->next_)
+ identifier->Set(name);
+ }
}
void CYProperty::Replace(CYContext &context) { $T()
return this;
}
-void CYScope::Add(CYContext &context, CYIdentifierAddressSet &external) {
- for (CYIdentifierAddressSet::const_iterator i(external.begin()); i != external.end(); ++i) {
+void CYScope::Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags) {
+ internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, flags));
+}
+
+CYIdentifier *CYScope::Lookup(CYContext &context, CYIdentifier *identifier) {
+ std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers_.insert(identifier));
+ return *insert.first;
+}
+
+void CYScope::Merge(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::Scope(CYContext &context, CYStatement *&statements) {
- CYIdentifierAddressSet external;
+ CYIdentifierAddressVector external;
- if (context.options_.verbose_)
- std::cout << this << ':';
+ for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
+ if (internal_.find(*i) == internal_.end())
+ external.push_back(*i);
CYDeclarations *last(NULL), *curr(NULL);
+ CYProgram *program(context.program_);
+
+ // 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;
+ }
- for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
- if (internal_.find(*i) == internal_.end()) {
- if (context.options_.verbose_)
- std::cout << ' ' << (*i)->Word() << '@' << static_cast<const CYWord *>(*i);
- external.insert(*i);
- } else {
- if (context.options_.verbose_) {
- std::cout << ' ' << offset_ << ':' << (*i)->Word() << '@' << static_cast<const CYWord *>(*i);
- (*i)->Set(apr_psprintf(context.pool_, "$%u", offset_++));
- } else {
- (*i)->Set(apr_psprintf(context.pool_, "$%u", offset_++));
- }
-
- CYDeclarations *next($ CYDeclarations($ CYDeclaration(*i)));
+ if (i->second == CYIdentifierVariable) {
+ CYDeclarations *next($ CYDeclarations($ CYDeclaration(i->first)));
if (last == NULL)
last = next;
if (curr != NULL)
curr->SetNext(next);
curr = next;
}
-
- if (context.options_.verbose_)
- std::cout << " ->" << parent_ << std::endl;
+ }
if (last != NULL) {
CYVar *var($ CYVar(last));
if (parent_ != NULL) {
if (parent_->offset_ < offset_)
parent_->offset_ = offset_;
- parent_->Add(context, external);
- }
+ parent_->Merge(context, external);
+ } else if (program != NULL)
+ for (CYIdentifierAddressVector::const_iterator i(external.begin()); i != external.end(); ++i)
+ program->external_.insert((*i)->Word());
}
CYStatement *CYStatement::Collapse(CYContext &context) {