return res
end
+ fun value_instance(object: Object): RuntimeVariable
+ 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
+
# Generate an array value
fun array_instance(array: Array[RuntimeVariable], elttype: MType): RuntimeVariable is abstract
fun compile_inside_to_c(v: VISITOR, arguments: Array[RuntimeVariable]): nullable RuntimeVariable
do
var modelbuilder = v.compiler.modelbuilder
+ var val = constant_value
if modelbuilder.mpropdef2npropdef.has_key(self) then
var npropdef = modelbuilder.mpropdef2npropdef[self]
var oldnode = v.current_node
self.compile_parameter_check(v, arguments)
nclassdef.compile_to_c(v, self, arguments)
v.current_node = oldnode
+ else if val != null then
+ v.ret(v.value_instance(val))
else
abort
end
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
# 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
redef class ToolContext
# --mixin
var opt_mixins = new OptionArray("Additionals module to min-in", "-m", "--mixin")
+ # --define
+ var opt_defines = new OptionArray("Define a specific property", "-D", "--define")
redef init
do
super
- option_context.add_option(opt_mixins)
+ option_context.add_option(opt_mixins, opt_defines)
end
redef fun make_main_module(mmodules)
var mainmodule = super
+ var defines = opt_defines.value
+ if not defines.is_empty then
+ var location = mainmodule.location
+ var model = mainmodule.model
+
+ if mainmodule == mmodules.first then
+ mainmodule = new MModule(model, null, mainmodule.name + "-d", location)
+ mainmodule.set_imported_mmodules(mmodules)
+ mainmodule.is_fictive = true
+ end
+
+ var recv = mainmodule.object_type
+ var mclassdef = new MClassDef(mainmodule, recv, location)
+ mclassdef.add_in_hierarchy
+
+ for define in defines do
+ var spl = define.split_once_on('=')
+ var name = spl.first
+ var val = null
+ if spl.length > 1 then val = spl[1]
+ var prop = mainmodule.try_get_primitive_method(name, recv.mclass)
+ if prop == null then
+ error(null, "Error: --define: no top-level function `{name}`")
+ continue
+ end
+ var ret = prop.intro.msignature.return_mtype
+ var v
+ if ret == null then
+ error(null, "Error: --define: Method `{prop}` is not a function")
+ continue
+ else if ret.to_s == "Bool" then
+ if val == null or val == "true" then
+ v = true
+ else if val == "false" then
+ v = false
+ else
+ error(null, "Error: --define: Method `{prop}` need a Bool.")
+ continue
+ end
+ else if ret.to_s == "Int" then
+ if val != null and val.is_numeric then
+ v = val.to_i
+ else
+ error(null, "Error: --define: Method `{prop}` need a Int.")
+ continue
+ end
+ else if ret.to_s == "String" then
+ if val != null then
+ v = val
+ else
+ error(null, "Error: --define: Method `{prop}` need a String.")
+ continue
+ end
+ else
+ error(null, "Error: --define: Method `{prop}` return an unmanaged type {ret}.")
+ continue
+ end
+ var pd = new MMethodDef(mclassdef, prop, location)
+ pd.msignature = prop.intro.msignature
+ pd.constant_value = v
+ end
+ check_errors
+ end
+
return mainmodule
end
end
# Is the method definition extern?
var is_extern = false is writable
+
+ # An optional constant value returned in functions.
+ #
+ # Only some specific primitife value are accepted by engines.
+ # Is used when there is no better implementation available.
+ #
+ # Currently used only for the implementation of the `--define`
+ # command-line option.
+ # SEE: module `mixin`.
+ var constant_value: nullable Object = null is writable
end
# A local definition of an attribute
if mmethoddef.mproperty.is_root_init and not mmethoddef.is_intro then
self.add_super_send(v.receiver, mmethoddef)
end
+ else if mmethoddef.constant_value != null then
+ # Make the return type live
+ v.add_type(mmethoddef.msignature.return_mtype.as(MClassType))
else
abort
end