 
   compileExpression: (o) ->
     @func = o.namespace.createFunc this
-    {type: new Type("func", (new Type for _ in @params)), access: @func.label}
+    @func.type = new Type "func", (new Type for _ in @params), new Type
+    @func.type.codeNodes.push this
+    {type: @func.type, access: @func.label}
 
   compileFunc: (o) ->
     o = {namespace: o.namespace.createSubNamespace()}
     code = @body.compileStatement o
     # TODO figure returning stuff
-    @func.type.returnType = voidType
+    linkTypes @func.type.findRoot().returnType, voidType
     returnCode = "set pc, pop"
-    ":#{@func.label}\n#{code}\n#{returnCode}"
+    o.namespace.extraAsm.push {asm: ":#{@func.label}\n#{code}\n#{returnCode}"}
 
   children: ['params', 'body']
 

class Namespace
  constructor: (@parent)->
    @names = {}
    if @parent?
      @root = @parent.root
    else
      @root = this
      @extraAsm = []
      labelCount = 0
      @nextLabel = -> "_#{labelCount++}"
  find: (name) ->
    @names[name] or @parent?.find name
  createVariable: (name, type) ->
    variable = new Variable "_"+name, type, this
    @names[name] = variable
    @root.extraAsm.push variable
    variable
  createLiteralString: (value) ->
    label = @root.nextLabel()
    asm = ":#{label} dat #{value.length}, #{JSON.stringify value}"
    @root.extraAsm.push {asm}
    label
  createFunc: (codeNode) ->
    func = new Func @root.nextLabel(), codeNode
    @root.extraAsm.push func
    func
  createSubNamespace: ->
    new Namespace this


  return if leftType is rightType
  # if one of them is totally unknown, it's safe to link them.
  unless leftType.basic?
    return leftType.linkTo rightType
  unless rightType.basic?
    return rightType.linkTo leftType
  unless leftType.basic is rightType.basic
    throw TypeError "incompatible types #{leftType.basic} and #{rightType.basic}"
  unless leftType.basic is "func"
    return leftType.linkTo rightType
  unless leftType.args.length is rightType.args.length
    throw TypeError "number of arguments must match"
  for leftArg, i in leftType.args
