%union { CYForInInitializer *forin_; }
 %union { CYFunctionParameter *functionParameter_; }
 %union { CYIdentifier *identifier_; }
+%union { CYImportSpecifier *import_; }
 %union { CYInfix *infix_; }
 %union { CYLiteral *literal_; }
 %union { CYMethod *method_; }
 %token _null_ "null"
 %token _true_ "true"
 
+%token _as_ "as"
 %token _break_ "break"
 %token _case_ "case"
 %token _catch_ "catch"
 %type <functionParameter_> FormalParameterList_
 %type <functionParameter_> FormalParameterList
 %type <functionParameter_> FormalParameters
+%type <string_> FromClause
 %type <statement_> FunctionBody
 %type <statement_> FunctionDeclaration
 %type <target_> FunctionExpression
 %type <word_> IdentifierName
 %type <variable_> IdentifierReference
 %type <statement_> IfStatement
+%type <import_> ImportClause
+%type <statement_> ImportDeclaration
+%type <import_> ImportSpecifier
+%type <identifier_> ImportedBinding
+%type <import_> ImportedDefaultBinding
+%type <import_> ImportsList_
+%type <import_> ImportsList
+%type <import_> ImportsListOpt
 %type <target_> IndirectExpression
 %type <expression_> Initializer
 %type <expression_> InitializerOpt
 %type <access_> MemberAccess
 %type <target_> MemberExpression
 %type <method_> MethodDefinition
+%type <statement_> ModuleBody
+%type <statement_> ModuleBodyOpt
+%type <statement_> ModuleItem
+%type <statement_> ModuleItemList
+%type <statement_> ModuleItemListOpt
 %type <module_> ModulePath
+%type <string_> ModuleSpecifier
 %type <expression_> MultiplicativeExpression
+%type <import_> NameSpaceImport
+%type <import_> NamedImports
 %type <target_> NewExpression
 %type <null_> NullLiteral
 %type <literal_> ObjectLiteral
 IdentifierTypeNoOf
     : Identifier_[pass] { $$ = $pass; }
     | "abstract" { $$ = CYNew CYIdentifier("abstract"); }
+    | "as" { $$ = CYNew CYIdentifier("as"); }
     | "await" { $$ = CYNew CYIdentifier("await"); }
     | "boolean" { $$ = CYNew CYIdentifier("boolean"); }
     | "byte" { $$ = CYNew CYIdentifier("byte"); }
 /* }}} */
 /* 15.2 Modules {{{ */
 Module
-    : ModuleBodyOpt
+    : ModuleBodyOpt[code] { driver.script_ = CYNew CYScript($code); }
     ;
 
 ModuleBody
-    : ModuleItemList
+    : ModuleItemList[pass] { $$ = $pass; }
     ;
 
 ModuleBodyOpt
-    : ModuleBody
-    |
+    : ModuleBody[pass] { $$ = $pass; }
+    | LexSetStatement LexLet LexOf { $$ = NULL; }
     ;
 
 ModuleItemList
-    : ModuleItemListOpt ModuleItem
+    : ModuleItem[statement] ModuleItemListOpt[next] { $$ = $statement; CYSetLast($$) = $next; }
     ;
 
 ModuleItemListOpt
-    : ModuleItemList
-    |
+    : ModuleItemList[pass] { $$ = $pass; }
+    | LexSetStatement LexLet LexOf { $$ = NULL; }
     ;
 
 ModuleItem
-    : LexSetStatement LexLet LexOf ImportDeclaration
-    | LexSetStatement LexLet LexOf ExportDeclaration
-    | StatementListItem
+    : LexSetStatement LexLet LexOf ImportDeclaration[pass] { $$ = $pass; }
+    | LexSetStatement LexLet LexOf ExportDeclaration { CYNOT(@$); }
+    | StatementListItem[pass] { $$ = $pass; }
     ;
 /* }}} */
 /* 15.2.2 Imports {{{ */
 ImportDeclaration
-    : "import" ImportClause FromClause Terminator
-    | "import" LexOf ModuleSpecifier Terminator
+    : "import" ImportClause[specifiers] FromClause[module] Terminator { $$ = CYNew CYImportDeclaration($specifiers, $module); }
+    | "import" LexOf ModuleSpecifier[module] Terminator { $$ = CYNew CYImportDeclaration(NULL, $module); }
     ;
 
 ImportClause
-    : ImportedDefaultBinding
-    | LexOf NameSpaceImport
-    | LexOf NamedImports
-    | ImportedDefaultBinding "," NameSpaceImport
-    | ImportedDefaultBinding "," NamedImports
+    : ImportedDefaultBinding[default] { $$ = $default; }
+    | LexOf NameSpaceImport[pass] { $$ = $pass; }
+    | LexOf NamedImports[pass] { $$ = $pass; }
+    | ImportedDefaultBinding[default] "," NameSpaceImport[next] { $$ = $default; CYSetLast($$) = $next; }
+    | ImportedDefaultBinding[default] "," NamedImports[next] { $$ = $default; CYSetLast($$) = $next; }
     ;
 
 ImportedDefaultBinding
-    : ImportedBinding
+    : ImportedBinding[binding] { $$ = CYNew CYImportSpecifier(CYNew CYIdentifier("default"), $binding); }
     ;
 
 NameSpaceImport
-    : "*" "as" ImportedBinding
+    : "*" "as" ImportedBinding[binding] { $$ = CYNew CYImportSpecifier(NULL, $binding); }
     ;
 
 NamedImports
-    : "{" ImportsListOpt "}"
+    : "{" ImportsListOpt[pass] "}" { $$ = $pass; }
     ;
 
 FromClause
-    : "from" ModuleSpecifier
+    : "from" ModuleSpecifier[pass] { $$ = $pass; }
     ;
 
 ImportsList_
-    : "," ImportsListOpt
-    |
+    : "," ImportsListOpt[pass] { $$ = $pass; }
+    | { $$ = NULL; }
     ;
 
 ImportsList
-    : ImportSpecifier ImportsList_
+    : ImportSpecifier[import] ImportsList_[next] { $$ = $import; CYSetLast($$) = $next; }
     ;
 
 ImportsListOpt
-    : ImportsList
-    | LexOf
+    : ImportsList[pass] { $$ = $pass; }
+    | LexOf { $$ = NULL; }
     ;
 
 ImportSpecifier
-    : ImportedBinding
-    | LexOf IdentifierName "as" ImportedBinding
+    : ImportedBinding[binding] { $$ = CYNew CYImportSpecifier($binding, $binding); }
+    | LexOf IdentifierName[name] "as" ImportedBinding[binding] { $$ = CYNew CYImportSpecifier($name, $binding); }
     ;
 
 ModuleSpecifier
-    : StringLiteral
+    : StringLiteral[pass] { $$ = $pass; }
     ;
 
 ImportedBinding
-    : BindingIdentifier
+    : BindingIdentifier[pass] { $$ = $pass; }
     ;
 /* }}} */
 /* 15.2.3 Exports {{{ */
 
     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) {
     return $M(rhs_, $S("$cyi"));
 }