     ++ ["pop #{segment_of(kind)} #{index}"]
   end
 
-  def compile_do_statement([{:keyword, "do"},
-                            {:identifier, class_name, :attr, %{category: :class}},
-                            {:symbol, "."},
-                            {:identifier, fn_name, :attr, _},
-                            {:symbol, "("},
-                            {:expressionList, exp_list_parsed},
-                            {:symbol, ")"},
-                            {:symbol, ";"}]) do
+  def compile_do_statement(_class_name,
+        [{:keyword, "do"},
+         {:identifier, class_name, :attr, %{category: :class}},
+         {:symbol, "."},
+         {:identifier, fn_name, :attr, _},
+         {:symbol, "("},
+         {:expressionList, exp_list_parsed},
+         {:symbol, ")"},
+         {:symbol, ";"}]) do
     compile_exp_list(exp_list_parsed)
     ++ ["call #{class_name}.#{fn_name} #{number_of_expressions(exp_list_parsed)}"]
   end
     
-  def compile_do_statement([{:keyword, "do"},
-                            {:identifier, _var_name, :attr, %{type: type, category: :var, kind: kind, index: index}},
-                            {:symbol, "."},
-                            {:identifier, fn_name, :attr, _},
-                            {:symbol, "("},
-                            {:expressionList, exp_list_parsed},
-                            {:symbol, ")"},
-                            {:symbol, ";"}]) do
-    compile_exp_list(exp_list_parsed)
-    ++ ["push #{segment_of(kind)} #{index}",
-        "call #{type}.#{fn_name} #{number_of_expressions(exp_list_parsed)}"]
-  end
-
-  def compile_while_statement([{:keyword, "while"},
-                               {:symbol, "("},
-                               {:expression, exp_parsed},
-                               {:symbol, ")"},
-                               {:symbol, "{"} | rest]) do
+  def compile_do_statement(_class_name,
+        [{:keyword, "do"},
+         {:identifier, _var_name, :attr, %{type: type, category: :var, kind: kind, index: index}},
+         {:symbol, "."},
+         {:identifier, fn_name, :attr, _},
+         {:symbol, "("},
+         {:expressionList, exp_list_parsed},
+         {:symbol, ")"},
+         {:symbol, ";"}]) do
+    ["push #{segment_of(kind)} #{index}"]
+    ++ compile_exp_list(exp_list_parsed)
+    ++ ["call #{type}.#{fn_name} #{number_of_expressions(exp_list_parsed) + 1}"]
+  end
+
+  def compile_do_statement(class_name,
+        [{:keyword, "do"},
+         {:identifier, fn_name, :attr, _},
+         {:symbol, "("},
+         {:expressionList, exp_list_parsed},
+         {:symbol, ")"},
+         {:symbol, ";"}]) do
+    ["push pointer 0"]
+    ++ compile_exp_list(exp_list_parsed)
+    ++ ["call #{class_name}.#{fn_name} #{number_of_expressions(exp_list_parsed) + 1}"]
+  end
+
+  def compile_while_statement(class_name,
+        [{:keyword, "while"},
+         {:symbol, "("},
+         {:expression, exp_parsed},
+         {:symbol, ")"},
+         {:symbol, "{"} | rest]) do
     label1 = "whileL1$#{JackUuid.generate()}"
     label2 = "whileL2$#{JackUuid.generate()}"
     exp = compile_exp(exp_parsed)
-    {statements, rest1} = compile_statements(rest)
+    {statements, rest1} = compile_statements(class_name, rest)
     [{:symbol, "}"}] = rest1
     ["label #{label1}"]
     ++ exp

                     {:identifier, class_name, :attr, _},
                     {:symbol, "{"}
                     | rest]) do
    compile_class(class_name, rest)
  end

  def compile_class(class_name,
        [{:subroutineDec, inner} | rest]) do
    compile_subroutine_dec(class_name, inner)
    ++ compile_class(class_name, rest)
  end

  def compile_class(_class_name, [{:symbol, "}"}]), do: []

  def compile_subroutine_dec(class_name,
        [{:keyword, "function"},
         {keyword_or_identifier, _return_type},
         {:identifier, fn_name, :attr, _},
         {:symbol, "("},
         {:parameterList, _param_list},
         {:symbol, ")"},
         {:subroutineBody, body_parsed}])
  when keyword_or_identifier in [:keyword, :identifier] do
    body_vm = compile_subroutine_body(body_parsed)
    ["function #{class_name}.#{fn_name} #{number_of_locals(body_parsed)}"]
    ++ body_vm
  end

  def compile_subroutine_body([{:symbol, "{"} | rest]) do
    {locals, rest1} = compile_var_dec(rest)
    {statements, rest2} = compile_statements(rest1)
    [{:symbol, "}"}] = rest2
    locals ++ statements
  end

        "label #{label2}"]
  end

  def compile_if_statement(class_name,
        [{:keyword, "if"},
         {:symbol, "("},
         {:expression, exp_parsed},
         {:symbol, ")"},
         {:symbol, "{"},
         {:statements, statements_parsed},
         {:symbol, "}"}]) do
    label1 = "ifL1$#{JackUuid.generate()}"
    exp = compile_exp(exp_parsed)
    statements = compile_statement(class_name, statements_parsed)
    exp
    ++ ["not",
        "if-goto #{label1}"]
    ++ statements
    ++ ["label #{label1}"]
  end

  def compile_if_statement(class_name,
        [{:keyword, "if"},
         {:symbol, "("},
         {:expression, exp_parsed},
         {:symbol, ")"},
         {:symbol, "{"},
         {:statements, statements_parsed},
         {:symbol, "}"},
         {:keyword, "else"},
         {:symbol, "{"},
         {:statements, else_parsed},
         {:symbol, "}"}]) do
    label1 = "ifL1$#{JackUuid.generate()}"
    label2 = "ifL2$#{JackUuid.generate()}"
    exp = compile_exp(exp_parsed)
    statements = compile_statement(class_name, statements_parsed)
    else_statements = compile_statement(class_name, else_parsed)
    exp
    ++ ["not",
        "if-goto #{label1}"]
