/* }}} */
#include "cycript.hpp"
+#include "Context.hpp"
#ifdef CY_EXECUTE
#include "JavaScript.hpp"
void Setup(CYOutput &out, CYDriver &driver) {
out.pretty_ = pretty_;
- CYContext context(driver.pool_);
+ CYOptions options;
+ CYContext context(driver.pool_, options);
driver.program_->Replace(context);
}
code = command;
else {
std::ostringstream str;
- CYOutput out(str);
+ CYOptions options;
+ CYOutput out(str, options);
Setup(out, driver);
out << *driver.program_;
code = str.str();
Run(client, code, stdout);
} else {
std::ostringstream str;
- CYOutput out(str);
+ CYOptions options;
+ CYOutput out(str, options);
Setup(out, driver);
out << *driver.program_;
std::string code(str.str());
--- /dev/null
+/* Cycript - Inlining/Optimizing JavaScript Compiler
+ * Copyright (C) 2009 Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ * Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ * above copyright notice, this list of conditions
+ * and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions
+ * and the following disclaimer in the documentation
+ * and/or other materials provided with the
+ * distribution.
+ * 3. The name of the author may not be used to endorse
+ * or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
+#ifndef CYCRIPT_CONTEXT_HPP
+#define CYCRIPT_CONTEXT_HPP
+
+#include "Options.hpp"
+
+class CYScope;
+
+struct CYContext {
+ apr_pool_t *pool_;
+ CYOptions &options_;
+ CYScope *scope_;
+
+ CYContext(apr_pool_t *pool, CYOptions &options) :
+ pool_(pool),
+ options_(options),
+ scope_(NULL)
+ {
+ }
+
+ template <typename Type_>
+ void Replace(Type_ *&value) {
+ for (;;) if (value == NULL)
+ break;
+ else {
+ Type_ *replace(value->Replace(*this));
+ if (replace != value)
+ value = replace;
+ else break;
+ }
+ }
+};
+
+#endif/*CYCRIPT_CONTEXT_HPP*/
delete reinterpret_cast<CYData *>(JSObjectGetPrivate(object));
}
-struct CStringMapLess :
- std::binary_function<const char *, const char *, bool>
-{
- _finline bool operator ()(const char *lhs, const char *rhs) const {
- return strcmp(lhs, rhs) < 0;
- }
-};
-
void Structor_(apr_pool_t *pool, sig::Type *&type) {
if (
type->primitive == sig::pointer_P &&
}
};
-typedef std::map<const char *, Type_privateData *, CStringMapLess> TypeMap;
+typedef std::map<const char *, Type_privateData *, CStringLess> TypeMap;
static TypeMap Types_;
JSObjectRef CYMakeStruct(JSContextRef context, void *data, sig::Type *type, ffi_type *ffi, JSObjectRef owner) {
#include "Pooling.hpp"
#include "Parser.hpp"
+#include "Context.hpp"
#include "Cycript.tab.hh"
#include "cycript.hpp"
#include "Pooling.hpp"
+#include "Context.hpp"
#include <sys/mman.h>
if (parser.parse() != 0 || !driver.errors_.empty())
return;
- CYContext context(driver.pool_);
+ CYOptions options;
+ CYContext context(driver.pool_, options);
driver.program_->Replace(context);
std::ostringstream str;
- CYOutput out(str);
+ CYOutput out(str, options);
out << *driver.program_;
std::string code(str.str());
/* }}} */
#include "Replace.hpp"
+#include "Context.hpp"
#include "ObjectiveC/Syntax.hpp"
#include <Foundation/Foundation.h>
--- /dev/null
+/* Cycript - Inlining/Optimizing JavaScript Compiler
+ * Copyright (C) 2009 Jay Freeman (saurik)
+*/
+
+/* Modified BSD License {{{ */
+/*
+ * Redistribution and use in source and binary
+ * forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the
+ * above copyright notice, this list of conditions
+ * and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions
+ * and the following disclaimer in the documentation
+ * and/or other materials provided with the
+ * distribution.
+ * 3. The name of the author may not be used to endorse
+ * or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/* }}} */
+
+#ifndef CYCRIPT_OPTIONS_HPP
+#define CYCRIPT_OPTIONS_HPP
+
+struct CYOptions {
+ bool verbose_;
+
+ CYOptions() :
+ verbose_(false)
+ {
+ }
+};
+
+#endif/*CYCRIPT_OPTIONS_HPP*/
}
const char *CYDeclaration::ForEachIn() const {
- return identifier_->Value();
+ return identifier_->Word();
}
void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const {
}
void CYEmpty::Output(CYOutput &out, CYFlags flags) const {
+ out << '`';
out.Terminate();
}
void CYForIn::Output(CYOutput &out, CYFlags flags) const {
out << "for" << ' ' << '(';
- initialiser_->ForIn(out, CYNoIn);
+ if (initialiser_ != NULL)
+ initialiser_->ForIn(out, CYNoIn);
out << "in" << *set_ << ')';
code_->Single(out, CYRight(flags));
}
if (protect)
out << '(';
out << "function";
+ if (out.options_.verbose_)
+ out.out_ << ':' << static_cast<const CYScope *>(this);
if (name_ != NULL)
out << ' ' << *name_;
out << '(' << parameters_ << ')';
out << ',' << ' ' << *next_;
}
+const char *CYIdentifier::Word() const {
+ return replace_ == NULL || replace_ == this ? CYWord::Word() : replace_->Word();
+}
+
void CYIf::Output(CYOutput &out, CYFlags flags) const {
bool protect(false);
if (false_ == NULL && (flags & CYNoDangle) != 0) {
void CYWord::ClassName(CYOutput &out, bool object) const {
if (object)
out << "objc_getClass(";
- out << '"' << Value() << '"';
+ out << '"' << Word() << '"';
if (object)
out << ')';
}
void CYWord::Output(CYOutput &out) const {
- out << Value();
+ out << Word();
+ if (out.options_.verbose_)
+ out.out_ << '@' << this;
}
void CYWord::PropertyName(CYOutput &out) const {
Output(out);
}
+
+const char *CYWord::Word() const {
+ return word_;
+}
#include <string>
#include <vector>
+#include <map>
+#include <set>
#include <cstdlib>
#include "location.hh"
#include "Pooling.hpp"
+#include "Options.hpp"
+
+class CYContext;
template <typename Type_>
struct CYNext {
struct CYOutput {
std::ostream &out_;
+ CYOptions &options_;
bool pretty_;
unsigned indent_;
bool right_;
Terminated
} mode_;
- CYOutput(std::ostream &out) :
+ CYOutput(std::ostream &out, CYOptions &options) :
out_(out),
+ options_(options),
pretty_(false),
indent_(0),
right_(false),
CYNoBF = (CYNoBrace | CYNoFunction),
};
-struct CYContext {
- apr_pool_t *pool_;
-
- CYContext(apr_pool_t *pool) :
- pool_(pool)
- {
- }
-
- template <typename Type_>
- void Replace(Type_ *&value) {
- if (value != NULL)
- while (Type_ *replace = value->Replace(*this))
- value = replace;
- }
-};
-
struct CYStatement :
CYNext<CYStatement>
{
void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
CYStatement *ReplaceAll(CYContext &context);
+ virtual CYStatement *Collapse(CYContext &context);
virtual CYStatement *Replace(CYContext &context) = 0;
{
}
- const char *Value() const {
- return word_;
+ void Set(const char *value) {
+ word_ = value;
}
+ virtual const char *Word() const;
virtual void Output(CYOutput &out) const;
virtual CYExpression *ClassName(CYContext &context, bool object);
};
_finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) {
- return lhs << rhs.Value();
+ lhs << &rhs << '=';
+ return lhs << rhs.Word();
}
struct CYIdentifier :
CYWord
{
+ CYIdentifier *replace_;
+
CYIdentifier(const char *word) :
- CYWord(word)
+ CYWord(word),
+ replace_(NULL)
{
}
+
+ virtual const char *Word() const;
+ CYIdentifier *Replace(CYContext &context);
};
struct CYComment :
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CStringLess :
+ std::binary_function<const char *, const char *, bool>
+{
+ _finline bool operator ()(const char *lhs, const char *rhs) const {
+ return strcmp(lhs, rhs) < 0;
+ }
+};
+
+struct CYIdentifierValueLess :
+ std::binary_function<CYIdentifier *, CYIdentifier *, bool>
+{
+ _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
+ return CStringLess()(lhs->Word(), rhs->Word());
+ }
+};
+
+enum CYIdentifierFlags {
+ CYIdentifierArgument,
+ CYIdentifierInternal,
+ CYIdentifierVariable
+};
+
+typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
+typedef std::set<CYIdentifier *> CYIdentifierAddressSet;
+typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
+
+struct CYScope {
+ CYScope *parent_;
+ CYIdentifierValueSet identifiers_;
+ CYIdentifierAddressFlagsMap internal_;
+ unsigned offset_;
+
+ CYScope() :
+ parent_(NULL),
+ offset_(0)
+ {
+ }
+
+ void Add(CYContext &context, CYIdentifierAddressSet &external);
+ void Scope(CYContext &context, CYStatement *&statements);
+};
+
struct CYProgram :
+ CYScope,
CYThing
{
CYStatement *statements_;
CYThing
{
CYStatement *statements_;
+ CYScope *scope_;
- CYBlock(CYStatement *statements) :
- statements_(statements)
+ CYBlock(CYStatement *statements, CYScope *scope = NULL) :
+ statements_(statements),
+ scope_(scope)
{
}
return statements_;
}
+ void AddPrev(CYStatement *statement) {
+ CYStatement *last(statement);
+ while (last->next_ != NULL)
+ last = last->next_;
+ last->SetNext(statements_);
+ statements_ = statement;
+ }
+
virtual CYStatement *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
}
virtual void For(CYOutput &out) const = 0;
+ virtual CYExpression *Replace(CYContext &context) = 0;
};
struct CYForInInitialiser {
virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
virtual const char *ForEachIn() const = 0;
virtual CYExpression *ForEachIn(CYContext &out) = 0;
+ virtual CYExpression *Replace(CYContext &context) = 0;
};
struct CYNumber;
{
CYExpression *expressions_;
- CYCompound(CYExpression *expressions) :
+ CYCompound(CYExpression *expressions = NULL) :
expressions_(expressions)
{
}
{
}
+ void Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
}
virtual const char *Name() const {
- return name_->Value();
+ return name_->Word();
}
virtual CYFunctionParameter *Parameter(CYContext &context) const;
}
virtual const char *Name() const {
- return name_->Value();
+ return name_->Word();
}
virtual CYFunctionParameter *Parameter(CYContext &context) const;
}
CYString(const CYWord *word) :
- value_(word->Value()),
+ value_(word->Word()),
size_(strlen(value_))
{
}
virtual const char *ForEachIn() const;
virtual CYExpression *ForEachIn(CYContext &out);
- void Replace(CYContext &context);
+ virtual CYExpression *Replace(CYContext &context);
+ virtual CYAssignment *Assignment(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
struct CYDeclarations :
CYNext<CYDeclarations>,
- CYForInitialiser,
- CYThing
+ CYThing,
+ CYForInitialiser
{
CYDeclaration *declaration_;
virtual void For(CYOutput &out) const;
- void Replace(CYContext &context);
+ virtual CYCompound *Replace(CYContext &context);
CYProperty *Property(CYContext &context);
virtual void Output(CYOutput &out) const;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYFunction {
+struct CYFunction :
+ CYScope
+{
CYIdentifier *name_;
CYFunctionParameter *parameters_;
CYBlock code_;
CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) :
name_(name),
parameters_(parameters),
- code_(statements)
+ code_(statements, this)
{
}
CYExpress(CYExpression *expression) :
expression_(expression)
{
+ if (expression == NULL)
+ throw;
}
+ virtual CYStatement *Collapse(CYContext &context);
virtual CYStatement *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
struct CYEmpty :
CYStatement
{
+ virtual CYStatement *Collapse(CYContext &context);
virtual CYStatement *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
/* }}} */
#include "Parser.hpp"
+#include "Context.hpp"
#include <iomanip>
if (lhs == NULL) {
lhs = lhp->String(context);
if (lhs == NULL)
- return NULL;
+ return this;
} else if (rhs == NULL) {
rhs = rhp->String(context);
if (rhs == NULL)
- return NULL;
+ return this;
}
return lhs->Concat(context, rhs);
if (CYNumber *rhn = rhp->Number(context))
return $D(lhn->Value() + rhn->Value());
- return NULL;
+ return this;
}
CYExpression *CYAddressOf::Replace(CYContext &context) {
CYExpression *CYArray::Replace(CYContext &context) {
elements_->Replace(context);
- return NULL;
+ return this;
}
CYExpression *CYArrayComprehension::Replace(CYContext &context) {
CYExpression *CYAssignment::Replace(CYContext &context) {
context.Replace(lhs_);
context.Replace(rhs_);
- return NULL;
+ return this;
}
CYStatement *CYBlock::Replace(CYContext &context) {
statements_ = statements_->ReplaceAll(context);
- return NULL;
+ if (statements_ == NULL)
+ return $ CYEmpty();
+ return this;
}
CYStatement *CYBreak::Replace(CYContext &context) {
- return NULL;
+ return this;
}
CYExpression *CYCall::Replace(CYContext &context) {
context.Replace(function_);
arguments_->Replace(context);
- return NULL;
+ return this;
}
namespace cy {
}
CYStatement *CYComment::Replace(CYContext &context) {
- return NULL;
+ return this;
}
CYExpression *CYCompound::Replace(CYContext &context) {
expressions_ = expressions_->ReplaceAll(context);
- return NULL;
+ return expressions_ == NULL ? NULL : this;
}
CYFunctionParameter *CYComprehension::Parameters(CYContext &context) const { $T(NULL)
context.Replace(test_);
context.Replace(true_);
context.Replace(false_);
- return NULL;
+ return this;
}
CYStatement *CYContinue::Replace(CYContext &context) {
- return NULL;
+ return this;
+}
+
+CYAssignment *CYDeclaration::Assignment(CYContext &context) {
+ CYExpression *variable(Replace(context));
+ return initialiser_ == NULL ? NULL : $ CYAssign(variable, initialiser_);
}
CYExpression *CYDeclaration::ForEachIn(CYContext &context) {
return $ CYVariable(identifier_);
}
-void CYDeclaration::Replace(CYContext &context) {
- context.Replace(initialiser_);
+CYExpression *CYDeclaration::Replace(CYContext &context) {
+ CYIdentifier *identifier(identifier_->Replace(context));
+ context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, CYIdentifierVariable));
+ return $ CYVariable(identifier);
}
CYProperty *CYDeclarations::Property(CYContext &context) { $T(NULL)
return $ CYProperty(declaration_->identifier_, declaration_->initialiser_ ?: $U, next_->Property(context));
}
-void CYDeclarations::Replace(CYContext &context) { $T()
- declaration_->Replace(context);
- next_->Replace(context);
+CYCompound *CYDeclarations::Replace(CYContext &context) {
+ CYCompound *compound;
+ if (next_ == NULL) compound:
+ compound = $ CYCompound();
+ else {
+ compound = next_->Replace(context);
+ if (compound == NULL)
+ goto compound;
+ }
+
+ if (CYAssignment *assignment = declaration_->Assignment(context))
+ compound->AddPrev(assignment);
+ return compound;
}
CYExpression *CYDirectMember::Replace(CYContext &context) {
Replace_(context);
- return NULL;
+ return this;
}
CYStatement *CYDoWhile::Replace(CYContext &context) {
context.Replace(test_);
context.Replace(code_);
- return NULL;
+ return this;
}
void CYElement::Replace(CYContext &context) { $T()
next_->Replace(context);
}
+CYStatement *CYEmpty::Collapse(CYContext &context) {
+ return next_;
+}
+
CYStatement *CYEmpty::Replace(CYContext &context) {
- return NULL;
+ return this;
+}
+
+CYStatement *CYExpress::Collapse(CYContext &context) {
+ if (CYExpress *express = dynamic_cast<CYExpress *>(next_)) {
+ CYCompound *next(dynamic_cast<CYCompound *>(express->expression_));
+ if (next == NULL)
+ next = $ CYCompound(express->expression_);
+ next->AddPrev(expression_);
+ expression_ = next;
+ SetNext(express->next_);
+ }
+
+ return this;
}
CYStatement *CYExpress::Replace(CYContext &context) {
context.Replace(expression_);
- return NULL;
+ if (expression_ == NULL)
+ return $ CYEmpty();
+ return this;
}
CYExpression *CYExpression::ClassName(CYContext &context, bool object) {
}
CYStatement *CYFor::Replace(CYContext &context) {
- // XXX: initialiser_
+ context.Replace(initialiser_);
context.Replace(test_);
context.Replace(increment_);
context.Replace(code_);
- return NULL;
+ return this;
}
CYStatement *CYForIn::Replace(CYContext &context) {
- // XXX: initialiser_
+ // XXX: this actually might need a prefix statement
+ context.Replace(initialiser_);
context.Replace(set_);
context.Replace(code_);
- return NULL;
+ return this;
}
CYFunctionParameter *CYForInComprehension::Parameter(CYContext &context) const {
}
void CYFunction::Replace_(CYContext &context) {
+ parent_ = context.scope_;
+ context.scope_ = this;
+
+ parameters_->Replace(context);
code_.Replace(context);
+
+ context.scope_ = parent_;
+ Scope(context, code_.statements_);
}
CYExpression *CYFunctionExpression::Replace(CYContext &context) {
Replace_(context);
- return NULL;
+ return this;
+}
+
+void CYFunctionParameter::Replace(CYContext &context) { $T()
+ name_ = name_->Replace(context);
+ context.scope_->internal_.insert(CYIdentifierAddressFlagsMap::value_type(name_, CYIdentifierArgument));
+ next_->Replace(context);
}
CYStatement *CYFunctionStatement::Replace(CYContext &context) {
Replace_(context);
- return NULL;
+ 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;
}
CYStatement *CYIf::Replace(CYContext &context) {
context.Replace(test_);
context.Replace(true_);
context.Replace(false_);
- return NULL;
+ return this;
}
CYFunctionParameter *CYIfComprehension::Parameter(CYContext &context) const {
CYExpression *CYInfix::Replace(CYContext &context) {
context.Replace(lhs_);
context.Replace(rhs_);
- return NULL;
+ return this;
}
CYStatement *CYLabel::Replace(CYContext &context) {
context.Replace(statement_);
- return NULL;
+ return this;
}
CYStatement *CYLet::Replace(CYContext &context) {
CYExpression *CYNew::Replace(CYContext &context) {
context.Replace(constructor_);
arguments_->Replace(context);
- return NULL;
+ return this;
}
CYNumber *CYNull::Number(CYContext &context) {
CYExpression *CYObject::Replace(CYContext &context) {
properties_->Replace(context);
- return NULL;
+ return this;
}
CYExpression *CYPostfix::Replace(CYContext &context) {
context.Replace(lhs_);
- return NULL;
+ return this;
}
CYExpression *CYPrefix::Replace(CYContext &context) {
context.Replace(rhs_);
- return NULL;
+ return this;
}
void CYProgram::Replace(CYContext &context) {
+ parent_ = context.scope_;
+ context.scope_ = this;
statements_ = statements_->ReplaceAll(context);
+ context.scope_ = parent_;
+ Scope(context, statements_);
}
void CYProperty::Replace(CYContext &context) { $T()
CYStatement *CYReturn::Replace(CYContext &context) {
context.Replace(value_);
- return NULL;
+ return this;
+}
+
+void CYScope::Add(CYContext &context, CYIdentifierAddressSet &external) {
+ for (CYIdentifierAddressSet::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;
+
+ if (context.options_.verbose_)
+ std::cout << this << ':';
+
+ CYDeclarations *last(NULL), *curr(NULL);
+
+ 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 (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));
+ var->SetNext(statements);
+ statements = var;
+ }
+
+ if (parent_ != NULL) {
+ if (parent_->offset_ < offset_)
+ parent_->offset_ = offset_;
+ parent_->Add(context, external);
+ }
+}
+
+CYStatement *CYStatement::Collapse(CYContext &context) {
+ return this;
}
CYStatement *CYStatement::ReplaceAll(CYContext &context) { $T(NULL)
CYStatement *replace(this);
context.Replace(replace);
-
- if (CYStatement *next = next_->ReplaceAll(context))
- replace->SetNext(next);
- else
- replace->SetNext(next_);
-
- return replace;
+ replace->SetNext(next_->ReplaceAll(context));
+ return replace->Collapse(context);
}
CYString *CYString::Concat(CYContext &context, CYString *rhs) const {
CYStatement *CYSwitch::Replace(CYContext &context) {
context.Replace(value_);
clauses_->Replace(context);
- return NULL;
+ return this;
}
CYExpression *CYThis::Replace(CYContext &context) {
- return NULL;
+ return this;
}
namespace cy {
CYStatement *Throw::Replace(CYContext &context) {
context.Replace(value_);
- return NULL;
+ return this;
}
} }
CYExpression *CYTrivial::Replace(CYContext &context) {
- return NULL;
+ return this;
}
CYNumber *CYTrue::Number(CYContext &context) {
code_.Replace(context);
catch_->Replace(context);
finally_->Replace(context);
- return NULL;
+ return this;
}
} }
CYStatement *CYVar::Replace(CYContext &context) {
- declarations_->Replace(context);
- return NULL;
+ return $E(declarations_->Replace(context));
}
CYExpression *CYVariable::Replace(CYContext &context) {
- return NULL;
+ name_ = name_->Replace(context);
+ return this;
}
CYStatement *CYWhile::Replace(CYContext &context) {
context.Replace(test_);
context.Replace(code_);
- return NULL;
+ return this;
}
CYStatement *CYWith::Replace(CYContext &context) {
context.Replace(scope_);
context.Replace(code_);
- return NULL;
+ return this;
}
CYExpression *CYWord::ClassName(CYContext &context, bool object) {
arch := $(shell $(dpkg_architecture) -qDEB_HOST_ARCH 2>/dev/null)
endif
-header := Cycript.tab.hh Parser.hpp Pooling.hpp cycript.hpp Internal.hpp Error.hpp String.hpp Exception.hpp Standard.hpp
+header := Cycript.tab.hh Parser.hpp Pooling.hpp cycript.hpp Internal.hpp Error.hpp String.hpp Exception.hpp Standard.hpp Context.hpp
code :=
code += Replace.o Output.o
test: $(deb)
dpkg -i $(deb)
- cycript test.cy
+ if [[ -e target.cy ]]; then cycript -c target.cy && echo; fi
+ if [[ -e jquery.js ]]; then cycript -c jquery.js >jquery.cyc.js; gzip -9c jquery.cyc.js >jquery.cyc.js.gz; ls -la jquery.{cyc,yui}.js{,.gz}; fi
+ if [[ -e test.cy ]]; then cycript test.cy; fi
.PHONY: all clean extra package control
NSArray's .toString() and .toLocaleString() fail hard, as Array.prototype.to*String are Array-specific
(4).toString() is legal, but I'm stripping the ()'s somehow in the serializer
applyOnMainThread, when done at console, loops the cyonifier
+
+!! CYScope has a bunch of STL container objects that are leaking /all/ of their memory