 
   # A **Block** is the only node that can serve as the root.
   compileRoot: ->
-    o =
-      namespace: new Namespace
+    o = {namespace: new GlobalNamespace}
     o.namespace.createVariable("printc", getType new Type "func", [intType]).asm = stdlib.printc
     o.namespace.createVariable("prints", getType new Type "func", [stringType]).asm = stdlib.prints
     code = @compileStatement o

    {type: getType(new Type "func"), access: @func.label}

  compileFunc: (o) ->
    code = "; TODO function body here"
    ":#{@func.label}\n#{code}"

  children: ['params', 'body']


  constructor: (@label, @code) ->

class Namespace
  constructor: (@parent) ->
    @names = {}
    @root = @parent?.root
  find: (name) ->
    @names[name] or @parent?.find name
  createLocalNamespace: ->
    new LocalNamespace this
  scopeNameMangle: ->
    return "" unless @parent?
    return @parent.scopeNameMangle() + @index + ".."
class LocalNamespace extends Namespace
  constructor: (args...) ->
    super(args...)
    createRootRedirect = (name) =>
      @[name] = (args...) ->
        @root[name](args...)
    createRootRedirect "createLiteralString"
    createRootRedirect "createFunc"
  createVariable: (name, type) ->
    variable = new Variable name, type
class GlobalNamespace extends Namespace
  constructor: ->
    super(null)
    @root = this
    @variables = []
    @funcs = []
    labelCount = 0
    @nextLabel = -> "_#{labelCount++}"
  createVariable: (name, type) ->
    variable = new Variable name, type, this
    @names[name] = variable
