The visitor that interprets the Nit Program by walking on the AST

Introduced properties

type FRAME: Frame

nitc :: NaiveInterpreter :: FRAME

The virtual type of the frames used in the execution engine
private var _arguments: Array[String]

nitc :: NaiveInterpreter :: _arguments

The command line arguments of the interpreted program
private var _c_compiler: String

nitc :: NaiveInterpreter :: _c_compiler

External compiler used to generate the foreign code library
private var _catch_count: Int

nitc :: NaiveInterpreter :: _catch_count

The count of catch blocs that have been encountered and can catch an abort
private var _compile_dir: String

nitc :: NaiveInterpreter :: _compile_dir

Where to store generated C and extracted code
private var _discover_call_trace: Set[MMethodDef]

nitc :: NaiveInterpreter :: _discover_call_trace

Store known methods, used to trace methods as they are reached
private var _error_instance: MutableInstance

nitc :: NaiveInterpreter :: _error_instance

Placebo instance used to mark internal error result when null already have a meaning.
private var _escapemark: nullable EscapeMark

nitc :: NaiveInterpreter :: _escapemark

Is a return, a break or a continue executed?
private var _escapevalue: nullable Instance

nitc :: NaiveInterpreter :: _escapevalue

The value associated with the current return/break/continue, if any.
private var _false_instance: Instance

nitc :: NaiveInterpreter :: _false_instance

The unique instance of the false value.
private var _frames: List[FRAME]

nitc :: NaiveInterpreter :: _frames

The stack of all frames. The first one is the current one.
private var _last_error: nullable FatalError

nitc :: NaiveInterpreter :: _last_error

The last error thrown on abort/runtime error where catch_count > 0
private var _mainmodule: MModule

nitc :: NaiveInterpreter :: _mainmodule

The main module of the program (used to lookup method)
private var _mainobj: nullable Instance

nitc :: NaiveInterpreter :: _mainobj

The main Sys instance
private var _modelbuilder: ModelBuilder

nitc :: NaiveInterpreter :: _modelbuilder

The modelbuilder that know the AST and its associations with the model
private var _null_instance: Instance

nitc :: NaiveInterpreter :: _null_instance

The unique instance of the null value.
private var _onces: Map[ANode, Instance]

nitc :: NaiveInterpreter :: _onces

Map used to store values of nodes that must be evaluated once in the system (AOnceExpr)
private var _routine_types: Set[String]

nitc :: NaiveInterpreter :: _routine_types

Name of all supported functional names
private var _true_instance: Instance

nitc :: NaiveInterpreter :: _true_instance

The unique instance of the true value.
fun aexprs_to_instances(aexprs: Iterator[AExpr]): nullable Array[Instance]

nitc :: NaiveInterpreter :: aexprs_to_instances

Consumes an iterator of expressions and tries to map each element to
fun arguments: Array[String]

nitc :: NaiveInterpreter :: arguments

The command line arguments of the interpreted program
protected fun arguments=(arguments: Array[String])

nitc :: NaiveInterpreter :: arguments=

The command line arguments of the interpreted program
fun array_instance(values: Array[Instance], elttype: MType): Instance

nitc :: NaiveInterpreter :: array_instance

Return a new array made of values.
fun bool_instance(val: Bool): Instance

nitc :: NaiveInterpreter :: bool_instance

Return the boolean instance associated with val.
fun byte_instance(val: Byte): Instance

nitc :: NaiveInterpreter :: byte_instance

Return the byte instance associated with val.
private fun c_compiler: String

nitc :: NaiveInterpreter :: c_compiler

External compiler used to generate the foreign code library
private fun c_compiler=(c_compiler: String)

nitc :: NaiveInterpreter :: c_compiler=

External compiler used to generate the foreign code library
fun c_string_instance(txt: String): Instance

nitc :: NaiveInterpreter :: c_string_instance

Return a new C string initialized with txt
fun c_string_instance_fast_cstr(txt: CString, from: Int): Instance

nitc :: NaiveInterpreter :: c_string_instance_fast_cstr

Return a new C string instance sharing the same data space as txt
fun c_string_instance_from_ns(txt: CString, len: Int): Instance

nitc :: NaiveInterpreter :: c_string_instance_from_ns

Return a new C string initialized with txt
fun c_string_instance_len(length: Int): PrimitiveInstance[CString]

nitc :: NaiveInterpreter :: c_string_instance_len

Return a new C string initialized of length
fun call(mpropdef: MMethodDef, args: Array[Instance]): nullable Instance

nitc :: NaiveInterpreter :: call

Execute mpropdef for a args (where args[0] is the receiver).
fun callsite(callsite: nullable CallSite, arguments: Array[Instance]): nullable Instance

nitc :: NaiveInterpreter :: callsite

Execute a full callsite for given args
fun catch_count: Int

nitc :: NaiveInterpreter :: catch_count

The count of catch blocs that have been encountered and can catch an abort
fun catch_count=(catch_count: Int)

nitc :: NaiveInterpreter :: catch_count=

The count of catch blocs that have been encountered and can catch an abort
fun char_instance(val: Char): Instance

nitc :: NaiveInterpreter :: char_instance

Return the char instance associated with val.
fun collect_attr_propdef(mtype: MType): Array[AAttrPropdef]

nitc :: NaiveInterpreter :: collect_attr_propdef

Collect attributes of a type in the order of their init
private fun compile_dir: String

nitc :: NaiveInterpreter :: compile_dir

Where to store generated C and extracted code
private fun compile_dir=(compile_dir: String)

nitc :: NaiveInterpreter :: compile_dir=

Where to store generated C and extracted code
fun current_node: nullable ANode

nitc :: NaiveInterpreter :: current_node

The current node, used to print errors, debug and stack-traces
fun current_receiver_class: MClassType

nitc :: NaiveInterpreter :: current_receiver_class

The dynamic type of the current self
fun debug(message: String)

nitc :: NaiveInterpreter :: debug

Debug on the current node
init defaultinit(modelbuilder: ModelBuilder, mainmodule: MModule, arguments: Array[String])

nitc :: NaiveInterpreter :: defaultinit

fun discover_call_trace: Set[MMethodDef]

nitc :: NaiveInterpreter :: discover_call_trace

Store known methods, used to trace methods as they are reached
protected fun discover_call_trace=(discover_call_trace: Set[MMethodDef])

