aboutsummaryrefslogtreecommitdiff
path: root/lib/core/errors.nom
diff options
context:
space:
mode:
Diffstat (limited to 'lib/core/errors.nom')
-rw-r--r--lib/core/errors.nom131
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/core/errors.nom b/lib/core/errors.nom
new file mode 100644
index 0000000..c878bb7
--- /dev/null
+++ b/lib/core/errors.nom
@@ -0,0 +1,131 @@
+#!/usr/bin/env nomsu -V6.14
+#
+ This file contains basic error reporting code
+
+use "core/metaprogramming"
+use "core/operators"
+use "core/control_flow"
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(fail $msg) compiles to "error(\(($msg as lua expr) if $msg else "nil"), 0);"
+(assume $condition) compiles to:
+ lua> ("
+ local \$assumption = 'Assumption failed: '..tostring((\$condition):get_source_code())
+ ")
+
+ return
+ Lua ("
+ if not \($condition as lua expr) then
+ error(\(quote "\$assumption"), 0)
+ end
+ ")
+
+(assume $a == $b) compiles to:
+ lua> "local \$assumption = 'Assumption failed: '..tostring(\(\($a == $b) as nomsu))"
+
+ define mangler
+
+ return
+ Lua ("
+ do
+ local \(mangle "a"), \(mangle "b") = \($a as lua expr), \($b as lua expr)
+ if \(mangle "a") ~= \(mangle "b") then
+ error(\(quote "\$assumption").."\\n"..tostring(\(mangle "a")).." != "..tostring(\
+ ..\(mangle "b")), 0)
+ end
+ end
+ ")
+
+test:
+ try: fail
+ $worked = (no)
+ try:
+ fail "xx"
+ ..if it fails with $failure:
+ $worked = (yes)
+ ..if it succeeds:
+ fail "'try' incorrectly ran success case."
+ assume $failure == "xx"
+ unless $worked:
+ fail "'try' failed to recover from failure"
+
+# Try/except
+[
+ try $action if it succeeds $success if it fails with $msg $fallback
+ try $action if it fails with $msg $fallback if it succeeds $success
+] all compile to:
+ $success_lua = ($success as lua)
+ if ((#"\$success_lua") > 0):
+ $success_lua, add "\n"
+ $success_lua, prepend "-- Success:\n"
+ $success_lua,
+ add "if not _fell_through then return table.unpack(_result, 2) end"
+ $fallback_lua = ($fallback as lua)
+ if ((#"\$fallback_lua") > 0):
+ $msg_lua = ($msg as lua expr)
+ if ((#"\$msg_lua") > 0):
+ $fallback_lua, prepend "\n\$msg_lua = _result[2]\n"
+ if ($msg_lua, text, is lua id):
+ $fallback_lua, add free vars [($msg_lua, text)]
+ $fallback_lua, prepend "-- Failure:"
+ return
+ Lua ("
+ do
+ local _fell_through = false
+ local _result = {pcall(function()
+ \($action as lua)
+ _fell_through = true
+ end)}
+ if _result[1] then
+ \$success_lua
+ else
+ \$fallback_lua
+ end
+ end
+ ")
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(try $action) parses as
+ try $action if it succeeds (do nothing) if it fails (do nothing)
+
+(try $action if it fails $fallback) parses as
+ try $action if it succeeds (do nothing) if it fails $fallback
+
+(try $action if it fails with $msg $fallback) parses as
+ try $action if it succeeds (do nothing) if it fails with $msg $fallback
+
+(try $action if it succeeds $success) parses as
+ try $action if it succeeds $success if it fails (do nothing)
+
+(try $action if it fails $fallback if it succeeds $success) parses as
+ try $action if it fails with (=lua "") $fallback if it succeeds $success
+
+(try $action if it succeeds $success if it fails $fallback) parses as
+ try $action if it succeeds $success if it fails with (=lua "") $fallback
+
+test:
+ $success = (no)
+ try:
+ do: fail
+ ..then always:
+ $success = (yes)
+ ..if it succeeds:
+ fail "'try ... then always ...' didn't propagate failure"
+
+ unless $success:
+ fail "'try ... then always ...' didn't execute the 'always' code"
+
+(do $action then always $final_action) compiles to ("
+ do -- do/then always
+ local _fell_through = false
+ local _results = {pcall(function()
+ \($action as lua)
+ _fell_through = true
+ end)}
+ \($final_action as lua)
+ if not _results[1] then error(_results[2], 0) end
+ if not _fell_through then return table.unpack(_results, 2) end
+ end
+")