From c1c32688a4afc43f6addb99b8b5fa878944a70e3 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 14 Jan 2019 15:42:48 -0800 Subject: Overhaul in progress, mostly working. Moved all the nomsu packages into lib/, including core/*. Changes to how nomsu environments and importing work. --- lib/core/errors.nom | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 lib/core/errors.nom (limited to 'lib/core/errors.nom') 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 +") -- cgit v1.2.3