nitc :: NaiveInterpreter :: discover_call_trace=

Store known methods, used to trace methods as they are reached
fun error_instance: MutableInstance

nitc :: NaiveInterpreter :: error_instance

Placebo instance used to mark internal error result when null already have a meaning.
protected fun error_instance=(error_instance: MutableInstance)

nitc :: NaiveInterpreter :: error_instance=

Placebo instance used to mark internal error result when null already have a meaning.
fun escapemark: nullable EscapeMark

nitc :: NaiveInterpreter :: escapemark

Is a return, a break or a continue executed?
protected fun escapemark=(escapemark: nullable EscapeMark)

nitc :: NaiveInterpreter :: escapemark=

Is a return, a break or a continue executed?
fun escapevalue: nullable Instance

nitc :: NaiveInterpreter :: escapevalue

The value associated with the current return/break/continue, if any.
protected fun escapevalue=(escapevalue: nullable Instance)

nitc :: NaiveInterpreter :: escapevalue=

The value associated with the current return/break/continue, if any.
fun expr(n: AExpr): nullable Instance

nitc :: NaiveInterpreter :: expr

Evaluate n as an expression in the current context.
fun false_instance: Instance

nitc :: NaiveInterpreter :: false_instance

The unique instance of the false value.
protected fun false_instance=(false_instance: Instance)

nitc :: NaiveInterpreter :: false_instance=

The unique instance of the false value.
fun fatal(message: String)

nitc :: NaiveInterpreter :: fatal

Exit the program with a message
fun float_instance(val: Float): Instance

nitc :: NaiveInterpreter :: float_instance

Return the float instance associated with val.
fun force_get_primitive_method(name: String, recv: MType): MMethod

nitc :: NaiveInterpreter :: force_get_primitive_method

Get a primitive method in the context of the main module
fun foreign_code_lib_path(mmodule: MModule): String

nitc :: NaiveInterpreter :: foreign_code_lib_path

Path of the compiled foreign code library
fun frame: FRAME

nitc :: NaiveInterpreter :: frame

The current frame used to store local variables of the current method executed
fun frames: List[FRAME]

nitc :: NaiveInterpreter :: frames

The stack of all frames. The first one is the current one.
protected fun frames=(frames: List[FRAME])

nitc :: NaiveInterpreter :: frames=

The stack of all frames. The first one is the current one.
fun init_instance(recv: Instance)

nitc :: NaiveInterpreter :: init_instance

Fill the initial values of the newly created instance recv.
fun init_instance_primitive(recv: Instance)

nitc :: NaiveInterpreter :: init_instance_primitive

A hook to initialize a PrimitiveInstance
fun int16_instance(val: Int16): Instance

nitc :: NaiveInterpreter :: int16_instance

Return the int16 instance associated with val.
fun int32_instance(val: Int32): Instance

nitc :: NaiveInterpreter :: int32_instance

Return the int32 instance associated with val.
fun int8_instance(val: Int8): Instance

nitc :: NaiveInterpreter :: int8_instance

Return the int8 instance associated with val.
fun int_instance(val: Int): Instance

nitc :: NaiveInterpreter :: int_instance

Return the integer instance associated with val.
fun is_escape(escapemark: nullable EscapeMark): Bool

nitc :: NaiveInterpreter :: is_escape

If there is a break/continue and is associated with escapemark, then return true and clear the mark.
fun is_escaping: Bool

nitc :: NaiveInterpreter :: is_escaping

Is a return or a break or a continue executed?
fun is_subtype(sub: MType, sup: MType): Bool

nitc :: NaiveInterpreter :: is_subtype

Subtype test in the context of the mainmodule
fun isset_attribute(mproperty: MAttribute, recv: Instance): Bool

nitc :: NaiveInterpreter :: isset_attribute

Is the attribute mproperty initialized the instance recv?
fun last_error: nullable FatalError

nitc :: NaiveInterpreter :: last_error

The last error thrown on abort/runtime error where catch_count > 0
protected fun last_error=(last_error: nullable FatalError)

nitc :: NaiveInterpreter :: last_error=

The last error thrown on abort/runtime error where catch_count > 0
fun mainmodule: MModule

nitc :: NaiveInterpreter :: mainmodule

The main module of the program (used to lookup method)
fun mainmodule=(mainmodule: MModule)

nitc :: NaiveInterpreter :: mainmodule=

The main module of the program (used to lookup method)
fun mainobj: nullable Instance

nitc :: NaiveInterpreter :: mainobj

The main Sys instance
protected fun mainobj=(mainobj: nullable Instance)

nitc :: NaiveInterpreter :: mainobj=

The main Sys instance
fun modelbuilder: ModelBuilder

nitc :: NaiveInterpreter :: modelbuilder

The modelbuilder that know the AST and its associations with the model
protected fun modelbuilder=(modelbuilder: ModelBuilder)

nitc :: NaiveInterpreter :: modelbuilder=

The modelbuilder that know the AST and its associations with the model
fun new_frame(node: ANode, mpropdef: MPropDef, args: Array[Instance]): FRAME

nitc :: NaiveInterpreter :: new_frame

Initialize the environment for a call and return a new Frame
fun null_instance: Instance

nitc :: NaiveInterpreter :: null_instance

The unique instance of the null value.
protected fun null_instance=(null_instance: Instance)

nitc :: NaiveInterpreter :: null_instance=

The unique instance of the null value.
fun onces: Map[ANode, Instance]

nitc :: NaiveInterpreter :: onces

Map used to store values of nodes that must be evaluated once in the system (AOnceExpr)
protected fun onces=(onces: Map[ANode, Instance])

nitc :: NaiveInterpreter :: onces=

Map used to store values of nodes that must be evaluated once in the system (AOnceExpr)
fun parameter_check(node: ANode, mpropdef: MMethodDef, args: Array[Instance])

nitc :: NaiveInterpreter :: parameter_check

Execute type checks of covariant parameters
private fun process_id: Int

nitc :: NaiveInterpreter :: process_id

Identifier for this process, unique between running interpreters
fun read_attribute(mproperty: MAttribute, recv: Instance): Instance

nitc :: NaiveInterpreter :: read_attribute

Read the attribute mproperty of an instance recv and return its value.
fun read_variable(v: Variable): Instance

nitc :: NaiveInterpreter :: read_variable

