Current grammar:
```ebnf
component-def ::= 'component' id '{' component-def-items* '}' .
component-def-items ::= import | let-stmt | export .
import ::= interface-import | component-import | func-import .
interface-import ::= 'interface' use-path 'as' id .
component-import ::= 'component' package-id 'as' id .
func-import ::= 'func' id param-list result-list .
export ::= 'export' path ('as' use-path)? .
let-stmt ::= 'let' id '=' expression .
expression ::= instantiation | path .
instantiation ::= 'new' id arguments? .
arguments ::= '{' argument (',' argument)* ','? '}' .
argument ::= (id '=')? expression .
path ::= id ('[' use-path ']')* .
id-or-interface ::= id | interface .
package-id ::= id ':' id ('@' valid-semver)? .
param-list ::= /* from CM */
result-list ::= /* from CM */
use-path ::= /* from CM, e.g.: foo-bar OR foo:bar/baz@0.1.0 */ .
interface ::= /* from CM, e.g.: foo:bar/baz@0.1.0 */ .
id ::= /* from CM, e.g.: foo-bar */ .
```
Old grammar:
```ebnf
component-def ::= 'component' id '{' component-def-items* '}' .
component-def-items ::= import | let-stmt | export .
import ::= id `:` interface-import | component-import .
interface-import ::= /* from CM, i.e.: world-import-item */ .
component-import ::= 'use' package-id 'as' id? .
export ::= 'export' path ('as' use-path)? .
let-stmt ::= 'let' id '=' expression .
expression ::= instantiation | path .
instantiation ::= 'new' id arguments? .
arguments ::= '{' argument (',' argument)* ','? '}' .
argument ::= (id '=')? expression .
path ::= id ('[' use-path ']')* .
id-or-interface ::= id | interface .
package-id ::= id ':' id ('@' valid-semver)? .
use-path ::= /* from CM, e.g.: foo-bar OR foo:bar/baz@0.1.0 */ .
interface ::= /* from CM, e.g.: foo:bar/baz@0.1.0 */ .
id ::= /* from CM, e.g.: foo-bar */ .
```
Random motivating scratch:
```
interface bar {
record baz {}
buz: func(b: baz)
}
interface buz {
use bar.{baz}
}
world foo {
import buz
}
component foo {
import component test:foo as foo
import interface bar as bar1
import type foo = resource { bar: func() } // possible future ext.
import func foo(b: baz)
let baz = bar1[baz]
// import bar: interface { ... }
import buz: bar:baz/buz@0.1.0
// potential alternative: import bar:baz/buz@0.1.0 as buz
// potential alternative: let buz = import bar:baz/buz@0.1.0
// something to indicate `buz` is a local name, not an import name
use test:wow as wow
let y = bar[buz][foo]
let x = wow{buz}
}
```
```
interface bar {
record baz {}
buz: func(b: baz)
}
interface buz {
use bar.{baz}
}
world foo {
import buz
}
// Alternate syntax for expression the top-level component: leaving
// off the identifier to implicitly target the top-level
component {
import component test:foo as foo
import interface bar as bar1
import type foo = resource { bar: func() } // possible future ext.
import func foo(b: baz)
let baz = bar1[baz]
// import bar: interface { ... }
import buz: bar:baz/buz@0.1.0
// potential alternative: import bar:baz/buz@0.1.0 as buz
// potential alternative: let buz = import bar:baz/buz@0.1.0
// something to indicate `buz` is a local name, not an import name
use test:wow as wow
let y = bar[buz][foo]
let x = wow{buz}
}
// Another possibility, using a single top-level expression to express
// a component
let {
import component test:foo as foo
import interface bar as bar1
import type foo = resource { bar: func() } // possible future ext.
import func foo(b: baz)
baz = bar1[baz]
// ...
} in export {
y, x
}
```