]> git.saurik.com Git - cycript.git/blobdiff - Replace.cpp
Parse scope and symbol colon operators, from Ruby.
[cycript.git] / Replace.cpp
index cab4cddac8f4a7dbc1499a8c0afa8ee3ec576f63..ed486f7d96e6794d08b8dff80fa2c7643e90b459 100644 (file)
@@ -101,18 +101,18 @@ CYArgument *CYArgument::Replace(CYContext &context) { $T(NULL)
 }
 
 CYTarget *CYArray::Replace(CYContext &context) {
-    if (elements_ != NULL)
-        elements_->Replace(context);
+    CYForEach (element, elements_)
+        element->Replace(context);
     return this;
 }
 
 CYTarget *CYArrayComprehension::Replace(CYContext &context) {
-    CYVariable *cyv($V("$cyv"));
+    CYIdentifier *cyv(context.Unique());
 
-    return $C0($F(NULL, $P1($L($I("$cyv")), comprehensions_->Parameters(context)), $$->*
-        $E($ CYAssign(cyv, $ CYArray()))->*
-        comprehensions_->Replace(context, $E($C1($M(cyv, $S("push")), expression_)))->*
-        $ CYReturn(cyv)
+    return $C0($F(NULL, $P1($B(cyv), comprehensions_->Parameters(context)), $$
+        ->* $E($ CYAssign($V(cyv), $ CYArray()))
+        ->* comprehensions_->Replace(context, $E($C1($M($V(cyv), $S("push")), expression_)))
+        ->* $ CYReturn($V(cyv))
     ));
 }
 
@@ -183,13 +183,13 @@ CYTarget *CYClassExpression::Replace(CYContext &context) {
 
     context.super_ = old;
 
-    return $C1($ CYFunctionExpression(NULL, $P($L(super)), $$
-        ->* $ CYVar($L1($L(constructor, tail_->constructor_)))
-        ->* $ CYVar($L1($L(prototype, $ CYFunctionExpression(NULL, NULL, NULL))))
+    return $C1($ CYFunctionExpression(NULL, $P($B(super)), $$
+        ->* $ CYVar($B1($B(constructor, tail_->constructor_)))
+        ->* $ CYVar($B1($B(prototype, $ CYFunctionExpression(NULL, NULL, NULL))))
         ->* $E($ CYAssign($M($V(prototype), $S("prototype")), $M($V(super), $S("prototype"))))
         ->* $E($ CYAssign($V(prototype), $N($V(prototype))))
         ->* CYDefineProperty($V(prototype), $S("constructor"), false, false, $ CYPropertyValue($S("value"), $V(constructor)))
-        ->* $ CYVar(builder.declarations_)
+        ->* $ CYVar(builder.bindings_)
         ->* builder.statements_
         ->* CYDefineProperty($V(constructor), $S("prototype"), false, false, $ CYPropertyValue($S("value"), $V(prototype)))
         ->* $ CYReturn($V(constructor))
@@ -197,11 +197,11 @@ CYTarget *CYClassExpression::Replace(CYContext &context) {
 }
 
 CYStatement *CYClassStatement::Replace(CYContext &context) {
-    return $ CYVar($L1($L(name_, $ CYClassExpression(name_, tail_))));
+    return $ CYVar($B1($B(name_, $ CYClassExpression(name_, tail_))));
 }
 
 void CYClause::Replace(CYContext &context) { $T()
-    context.Replace(case_);
+    context.Replace(value_);
     context.ReplaceAll(code_);
     next_->Replace(context);
 }
@@ -265,20 +265,20 @@ void CYContext::NonLocal(CYStatement *&statements) {
         CYIdentifier *unique(nextlocal_->identifier_->Replace(context, CYIdentifierGlobal));
 
         CYStatement *declare(
-            $ CYVar($L1($L(unique, $ CYObject()))));
+            $ CYVar($B1($B(unique, $ CYObject()))));
 
         cy::Syntax::Catch *rescue(
-            $ cy::Syntax::Catch(cye, $$->*
-                $ CYIf($ CYIdentical($M($V(cye), $S("$cyk")), $V(unique)), $$->*
-                    $ CYReturn($M($V(cye), $S("$cyv"))))->*
-                $ cy::Syntax::Throw($V(cye))));
+            $ cy::Syntax::Catch(cye, $$
+                ->* $ CYIf($ CYIdentical($M($V(cye), $S("$cyk")), $V(unique)), $$
+                    ->* $ CYReturn($M($V(cye), $S("$cyv"))))
+                ->* $ cy::Syntax::Throw($V(cye))));
 
         context.Replace(declare);
         rescue->Replace(context);
 
-        statements = $$->*
-            declare->*
-            $ cy::Syntax::Try(statements, rescue, NULL);
+        statements = $$
+            ->* declare
+            ->* $ cy::Syntax::Try(statements, rescue, NULL);
     }
 }
 
@@ -294,23 +294,23 @@ CYStatement *CYDebugger::Replace(CYContext &context) {
     return this;
 }
 
-CYTarget *CYDeclaration::Target(CYContext &context) {
+CYTarget *CYBinding::Target(CYContext &context) {
     return $V(identifier_);
 }
 
-CYAssignment *CYDeclaration::Replace(CYContext &context, CYIdentifierKind kind) {
+CYAssignment *CYBinding::Replace(CYContext &context, CYIdentifierKind kind) {
     identifier_ = identifier_->Replace(context, kind);
 
-    if (initialiser_ == NULL)
+    if (initializer_ == NULL)
         return NULL;
 
-    CYAssignment *value($ CYAssign(Target(context), initialiser_));
-    initialiser_ = NULL;
+    CYAssignment *value($ CYAssign(Target(context), initializer_));
+    initializer_ = NULL;
     return value;
 }
 
-CYExpression *CYDeclarations::Replace(CYContext &context, CYIdentifierKind kind) { $T(NULL)
-    CYAssignment *assignment(declaration_->Replace(context, kind));
+CYExpression *CYBindings::Replace(CYContext &context, CYIdentifierKind kind) { $T(NULL)
+    CYAssignment *assignment(binding_->Replace(context, kind));
     CYExpression *compound(next_->Replace(context, kind));
 
     if (assignment != NULL)
@@ -321,12 +321,12 @@ CYExpression *CYDeclarations::Replace(CYContext &context, CYIdentifierKind kind)
     return compound;
 }
 
-CYFunctionParameter *CYDeclarations::Parameter(CYContext &context) { $T(NULL)
-    return $ CYFunctionParameter($ CYDeclaration(declaration_->identifier_), next_->Parameter(context));
+CYFunctionParameter *CYBindings::Parameter(CYContext &context) { $T(NULL)
+    return $ CYFunctionParameter($ CYBinding(binding_->identifier_), next_->Parameter(context));
 }
 
-CYArgument *CYDeclarations::Argument(CYContext &context) { $T(NULL)
-    return $ CYArgument(declaration_->initialiser_, next_->Argument(context));
+CYArgument *CYBindings::Argument(CYContext &context) { $T(NULL)
+    return $ CYArgument(binding_->initializer_, next_->Argument(context));
 }
 
 CYTarget *CYDirectMember::Replace(CYContext &context) {
@@ -347,8 +347,6 @@ void CYElementSpread::Replace(CYContext &context) {
 
 void CYElementValue::Replace(CYContext &context) {
     context.Replace(value_);
-    if (next_ != NULL)
-        next_->Replace(context);
 }
 
 CYForInitializer *CYEmpty::Replace(CYContext &context) {
@@ -409,7 +407,7 @@ void CYFinally::Replace(CYContext &context) { $T()
 
 CYStatement *CYFor::Replace(CYContext &context) {
     CYScope outer(true, context);
-    context.Replace(initialiser_);
+    context.Replace(initializer_);
 
     context.Replace(test_);
 
@@ -427,77 +425,83 @@ CYStatement *CYFor::Replace(CYContext &context) {
 
 CYStatement *CYForLexical::Initialize(CYContext &context, CYExpression *value) {
     if (value == NULL) {
-        if (declaration_->initialiser_ == NULL)
+        if (binding_->initializer_ == NULL)
             return NULL;
-        value = declaration_->initialiser_;
+        value = binding_->initializer_;
     }
 
-    return $ CYLet(constant_, $L1($ CYDeclaration(declaration_->identifier_, value)));
+    return $ CYLexical(constant_, $B1($ CYBinding(binding_->identifier_, value)));
 }
 
 CYTarget *CYForLexical::Replace(CYContext &context) {
-    _assert(declaration_->Replace(context, CYIdentifierLexical) == NULL);
-    return declaration_->Target(context);
+    _assert(binding_->Replace(context, CYIdentifierLexical) == NULL);
+    return binding_->Target(context);
 }
 
 CYStatement *CYForIn::Replace(CYContext &context) {
     CYScope scope(true, context);
-    context.Replace(initialiser_);
-    context.Replace(set_);
+    context.Replace(initializer_);
+    context.Replace(iterable_);
     context.ReplaceAll(code_);
     scope.Close(context);
     return this;
 }
 
+CYStatement *CYForInitialized::Replace(CYContext &context) {
+    CYAssignment *assignment(binding_->Replace(context, CYIdentifierVariable));
+    return $ CYBlock($$
+        ->* (assignment == NULL ? NULL : $ CYExpress(assignment))
+        ->* $ CYForIn(binding_->Target(context), iterable_, code_));
+}
+
 CYFunctionParameter *CYForInComprehension::Parameter(CYContext &context) const {
-    return $ CYFunctionParameter(declaration_);
+    return $ CYFunctionParameter(binding_);
 }
 
 CYStatement *CYForInComprehension::Replace(CYContext &context, CYStatement *statement) const {
-    return $ CYForIn(declaration_->Target(context), set_, CYComprehension::Replace(context, statement));
+    return $ CYForIn(binding_->Target(context), iterable_, CYComprehension::Replace(context, statement));
 }
 
 CYStatement *CYForOf::Replace(CYContext &context) {
     CYIdentifier *item(context.Unique()), *list(context.Unique());
 
     return $ CYBlock($$
-        ->* initialiser_->Initialize(context, NULL)
-        ->* $ CYLet(false, $L2($L(list, set_), $L(item)))
+        ->* initializer_->Initialize(context, NULL)
+        ->* $ CYLexical(false, $B2($B(list, iterable_), $B(item)))
         ->* $ CYForIn($V(item), $V(list), $ CYBlock($$
-            ->* initialiser_->Initialize(context, $M($V(list), $V(item)))
+            ->* initializer_->Initialize(context, $M($V(list), $V(item)))
             ->* code_
     )));
 }
 
 CYFunctionParameter *CYForOfComprehension::Parameter(CYContext &context) const {
-    return $ CYFunctionParameter(declaration_);
+    return $ CYFunctionParameter(binding_);
 }
 
 CYStatement *CYForOfComprehension::Replace(CYContext &context, CYStatement *statement) const {
-    CYIdentifier *cys($I("$cys"));
-
-    return $E($C0($F(NULL, $P1($L($I("$cys"))), $$->*
-        $E($ CYAssign($V(cys), set_))->*
-        $ CYForIn(declaration_->Target(context), $V(cys), $ CYBlock($$->*
-            $E($ CYAssign(declaration_->Target(context), $M($V(cys), declaration_->Target(context))))->*
-            CYComprehension::Replace(context, statement)
-        ))
+    CYIdentifier *cys(context.Unique());
+
+    return $ CYBlock($$
+        ->* $ CYLexical(false, $B1($B(cys, iterable_)))
+        ->* $ CYForIn(binding_->Target(context), $V(cys), $ CYBlock($$
+            ->* $E($ CYAssign(binding_->Target(context), $M($V(cys), binding_->Target(context))))
+            ->* CYComprehension::Replace(context, statement)
     )));
 }
 
 CYStatement *CYForVariable::Initialize(CYContext &context, CYExpression *value) {
     if (value == NULL) {
-        if (declaration_->initialiser_ == NULL)
+        if (binding_->initializer_ == NULL)
             return NULL;
-        value = declaration_->initialiser_;
+        value = binding_->initializer_;
     }
 
-    return $ CYVar($L1($ CYDeclaration(declaration_->identifier_, value)));
+    return $ CYVar($B1($ CYBinding(binding_->identifier_, value)));
 }
 
 CYTarget *CYForVariable::Replace(CYContext &context) {
-    _assert(declaration_->Replace(context, CYIdentifierVariable) == NULL);
-    return declaration_->Target(context);
+    _assert(binding_->Replace(context, CYIdentifierVariable) == NULL);
+    return binding_->Target(context);
 }
 
 // XXX: this is evil evil black magic. don't ask, don't tell... don't believe!
@@ -527,6 +531,8 @@ void CYFunction::Replace(CYContext &context) {
 
     CYScope scope(!localize, context);
 
+    $I("arguments")->Replace(context, CYIdentifierMagic);
+
     parameters_->Replace(context, code_);
 
     context.ReplaceAll(code_);
@@ -537,9 +543,8 @@ void CYFunction::Replace(CYContext &context) {
     if (CYIdentifier *identifier = this_.identifier_) {
         context.scope_->Declare(context, identifier, CYIdentifierVariable);
         code_ = $$
-            ->*$E($ CYAssign($V(identifier), $ CYThis()))
-            ->*code_
-        ;
+            ->* $E($ CYAssign($V(identifier), $ CYThis()))
+            ->* code_;
     }
 
     if (localize)
@@ -565,16 +570,15 @@ CYTarget *CYFunctionExpression::Replace(CYContext &context) {
 }
 
 void CYFunctionParameter::Replace(CYContext &context, CYStatement *&statements) { $T()
-    CYAssignment *assignment(initialiser_->Replace(context, CYIdentifierArgument));
+    CYAssignment *assignment(binding_->Replace(context, CYIdentifierArgument));
 
     next_->Replace(context, statements);
 
     if (assignment != NULL)
-        statements = $$->*
-            $ CYIf($ CYIdentical($ CYTypeOf(initialiser_->Target(context)), $S("undefined")), $$->*
-                $E(assignment)
-            )->*
-            statements;
+        statements = $$
+            ->* $ CYIf($ CYIdentical($ CYTypeOf(binding_->Target(context)), $S("undefined")), $$
+                ->* $E(assignment))
+            ->* statements;
 }
 
 CYStatement *CYFunctionStatement::Replace(CYContext &context) {
@@ -614,7 +618,28 @@ CYStatement *CYIfComprehension::Replace(CYContext &context, CYStatement *stateme
 }
 
 CYStatement *CYImport::Replace(CYContext &context) {
-    return $ CYVar($L1($L($I(module_->part_->Word()), $C1($V("require"), module_->Replace(context, "/")))));
+    return $ CYVar($B1($B($I(module_->part_->Word()), $C1($V("require"), module_->Replace(context, "/")))));
+}
+
+CYStatement *CYImportDeclaration::Replace(CYContext &context) {
+    CYIdentifier *module(context.Unique());
+
+    CYList<CYStatement> statements;
+    CYForEach (specifier, specifiers_)
+        statements->*specifier->Replace(context, module);
+
+    return $ CYBlock($$
+        ->* $ CYLexical(false, $B1($B(module, $C1($V("require"), module_))))
+        ->* statements);
+}
+
+CYStatement *CYImportSpecifier::Replace(CYContext &context, CYIdentifier *module) {
+    binding_ = binding_->Replace(context, CYIdentifierLexical);
+
+    CYExpression *import($V(module));
+    if (name_ != NULL)
+        import = $M(import, $S(name_));
+    return $E($ CYAssign($V(binding_), import));
 }
 
 CYTarget *CYIndirect::Replace(CYContext &context) {
@@ -640,8 +665,8 @@ CYTarget *CYLambda::Replace(CYContext &context) {
     return $N2($V("Functor"), $ CYFunctionExpression(NULL, parameters_->Parameters(context), code_), parameters_->TypeSignature(context, typed_->Replace(context)));
 }
 
-CYForInitializer *CYLet::Replace(CYContext &context) {
-    if (CYExpression *expression = declarations_->Replace(context, CYIdentifierLexical))
+CYForInitializer *CYLexical::Replace(CYContext &context) {
+    if (CYExpression *expression = bindings_->Replace(context, CYIdentifierLexical))
         return $E(expression);
     return $ CYEmpty();
 }
@@ -713,10 +738,10 @@ CYTarget *CYObject::Replace(CYContext &context) {
         properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), false);
 
     if (builder) {
-        return $C1($M($ CYFunctionExpression(NULL, builder.declarations_->Parameter(context),
-            builder.statements_->*
-                $ CYReturn($ CYThis())
-        ), $S("call")), this, builder.declarations_->Argument(context));
+        return $C1($M($ CYFunctionExpression(NULL, builder.bindings_->Parameter(context),
+            builder.statements_
+                ->* $ CYReturn($ CYThis())
+        ), $S("call")), this, builder.bindings_->Argument(context));
     }
 
     CYForEach (property, properties_)
@@ -741,7 +766,7 @@ CYExpression *CYPrefix::Replace(CYContext &context) {
 }
 
 CYProperty *CYProperty::ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update) {
-    update |= name_->Computed();
+    update |= Update();
     if (update)
         Replace(context, builder, self, false);
     if (next_ != NULL)
@@ -753,17 +778,22 @@ void CYProperty::Replace(CYContext &context, CYBuilder &builder, CYExpression *s
     CYExpression *name(name_->PropertyName(context));
     if (name_->Computed()) {
         CYIdentifier *unique(context.Unique());
-        builder.declarations_->*$L1($L(unique, name));
+        builder.bindings_
+            ->* $B1($B(unique, name));
         name = $V(unique);
     }
 
     Replace(context, builder, self, name, protect);
 }
 
+bool CYProperty::Update() const {
+    return name_->Computed();
+}
+
 void CYPropertyGetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
     CYIdentifier *unique(context.Unique());
-    builder.declarations_
-        ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
+    builder.bindings_
+        ->* $B1($B(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
     builder.statements_
         ->* CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("get"), $V(unique)));
 }
@@ -774,17 +804,21 @@ CYFunctionExpression *CYPropertyMethod::Constructor() {
 
 void CYPropertyMethod::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
     CYIdentifier *unique(context.Unique());
-    builder.declarations_
-        ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
+    builder.bindings_
+        ->* $B1($B(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
     builder.statements_
         ->* (!protect ? $E($ CYAssign($M(self, name), $V(unique))) :
             CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("value"), $V(unique), $ CYPropertyValue($S("writable"), $ CYTrue()))));
 }
 
+bool CYPropertyMethod::Update() const {
+    return true;
+}
+
 void CYPropertySetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
     CYIdentifier *unique(context.Unique());
-    builder.declarations_
-        ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
+    builder.bindings_
+        ->* $B1($B(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
     builder.statements_
         ->* CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("set"), $V(unique)));
 }
@@ -792,8 +826,8 @@ void CYPropertySetter::Replace(CYContext &context, CYBuilder &builder, CYExpress
 void CYPropertyValue::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
     _assert(!protect);
     CYIdentifier *unique(context.Unique());
-    builder.declarations_
-        ->* $L1($L(unique, value_));
+    builder.bindings_
+        ->* $B1($B(unique, value_));
     builder.statements_
         ->* $E($ CYAssign($M(self, name), $V(unique)));
 }
@@ -844,6 +878,10 @@ void CYScript::Replace(CYContext &context) {
     }
 }
 
+CYTarget *CYResolveMember::Replace(CYContext &context) {
+    return $M($M(object_, $S("$cyr")), property_);
+}
+
 CYStatement *CYReturn::Replace(CYContext &context) {
     if (context.nonlocal_ != NULL) {
         CYProperty *value(value_ == NULL ? NULL : $ CYPropertyValue($S("$cyv"), value_));
@@ -909,19 +947,9 @@ CYIdentifierFlags *CYScope::Declare(CYContext &context, CYIdentifier *identifier
     if (existing == NULL)
         return internal_;
 
-    switch (kind) {
-        case CYIdentifierArgument:
-        case CYIdentifierCatch:
-        case CYIdentifierMagic:
-            _assert(false);
-        default:
-            break;
-    }
-
-    if (existing->kind_ == CYIdentifierGlobal)
+    if (kind == CYIdentifierGlobal);
+    else if (existing->kind_ == CYIdentifierGlobal || existing->kind_ == CYIdentifierMagic)
         existing->kind_ = kind;
-    else if (kind == CYIdentifierGlobal)
-        ;
     else if (existing->kind_ == CYIdentifierLexical || kind == CYIdentifierLexical)
         _assert(false); // XXX: throw new SyntaxError()
 
@@ -941,14 +969,15 @@ void CYScope::Merge(CYContext &context, const CYIdentifierFlags *flags) {
 void CYScope::Close(CYContext &context, CYStatement *&statements) {
     Close(context);
 
-    CYList<CYDeclarations> declarations;
+    CYList<CYBindings> bindings;
 
     CYForEach (i, internal_)
         if (i->kind_ == CYIdentifierVariable)
-            declarations ->* $ CYDeclarations($ CYDeclaration(i->identifier_));
+            bindings
+                ->* $ CYBindings($ CYBinding(i->identifier_));
 
-    if (declarations) {
-        CYVar *var($ CYVar(declarations));
+    if (bindings) {
+        CYVar *var($ CYVar(bindings));
         var->SetNext(statements);
         statements = var;
     }
@@ -1063,6 +1092,32 @@ CYString *CYString::String(CYContext &context) {
     return this;
 }
 
+CYStatement *CYStructDefinition::Replace(CYContext &context) {
+    CYTarget *target(tail_->Replace(context));
+    if (name_ != NULL)
+        target = $C1($M(target, $S("withName")), $S(name_->Word()));
+    return $ CYLexical(false, $B1($B($I($pool.strcat(name_->Word(), "$cy", NULL)), target)));
+}
+
+CYTarget *CYStructTail::Replace(CYContext &context) {
+    CYList<CYElementValue> types;
+    CYList<CYElementValue> names;
+
+    CYForEach (field, fields_) {
+        CYTypedIdentifier *typed(field->typed_);
+        types->*$ CYElementValue(typed->Replace(context));
+
+        CYExpression *name;
+        if (typed->identifier_ == NULL)
+            name = NULL;
+        else
+            name = $S(typed->identifier_->Word());
+        names->*$ CYElementValue(name);
+    }
+
+    return $N2($V("Type"), $ CYArray(types), $ CYArray(names));
+}
+
 CYTarget *CYSuperAccess::Replace(CYContext &context) {
     return $C1($M($M($M($V(context.super_), $S("prototype")), property_), $S("bind")), $ CYThis());
 }
@@ -1071,6 +1126,10 @@ CYTarget *CYSuperCall::Replace(CYContext &context) {
     return $C($C1($M($V(context.super_), $S("bind")), $ CYThis()), arguments_);
 }
 
+CYTarget *CYSymbol::Replace(CYContext &context) {
+    return $C1($M($V("Symbol"), $S("for")), $S(name_));
+}
+
 CYStatement *CYSwitch::Replace(CYContext &context) {
     context.Replace(value_);
     clauses_->Replace(context);
@@ -1138,12 +1197,23 @@ CYTarget *CYTypeBlockWith::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("blockWith")), parameters_->Argument(context)));
 }
 
+CYTarget *CYTypeCharacter::Replace(CYContext &context) {
+    switch (signing_) {
+        case CYTypeNeutral: return $V("char");
+        case CYTypeSigned: return $V("schar");
+        case CYTypeUnsigned: return $V("uchar");
+        default: _assert(false);
+    }
+}
+
 CYTarget *CYTypeConstant::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("constant"))));
 }
 
 CYStatement *CYTypeDefinition::Replace(CYContext &context) {
-    return $E($ CYAssign($V(typed_->identifier_), typed_->Replace(context)));
+    CYIdentifier *identifier(typed_->identifier_);
+    typed_->identifier_ = NULL;
+    return $ CYLexical(false, $B1($B(identifier, $ CYTypeExpression(typed_))));
 }
 
 CYTarget *CYTypeError::Replace(CYContext &context) {
@@ -1151,32 +1221,45 @@ CYTarget *CYTypeError::Replace(CYContext &context) {
     return NULL;
 }
 
+CYTarget *CYTypeExpression::Replace(CYContext &context) {
+    return typed_->Replace(context);
+}
+
+CYTarget *CYTypeIntegral::Replace(CYContext &context) {
+    bool u(signing_ == CYTypeUnsigned);
+    switch (length_) {
+        case 0: return $V(u ? "ushort" : "short");
+        case 1: return $V(u ? "uint" : "int");
+        case 2: return $V(u ? "ulong" : "long");
+        case 3: return $V(u ? "ulonglong" : "longlong");
+        default: _assert(false);
+    }
+}
+
 CYTarget *CYTypeModifier::Replace(CYContext &context, CYTarget *type) { $T(type)
     return Replace_(context, type);
 }
 
 CYTarget *CYTypeFunctionWith::Replace_(CYContext &context, CYTarget *type) {
-    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), parameters_->Argument(context)));
-}
-
-CYTarget *CYTypeLong::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("long")));
+    CYList<CYArgument> arguments(parameters_->Argument(context));
+    if (variadic_)
+        arguments->*$C_($ CYNull());
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), arguments));
 }
 
 CYTarget *CYTypePointerTo::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("pointerTo"))));
 }
 
-CYTarget *CYTypeShort::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("short")));
+CYTarget *CYTypeReference::Replace(CYContext &context) {
+    return $V($pool.strcat(name_->Word(), "$cy", NULL));
 }
 
-CYTarget *CYTypeSigned::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("signed")));
-}
-
-CYTarget *CYTypeUnsigned::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("unsigned")));
+CYTarget *CYTypeStruct::Replace(CYContext &context) {
+    CYTarget *target(tail_->Replace(context));
+    if (name_ != NULL)
+        target = $C1($M(target, $S("withName")), $S(name_->Word()));
+    return target;
 }
 
 CYTarget *CYTypeVariable::Replace(CYContext &context) {
@@ -1196,15 +1279,15 @@ CYTarget *CYTypedIdentifier::Replace(CYContext &context) {
 }
 
 CYTypeFunctionWith *CYTypedIdentifier::Function() {
-    CYTypeModifier **modifier(&modifier_);
-    if (*modifier == NULL)
+    CYTypeModifier *&modifier(CYGetLast(modifier_));
+    if (modifier == NULL)
         return NULL;
-    while ((*modifier)->next_ != NULL)
-        modifier = &(*modifier)->next_;
-    CYTypeFunctionWith *function((*modifier)->Function());
+
+    CYTypeFunctionWith *function(modifier->Function());
     if (function == NULL)
         return NULL;
-    *modifier = NULL;
+
+    modifier = NULL;
     return function;
 }
 
@@ -1213,7 +1296,7 @@ CYArgument *CYTypedParameter::Argument(CYContext &context) { $T(NULL)
 }
 
 CYFunctionParameter *CYTypedParameter::Parameters(CYContext &context) { $T(NULL)
-    return $ CYFunctionParameter($ CYDeclaration(typed_->identifier_ ?: context.Unique()), next_->Parameters(context));
+    return $ CYFunctionParameter($ CYBinding(typed_->identifier_ ?: context.Unique()), next_->Parameters(context));
 }
 
 CYExpression *CYTypedParameter::TypeSignature(CYContext &context, CYExpression *prefix) { $T(prefix)
@@ -1221,7 +1304,7 @@ CYExpression *CYTypedParameter::TypeSignature(CYContext &context, CYExpression *
 }
 
 CYForInitializer *CYVar::Replace(CYContext &context) {
-    if (CYExpression *expression = declarations_->Replace(context, CYIdentifierVariable))
+    if (CYExpression *expression = bindings_->Replace(context, CYIdentifierVariable))
         return $E(expression);
     return $ CYEmpty();
 }
@@ -1232,7 +1315,7 @@ CYTarget *CYVariable::Replace(CYContext &context) {
 }
 
 CYFunctionParameter *CYVariable::Parameter() const {
-    return $ CYFunctionParameter($ CYDeclaration(name_));
+    return $ CYFunctionParameter($ CYBinding(name_));
 }
 
 CYStatement *CYWhile::Replace(CYContext &context) {
@@ -1243,7 +1326,10 @@ CYStatement *CYWhile::Replace(CYContext &context) {
 
 CYStatement *CYWith::Replace(CYContext &context) {
     context.Replace(scope_);
+    CYScope scope(true, context);
+    scope.Damage();
     context.ReplaceAll(code_);
+    scope.Close(context);
     return this;
 }