Retrieve the value of the variable in the current frame
fun routine_types: Set[String]

nitc :: NaiveInterpreter :: routine_types

Name of all supported functional names
protected fun routine_types=(routine_types: Set[String])

nitc :: NaiveInterpreter :: routine_types=

Name of all supported functional names
fun send(mproperty: MMethod, args: Array[Instance]): nullable Instance

nitc :: NaiveInterpreter :: send

Execute mproperty for a args (where args[0] is the receiver).
fun send_commons(mproperty: MMethod, args: Array[Instance], mtype: MType): nullable Instance

nitc :: NaiveInterpreter :: send_commons

Common code for runtime injected calls and normal calls
fun stack_trace: String

nitc :: NaiveInterpreter :: stack_trace

Return a stack trace. One line per function
fun start(mainmodule: MModule)

nitc :: NaiveInterpreter :: start

Starts the interpreter on the main module of a program
fun stmt(n: nullable AExpr)

nitc :: NaiveInterpreter :: stmt

Evaluate n as a statement in the current context.
fun string_instance(txt: String): Instance

nitc :: NaiveInterpreter :: string_instance

Return a new String instance for txt
fun true_instance: Instance

nitc :: NaiveInterpreter :: true_instance

The unique instance of the true value.
protected fun true_instance=(true_instance: Instance)

nitc :: NaiveInterpreter :: true_instance=

The unique instance of the true value.
fun uint16_instance(val: UInt16): Instance

nitc :: NaiveInterpreter :: uint16_instance

Return the uint16 instance associated with val.
fun uint32_instance(val: UInt32): Instance

nitc :: NaiveInterpreter :: uint32_instance

Return the uint32 instance associated with val.
fun unanchor_type(mtype: MType): MType

nitc :: NaiveInterpreter :: unanchor_type

This function determines the correct type according to the receiver of the current propdef (self).
fun value_instance(object: Object): Instance

nitc :: NaiveInterpreter :: value_instance

Return a instance associated to a primitive class
fun varargize(mpropdef: MMethodDef, map: nullable SignatureMap, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance]

nitc :: NaiveInterpreter :: varargize

Evaluate args as expressions in the call of mpropdef on recv.
fun write_attribute(mproperty: MAttribute, recv: Instance, value: Instance)

nitc :: NaiveInterpreter :: write_attribute

Replace in recv the value of the attribute mproperty by value
fun write_variable(v: Variable, value: Instance)

nitc :: NaiveInterpreter :: write_variable

Assign the value of the variable in the current frame

Redefined properties

redef type SELF: NaiveInterpreter

nitc $ NaiveInterpreter :: SELF

Type of this instance, automatically specialized in every class
redef init init

nitc $ NaiveInterpreter :: init

redef fun start(mainmodule: MModule)

nitc :: on_demand_compiler $ NaiveInterpreter :: start

Starts the interpreter on the main module of a program

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type FRAME: Frame

nitc :: NaiveInterpreter :: FRAME

The virtual type of the frames used in the execution engine
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _arguments: Array[String]

nitc :: NaiveInterpreter :: _arguments

The command line arguments of the interpreted program
private var _c_compiler: String

nitc :: NaiveInterpreter :: _c_compiler

External compiler used to generate the foreign code library
private var _catch_count: Int

nitc :: NaiveInterpreter :: _catch_count

The count of catch blocs that have been encountered and can catch an abort
private var _compile_dir: String

nitc :: NaiveInterpreter :: _compile_dir

Where to store generated C and extracted code
private var _discover_call_trace: Set[MMethodDef]

nitc :: NaiveInterpreter :: _discover_call_trace

Store known methods, used to trace methods as they are reached
private var _error_instance: MutableInstance

nitc :: NaiveInterpreter :: _error_instance

Placebo instance used to mark internal error result when null already have a meaning.
private var _escapemark: nullable EscapeMark

nitc :: NaiveInterpreter :: _escapemark

Is a return, a break or a continue executed?
private var _escapevalue: nullable Instance

nitc :: NaiveInterpreter :: _escapevalue

The value associated with the current return/break/continue, if any.
private var _false_instance: Instance

nitc :: NaiveInterpreter :: _false_instance

The unique instance of the false value.
private var _frames: List[FRAME]

nitc :: NaiveInterpreter :: _frames

The stack of all frames. The first one is the current one.
private var _last_error: nullable FatalError

nitc :: NaiveInterpreter :: _last_error

The last error thrown on abort/runtime error where catch_count > 0
private var _mainmodule: MModule

nitc :: NaiveInterpreter :: _mainmodule

The main module of the program (used to lookup method)
private var _mainobj: nullable Instance

nitc :: NaiveInterpreter :: _mainobj

The main Sys instance
private var _modelbuilder: ModelBuilder

nitc :: NaiveInterpreter :: _modelbuilder

The modelbuilder that know the AST and its associations with the model
private var _null_instance: Instance

nitc :: NaiveInterpreter :: _null_instance

The unique instance of the null value.
private var _onces: Map[ANode, Instance]

nitc :: NaiveInterpreter :: _onces

Map used to store values of nodes that must be evaluated once in the system (AOnceExpr)
private var _routine_types: Set[String]

nitc :: NaiveInterpreter :: _routine_types

Name of all supported functional names
private var _true_instance: Instance

nitc :: NaiveInterpreter :: _true_instance

The unique instance of the true value.
fun aexprs_to_instances(aexprs: Iterator[AExpr]): nullable Array[Instance]

nitc :: NaiveInterpreter :: aexprs_to_instances

Consumes an iterator of expressions and tries to map each element to
fun arguments: Array[String]

nitc :: NaiveInterpreter :: arguments

The command line arguments of the interpreted program
protected fun arguments=(arguments: Array[String])

nitc :: NaiveInterpreter :: arguments=

The command line arguments of the interpreted program
fun array_instance(values: Array[Instance], elttype: MType): Instance

nitc :: NaiveInterpreter :: array_instance

Return a new array made of values.
fun bool_instance(val: Bool): Instance

nitc :: NaiveInterpreter :: bool_instance

Return the boolean instance associated with val.
fun byte_instance(val: Byte): Instance

nitc :: NaiveInterpreter :: byte_instance

Return the byte instance associated with val.
private fun c_compiler: String

nitc :: NaiveInterpreter :: c_compiler

