import typing
import auto_super_init
+redef class ToolContext
+ # --discover-call-trace
+ var opt_discover_call_trace: OptionBool = new OptionBool("Trace calls of the first invocation of a method", "--discover-call-trace")
+
+ redef init
+ do
+ super
+ self.option_context.add_option(self.opt_discover_call_trace)
+ end
+end
+
redef class ModelBuilder
# Execute the program from the entry point (Sys::main) of the `mainmodule'
# `arguments' are the command-line arguments in order
exit(1)
end
+ # Debug on the current node
+ fun debug(message: String)
+ do
+ if frames.is_empty then
+ print message
+ else
+ self.frame.current_node.debug(message)
+ end
+ end
+
+ # Store known method, used to trace methods as thez are reached
+ var discover_call_trace: Set[MMethodDef] = new HashSet[MMethodDef]
+
# Execute `mpropdef' for a `args' (where args[0] is the receiver).
# Return a falue if `mpropdef' is a function, or null if it is a procedure.
# The call is direct/static. There is no message-seding/late-bindng.
fun call(mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
do
+ if self.modelbuilder.toolcontext.opt_discover_call_trace.value and not self.discover_call_trace.has(mpropdef) then
+ self.discover_call_trace.add mpropdef
+ self.debug("Discovered {mpropdef}")
+ end
var vararg_rank = mpropdef.msignature.vararg_rank
if vararg_rank >= 0 then
assert args.length >= mpropdef.msignature.arity + 1 # because of self
return v.int_instance(recv <=> args[1].val.as(Char))
end
else if cname == "Float" then
- if pname == "+" then
+ if pname == "unary -" then
+ return v.float_instance(-args[0].to_f)
+ else if pname == "+" then
return v.float_instance(args[0].to_f + args[1].to_f)
else if pname == "-" then
return v.float_instance(args[0].to_f - args[1].to_f)
var res = sys.system(recvval.to_s)
return v.int_instance(res)
end
+ else if cname == "Int" then
+ if pname == "rand" then
+ return v.int_instance(args[0].to_i.rand)
+ end
+ else if cname == "Float" then
+ if pname == "cos" then
+ return v.float_instance(args[0].to_f.cos)
+ else if pname == "sin" then
+ return v.float_instance(args[0].to_f.sin)
+ end
else if pname == "native_argc" then
return v.int_instance(v.arguments.length)
else if pname == "native_argv" then
return v.native_string_instance(txt)
else if pname == "get_time" then
return v.int_instance(get_time)
+ else if pname == "atan2" then
+ return v.float_instance(atan2(args[1].to_f, args[2].to_f))
+ else if pname == "pi" then
+ return v.float_instance(pi)
else if pname == "lexer_goto" then
return v.int_instance(lexer_goto(args[1].to_i, args[2].to_i))
else if pname == "lexer_accept" then