 labelFnBody = (node) ->
   return
 
+labelClasses = (ast) ->
+  macro 'class', ast, (node, args) ->
+    node.type = 'class'
+    {params, wheres} = classDefinition node
+    labelWhere wheres
+    labelParams node, params if params?
+    node
+
+labelInstances = (ast) ->
+  macro 'instance', ast, (node, args) ->
+    node.type = 'instance'
+    {klass, wheres} = instanceDefinition node
+    klass.label = 'operator'
+    labelWhere wheres
+    node
+
 labelNames = (pattern) ->
   if Array.isArray pattern
     if isList(pattern) or isTuple pattern

    node

typeTypes = (ast) ->
  macro '::', ast, (node) ->
    node.type = 'type'
    node


  params = if Array.isArray(paramList) then paramList else undefined
  defs ?= []
  for def, i in defs
    if matchNode '->', def
      type = def
    else if matchNode '#', def
      doc = def
    if not matchAnyNode ['->', '#'], def
      implementation = defs[i...]
      break
  {body, wheres} = fnImplementation implementation ? []
  {params, type, doc, body, wheres}

classDefinition = (node) ->
  words = inside node
  [keyword, paramList, defs...] = words
  params = if Array.isArray(paramList) then paramList else undefined
  defs ?= []
  if defs.length > 0
    [first] = defs
    if Array.isArray first
      context = first
      defs = defs[1..]
  wheres = whereList defs
  {params, context, wheres}

instanceDefinition = (node) ->
  words = inside node
  [keyword, klass, defs...] = words
  wheres = whereList defs
  {klass, wheres}

fnImplementation = (defs) ->
  [body, where...] = defs