External compiler used to generate the foreign code library
private fun c_compiler=(c_compiler: String)

nitc :: NaiveInterpreter :: c_compiler=

External compiler used to generate the foreign code library
fun c_string_instance(txt: String): Instance

nitc :: NaiveInterpreter :: c_string_instance

Return a new C string initialized with txt
fun c_string_instance_fast_cstr(txt: CString, from: Int): Instance

nitc :: NaiveInterpreter :: c_string_instance_fast_cstr

Return a new C string instance sharing the same data space as txt
fun c_string_instance_from_ns(txt: CString, len: Int): Instance

nitc :: NaiveInterpreter :: c_string_instance_from_ns

Return a new C string initialized with txt
fun c_string_instance_len(length: Int): PrimitiveInstance[CString]

nitc :: NaiveInterpreter :: c_string_instance_len

Return a new C string initialized of length
fun call(mpropdef: MMethodDef, args: Array[Instance]): nullable Instance

nitc :: NaiveInterpreter :: call

Execute mpropdef for a args (where args[0] is the receiver).
fun callsite(callsite: nullable CallSite, arguments: Array[Instance]): nullable Instance

nitc :: NaiveInterpreter :: callsite

Execute a full callsite for given args
fun catch_count: Int

nitc :: NaiveInterpreter :: catch_count

The count of catch blocs that have been encountered and can catch an abort
fun catch_count=(catch_count: Int)

nitc :: NaiveInterpreter :: catch_count=

The count of catch blocs that have been encountered and can catch an abort
fun char_instance(val: Char): Instance

nitc :: NaiveInterpreter :: char_instance

Return the char instance associated with val.
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun collect_attr_propdef(mtype: MType): Array[AAttrPropdef]

nitc :: NaiveInterpreter :: collect_attr_propdef

Collect attributes of a type in the order of their init
private fun compile_dir: String

nitc :: NaiveInterpreter :: compile_dir

Where to store generated C and extracted code
private fun compile_dir=(compile_dir: String)

nitc :: NaiveInterpreter :: compile_dir=

Where to store generated C and extracted code
fun current_node: nullable ANode

nitc :: NaiveInterpreter :: current_node

The current node, used to print errors, debug and stack-traces
fun current_receiver_class: MClassType

nitc :: NaiveInterpreter :: current_receiver_class

The dynamic type of the current self
fun debug(message: String)

nitc :: NaiveInterpreter :: debug

Debug on the current node
init defaultinit(modelbuilder: ModelBuilder, mainmodule: MModule, arguments: Array[String])

nitc :: NaiveInterpreter :: defaultinit

fun discover_call_trace: Set[MMethodDef]

nitc :: NaiveInterpreter :: discover_call_trace

Store known methods, used to trace methods as they are reached
protected fun discover_call_trace=(discover_call_trace: Set[MMethodDef])

nitc :: NaiveInterpreter :: discover_call_trace=

Store known methods, used to trace methods as they are reached
fun error_instance: MutableInstance

nitc :: NaiveInterpreter :: error_instance

Placebo instance used to mark internal error result when null already have a meaning.
protected fun error_instance=(error_instance: MutableInstance)

nitc :: NaiveInterpreter :: error_instance=

Placebo instance used to mark internal error result when null already have a meaning.
fun escapemark: nullable EscapeMark

nitc :: NaiveInterpreter :: escapemark

Is a return, a break or a continue executed?
protected fun escapemark=(escapemark: nullable EscapeMark)

nitc :: NaiveInterpreter :: escapemark=

Is a return, a break or a continue executed?
fun escapevalue: nullable Instance

nitc :: NaiveInterpreter :: escapevalue

The value associated with the current return/break/continue, if any.
protected fun escapevalue=(escapevalue: nullable Instance)

nitc :: NaiveInterpreter :: escapevalue=

The value associated with the current return/break/continue, if any.
fun expr(n: AExpr): nullable Instance

nitc :: NaiveInterpreter :: expr

Evaluate n as an expression in the current context.
fun false_instance: Instance

nitc :: NaiveInterpreter :: false_instance

The unique instance of the false value.
protected fun false_instance=(false_instance: Instance)

nitc :: NaiveInterpreter :: false_instance=

The unique instance of the false value.
fun fatal(message: String)

nitc :: NaiveInterpreter :: fatal

Exit the program with a message
fun float_instance(val: Float): Instance

nitc :: NaiveInterpreter :: float_instance

Return the float instance associated with val.
fun force_get_primitive_method(name: String, recv: MType): MMethod

nitc :: NaiveInterpreter :: force_get_primitive_method

Get a primitive method in the context of the main module
fun foreign_code_lib_path(mmodule: MModule): String

nitc :: NaiveInterpreter :: foreign_code_lib_path

Path of the compiled foreign code library
fun frame: FRAME

nitc :: NaiveInterpreter :: frame

The current frame used to store local variables of the current method executed
fun frames: List[FRAME]

nitc :: NaiveInterpreter :: frames

The stack of all frames. The first one is the current one.
protected fun frames=(frames: List[FRAME])

nitc :: NaiveInterpreter :: frames=

The stack of all frames. The first one is the current one.
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun init_instance(recv: Instance)

nitc :: NaiveInterpreter :: init_instance

Fill the initial values of the newly created instance recv.
fun init_instance_primitive(recv: Instance)

nitc :: NaiveInterpreter :: init_instance_primitive

A hook to initialize a PrimitiveInstance
fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
fun int16_instance(val: Int16): Instance

nitc :: NaiveInterpreter :: int16_instance

Return the int16 instance associated with val.
fun int32_instance(val: Int32): Instance

nitc :: NaiveInterpreter :: int32_instance

Return the int32 instance associated with val.
fun int8_instance(val: Int8): Instance

nitc :: NaiveInterpreter :: int8_instance

Return the int8 instance associated with val.
fun int_instance(val: Int): Instance

nitc :: NaiveInterpreter :: int_instance

Return the integer instance associated with val.
fun is_escape(escapemark: nullable EscapeMark): Bool

nitc :: NaiveInterpreter :: is_escape

If there is a break/continue and is associated with escapemark, then return true and clear the mark.
fun is_escaping: Bool

nitc :: NaiveInterpreter :: is_escaping

Is a return or a break or a continue executed?
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun is_subtype(sub: MType, sup: MType): Bool

nitc :: NaiveInterpreter :: is_subtype

