literal") shorthand, deprecating Lua value, and more use of Lua "..." with text interpolations.
106 lines
3.6 KiB
Plaintext
106 lines
3.6 KiB
Plaintext
#!/usr/bin/env nomsu -V4.8.10
|
|
#
|
|
This file contains basic error reporting code
|
|
|
|
use "core/metaprogramming.nom"
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(barf %msg) compiles to "error(\(=lua "\%msg and \(%msg as lua expr) or 'nil'"), 0);"
|
|
(compile error at %tree %msg) compiles to "\
|
|
..nomsu:compile_error(\(%tree as lua expr), \(%msg as lua expr))"
|
|
(compile error at %tree %msg hint %hint) compiles to "\
|
|
..nomsu:compile_error(\(%tree as lua expr), \(%msg as lua expr), \(%hint as lua expr))"
|
|
|
|
(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"
|
|
|
|
(assume %condition or barf %message) compiles to "\
|
|
..if not \(%condition as lua expr) then
|
|
error(\(%message as lua expr), 0)
|
|
end"
|
|
|
|
test:
|
|
try (barf) and if it succeeds: barf "try failed."
|
|
%worked = (no)
|
|
try (barf) and if it barfs: %worked = (yes)
|
|
assume %worked or barf "try/catch failed"
|
|
%x = 1
|
|
try:
|
|
%x = 2
|
|
do (barf) then always: %x = 3
|
|
..and if it barfs: do nothing
|
|
|
|
assume (%x == 3) or barf "do/then always failed"
|
|
|
|
# Try/except
|
|
[..]
|
|
try %action and if it succeeds %success or if it barfs %msg %fallback
|
|
try %action and if it barfs %msg %fallback or if it succeeds %success
|
|
..all compile to "\
|
|
..do
|
|
local fell_through = false
|
|
local err, erred = nil, false
|
|
local ok, ret = xpcall(function()
|
|
\(%action as lua statements)
|
|
fell_through = true
|
|
end, function(\(=lua "\%fallback and \(%msg as lua expr) or ''"))
|
|
local ok, ret = pcall(function()
|
|
\((=lua "\%fallback or \%msg") as lua statements)
|
|
end)
|
|
if not ok then err, erred = ret, true end
|
|
end)
|
|
if ok then
|
|
\(%success as lua statements)
|
|
if not fell_through then
|
|
return ret
|
|
end
|
|
elseif erred then
|
|
error(err, 0)
|
|
end
|
|
end"
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#
|
|
[..]
|
|
try %action and if it succeeds %success or if it barfs %fallback
|
|
try %action and if it barfs %fallback or if it succeeds %success
|
|
..all parse as (..)
|
|
try %action and if it succeeds %success or if it barfs (=lua "") %fallback
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
(try %action) parses as (..)
|
|
try %action and if it succeeds (do nothing) or if it barfs (do nothing)
|
|
|
|
#(try %action and if it barfs %fallback) parses as (..)
|
|
try %action and if it succeeds (do nothing) or if it barfs %fallback
|
|
|
|
(try %action and if it barfs %msg %fallback) parses as (..)
|
|
try %action and if it succeeds (do nothing) or if it barfs %msg %fallback
|
|
|
|
(try %action and if it succeeds %success) parses as (..)
|
|
try %action and if it succeeds %success or if it barfs (do nothing)
|