py: Protect mp_parse and mp_compile with nlr push/pop block.

To enable parsing constants more efficiently, mp_parse should be allowed
to raise an exception, and mp_compile can already raise a MemoryError.
So these functions need to be protected by an nlr push/pop block.

This patch adds that feature in all places.  This allows to simplify how
mp_parse and mp_compile are called: they now raise an exception if they
have an error and so explicit checking is not needed anymore.
diff --git a/py/parse.c b/py/parse.c
index 881a11e..569cf25 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -30,6 +30,7 @@
 #include <assert.h>
 #include <string.h>
 
+#include "py/nlr.h"
 #include "py/lexer.h"
 #include "py/parse.h"
 #include "py/parsenum.h"
@@ -382,7 +383,7 @@
     push_result_node(parser, (mp_parse_node_t)pn);
 }
 
-mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_parse_error_kind_t *parse_error_kind_out) {
+mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
 
     // initialise parser and allocate memory for its stacks
 
@@ -717,15 +718,15 @@
         }
     }
 
-    mp_parse_node_t result;
+    mp_obj_t exc = MP_OBJ_NULL;
+    mp_parse_node_t result = MP_PARSE_NODE_NULL;
 
     // check if we had a memory error
     if (parser.had_memory_error) {
 memory_error:
-        *parse_error_kind_out = MP_PARSE_ERROR_MEMORY;
-        result = MP_PARSE_NODE_NULL;
+        exc = mp_obj_new_exception_msg(&mp_type_MemoryError,
+            "parser could not allocate enough memory");
         goto finished;
-
     }
 
     // check we are at the end of the token stream
@@ -747,17 +748,30 @@
     // free the memory that we don't need anymore
     m_del(rule_stack_t, parser.rule_stack, parser.rule_stack_alloc);
     m_del(mp_parse_node_t, parser.result_stack, parser.result_stack_alloc);
+    // we also free the lexer on behalf of the caller (see below)
 
-    // return the result
-    return result;
+    if (exc != MP_OBJ_NULL) {
+        // had an error so raise the exception
+        // add traceback to give info about file name and location
+        // we don't have a 'block' name, so just pass the NULL qstr to indicate this
+        mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTR_NULL);
+        mp_lexer_free(lex);
+        nlr_raise(exc);
+    } else {
+        mp_lexer_free(lex);
+        return result;
+    }
 
 syntax_error:
     if (lex->tok_kind == MP_TOKEN_INDENT) {
-        *parse_error_kind_out = MP_PARSE_ERROR_UNEXPECTED_INDENT;
+        exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
+            "unexpected indent");
     } else if (lex->tok_kind == MP_TOKEN_DEDENT_MISMATCH) {
-        *parse_error_kind_out = MP_PARSE_ERROR_UNMATCHED_UNINDENT;
+        exc = mp_obj_new_exception_msg(&mp_type_IndentationError,
+            "unindent does not match any outer indentation level");
     } else {
-        *parse_error_kind_out = MP_PARSE_ERROR_INVALID_SYNTAX;
+        exc = mp_obj_new_exception_msg(&mp_type_SyntaxError,
+            "invalid syntax");
 #ifdef USE_RULE_NAME
         // debugging: print the rule name that failed and the token
         printf("rule: %s\n", rule->rule_name);
@@ -766,6 +780,5 @@
 #endif
 #endif
     }
-    result = MP_PARSE_NODE_NULL;
     goto finished;
 }