     do: parse(:json, iodata, pos + 1)
   defp parse(:json, <<@left_square_bracket>> <> iodata, pos),
     do: parse(:list, iodata, pos + 1, [])
-  defp parse(:json, iodata, pos),
-    do: throw {:json, pos}
+  defp parse(:json, <<@left_curly_bracket>> <> iodata, pos),
+    do: parse(:map, iodata, pos + 1, [])
+  defp parse(:json, <<@json_true>> <> iodata, pos),
+    do: {true, iodata, pos + 4}
+  defp parse(:json, <<@json_false>> <> iodata, pos),
+    do: {false, iodata, pos + 5}
+  defp parse(:json, <<@json_null>> <> iodata, pos),
+    do: {nil, iodata, pos + 5}
+  defp parse(:json, _iodata, pos),
+    do: throw {:json, pos + 1}
+
+  defp parse(:key, <<char>> <> iodata, pos)
+    when char in @whitespace,
+    do: parse(:key, iodata, pos + 1)
+  defp parse(:key, <<char>> <> iodata, pos)
+    when char == @quotation_mark,
+    do: parse(:string, iodata, pos + 1, [])
+  defp parse(:key, _iodata, pos),
+    do: throw {:key, pos + 1}
 
   defp parse(:number, <<char>> <> iodata, pos, chars)
     when char in @digits,

  defp parse(:list, <<char>> <> iodata, pos, list)
    when char in @whitespace,
    do: parse(:list, iodata, pos + 1, list)
  defp parse(:list, iodata, pos, list) do
    {result, iodata, pos} = parse(:json, iodata, pos)
    parse(:list, iodata, pos, [result|list])
  end

end

  @surrogate_b2 'cedfCDEF'
  @left_square_bracket ?[
  @right_square_bracket ?]
  @left_curly_bracket ?{
  @right_curly_bracket ?}
  @colon ?:
  @comma ?,
  @json_true "true"
  @json_false "false"
  @json_null "null"

  @spec parse(iodata) :: {:ok, json} | {:error, String.t}
  def parse(iodata) do
