#!/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 ")