Subtype test in the context of the mainmodule
fun isset_attribute(mproperty: MAttribute, recv: Instance): Bool

nitc :: NaiveInterpreter :: isset_attribute

Is the attribute mproperty initialized the instance recv?
fun last_error: nullable FatalError

nitc :: NaiveInterpreter :: last_error

The last error thrown on abort/runtime error where catch_count > 0
protected fun last_error=(last_error: nullable FatalError)

nitc :: NaiveInterpreter :: last_error=

The last error thrown on abort/runtime error where catch_count > 0
fun mainmodule: MModule

nitc :: NaiveInterpreter :: mainmodule

The main module of the program (used to lookup method)
fun mainmodule=(mainmodule: MModule)

nitc :: NaiveInterpreter :: mainmodule=

The main module of the program (used to lookup method)
fun mainobj: nullable Instance

nitc :: NaiveInterpreter :: mainobj

The main Sys instance
protected fun mainobj=(mainobj: nullable Instance)

nitc :: NaiveInterpreter :: mainobj=

The main Sys instance
fun modelbuilder: ModelBuilder

nitc :: NaiveInterpreter :: modelbuilder

The modelbuilder that know the AST and its associations with the model
protected fun modelbuilder=(modelbuilder: ModelBuilder)

nitc :: NaiveInterpreter :: modelbuilder=

The modelbuilder that know the AST and its associations with the model
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
fun new_frame(node: ANode, mpropdef: MPropDef, args: Array[Instance]): FRAME

nitc :: NaiveInterpreter :: new_frame

Initialize the environment for a call and return a new Frame
fun null_instance: Instance

nitc :: NaiveInterpreter :: null_instance

The unique instance of the null value.
protected fun null_instance=(null_instance: Instance)

nitc :: NaiveInterpreter :: null_instance=

The unique instance of the null value.
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun onces: Map[ANode, Instance]

nitc :: NaiveInterpreter :: onces

Map used to store values of nodes that must be evaluated once in the system (AOnceExpr)
protected fun onces=(onces: Map[ANode, Instance])

nitc :: NaiveInterpreter :: onces=

Map used to store values of nodes that must be evaluated once in the system (AOnceExpr)
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun parameter_check(node: ANode, mpropdef: MMethodDef, args: Array[Instance])

nitc :: NaiveInterpreter :: parameter_check

Execute type checks of covariant parameters
private fun process_id: Int

nitc :: NaiveInterpreter :: process_id

Identifier for this process, unique between running interpreters
fun read_attribute(mproperty: MAttribute, recv: Instance): Instance

nitc :: NaiveInterpreter :: read_attribute

Read the attribute mproperty of an instance recv and return its value.
fun read_variable(v: Variable): Instance

nitc :: NaiveInterpreter :: read_variable

Retrieve the value of the variable in the current frame
fun routine_types: Set[String]

nitc :: NaiveInterpreter :: routine_types

Name of all supported functional names
protected fun routine_types=(routine_types: Set[String])

nitc :: NaiveInterpreter :: routine_types=

Name of all supported functional names
fun send(mproperty: MMethod, args: Array[Instance]): nullable Instance

nitc :: NaiveInterpreter :: send

Execute mproperty for a args (where args[0] is the receiver).
fun send_commons(mproperty: MMethod, args: Array[Instance], mtype: MType): nullable Instance

nitc :: NaiveInterpreter :: send_commons

Common code for runtime injected calls and normal calls
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
fun stack_trace: String

nitc :: NaiveInterpreter :: stack_trace

Return a stack trace. One line per function
fun start(mainmodule: MModule)

nitc :: NaiveInterpreter :: start

Starts the interpreter on the main module of a program
fun stmt(n: nullable AExpr)

nitc :: NaiveInterpreter :: stmt

Evaluate n as a statement in the current context.
fun string_instance(txt: String): Instance

nitc :: NaiveInterpreter :: string_instance

Return a new String instance for txt
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
fun true_instance: Instance

nitc :: NaiveInterpreter :: true_instance

The unique instance of the true value.
protected fun true_instance=(true_instance: Instance)

nitc :: NaiveInterpreter :: true_instance=

The unique instance of the true value.
fun uint16_instance(val: UInt16): Instance

nitc :: NaiveInterpreter :: uint16_instance

Return the uint16 instance associated with val.
fun uint32_instance(val: UInt32): Instance

nitc :: NaiveInterpreter :: uint32_instance

Return the uint32 instance associated with val.
fun unanchor_type(mtype: MType): MType

nitc :: NaiveInterpreter :: unanchor_type

This function determines the correct type according to the receiver of the current propdef (self).
fun value_instance(object: Object): Instance

nitc :: NaiveInterpreter :: value_instance

Return a instance associated to a primitive class
fun varargize(mpropdef: MMethodDef, map: nullable SignatureMap, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance]

nitc :: NaiveInterpreter :: varargize

Evaluate args as expressions in the call of mpropdef on recv.
fun write_attribute(mproperty: MAttribute, recv: Instance, value: Instance)

nitc :: NaiveInterpreter :: write_attribute

Replace in recv the value of the attribute mproperty by value
fun write_variable(v: Variable, value: Instance)

nitc :: NaiveInterpreter :: write_variable

Assign the value of the variable in the current frame
package_diagram nitc::NaiveInterpreter NaiveInterpreter core::Object Object nitc::NaiveInterpreter->core::Object nitc::VirtualMachine VirtualMachine nitc::VirtualMachine->nitc::NaiveInterpreter

Parents

interface Object

core :: Object

The root of the class hierarchy.

Children

class VirtualMachine

nitc :: VirtualMachine

A virtual machine based on the naive_interpreter

Class definitions

