import literal
import semantize
private import parser::tables
+import mixin
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")
+ var opt_discover_call_trace = new OptionBool("Trace calls of the first invocation of a method", "--discover-call-trace")
redef init
do
# The modelbuilder that know the AST and its associations with the model
var modelbuilder: ModelBuilder
- # The main moduleof the program (used to lookup methoda
+ # The main module of the program (used to lookup method)
var mainmodule: MModule
# The command line arguments of the interpreted program
# arguments[1] is the first argument
var arguments: Array[String]
+ # The main Sys instance
var mainobj: nullable Instance
init(modelbuilder: ModelBuilder, mainmodule: MModule, arguments: Array[String])
return new PrimitiveInstance[Float](ic.mclass_type, val)
end
- # The unique intance of the `true` value.
+ # The unique instance of the `true` value.
var true_instance: Instance
- # The unique intance of the `false` value.
+ # The unique instance of the `false` value.
var false_instance: Instance
- # The unique intance of the `null` value.
+ # The unique instance of the `null` value.
var null_instance: Instance
# Return a new array made of `values`.
return res
end
+ fun value_instance(object: Object): Instance
+ do
+ if object isa Int then
+ return int_instance(object)
+ else if object isa Bool then
+ return bool_instance(object)
+ else if object isa String then
+ return string_instance(object)
+ else
+ abort
+ end
+ end
+
# Return a new native string initialized with `txt`
fun native_string_instance(txt: String): Instance
do
return new PrimitiveInstance[Buffer](ic.mclass_type, val)
end
+ # Return a new String instance for `txt`
+ fun string_instance(txt: String): Instance
+ do
+ var nat = native_string_instance(txt)
+ var res = self.send(self.force_get_primitive_method("to_s_with_length", nat.mtype), [nat, self.int_instance(txt.length)])
+ assert res != null
+ return res
+ end
+
# The current frame used to store local variables of the current method executed
fun frame: Frame do return frames.first
# The stack of all frames. The first one is the current one.
- var frames: List[Frame] = new List[Frame]
+ var frames = new List[Frame]
- # Return a stack stace. One line per function
+ # Return a stack trace. One line per function
fun stack_trace: String
do
var b = new FlatBuffer
f.map[v] = value
end
- # Store known method, used to trace methods as thez are reached
+ # Store known methods, used to trace methods as they are reached
var discover_call_trace: Set[MMethodDef] = new HashSet[MMethodDef]
# Common code for calls to injected methods and normal methods
end
# 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-binding.
+ # Return a value if `mpropdef` is a function, or null if it is a procedure.
+ # The call is direct/static. There is no message-sending/late-binding.
fun call(mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
do
args = call_commons(mpropdef, args)
# Look for the AST node that implements the property
var mproperty = mpropdef.mproperty
+ var val = mpropdef.constant_value
if self.modelbuilder.mpropdef2npropdef.has_key(mpropdef) then
var npropdef = self.modelbuilder.mpropdef2npropdef[mpropdef]
self.parameter_check(npropdef, mpropdef, args)
var nclassdef = self.modelbuilder.mclassdef2nclassdef[mpropdef.mclassdef]
self.parameter_check(nclassdef, mpropdef, args)
return nclassdef.call(self, mpropdef, args)
+ else if val != null then
+ return value_instance(val)
else
fatal("Fatal Error: method {mpropdef} not found in the AST")
abort
end
# Execute a full `callsite` for given `args`
- # Use this method, instead of `send` to execute and control the aditionnal behavior of the call-sites
+ # Use this method, instead of `send` to execute and control the additional behavior of the call-sites
fun callsite(callsite: nullable CallSite, arguments: Array[Instance]): nullable Instance
do
var initializers = callsite.mpropdef.initializers
end
# Execute `mproperty` for a `args` (where `args[0]` is the receiver).
- # Return a falue if `mproperty` is a function, or null if it is a procedure.
- # The call is polimotphic. There is a message-seding/late-bindng according to te receiver (args[0]).
+ # Return a value if `mproperty` is a function, or null if it is a procedure.
+ # The call is polymorphic. There is a message-sending/late-binding according to the receiver (args[0]).
fun send(mproperty: MMethod, args: Array[Instance]): nullable Instance
do
var recv = args.first
var cds = mtype.collect_mclassdefs(self.mainmodule).to_a
self.mainmodule.linearize_mclassdefs(cds)
for cd in cds do
+ if not self.modelbuilder.mclassdef2nclassdef.has_key(cd) then continue
var n = self.modelbuilder.mclassdef2nclassdef[cd]
for npropdef in n.n_propdefs do
if npropdef isa AAttrPropdef then
return res
end
- var collect_attr_propdef_cache = new HashMap[MType, Array[AAttrPropdef]]
+ private var collect_attr_propdef_cache = new HashMap[MType, Array[AAttrPropdef]]
# Fill the initial values of the newly created instance `recv`.
# `recv.mtype` is used to know what must be filled.
var txt = recv.mtype.to_s
return v.native_string_instance(txt)
else if pname == "==" then
- # == is correclt redefined for instances
+ # == is correctly redefined for instances
return v.bool_instance(args[0] == args[1])
else if pname == "!=" then
return v.bool_instance(args[0] != args[1])
else if pname == "is_same_type" then
return v.bool_instance(args[0].mtype == args[1].mtype)
else if pname == "is_same_instance" then
- return v.bool_instance(args[1] != null and args[0].eq_is(args[1]))
+ return v.bool_instance(args[0].eq_is(args[1]))
else if pname == "exit" then
exit(args[1].to_i)
abort
redef fun expr(v)
do
var txt = self.value.as(not null)
- var nat = v.native_string_instance(txt)
- var res = v.send(v.force_get_primitive_method("to_s", nat.mtype), [nat]).as(not null)
- return res
+ return v.string_instance(txt)
end
end
do
var i = v.expr(self.n_expr)
if i == null then return null
- var mtype = v.unanchor_type(self.mtype.as(not null))
if i.mtype isa MNullType then
fatal(v, "Cast failed")
end
var callsite = self.callsite
if callsite != null then
- # Add additionnals arguments for the super init call
+ # Add additional arguments for the super init call
if args.length == 1 then
for i in [0..callsite.msignature.arity[ do
args.add(v.frame.arguments[i+1])
args = v.frame.arguments
end
- # stantard call-next-method
+ # standard call-next-method
var mpropdef = self.mpropdef
mpropdef = mpropdef.lookup_next_definition(v.mainmodule, recv.mtype)
var res = v.call_without_varargs(mpropdef, args)