aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2019-01-16 16:31:49 -0800
committerBruce Hill <bruce@bruce-hill.com>2019-01-16 16:32:02 -0800
commit8ca7749b5509a40256195563fa52d3ede4bd1a34 (patch)
treea3e597668b6a53048e440d9630b48f3a2efb3926 /lib
parent25e1ccc025e27d5ef7f1cc23e82e4836aa5a07f4 (diff)
Better error messaging (using pretty_error in more places)
Diffstat (limited to 'lib')
-rw-r--r--lib/compatibility/3.5.5.6.nom2
-rw-r--r--lib/compatibility/3.nom6
-rw-r--r--lib/compatibility/4.11.nom6
-rw-r--r--lib/compatibility/4.12.nom12
-rw-r--r--lib/core/control_flow.nom64
-rw-r--r--lib/core/errors.nom56
-rw-r--r--lib/core/metaprogramming.nom30
-rw-r--r--lib/object.nom125
8 files changed, 101 insertions, 200 deletions
diff --git a/lib/compatibility/3.5.5.6.nom b/lib/compatibility/3.5.5.6.nom
index d9bba4f..9887498 100644
--- a/lib/compatibility/3.5.5.6.nom
+++ b/lib/compatibility/3.5.5.6.nom
@@ -8,4 +8,4 @@ use "compatibility/compatibility"
upgrade action "traceback" to "3.5.5.6" via
for $tree:
- compile error at $tree "'traceback' has been deprecated."
+ at $tree fail "Upgrade error: 'traceback' has been deprecated."
diff --git a/lib/compatibility/3.nom b/lib/compatibility/3.nom
index 966dbf9..6ce3fdc 100644
--- a/lib/compatibility/3.nom
+++ b/lib/compatibility/3.nom
@@ -11,5 +11,7 @@ upgrade action (me) to "3" as $me
upgrade action (@) to "3" as $me
upgrade action "as" to "3" via
for $tree:
- compile error at $tree "Object API has changed and 'as' is no longer supported."
- "Use ($obj, action ...) instead of (as $obj: action ...)"
+ at $tree fail ("
+ Upgrade error: Object API has changed and 'as' is no longer supported.
+ Hint: Use ($obj, action ...) instead of (as $obj: action ...)
+ ")
diff --git a/lib/compatibility/4.11.nom b/lib/compatibility/4.11.nom
index 88ea7b3..053e1c8 100644
--- a/lib/compatibility/4.11.nom
+++ b/lib/compatibility/4.11.nom
@@ -29,8 +29,10 @@ upgrade action "set" to "4.11" via
upgrade action "1 with 2 ~>" to "4.11" via
for $tree:
- compile error at $tree "This method has been deprecated."
- "Perhaps this could be use ($tree, map ...) instead."
+ at $tree fail ("
+ Upgrade error: This method has been deprecated.
+ Hint: Perhaps this could be use ($tree, map ...) instead.
+ ")
# Changing filesystem API:
upgrade action (for file $f in $path $body) to "4.11" as
diff --git a/lib/compatibility/4.12.nom b/lib/compatibility/4.12.nom
index bb1af0b..033f6ed 100644
--- a/lib/compatibility/4.12.nom
+++ b/lib/compatibility/4.12.nom
@@ -9,10 +9,14 @@ use "compatibility/compatibility"
upgrade action "do next repeat" to "4.12" via
for $tree:
- compile error at $tree "This method has been deprecated."
- "Use either (do next) or (go to (label)) instead."
+ at $tree fail ("
+ Upgrade error: This method has been deprecated.
+ Hint: Use either (do next) or (go to (label)) instead.
+ ")
upgrade action "stop repeating" to "4.12" via
for $tree:
- compile error at $tree "This method has been deprecated."
- "Use either (stop) or (go to (label)) instead."
+ at $tree fail ("
+ Upgrade error: This method has been deprecated.
+ Hint: Use either (stop) or (go to (label)) instead.
+ ")
diff --git a/lib/core/control_flow.nom b/lib/core/control_flow.nom
index 715630b..c4c1770 100644
--- a/lib/core/control_flow.nom
+++ b/lib/core/control_flow.nom
@@ -328,29 +328,34 @@ test:
$clause = "if"
$else_allowed = (yes)
unless ($body.type is "Block"):
- compile error at $body "'if' expected a Block, but got a \($body.type)."
- "Perhaps you forgot to put a ':' after 'if'?"
+ at $body fail ("
+ Compile error: 'if' expected a Block, but got a \($body.type).
+ Hint: Perhaps you forgot to put a ':' after 'if'?
+ ")
for $line in $body:
unless
(($line.type is "Action") and ((size of $line) >= 2)) and
$line.(size of $line) is "Block" syntax tree
..:
- compile error at $line "Invalid line for the body of an 'if' block." ("
- Each line should contain one or more conditional expressions followed by a block, or "else"\
- .. followed by a block.
+ at $line fail ("
+ Compile error: Invalid line for the body of an 'if' block.
+ Hint: Each line should contain one or more conditional expressions followed \
+ ..by a block, or "else" followed by a block.
")
$action = $line.(size of $line)
if (($line.1 is "else") and ((size of $line) == 2)):
unless $else_allowed:
- compile error at $line "You can't have two 'else' blocks."
- "Merge all of the 'else' blocks together."
+ at $line fail ("
+ Compile error: You can't have two 'else' blocks.
+ Hint: Merge all of the 'else' blocks together.
+ ")
unless ((size of "\$code") > 0):
- compile error at $line
- .."You can't have an 'else' block without a preceding condition" ("
- If you want the code in this block to always execute, you don't need a conditional block \
- ..around it. Otherwise, make sure the 'else' block comes last.
+ at $line fail ("
+ Compile error: You can't have an 'else' block without a preceding condition.
+ Hint: If you want the code in this block to always execute, you don't need a \
+ ..conditional block around it. Otherwise, make sure the 'else' block comes last.
")
$code, add "\nelse\n " ($action as lua)
@@ -365,8 +370,10 @@ test:
$clause = "\nelseif"
if ((size of "\$code") == 0):
- compile error at $body "'if' block has an empty body."
- "This means nothing would happen, so the 'if' block should be deleted."
+ at $body fail ("
+ Compile error: 'if' block has an empty body.
+ Hint: This means nothing would happen, so the 'if' block should be deleted.
+ ")
$code, add "\nend --when"
return $code
@@ -392,28 +399,33 @@ test:
$else_allowed = (yes)
define mangler
unless ($body.type is "Block"):
- compile error at $body "'if' expected a Block, but got a \($body.type)"
- "Perhaps you forgot to put a ':' after the 'is'?"
+ at $body fail ("
+ Compile error: 'if' expected a Block, but got a \($body.type).
+ Hint: Perhaps you forgot to put a ':' after the 'is'?
+ ")
for $line in $body:
unless
(($line.type is "Action") and ((size of $line) >= 2)) and
$line.(size of $line) is "Block" syntax tree
..:
- compile error at $line "Invalid line for 'if' block." ("
- Each line should contain expressions followed by a block, or "else" followed by a block
+ at $line fail ("
+ Compile error: Invalid line for 'if' block.
+ Hint: Each line should contain expressions followed by a block, or "else" followed by a block.
")
$action = $line.(size of $line)
if (($line.1 is "else") and ((size of $line) == 2)):
unless $else_allowed:
- compile error at $line "You can't have two 'else' blocks."
- "Merge all of the 'else' blocks together."
+ at $line fail ("
+ Compile error: You can't have two 'else' blocks.
+ Hint: Merge all of the 'else' blocks together.
+ ")
unless ((size of "\$code") > 0):
- compile error at $line
- .."You can't have an 'else' block without a preceding condition" ("
- If you want the code in this block to always execute, you don't need a conditional block \
- ..around it. Otherwise, make sure the 'else' block comes last.
+ at $line fail ("
+ Compile error: You can't have an 'else' block without a preceding condition.
+ Hint: If you want the code in this block to always execute, you don't need \
+ ..a conditional block around it. Otherwise, make sure the 'else' block comes last.
")
$code, add "\nelse\n " ($action as lua)
@@ -428,8 +440,10 @@ test:
$clause = "\nelseif"
if ((size of "\$code") == 0):
- compile error at $body "'if' block has an empty body."
- "This means nothing would happen, so the 'if' block should be deleted."
+ at $body fail ("
+ Compile error: 'if' block has an empty body.
+ Hint: This means nothing would happen, so the 'if' block should be deleted.
+ ")
$code, add "\nend --when"
return
diff --git a/lib/core/errors.nom b/lib/core/errors.nom
index 9a2cc9b..0b67400 100644
--- a/lib/core/errors.nom
+++ b/lib/core/errors.nom
@@ -8,32 +8,36 @@ 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
- ")
+(fail $msg) compiles to
+ LuaCode
+ "at_1_fail(\(quote $msg.source), 'Failure: '..\($msg as lua expr))"
+ ..if $msg else "error('Failure', 0)"
-(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) compiles to ("
+ if not \($condition as lua expr) then
+ at_1_fail(\(quote "\($condition.source)"), "Assumption failed: This is not true.")
+ end
+")
+
+(assume $a == $b) compiles to ("
+ do
+ local _a, _b = \($a as lua expr), \($b as lua expr)
+ if _a ~= _b then
+ at_1_fail(\(quote "\($a.source)"),
+ "Assumption failed: This value is "..tostring(_a)..", but it was supposed to be "..tostring(_b)..".")
+ end
+ end
+")
+
+(assume $a != $b) compiles to ("
+ do
+ local _a, _b = \($a as lua expr), \($b as lua expr)
+ if _a == _b then
+ at_1_fail(\(quote "\($a.source)"),
+ "Assumption failed: This value is "..tostring(_a)..", but it wasn't supposed to be.")
+ end
+ end
+")
test:
try: fail
@@ -44,7 +48,7 @@ test:
$worked = (yes)
..if it succeeds:
fail "'try' incorrectly ran success case."
- assume $failure == "xx"
+ assume ($failure, matches "xx")
unless $worked:
fail "'try' failed to recover from failure"
diff --git a/lib/core/metaprogramming.nom b/lib/core/metaprogramming.nom
index 9b3d5c4..a17a33c 100644
--- a/lib/core/metaprogramming.nom
+++ b/lib/core/metaprogramming.nom
@@ -34,14 +34,15 @@ lua> ("
local arg_lua = SyntaxTree:is_instance(arg) and \(nomsu environment):compile(arg):text() or arg
if arg_lua == "..." then
if i < #\$args then
- compile_error_at(SyntaxTree:is_instance(arg) and arg or nil,
- "Extra arguments must come last.", "Try removing any arguments after \
- ..(*extra arguments*)")
+ at_1_fail(SyntaxTree:is_instance(arg) and arg or nil,
+ "Compile error: Extra arguments must come last. "..
+ "Hint: Try removing any arguments after (*extra arguments*)")
end
elseif not arg_lua:is_lua_id() then
- compile_error_at(SyntaxTree:is_instance(arg) and arg or nil,
- "This does not compile to a Lua identifier, so it can't be used as a function argument.",
- "This should probably be a Nomsu variable instead (like $x).")
+ at_1_fail(SyntaxTree:is_instance(arg) and arg or nil,
+ "Compile error: This does not compile to a Lua identifier, so it "..
+ "can't be used as a function argument."..
+ "Hint: This should probably be a Nomsu variable instead (like $x).")
end
lua:add(i > 1 and ", " or "", arg_lua)
body_lua:remove_free_vars({arg_lua})
@@ -98,7 +99,7 @@ lua> ("
($actions all compile to $body) compiles to:
lua> ("
if \$actions.type ~= "List" then
- compile_error(\$actions, "This should be a list of actions.")
+ at_1_fail(\$actions, "Compile error: This should be a list of actions.")
end
local lua = \(\($actions.1 compiles to $body) as lua)
local \$args = List{"\(nomsu environment)", unpack(\$actions[1]:get_args())}
@@ -151,7 +152,7 @@ test:
lua:add(\$action:get_stub():as_lua_id())
lua:add_free_vars({\$action:get_stub():as_lua_id()})
else
- compile_error_at(\$action, "Expected an action or method call here")
+ at_1_fail(\$action, "Compile error: Expected an action or method call here")
end
lua:add(" = ", \(\($action -> $body) as lua), ";")
return lua
@@ -241,7 +242,7 @@ test:
lua> ("
local replacements = {}
if \$actions.type ~= "List" then
- compile_error(\$actions, "This should be a list.")
+ at_1_fail(\$actions, "Compile error: This should be a list.")
end
for i,arg in ipairs(\$actions[1]:get_args()) do
replacements[arg[1]] = \(nomsu environment):compile(arg):text()
@@ -293,9 +294,8 @@ external:
if \$tree.type == 'Block' then
tree_lua = LuaCode:from(\$tree.source, '(function()\\n ', tree_lua, '\\nend)()')
elseif \$tree.type == 'MethodCall' and #\$tree > 2 then
- compile_error_at(\$tree, "This must be a single value instead of "..(#\$tree - 1).."\
- .. method calls.",
- "Replace this with a single method call.")
+ at_1_fail(\$tree, "Compile error: This must be a single value instead of "..
+ (#\$tree - 1).." method calls. Hint: Replace this with a single method call.")
end
return tree_lua
")
@@ -311,9 +311,9 @@ external:
lua> ("
local lua = \($var as lua)
if not lua:text():is_a_lua_id() then
- compile_error(\$var,
- "This is supposed to be something that compiles to a valid Lua identifier.",
- "This should probably be a variable.")
+ at_1_fail(\$var, "Compile error: "..
+ "This is supposed to be something that compiles to a valid Lua identifier. "..
+ "Hint: This should probably be a variable.")
end
return lua
")
diff --git a/lib/object.nom b/lib/object.nom
deleted file mode 100644
index 99981a0..0000000
--- a/lib/object.nom
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env nomsu -V6.15.13.8
-#
- This file contains the implementation of an Object-Oriented programming system.
-
-$globals.METAMETHOD_MAP = {
- ."as text" = "__tostring", ."clean up" = "__gc", ."+ 1" = "__add"
- ."- 1" = "__sub", ."* 1" = "__mul", ."/ 1" = "__div", ."-" = "__unm"
- ."// 1" = "__idiv", ."mod 1" = "__mod", ."^ 1" = "__pow", ."& 1" = "__band"
- ."| 1" = "__bor", ."~ 1" = "__bxor", ."~" = "__bnot", ."<< 1" = "__bshl"
- .">> 1" = "__bshr", ."== 1" = "__eq", ."< 1" = "__lt", ."<= 1" = "__le"
- ."set 1 = 2" = "__newindex", .size = "__len", .iterate = "__ipairs"
- ."iterate all" = "__pairs"
-}
-
-test:
- object (Dog):
- (Dog).genus = "Canus"
- my action [set up]:
- $me.barks or= 0
-
- my action [bark, woof]:
- $barks = [: for $ in 1 to $me.barks: add "Bark!"]
- return ($barks, joined with " ")
-
- my action [get pissed off]: $me.barks += 1
- $d = (Dog {.barks = 2})
- assume (type of $d) == "Dog"
- assume ($d is a "Dog")
- assume $d.barks == 2
- assume (($d, bark) == "Bark! Bark!")
- assume (($d, woof) == "Bark! Bark!")
- $d, get pissed off
- assume ($d.barks == 3)
- assume (($d, bark) == "Bark! Bark! Bark!")
- assume ($d.genus == "Canus")
- assume ("\($d.class)" == "Dog")
- assume ($d.genus == "Canus")
- assume ($d.barks == 3)
- $d2 = (Dog {})
- unless ($d2.barks == 0):
- fail "Default initializer failed"
-
- with [$d = (Dog {.barks = 1})]:
- assume (($d, bark) == "Bark!")
-
- object (Corgi) extends (Dog):
- my action [sploot] "splooted"
- my action [bark, woof]:
- $barks = [: for $ in 1 to $me.barks: add "Yip!"]
- return ($barks, joined with " ")
-
- $corg = (Corgi {})
- assume ($corg.barks == 0)
- with [$d = (Corgi {.barks = 1})]:
- unless (($d, sploot) == "splooted"):
- fail "subclass method failed"
-
- unless (($d, bark) == "Yip!"):
- fail "inheritance failed"
-
- assume (($d, woof) == "Yip!")
-
- with [$d = (Dog {.barks = 2})]:
- assume (($d, bark) == "Bark! Bark!")
-
-(my action $actions $body) compiles to:
- lua> ("
- local fn_name = \$actions[1].stub:as_lua_id()
- local \$args = List(\$actions[1]:get_args())
- table.insert(\$args, 1, \(\$me))
- local lua = LuaCode("class.", fn_name, " = ", \(\($args -> $body) as lua))
- for i=2,#\$actions do
- local alias = \$actions[i]
- local alias_name = alias.stub:as_lua_id()
- local \$alias_args = List(alias:get_args())
- table.insert(\$alias_args, 1, \(\$me))
- lua:add("\\nclass.", alias_name, " = ")
- if \$args == \$alias_args then
- lua:add("class.", fn_name)
- else
- lua:add(\(\($alias_args -> $actions.1) as lua))
- end
- end
- return lua
- ")
-
-(object $classname extends $parent $class_body) compiles to:
- unless ($classname.type == "Action"):
- compile error at $classname
- "Expected this to be an action, not a \$classname.type"
-
- for $ in $classname:
- unless ($ is text):
- compile error at $ "Class names should not have arguments."
-
- return
- Lua ("
- do
- local class = {name=\(quote $classname.stub)}
- class.__type = class.name
- setmetatable(class, {
- __index=\($parent as lua expr),
- __tostring=function(cls) return cls.name end,
- __call=function(cls, inst)
- if inst == nil then return cls end
- inst = setmetatable(inst, cls)
- if inst.set_up then inst:set_up() end
- return inst
- end,
- })
- \(nomsu environment name)[class.name:as_lua_id()] = class
- class.__index = class
- class.class = class
- class.__tostring = function(inst)
- return inst.name..getmetatable(Dict{}).__tostring(inst)
- end
- \($class_body as lua)
- for stub,metamethod in pairs(globals.METAMETHOD_MAP) do
- class[metamethod] = class[stub:as_lua_id()]
- end
- end
- ")
-
-(object $classname $class_body) parses as
- object $classname extends (nil) $class_body