nitc $ NaiveInterpreter
# The visitor that interprets the Nit Program by walking on the AST
class NaiveInterpreter
	# The modelbuilder that know the AST and its associations with the model
	var modelbuilder: ModelBuilder

	# The main module of the program (used to lookup method)
	var mainmodule: MModule is writable

	# The command line arguments of the interpreted program
	# arguments.first is the program name
	# arguments[1] is the first argument
	var arguments: Array[String]

	# The main Sys instance
	var mainobj: nullable Instance is noinit

	# Name of all supported functional names
	var routine_types: Set[String] = new HashSet[String]

	init
	do
		if mainmodule.model.get_mclasses_by_name("Bool") != null then
			self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
			init_instance_primitive(self.true_instance)
			self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
			init_instance_primitive(self.false_instance)
		end
		self.null_instance = new PrimitiveInstance[nullable Object](mainmodule.model.null_type, null)

		routine_types.add("RoutineRef")
		for name in ["Proc", "Fun", "ProcRef", "FunRef"] do
			# 20 is a magic number = upper limit of the arity of each functional class.
			# i.e. Proc0, Proc1, ... Proc19
			for i  in [0..20[ do
				routine_types.add("{name}{i}")
			end
		end
	end

	# Starts the interpreter on the main module of a program
	fun start(mainmodule: MModule) do
		var interpreter = self
		var sys_type = mainmodule.sys_type
		if sys_type == null then return # no class Sys
		var mainobj = new MutableInstance(sys_type)
		interpreter.mainobj = mainobj
		interpreter.init_instance(mainobj)
		var initprop = mainmodule.try_get_primitive_method("init", sys_type.mclass)
		if initprop != null then
			interpreter.send(initprop, [mainobj])
		end
		var mainprop = mainmodule.try_get_primitive_method("run", sys_type.mclass) or else
			mainmodule.try_get_primitive_method("main", sys_type.mclass)
		if mainprop != null then
			interpreter.send(mainprop, [mainobj])
		end
	end

	# Subtype test in the context of the mainmodule
	fun is_subtype(sub, sup: MType): Bool
	do
		return sub.is_subtype(self.mainmodule, current_receiver_class, sup)
	end

	# Get a primitive method in the context of the main module
	fun force_get_primitive_method(name: String, recv: MType): MMethod
	do
		assert recv isa MClassType
		return self.modelbuilder.force_get_primitive_method(current_node, name, recv.mclass, self.mainmodule)
	end

	# Is a return, a break or a continue executed?
	# Set this mark to skip the evaluation until a labeled statement catch it with `is_escape`
	var escapemark: nullable EscapeMark = null

	# The count of `catch` blocs that have been encountered and can catch an abort
	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
	fun is_escaping: Bool do return escapemark != null

	# The value associated with the current return/break/continue, if any.
	# Set the value when you set a escapemark.
	# Read the value when you catch a mark or reach the end of a method
	var escapevalue: nullable Instance = null

	# If there is a break/continue and is associated with `escapemark`, then return true and clear the mark.
	# If there is no break/continue or if `escapemark` is null then return false.
	# Use this function to catch a potential break/continue.
	fun is_escape(escapemark: nullable EscapeMark): Bool
	do
		if escapemark != null and self.escapemark == escapemark then
			self.escapemark = null
			return true
		else
			return false
		end
	end

	# Evaluate `n` as an expression in the current context.
	# Return the value of the expression.
	# If `n` cannot be evaluated, then aborts.
	fun expr(n: AExpr): nullable Instance
	do
		var frame = self.frame
		var old = frame.current_node
		frame.current_node = n
		#n.debug("IN Execute expr")
		var i = n.expr(self)
		if i == null and not self.is_escaping then
			n.debug("inconsitance: no value and not escaping.")
		end
		var implicit_cast_to = n.implicit_cast_to
		if i != null and implicit_cast_to != null then
			var mtype = self.unanchor_type(implicit_cast_to)
			if not self.is_subtype(i.mtype, mtype) then n.fatal(self, "Cast failed. Expected `{implicit_cast_to}`, got `{i.mtype}`")
		end

		#n.debug("OUT Execute expr: value is {i}")
		#if not is_subtype(i.mtype, n.mtype.as(not null)) then n.debug("Expected {n.mtype.as(not null)} got {i}")
		frame.current_node = old
		return i
	end

	# Evaluate `n` as a statement in the current context.
	# Do nothing if `n` is null.
	# If `n` cannot be evaluated, then aborts.
	fun stmt(n: nullable AExpr)
	do
		if n == null then return

		if n.comprehension != null then
			var comprehension = frame.comprehension.as(not null)
			var i = expr(n)
			if i != null then comprehension.add(i)
			return
		end

		var frame = self.frame
		var old = frame.current_node
		frame.current_node = n
		n.stmt(self)
		frame.current_node = old
	end

	# Map used to store values of nodes that must be evaluated once in the system (`AOnceExpr`)
	var onces: Map[ANode, Instance] = new HashMap[ANode, Instance]

	# Return the boolean instance associated with `val`.
	fun bool_instance(val: Bool): Instance
	do
		if val then return self.true_instance else return self.false_instance
	end

	# Return the integer instance associated with `val`.
	fun int_instance(val: Int): Instance
	do
		var t = mainmodule.int_type
		var instance = new PrimitiveInstance[Int](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the byte instance associated with `val`.
	fun byte_instance(val: Byte): Instance
	do
		var t = mainmodule.byte_type
		var instance = new PrimitiveInstance[Byte](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the int8 instance associated with `val`.
	fun int8_instance(val: Int8): Instance
	do
		var t = mainmodule.int8_type
		var instance = new PrimitiveInstance[Int8](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the int16 instance associated with `val`.
	fun int16_instance(val: Int16): Instance
	do
		var t = mainmodule.int16_type
		var instance = new PrimitiveInstance[Int16](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the uint16 instance associated with `val`.
	fun uint16_instance(val: UInt16): Instance
	do
		var t = mainmodule.uint16_type
		var instance = new PrimitiveInstance[UInt16](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the int32 instance associated with `val`.
	fun int32_instance(val: Int32): Instance
	do
		var t = mainmodule.int32_type
		var instance = new PrimitiveInstance[Int32](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the uint32 instance associated with `val`.
	fun uint32_instance(val: UInt32): Instance
	do
		var t = mainmodule.uint32_type
		var instance = new PrimitiveInstance[UInt32](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the char instance associated with `val`.
	fun char_instance(val: Char): Instance
	do
		var t = mainmodule.char_type
		var instance = new PrimitiveInstance[Char](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return the float instance associated with `val`.
	fun float_instance(val: Float): Instance
	do
		var t = mainmodule.float_type
		var instance = new PrimitiveInstance[Float](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# The unique instance of the `true` value.
	var true_instance: Instance is noinit

	# The unique instance of the `false` value.
	var false_instance: Instance is noinit

	# The unique instance of the `null` value.
	var null_instance: Instance is noinit

	# Return a new array made of `values`.
	# The dynamic type of the result is Array[elttype].
	fun array_instance(values: Array[Instance], elttype: MType): Instance
	do
		assert not elttype.need_anchor
		var nat = new PrimitiveInstance[Array[Instance]](mainmodule.native_array_type(elttype), values)
		init_instance_primitive(nat)
		var mtype = mainmodule.array_type(elttype)
		var res = new MutableInstance(mtype)
		self.init_instance(res)
		self.send(self.force_get_primitive_method("with_native", mtype), [res, nat, self.int_instance(values.length)])
		return res
	end

	# Return a instance associated to a primitive class
	# Current primitive classes are `Int`, `Bool`, and `String`
	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 C string initialized with `txt`
	fun c_string_instance(txt: String): Instance
	do
		var instance = c_string_instance_len(txt.byte_length+1)
		var val = instance.val
		val[txt.byte_length] = 0
		txt.to_cstring.copy_to(val, txt.byte_length, 0, 0)

		return instance
	end

	# Return a new C string initialized with `txt`
	fun c_string_instance_from_ns(txt: CString, len: Int): Instance
	do
		var instance = c_string_instance_len(len)
		var val = instance.val
		txt.copy_to(val, len, 0, 0)

		return instance
	end

	# Return a new C string instance sharing the same data space as `txt`
	fun c_string_instance_fast_cstr(txt: CString, from: Int): Instance
	do
		var ncstr = txt.fast_cstring(from)
		var t = mainmodule.c_string_type

		var instance = new PrimitiveInstance[CString](t, ncstr)
		init_instance_primitive(instance)

		return instance
	end

	# Return a new C string initialized of `length`
	fun c_string_instance_len(length: Int): PrimitiveInstance[CString]
	do
		var val = new CString(length)

		var t = mainmodule.c_string_type
		var instance = new PrimitiveInstance[CString](t, val)
		init_instance_primitive(instance)
		return instance
	end

	# Return a new String instance for `txt`
	fun string_instance(txt: String): Instance
	do
		var nat = c_string_instance(txt)
		var res = self.send(self.force_get_primitive_method("to_s_unsafe", nat.mtype), [nat, self.int_instance(txt.byte_length), self.int_instance(txt.length), self.false_instance, self.false_instance])
		assert res != null
		return res
	end

	# The virtual type of the frames used in the execution engine
	type FRAME: Frame

	# 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 = new List[FRAME]

	# Return a stack trace. One line per function
	fun stack_trace: String
	do
		var b = new FlatBuffer
		b.append(",---- Stack trace -- - -  -\n")
		for f in frames do
			b.append("| {f.mpropdef} ({f.current_node.location})\n")
		end
		b.append("`------------------- - -  -")
		return b.to_s
	end

	# The current node, used to print errors, debug and stack-traces
	fun current_node: nullable ANode
	do
		if frames.is_empty then return null
		return frames.first.current_node
	end

	# The dynamic type of the current `self`
	fun current_receiver_class: MClassType
	do
		return frames.first.arguments.first.mtype.as(MClassType)
	end

	# Initialize the environment for a call and return a new Frame
	# *`node` The AST node
	# *`mpropdef` The corresponding mpropdef
	# *`args` Arguments of the call
	fun new_frame(node: ANode, mpropdef: MPropDef, args: Array[Instance]): FRAME
	do
		return new InterpreterFrame(node, mpropdef, args)
	end

	# Exit the program with a message
	fun fatal(message: String)
	do
		var node = current_node
		if node == null then
			print message
		else
			node.fatal(self, message)
		end
		exit(1)
	end

	# Debug on the current node
	fun debug(message: String)
	do
		var node = current_node
		if node == null then
			print message
		else
			node.debug(message)
		end
	end

	# Retrieve the value of the variable in the current frame
	fun read_variable(v: Variable): Instance
	do
		var f = frames.first.as(InterpreterFrame)
		return f.map[v]
	end

	# Assign the value of the variable in the current frame
	fun write_variable(v: Variable, value: Instance)
	do
		var f = frames.first.as(InterpreterFrame)
		f.map[v] = value
	end

	# Store known methods, used to trace methods as they are reached
	var discover_call_trace: Set[MMethodDef] = new HashSet[MMethodDef]

	# Consumes an iterator of expressions and tries to map each element to
	# its corresponding Instance.
	#
	# If any AExprs doesn't resolve to an Instance, then it returns null.
	# Otherwise return an array of instances
	fun aexprs_to_instances(aexprs: Iterator[AExpr]): nullable Array[Instance]
	do
		var accumulator = new Array[Instance]
		for aexpr in aexprs do
			var instance = expr(aexpr)
			if instance == null then return null
			accumulator.push(instance)
		end
		return accumulator
	end

	# Evaluate `args` as expressions in the call of `mpropdef` on `recv`.
	# This method is used to manage varargs in signatures and returns the real array
	# of instances to use in the call.
	# Return `null` if one of the evaluation of the arguments return null.
	fun varargize(mpropdef: MMethodDef, map: nullable SignatureMap, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance]
	do
		var msignature = mpropdef.msignature.as(not null)
		var res = new Array[Instance]
		res.add(recv)

		if msignature.arity == 0 then return res

		if map == null then
			assert args.length == msignature.arity else debug("Expected {msignature.arity} args, got {args.length}")
			var rest_args = aexprs_to_instances(args.iterator)
			if rest_args == null then return null
			res.append(rest_args)
			return res
		end

		# Eval in order of arguments, not parameters
		var exprs = aexprs_to_instances(args.iterator)
		if exprs == null then return null

		# Fill `res` with the result of the evaluation according to the mapping
		for i in [0..msignature.arity[ do
			var param = msignature.mparameters[i]
			var j = map.map.get_or_null(i)
			if j == null then
				# default value
				res.add(null_instance)
				continue
			end
			if param.is_vararg and args[i].vararg_decl > 0 then
				var vararg = exprs.sub(j, args[i].vararg_decl)
				var elttype = param.mtype.anchor_to(self.mainmodule, recv.mtype.as(MClassType))
				var arg = self.array_instance(vararg, elttype)
				res.add(arg)
				continue
			end
			res.add exprs[j]
		end
		return res
	end

	# Execute `mpropdef` for a `args` (where `args[0]` is the receiver).
	# 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
		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
		assert args.length == mpropdef.msignature.arity + 1 else debug("Invalid arity for {mpropdef}. {args.length} arguments given.")

		# Look for the AST node that implements the property
		var val = mpropdef.constant_value

		var node = modelbuilder.mpropdef2node(mpropdef)
		if mpropdef.is_abstract then
			if node != null then
				self.frames.unshift new_frame(node, mpropdef, args)
			end
			fatal("Abstract method `{mpropdef.mproperty.name}` called on `{args.first.mtype}`")
			abort
		end

		if node isa APropdef then
			self.parameter_check(node, mpropdef, args)
			return node.call(self, mpropdef, args)
		else if node isa AClassdef then
			self.parameter_check(node, mpropdef, args)
			return node.call(self, mpropdef, args)
		else if node != null then
			fatal("Fatal Error: method {mpropdef} associated to unexpected AST node {node.location}")
			abort
		else if val != null then
			return value_instance(val)
		else
			fatal("Fatal Error: method {mpropdef} not found in the AST")
			abort
		end
	end

	# Execute type checks of covariant parameters
	fun parameter_check(node: ANode, mpropdef: MMethodDef, args: Array[Instance])
	do
		var msignature = mpropdef.msignature.as(not null)
		for i in [0..msignature.arity[ do
			var mp = msignature.mparameters[i]

			# skip test for vararg since the array is instantiated with the correct polymorphic type
			if mp.is_vararg then continue

			# skip if the cast is not required
			var origmtype =  mpropdef.mproperty.intro.msignature.mparameters[i].mtype
			if not origmtype.need_anchor then continue

			#print "{mpropdef}: {mpropdef.mproperty.intro.msignature.mparameters[i]}"

			# get the parameter type
			var mtype = mp.mtype
			var anchor = args.first.mtype.as(MClassType)
			var amtype = mtype.anchor_to(self.mainmodule, anchor)
			if not args[i+1].mtype.is_subtype(self.mainmodule, anchor, amtype) then
				node.fatal(self, "Cast failed. Expected `{mtype}`, got `{args[i+1].mtype}`")
			end
		end
	end

	# Common code for runtime injected calls and normal calls
	fun send_commons(mproperty: MMethod, args: Array[Instance], mtype: MType): nullable Instance
	do
		if mtype isa MNullType then
			if mproperty.name == "==" or mproperty.name == "is_same_instance" then
				return self.bool_instance(args[0] == args[1])
			else if mproperty.name == "!=" then
				return self.bool_instance(args[0] != args[1])
			end
			#fatal("Receiver is null. {mproperty}. {args.join(" ")} {self.frame.current_node.class_name}")
			fatal("Receiver is null")
		end
		return null
	end

	# Execute a full `callsite` for given `args`
	# 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
		if callsite == null then return null
		return send(callsite.mproperty, arguments)
	end

	# Execute `mproperty` for a `args` (where `args[0]` is the receiver).
	# 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 mtype = recv.mtype
		var ret = send_commons(mproperty, args, mtype)
		if ret != null then return ret
		var propdef = mproperty.lookup_first_definition(self.mainmodule, mtype)
		return self.call(propdef, args)
	end

	# Read the attribute `mproperty` of an instance `recv` and return its value.
	# If the attribute in not yet initialized, then aborts with an error message.
	fun read_attribute(mproperty: MAttribute, recv: Instance): Instance
	do
		assert recv isa MutableInstance
		if not recv.attributes.has_key(mproperty) then
			fatal("Uninitialized attribute {mproperty.name}")
			abort
		end
		return recv.attributes[mproperty]
	end

	# Replace in `recv` the value of the attribute `mproperty` by `value`
	fun write_attribute(mproperty: MAttribute, recv: Instance, value: Instance)
	do
		assert recv isa MutableInstance
		recv.attributes[mproperty] = value
	end

	# Is the attribute `mproperty` initialized the instance `recv`?
	fun isset_attribute(mproperty: MAttribute, recv: Instance): Bool
	do
		assert recv isa MutableInstance
		return recv.attributes.has_key(mproperty)
	end

	# Collect attributes of a type in the order of their init
	fun collect_attr_propdef(mtype: MType): Array[AAttrPropdef]
	do
		var cache = self.collect_attr_propdef_cache
		if cache.has_key(mtype) then return cache[mtype]

		var res = new Array[AAttrPropdef]
		var cds = mtype.collect_mclassdefs(self.mainmodule).to_a
		self.mainmodule.linearize_mclassdefs(cds)
		for cd in cds do
			res.add_all(modelbuilder.collect_attr_propdef(cd))
		end

		cache[mtype] = res
		return res
	end

	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.
	fun init_instance(recv: Instance)
	do
		for npropdef in collect_attr_propdef(recv.mtype) do
			npropdef.init_expr(self, recv)
		end
	end

	# A hook to initialize a `PrimitiveInstance`
	fun init_instance_primitive(recv: Instance) do end

	# This function determines the correct type according to the receiver of the current propdef (self).
	fun unanchor_type(mtype: MType): MType
	do
		return mtype.anchor_to(self.mainmodule, current_receiver_class)
	end

	# Placebo instance used to mark internal error result when `null` already have a meaning.
	# TODO: replace with multiple return or something better
	var error_instance = new MutableInstance(modelbuilder.model.null_type) is lazy
end
src/interpreter/naive_interpreter.nit:58,1--700,3

nitc :: on_demand_compiler $ NaiveInterpreter
redef class NaiveInterpreter
	redef fun start(mainmodule)
	do
		super

		# Delete temporary files
		var compile_dir = compile_dir
		if compile_dir.file_exists then compile_dir.rmdir
	end

	# Where to store generated C and extracted code
	private var compile_dir: String is lazy do
		# Prioritize the user supplied directory
		var opt = modelbuilder.toolcontext.opt_compile_dir.value
		if opt != null then return opt
		return "/tmp/niti_ffi_{process_id}"
	end

	# Identifier for this process, unique between running interpreters
	private fun process_id: Int `{ return getpid(); `}

	# Path of the compiled foreign code library
	#
	# TODO change the ".so" extension per platform.
	fun foreign_code_lib_path(mmodule: MModule): String
	do
		return compile_dir / mmodule.c_name + ".so"
	end

	# External compiler used to generate the foreign code library
	private var c_compiler = "cc"
end
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit:65,1--96,3