nomsu/core/errors.nom
Bruce Hill 0f0fb2256a Major overhaul of how modules and environments work, along with some
steamlining and tweaks to the makefile. Version bump: 6.14.13.8
2019-01-10 16:35:08 -08:00

131 lines
4.0 KiB
Plaintext

#!/usr/bin/env nomsu -V6.14
#
This file contains basic error reporting code
use "core/metaprogramming"
use "core/operators"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(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
")