   else
     compiled
 
-importAny = (defaultImports) ->
-  concat (for name, names of values defaultImports
-    imports name, names)
-
-exportAll = (ctx, definitions) ->
-  shouldBeExported = (name, declaration) ->
-    not declaration.virtual and declaration.final
-  nonVirtual = filterMap shouldBeExported, ctx._scope()
-  exported = subtractSets nonVirtual, builtInDefinitions()
-  exportList = map validIdentifier, (setToArray exported)
-  (iife (concat [
-    toJsString 'use strict'
-    definitions
-    [(jsReturn (jsDictionary exportList, exportList))]]))
-
 ms = {}
 
-
-# module+ (syntax [..args]
-#   (` export (module ,..args)))
 ms['module+'] = ms_module_export = (ctx, call) ->
-  (call_ (token_ 'export'), [(call_ (token_ 'module'), (_arguments call))])
-
-ms.module = ms_module = (ctx, call) ->
+  (ms_module ctx, call, yes)
+
+ms.module = ms_module = (ctx, call, isExported = no) ->
   requireName ctx, 'Module name required'
   name = ctx.definitionName()
   if name
-    # TODO: here we need to propagate request and use compiled js
-    result = compileModuleTopLevelAst (form_ (_arguments call)), joinModuleNames ctx.moduleName, name
-    if result.request
-      ctx.req result.request, newSet()
-    else
-      console.log "submodule", result.js
-      if result.errors
-        ctx.extendSubstitution fails: result.errors # propagate errors TODO: rename substitution which is only used for type errors now
-      jsValue result.js
+    if ctx.isSubmodule name
+      # TODO: enabled malformed errors to point to other points in the code
+      malformed ctx, ctx.definitionPattern(), 'A submodule with this name already exists'
+    else
+      typedModulePath =
+        names: (join ctx.typedModulePath.names, [name])
+        types: (join ctx.typedModulePath.types, ['submodule'])
+        exported: isExported
+      result = compileModuleTopLevelAst (form_ (_arguments call)), typedModulePath
+      if result.request
+        ctx.req result.request, newSet()
+      else
+        ctx.addSubmodule name
+        if result.errors
+          ctx.extendSubstitution fails: result.errors # propagate errors TODO: rename substitution which is only used for type errors now
+        jsValue result.js
   else
     jsNoop()
-
-joinModuleNames = (parent, child) ->
-  "#{parent}/#{child}"
 
 ms.export = ms_export = (ctx, call) ->
   requireName ctx, 'Name to export required'

declareImported = (ctx, name) ->
  ctx.assignType name, (ctx.tempType name)
  ctx.declareAsFinal name, ctx.currentScopeIndex()

imports = (moduleName, names) ->
  validModuleName = validIdentifier moduleName
  for name in names
    validName = validIdentifier name
    jsVarDeclaration validName, (jsAccess (jsAccess "Shem", validModuleName), validName)

ms.format = ms_format = (ctx, call) ->
  typeTable =

compiledModules = newMap()
moduleGraph = newMap()

# TODO: pass this info in through context instead of a direct call
moduleNameToTypedModulePath = (moduleName, currentTypedModulePath) ->
  module = (lookupInMap moduleGraph, moduleName)
  if module
    if violating = moduleAccessViolation (moduleNameToPath moduleName), currentTypedModulePath
      nonExportedLink: violating
  module.typedModulePath

moduleAccessViolation = (toModulePath, fromTypedModulePath) ->
  for i, moduleName in toModulePath
    if fromTypedModulePath.names[i] isnt moduleName
      checkedModuleName = (modulePathToName toModulePath[0..i])
      module = (lookupInMap moduleGraph, checkedModuleName)
      if not module
        throw new Error "missing module #{checkedModuleName}
         that should have been compiled for #{moduleName}"
      if not module.exported
        return checkedModuleName
  false

lookupCompiledModule = (name) ->
  lookupInMap compiledModules, name

compileModule = (source) ->
  compileModuleTopLevel source, (names: ['.'], types: ['commonJs'])

defaultTypedModulePath = (names: ['@unnamed'], types: ['browser'])

compileModuleTopLevel = (source, typedModulePath = defaultTypedModulePath, requiredMap = newMap()) ->
  compileModuleTopLevelAst (astFromSource "(#{source})", -1, -1), typedModulePath, requiredMap

compileModuleTopLevelAst = (ast, typedModulePath = defaultTypedModulePath, requiredMap = newMap()) ->
  # addToMap requiredMap, 'Prelude', yes # TODO: Hardcoded prelude dependency
  moduleName = modulePathToName typedModulePath.names
  removeFromMap requiredMap, moduleName
  for requiredModuleName of values requiredMap
    if not lookupCompiledModule requiredModuleName
      return request: requiredModuleName
  replaceOrAddToMap moduleGraph, moduleName, requires: requiredMap, typedModulePath: typedModulePath
  toInject = requiresFor moduleName
  ctx = injectedContext toInject
  ctx.typedModulePath = typedModulePath
  defaultImports = importsFor newSet()#(subtractSets (newSetWith 'Prelude'), (newSetWith moduleName))
  declareImportedByDefault ctx, defaultImports
  compilationFn = (topLevelModule typedModulePath, defaultImports)
  {request, ir, js} = compileCtxAstToJs compilationFn, ctx, ast
  if request
    if not allInjected request, requiredMap
      return compileModuleTopLevelAst ast, typedModulePath, request
    else
      {js} = compileCtxIrToJs ctx, ir
  errors = checkTypes ctx
