1
0
mirror of https://github.com/janet-lang/janet synced 2025-03-28 19:16:56 +00:00

Add edefer.

Also improve error messages from vm internal errors.
(Show bad value, not its type).
This commit is contained in:
Calvin Rose 2020-04-13 20:24:11 -05:00
parent 6c4ed0409d
commit 93fc11ea21
3 changed files with 18 additions and 5 deletions

View File

@ -2,6 +2,7 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Unreleased - ??? ## Unreleased - ???
- Add `edefer` macro to core.
- A struct/table literal/constructor with duplicate keys will use the last value given. - A struct/table literal/constructor with duplicate keys will use the last value given.
Previously, this was inconsistent between tables and structs, literals and constructor functions. Previously, this was inconsistent between tables and structs, literals and constructor functions.
- Add debugger to core. The debugger functions are only available - Add debugger to core. The debugger functions are only available

View File

@ -301,7 +301,19 @@
,form ,form
(if (= (,fiber/status ,f) :dead) (if (= (,fiber/status ,f) :dead)
,r ,r
(propagate ,r ,f))))) (,propagate ,r ,f)))))
(defmacro edefer
"Run form after body in the case that body terminates abnormally (an error or user signal 0-4).
Otherwise, return last form in body."
[form & body]
(with-syms [f r]
~(do
(def ,f (,fiber/new (fn [] ,;body) :ti))
(def ,r (,resume ,f))
(if (= (,fiber/status ,f) :dead)
,r
(do ,form (,propagate ,r ,f))))))
(defmacro prompt (defmacro prompt
"Set up a checkpoint that can be returned to. Tag should be a value "Set up a checkpoint that can be returned to. Tag should be a value
@ -314,7 +326,7 @@
(def [,target ,payload] ,res) (def [,target ,payload] ,res)
(if (,= ,tag ,target) (if (,= ,tag ,target)
,payload ,payload
(propagate ,res ,fib))))) (,propagate ,res ,fib)))))
(defmacro chr (defmacro chr
"Convert a string of length 1 to its byte (ascii) value at compile time." "Convert a string of length 1 to its byte (ascii) value at compile time."

View File

@ -107,13 +107,13 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL;
#define vm_assert_type(X, T) do { \ #define vm_assert_type(X, T) do { \
if (!(janet_checktype((X), (T)))) { \ if (!(janet_checktype((X), (T)))) { \
vm_commit(); \ vm_commit(); \
janet_panicf("expected %T, got %t", (1 << (T)), (X)); \ janet_panicf("expected %T, got %v", (1 << (T)), (X)); \
} \ } \
} while (0) } while (0)
#define vm_assert_types(X, TS) do { \ #define vm_assert_types(X, TS) do { \
if (!(janet_checktypes((X), (TS)))) { \ if (!(janet_checktypes((X), (TS)))) { \
vm_commit(); \ vm_commit(); \
janet_panicf("expected %T, got %t", (TS), (X)); \ janet_panicf("expected %T, got %v", (TS), (X)); \
} \ } \
} while (0) } while (0)
@ -910,7 +910,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
if (janet_indexed_view(stack[D], &vals, &len)) { if (janet_indexed_view(stack[D], &vals, &len)) {
janet_fiber_pushn(fiber, vals, len); janet_fiber_pushn(fiber, vals, len);
} else { } else {
janet_panicf("expected %T, got %t", JANET_TFLAG_INDEXED, stack[D]); janet_panicf("expected %T, got %v", JANET_TFLAG_INDEXED, stack[D]);
} }
} }
stack = fiber->data + fiber->frame; stack = fiber->data + fiber->frame;