[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 2/2] pkl: Return exception value instead of exit_status
From: |
Mohammad-Reza Nabipoor |
Subject: |
[PATCH v3 2/2] pkl: Return exception value instead of exit_status |
Date: |
Thu, 13 Jan 2022 03:35:24 +0330 |
2022-01-12 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/pvm.h (pvm_run): Add new arg for exception.
* libpoke/pvm.c (pvm_run): Report exception.
(pvm_call_closure): Fix pvm_run invocation.
(PVM_STATE_EXCEPTION_VALUE): New macro.
* libpoke/pkl.h (pkl_execute_file): Add new arg for exception.
(pkl_execute_buffer): Likewise.
(pkl_execute_expression): Likewise.
(pkl_execute_statement): Likewise.
* libpoke/pkl.c (pkl_execute_file): Likewise.
(pkl_execute_buffer): Likewise.
(pkl_execute_expression): Likewise.
(pkl_execute_statement): Likewise.
* libpoke/libpoke.h (pk_file_compile): Likewise.
(pk_compile_buffer): Likewise.
(pk_compile_statement): Likewise.
(pk_compile_expression): Likewise.
* libpoke/libpoke.c (pk_file_compile): Likewise.
(pk_compile_buffer): Likewise.
(pk_compile_statement): Likewise.
(pk_compile_expression): Likewise.
(pk_call): Fix pvm_run invocation.
* libpoke/pvm.jitter (state-struct-backing-c): Add new field.
(popexite): Add new instruction.
* libpoke/pkl-insn.def: Likewise.
* libpoke/pkl-rt-1.pk (_pkl_exception_handler): Change return value
to `Exception` from `int<32>`.
* libpoke/pkl-asm.c (pkl_asm_finish): Update to report exception.
* poke/pk-cmd-ios.c (pk_cmd_load_file): Fix comment.
* poke/pk-map.c (pk_map_load_parsed_map): Likewise.
* poke/poke.c (parse_args_2): Update to use exception value.
* libpoke/std.pk (exit): Set `name` field.
---
ChangeLog | 34 +++++++++++++++++++++++++++++++++
libpoke/libpoke.c | 20 +++++++++++---------
libpoke/libpoke.h | 28 +++++++++++++++------------
libpoke/pkl-asm.c | 10 +++++++++-
libpoke/pkl-insn.def | 1 +
libpoke/pkl-rt-1.pk | 4 ++--
libpoke/pkl.c | 32 +++++++++----------------------
libpoke/pkl.h | 18 ++++++++++--------
libpoke/pvm.c | 9 +++++++--
libpoke/pvm.h | 7 ++++++-
libpoke/pvm.jitter | 15 +++++++++++++++
libpoke/std.pk | 2 +-
poke/pk-cmd-ios.c | 2 +-
poke/pk-map.c | 4 ++--
poke/poke.c | 45 +++++++++++++++++++++++++++++++++++++++-----
15 files changed, 164 insertions(+), 67 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5dc360bd..bab5ec83 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+2022-01-12 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
+
+ * libpoke/pvm.h (pvm_run): Add new arg for exception.
+ * libpoke/pvm.c (pvm_run): Report exception.
+ (pvm_call_closure): Fix pvm_run invocation.
+ (PVM_STATE_EXCEPTION_VALUE): New macro.
+ * libpoke/pkl.h (pkl_execute_file): Add new arg for exception.
+ (pkl_execute_buffer): Likewise.
+ (pkl_execute_expression): Likewise.
+ (pkl_execute_statement): Likewise.
+ * libpoke/pkl.c (pkl_execute_file): Likewise.
+ (pkl_execute_buffer): Likewise.
+ (pkl_execute_expression): Likewise.
+ (pkl_execute_statement): Likewise.
+ * libpoke/libpoke.h (pk_file_compile): Likewise.
+ (pk_compile_buffer): Likewise.
+ (pk_compile_statement): Likewise.
+ (pk_compile_expression): Likewise.
+ * libpoke/libpoke.c (pk_file_compile): Likewise.
+ (pk_compile_buffer): Likewise.
+ (pk_compile_statement): Likewise.
+ (pk_compile_expression): Likewise.
+ (pk_call): Fix pvm_run invocation.
+ * libpoke/pvm.jitter (state-struct-backing-c): Add new field.
+ (popexite): Add new instruction.
+ * libpoke/pkl-insn.def: Likewise.
+ * libpoke/pkl-rt-1.pk (_pkl_exception_handler): Change return value
+ to `Exception` from `int<32>`.
+ * libpoke/pkl-asm.c (pkl_asm_finish): Update to report exception.
+ * poke/pk-cmd-ios.c (pk_cmd_load_file): Fix comment.
+ * poke/pk-map.c (pk_map_load_parsed_map): Likewise.
+ * poke/poke.c (parse_args_2): Update to use exception value.
+ * libpoke/std.pk (exit): Set `name` field.
+
2022-01-12 Mohammad-Reza Nabipoor <mnabipoor@gnu.org>
* libpoke/libpoke.h (PK_E_*): Add macros for standard exception
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index 21bed8e3..99d784ad 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -122,29 +122,30 @@ pk_errno (pk_compiler pkc)
int
pk_compile_file (pk_compiler pkc, const char *filename,
- int *exit_status)
+ pk_val *exit_exception)
{
- PK_RETURN (pkl_execute_file (pkc->compiler, filename, exit_status)
+ PK_RETURN (pkl_execute_file (pkc->compiler, filename, exit_exception)
? PK_OK
: PK_ERROR);
}
int
pk_compile_buffer (pk_compiler pkc, const char *buffer,
- const char **end, int *exit_status)
+ const char **end, pk_val *exit_exception)
{
PK_RETURN (pkl_execute_buffer (pkc->compiler, buffer,
- end, exit_status) ? PK_OK : PK_ERROR);
+ end, exit_exception) ? PK_OK : PK_ERROR);
}
int
pk_compile_statement (pk_compiler pkc, const char *buffer,
const char **end, pk_val *valp,
- int *exit_status)
+ pk_val *exit_exception)
{
pvm_val val;
- if (!pkl_execute_statement (pkc->compiler, buffer, end, &val, exit_status))
+ if (!pkl_execute_statement (pkc->compiler, buffer, end, &val,
+ exit_exception))
PK_RETURN (PK_ERROR);
if (valp)
@@ -155,11 +156,12 @@ pk_compile_statement (pk_compiler pkc, const char *buffer,
int
pk_compile_expression (pk_compiler pkc, const char *buffer,
- const char **end, pk_val *valp, int *exit_status)
+ const char **end, pk_val *valp, pk_val *exit_exception)
{
pvm_val val;
- if (!pkl_execute_expression (pkc->compiler, buffer, end, &val, exit_status))
+ if (!pkl_execute_expression (pkc->compiler, buffer, end, &val,
+ exit_exception))
PK_RETURN (PK_ERROR);
if (valp)
@@ -741,7 +743,7 @@ pk_call (pk_compiler pkc, pk_val cls, pk_val *ret, int
narg, ...)
/* Run the program in the poke VM. */
pvm_program_make_executable (program);
- rret = pvm_run (pkc->vm, program, ret);
+ rret = pvm_run (pkc->vm, program, ret, NULL);
pvm_destroy_program (program);
PK_RETURN (rret == PVM_EXIT_OK ? PK_OK : PK_ERROR);
diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h
index 8fb12356..14223c5d 100644
--- a/libpoke/libpoke.h
+++ b/libpoke/libpoke.h
@@ -157,14 +157,15 @@ int pk_errno (pk_compiler pkc) LIBPOKE_API;
/* Compile an execute a Poke program from the given file FILENAME.
- If not NULL, *EXIT_STATUS is set to the status resulting from the
- execution of the program.
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL.
Return PK_ERROR in case of a compilation error. Otherwise,
return PK_OK. */
int pk_compile_file (pk_compiler pkc, const char *filename,
- int *exit_status) LIBPOKE_API;
+ pk_val *exit_exception) LIBPOKE_API;
/* Compile an execute a Poke program from a memory buffer.
@@ -176,11 +177,12 @@ int pk_compile_file (pk_compiler pkc, const char
*filename,
Return PK_ERROR in case of a compilation error. Otherwise,
return PK_OK.
- If not NULL, *EXIT_STATUS is set to the status resulting from the
- execution of the buffer contents. */
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL. */
int pk_compile_buffer (pk_compiler pkc, const char *buffer,
- const char **end, int *exit_status) LIBPOKE_API;
+ const char **end, pk_val *exit_exception) LIBPOKE_API;
/* Like pk_compile_buffer but compile and execute a single Poke
statement, which may evaluate to a value if it is an "expression
@@ -189,12 +191,13 @@ int pk_compile_buffer (pk_compiler pkc, const char
*buffer,
VAL, if given, is a pointer to a pk_val variable that is set to the
result value of an expression-statement, or to PK_NULL.
- If not NULL, *EXIT_STATUS is set to the status resulting from the
- execution of the buffer contents. */
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL. */
int pk_compile_statement (pk_compiler pkc, const char *buffer,
const char **end, pk_val *val,
- int *exit_status) LIBPOKE_API;
+ pk_val *exit_exception) LIBPOKE_API;
/* Like pk_compile_buffer but compile and execute a single Poke
expression, which evaluates to a value.
@@ -204,12 +207,13 @@ int pk_compile_statement (pk_compiler pkc, const char
*buffer,
Return PK_ERROR in case of a compilation error, PK_OK otherwise.
- If not NULL, *EXIT_STATUS is set to the status resulting from the
- execution of the buffer contents. */
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL. */
int pk_compile_expression (pk_compiler pkc, const char *buffer,
const char **end, pk_val *val,
- int *exit_status) LIBPOKE_API;
+ pk_val *exit_exception) LIBPOKE_API;
/* Load a module using the given compiler.
diff --git a/libpoke/pkl-asm.c b/libpoke/pkl-asm.c
index c6a4258e..9e614f20 100644
--- a/libpoke/pkl-asm.c
+++ b/libpoke/pkl-asm.c
@@ -1236,7 +1236,15 @@ pkl_asm_finish (pkl_asm pasm, int epilogue)
assembly. Otherwise, call the _pkl_exception_handler
function which is part of the compiler run-time. */
if (pkl_bootstrapped_p (pasm->compiler))
- pkl_asm_call (pasm, "_pkl_exception_handler");
+ {
+ pkl_asm_call (pasm, "_pkl_exception_handler"); /* EXC */
+ pkl_asm_insn (pasm, PKL_INSN_PUSH,
+ pvm_make_string ("exit_status")); /* EXC STR */
+ pkl_asm_insn (pasm, PKL_INSN_SREF); /* EXC STR VAL */
+ pkl_asm_insn (pasm, PKL_INSN_NIP); /* EXC VAL */
+ pkl_asm_insn (pasm, PKL_INSN_SWAP); /* VAL EXC */
+ pkl_asm_insn (pasm, PKL_INSN_POPEXITE); /* VAL */
+ }
else
{
pkl_asm_insn (pasm, PKL_INSN_DROP); /* Discard the exception. */
diff --git a/libpoke/pkl-insn.def b/libpoke/pkl-insn.def
index 918c6435..4a70eae2 100644
--- a/libpoke/pkl-insn.def
+++ b/libpoke/pkl-insn.def
@@ -441,6 +441,7 @@ PKL_DEF_INSN(PKL_INSN_GETENV,"","getenv")
PKL_DEF_INSN(PKL_INSN_PUSHE,"l","pushe")
PKL_DEF_INSN(PKL_INSN_POPE,"","pope")
PKL_DEF_INSN(PKL_INSN_RAISE,"","raise")
+PKL_DEF_INSN(PKL_INSN_POPEXITE,"","popexite")
/* IOS related instructions. */
diff --git a/libpoke/pkl-rt-1.pk b/libpoke/pkl-rt-1.pk
index c90d3770..6e1c3b91 100644
--- a/libpoke/pkl-rt-1.pk
+++ b/libpoke/pkl-rt-1.pk
@@ -187,7 +187,7 @@ var exception_code = lambda _ExceptionCodeGenerator:
or be ready to underflow the exception handlers stack and face some
ugly shit. You have been warned! */
-fun _pkl_exception_handler = (Exception exception) int<32>:
+fun _pkl_exception_handler = (Exception exception) Exception:
{
if (exception.code != EC_exit && exception.code != EC_signal)
{
@@ -203,7 +203,7 @@ fun _pkl_exception_handler = (Exception exception) int<32>:
}
}
- return exception.exit_status;
+ return exception;
}
/* Find the greatest common divisor of two unsigned 64-bit integrals A
diff --git a/libpoke/pkl.c b/libpoke/pkl.c
index bb52be9b..52a4d4bb 100644
--- a/libpoke/pkl.c
+++ b/libpoke/pkl.c
@@ -305,7 +305,8 @@ rest_of_compilation (pkl_compiler compiler,
int
pkl_execute_buffer (pkl_compiler compiler,
- const char *buffer, const char **end, int *exit_status)
+ const char *buffer, const char **end,
+ pvm_val *exit_exception)
{
pkl_ast ast = NULL;
pvm_program program;
@@ -336,12 +337,8 @@ pkl_execute_buffer (pkl_compiler compiler,
/* Execute the program in the poke vm. */
{
pvm_val val;
- int status = pvm_run (compiler->vm, program, &val);
- if (exit_status)
- *exit_status = status;
-
- if (status != PVM_EXIT_OK)
+ if (pvm_run (compiler->vm, program, &val, exit_exception) != PVM_EXIT_OK)
goto error;
/* Discard the value. */
@@ -360,13 +357,12 @@ pkl_execute_buffer (pkl_compiler compiler,
int
pkl_execute_statement (pkl_compiler compiler,
const char *buffer, const char **end,
- pvm_val *val, int *exit_status)
+ pvm_val *val, pvm_val *exit_exception)
{
pkl_ast ast = NULL;
pvm_program program;
int ret;
pkl_env env = NULL;
- int status;
compiler->compiling = PKL_COMPILING_STATEMENT;
env = pkl_env_dup_toplevel (compiler->env);
@@ -389,10 +385,7 @@ pkl_execute_statement (pkl_compiler compiler,
pvm_program_make_executable (program);
/* Execute the routine in the poke vm. */
- status = pvm_run (compiler->vm, program, val);
- if (exit_status)
- *exit_status = status;
- if (status != PVM_EXIT_OK)
+ if (pvm_run (compiler->vm, program, val, exit_exception) != PVM_EXIT_OK)
goto error;
pvm_destroy_program (program);
@@ -413,7 +406,6 @@ pkl_compile_expression (pkl_compiler compiler,
pvm_program program;
int ret;
pkl_env env = NULL;
- int status;
compiler->compiling = PKL_COMPILING_EXPRESSION;
env = pkl_env_dup_toplevel (compiler->env);
@@ -447,13 +439,12 @@ pkl_compile_expression (pkl_compiler compiler,
int
pkl_execute_expression (pkl_compiler compiler,
const char *buffer, const char **end,
- pvm_val *val, int *exit_status)
+ pvm_val *val, pvm_val *exit_exception)
{
pkl_ast ast = NULL;
pvm_program program;
int ret;
pkl_env env = NULL;
- int status;
compiler->compiling = PKL_COMPILING_EXPRESSION;
env = pkl_env_dup_toplevel (compiler->env);
@@ -476,10 +467,7 @@ pkl_execute_expression (pkl_compiler compiler,
pvm_program_make_executable (program);
/* Execute the routine in the poke vm. */
- status = pvm_run (compiler->vm, program, val);
- if (exit_status)
- *exit_status = status;
- if (status != PVM_EXIT_OK)
+ if (pvm_run (compiler->vm, program, val, exit_exception) != PVM_EXIT_OK)
goto error;
pvm_destroy_program (program);
@@ -494,7 +482,7 @@ pkl_execute_expression (pkl_compiler compiler,
int
pkl_execute_file (pkl_compiler compiler, const char *fname,
- int *exit_status)
+ pvm_val *exit_exception)
{
int ret;
pkl_ast ast = NULL;
@@ -532,10 +520,8 @@ pkl_execute_file (pkl_compiler compiler, const char *fname,
/* Execute the program in the poke vm. */
{
pvm_val val;
- int status = pvm_run (compiler->vm, program, &val);
- if (exit_status)
- *exit_status = status;
+ pvm_run (compiler->vm, program, &val, exit_exception);
}
pvm_destroy_program (program);
diff --git a/libpoke/pkl.h b/libpoke/pkl.h
index ebbdf5ab..9b0b6904 100644
--- a/libpoke/pkl.h
+++ b/libpoke/pkl.h
@@ -88,36 +88,38 @@ void pkl_free (pkl_compiler compiler);
/* Compile an execute a Poke program from the given file FNAME.
Return 1 if the compilation was successful, 0 otherwise.
- If EXIT_STATUS is not NULL, set it to the status in which the
- executed program terminated. */
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL. */
int pkl_execute_file (pkl_compiler compiler, const char *fname,
- int *exit_status);
+ pvm_val *exit_exception);
/* Compile and execute Poke program from a NULL-terminated string
BUFFER. Return 0 in case of a compilation error, 1 otherwise. If
not NULL, END is set to the first character in BUFFER that is not
part of the compiled entity.
- If EXIT_STATUS is not NULL, set it to the status in which the
- executed program terminated. */
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL. */
int pkl_execute_buffer (pkl_compiler compiler, const char *buffer,
- const char **end, int *exit_status);
+ const char **end, pvm_val *exit_exception);
/* Like pkl_execute_buffer, but compile and execute a single Poke
expression, that generates a value in VAL. */
int pkl_execute_expression (pkl_compiler compiler,
const char *buffer, const char **end,
- pvm_val *val, int *exit_status);
+ pvm_val *val, pvm_val *exit_exception);
/* Like pkl_execute_expression but compile and execute a single Poke statement,
which may generate a value in VAL if it is an "expression
statement". Otherwise VAL is set to PVM_NULL. */
int pkl_execute_statement (pkl_compiler compiler, const char *buffer, const
char **end,
- pvm_val *val, int *exit_status);
+ pvm_val *val, pvm_val *exit_exception);
/* Compile a single Poke expression and return the resulting PVM
program. */
diff --git a/libpoke/pvm.c b/libpoke/pvm.c
index 7529891b..6e2edfc2 100644
--- a/libpoke/pvm.c
+++ b/libpoke/pvm.c
@@ -35,6 +35,8 @@
#define PVM_STATE_RESULT_VALUE(PVM) \
(PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, result_value))
+#define PVM_STATE_EXIT_EXCEPTION_VALUE(PVM) \
+ (PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, exit_exception_value))
#define PVM_STATE_EXIT_CODE(PVM) \
(PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, exit_code))
#define PVM_STATE_VM(PVM) \
@@ -155,12 +157,13 @@ pvm_get_env (pvm apvm)
}
enum pvm_exit_code
-pvm_run (pvm apvm, pvm_program program, pvm_val *res)
+pvm_run (pvm apvm, pvm_program program, pvm_val *res, pvm_val *exc)
{
sighandler_t previous_handler;
pvm_routine routine = pvm_program_routine (program);
PVM_STATE_RESULT_VALUE (apvm) = PVM_NULL;
+ PVM_STATE_EXIT_EXCEPTION_VALUE (apvm) = PVM_NULL;
PVM_STATE_EXIT_CODE (apvm) = PVM_EXIT_OK;
previous_handler = signal (SIGINT, pvm_handle_signal);
@@ -169,6 +172,8 @@ pvm_run (pvm apvm, pvm_program program, pvm_val *res)
if (res != NULL)
*res = PVM_STATE_RESULT_VALUE (apvm);
+ if (exc != NULL)
+ *exc = PVM_STATE_EXIT_EXCEPTION_VALUE (apvm);
return PVM_STATE_EXIT_CODE (apvm);
}
@@ -197,7 +202,7 @@ pvm_call_closure (pvm vm, pvm_val cls, ...)
/* Run the program in the poke VM. */
program = pkl_asm_finish (pasm, 1 /* epilogue */);
pvm_program_make_executable (program);
- (void) pvm_run (vm, program, NULL);
+ (void) pvm_run (vm, program, NULL, NULL);
pvm_destroy_program (program);
}
diff --git a/libpoke/pvm.h b/libpoke/pvm.h
index 78d5471b..64345bf7 100644
--- a/libpoke/pvm.h
+++ b/libpoke/pvm.h
@@ -595,12 +595,17 @@ void pvm_reset_profile (pvm pvm);
If the execution of PROGRAM generates a result value, it is put in
RES.
+ If not NULL, *EXIT_EXCEPTION is set to an exception value if the
+ execution of the program gets interrupted by an unhandled exception.
+ Otherwise *EXIT_EXCEPTION is set to PK_NULL.
+
This function returns an exit code, indicating whether the
execution was successful or not. */
enum pvm_exit_code pvm_run (pvm vm,
pvm_program program,
- pvm_val *res);
+ pvm_val *res,
+ pvm_val *exit_exception);
/* Given a PVM and a closure value, call the closure.
diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
index 1ff133fe..bb16bf08 100644
--- a/libpoke/pvm.jitter
+++ b/libpoke/pvm.jitter
@@ -963,6 +963,7 @@ state-struct-backing-c
code
enum pvm_exit_code exit_code;
pvm_val result_value;
+ pvm_val exit_exception_value;
jitter_stack_height canary_stack;
jitter_stack_height canary_returnstack;
jitter_stack_height canary_exceptionstack;
@@ -6119,6 +6120,20 @@ instruction raise ()
end
end
+# Instruction: popexite
+#
+# Pops the exception on the stack and sets it in the VM.
+#
+# Stack: ( EXCEPTION -- )
+# Exceptions Stack: ( -- )
+
+instruction popexite ()
+ code
+ PVM_STATE_BACKING_FIELD (exit_exception_value) = JITTER_TOP_STACK ();
+ JITTER_DROP_STACK ();
+ end
+end
+
## Debugging Instructions
diff --git a/libpoke/std.pk b/libpoke/std.pk
index dfe75a76..fd6829ac 100644
--- a/libpoke/std.pk
+++ b/libpoke/std.pk
@@ -374,5 +374,5 @@ fun alignto = (offset<uint<64>,b> offset,
fun exit = (int<32> exit_code = 0) void:
{
- raise Exception { code = EC_exit, exit_status = exit_code };
+ raise Exception { code = EC_exit, name = "exit", exit_status = exit_code };
}
diff --git a/poke/pk-cmd-ios.c b/poke/pk-cmd-ios.c
index 3723b932..1f494e46 100644
--- a/poke/pk-cmd-ios.c
+++ b/poke/pk-cmd-ios.c
@@ -398,7 +398,7 @@ pk_cmd_load_file (int argc, struct pk_cmd_arg argv[],
uint64_t uflags)
else
goto no_file;
- if (pk_compile_file (poke_compiler, filename, NULL /* exit_status */)
+ if (pk_compile_file (poke_compiler, filename, NULL /* exception */)
!= PK_OK)
/* Note that the compiler emits its own error messages. */
goto error;
diff --git a/poke/pk-map.c b/poke/pk-map.c
index cc19c6f1..d4b61c81 100644
--- a/poke/pk-map.c
+++ b/poke/pk-map.c
@@ -502,7 +502,7 @@ pk_map_load_parsed_map (int ios_id, const char *mapname,
condition,
NULL /* end */,
&val,
- NULL /* exit_status */) != PK_OK)
+ NULL /* exception */) != PK_OK)
goto error;
if (pk_type_code (pk_typeof (val)) != PK_INT
@@ -538,7 +538,7 @@ pk_map_load_parsed_map (int ios_id, const char *mapname,
if (pk_compile_buffer (poke_compiler,
defvar_str,
NULL /* end */,
- NULL /* exit_status */) != PK_OK)
+ NULL /* exception */) != PK_OK)
goto error;
}
}
diff --git a/poke/poke.c b/poke/poke.c
index e317bf5d..32671e7c 100644
--- a/poke/poke.c
+++ b/poke/poke.c
@@ -433,10 +433,40 @@ parse_args_2 (int argc, char *argv[])
break;
case 'l':
case LOAD_ARG:
- if (pk_compile_file (poke_compiler, optarg,
- NULL /* exit_status */) != PK_OK)
+ {
+ pk_val exception;
+ int exc_code;
+ const char *exc_name;
+ const char *exc_loc;
+ const char *exc_msg;
+
+ if (pk_compile_file (poke_compiler, optarg, &exception) != PK_OK)
+ goto exit_success;
+ if (exception == PK_NULL)
+ break; /* Everything is good. */
+
+ /* There's an unhandled exception. */
+
+ exc_code = pk_int_value (pk_struct_ref_field_value (exception,
+ "code"));
+ if (exc_code == PK_E_EXIT || poke_quiet_p)
+ goto exit_success;
+
+ exc_name = pk_string_str (pk_struct_ref_field_value (exception,
+ "name"));
+ exc_loc = pk_string_str (pk_struct_ref_field_value (exception,
+ "location"));
+ exc_msg = pk_string_str (pk_struct_ref_field_value (exception,
+ "msg"));
+ pk_printf (_("error: unhandled %s exception while "
+ "loading '%s'%s%s%s%s\n"),
+ exc_name, optarg,
+ STREQ (exc_loc, "") ? "" : " at ",
+ STREQ (exc_loc, "") ? "" : exc_loc,
+ STREQ (exc_msg, "") ? "" : " ",
+ STREQ (exc_msg, "") ? "" : exc_msg);
goto exit_success;
- break;
+ }
case 'c':
case CMD_ARG:
{
@@ -454,14 +484,19 @@ parse_args_2 (int argc, char *argv[])
}
case 'L':
{
- int exit_status;
+ pk_val exception;
+ int exit_status = 0;
/* Build argv in the compiler, with the rest of the
command-line arguments. Then execute the script and
return. */
set_script_args (argc, argv);
- if (pk_compile_file (poke_compiler, optarg, &exit_status) != PK_OK)
+ if (pk_compile_file (poke_compiler, optarg, &exception) != PK_OK)
goto exit_failure;
+ if (exception != PK_NULL)
+ exit_status
+ = pk_int_value (pk_struct_ref_field_value (exception,
+ "exit_status"));
finalize ();
exit (exit_status);
--
2.34.1