nitlanguage
/
nit.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
niti: make `catch_count` writable
[nit.git]
/
src
/
interpreter
/
naive_interpreter.nit
diff --git
a/src/interpreter/naive_interpreter.nit
b/src/interpreter/naive_interpreter.nit
index
34530b7
..
eced30f
100644
(file)
--- a/
src/interpreter/naive_interpreter.nit
+++ b/
src/interpreter/naive_interpreter.nit
@@
-119,7
+119,10
@@
class NaiveInterpreter
var escapemark: nullable EscapeMark = null
# The count of `catch` blocs that have been encountered and can catch an abort
var escapemark: nullable EscapeMark = null
# The count of `catch` blocs that have been encountered and can catch an abort
- var catch_count = 0
+ var catch_count = 0 is writable
+
+ # The last error thrown on abort/runtime error where catch_count > 0
+ var last_error: nullable FatalError = null
# Is a return or a break or a continue executed?
# Use this function to know if you must skip the evaluation of statements
# Is a return or a break or a continue executed?
# Use this function to know if you must skip the evaluation of statements
@@
-685,15
+688,25
@@
class NaiveInterpreter
var error_instance = new MutableInstance(modelbuilder.model.null_type) is lazy
end
var error_instance = new MutableInstance(modelbuilder.model.null_type) is lazy
end
+# A runtime error
+class FatalError
+ # The error message
+ var message: String
+
+ # The problematic node, if any
+ var node: nullable ANode
+end
+
# An instance represents a value of the executed program.
abstract class Instance
# The dynamic type of the instance
# ASSERT: not self.mtype.is_anchored
var mtype: MType
# An instance represents a value of the executed program.
abstract class Instance
# The dynamic type of the instance
# ASSERT: not self.mtype.is_anchored
var mtype: MType
- # return true if the instance is the true value.
- # return false if the instance is the true value.
- # else aborts
+ # Return `true` if the instance is the `true` value.
+ #
+ # Return `false` if the instance is the `false` value.
+ # Abort if the instance is not a boolean value.
fun is_true: Bool do abort
# Return true if `self` IS `o` (using the Nit semantic of is)
fun is_true: Bool do abort
# Return true if `self` IS `o` (using the Nit semantic of is)
@@
-748,7
+761,7
@@
class MutableInstance
end
# Special instance to handle primitives values (int, bool, etc.)
end
# Special instance to handle primitives values (int, bool, etc.)
-# The trick it just to encapsulate the <<real>> value
+# The trick is just to encapsulate the “real” value.
class PrimitiveInstance[E]
super Instance
class PrimitiveInstance[E]
super Instance
@@
-820,6
+833,12
@@
redef class ANode
# `v` is used to know if a colored message is displayed or not
fun fatal(v: NaiveInterpreter, message: String)
do
# `v` is used to know if a colored message is displayed or not
fun fatal(v: NaiveInterpreter, message: String)
do
+ # Abort if there is a `catch` block
+ if v.catch_count > 0 then
+ v.last_error = new FatalError(message, self)
+ abort
+ end
+
if v.modelbuilder.toolcontext.opt_no_color.value == true then
sys.stderr.write("Runtime error: {message} ({location.file.filename}:{location.line_start})\n")
else
if v.modelbuilder.toolcontext.opt_no_color.value == true then
sys.stderr.write("Runtime error: {message} ({location.file.filename}:{location.line_start})\n")
else
@@
-1174,9
+1193,9
@@
redef class AMethPropdef
var ns = recvval.fast_cstring(args[1].to_i)
return v.c_string_instance(ns.to_s)
else if pname == "fetch_4_chars" then
var ns = recvval.fast_cstring(args[1].to_i)
return v.c_string_instance(ns.to_s)
else if pname == "fetch_4_chars" then
- return v.int_instance(args[0].val.as(CString).fetch_4_chars(args[1].to_i))
+ return v.uint32_instance(args[0].val.as(CString).fetch_4_chars(args[1].to_i))
else if pname == "fetch_4_hchars" then
else if pname == "fetch_4_hchars" then
- return v.int_instance(args[0].val.as(CString).fetch_4_hchars(args[1].to_i))
+ return v.uint32_instance(args[0].val.as(CString).fetch_4_hchars(args[1].to_i))
else if pname == "utf8_length" then
return v.int_instance(args[0].val.as(CString).utf8_length(args[1].to_i, args[2].to_i))
end
else if pname == "utf8_length" then
return v.int_instance(args[0].val.as(CString).utf8_length(args[1].to_i, args[2].to_i))
end
@@
-1688,13
+1707,8
@@
end
redef class AAbortExpr
redef fun stmt(v)
do
redef class AAbortExpr
redef fun stmt(v)
do
- # Abort as asked if there is no `catch` bloc
- if v.catch_count <= 0 then
- fatal(v, "Aborted")
- exit(1)
- else
- abort
- end
+ fatal(v, "Aborted")
+ exit(1)
end
end
end
end