Do not call this method directly, use v.expr
instead
# Try to compile self as an expression
# Do not call this method directly, use `v.expr` instead
private fun expr(v: AbstractCompilerVisitor): nullable RuntimeVariable
do
v.add("PRINT_ERROR(\"NOT YET IMPLEMENTED {class_name}:{location.to_s}\\n\");")
var mtype = self.mtype
if mtype == null then
return null
else
var res = v.new_var(mtype)
v.add("/* {res} = NOT YET {class_name} */")
return res
end
end
src/compiler/abstract_compiler.nit:3722,2--3735,4
redef fun expr(v)
do
var res = v.new_var(self.mtype.as(not null))
var cond = v.expr_bool(self.n_expr)
v.add("if ({cond})\{")
v.assign(res, v.expr(self.n_then.as(not null), null))
v.add("\} else \{")
v.assign(res, v.expr(self.n_else.as(not null), null))
v.add("\}")
return res
end
src/compiler/abstract_compiler.nit:3847,2--3857,4
redef fun expr(v)
do
var res = v.new_var(self.mtype.as(not null))
var cond = v.expr_bool(self.n_expr)
v.add("if ({cond})\{")
v.assign(res, v.expr(self.n_then, null))
v.add("\} else \{")
v.assign(res, v.expr(self.n_else, null))
v.add("\}")
return res
end
src/compiler/abstract_compiler.nit:3861,2--3871,4
redef fun expr(v) do
if value isa Int then return v.int_instance(value.as(Int))
if value isa Byte then return v.byte_instance(value.as(Byte))
if value isa Int8 then return v.int8_instance(value.as(Int8))
if value isa Int16 then return v.int16_instance(value.as(Int16))
if value isa UInt16 then return v.uint16_instance(value.as(UInt16))
if value isa Int32 then return v.int32_instance(value.as(Int32))
if value isa UInt32 then return v.uint32_instance(value.as(UInt32))
# Should never happen
abort
end
src/compiler/abstract_compiler.nit:4107,2--4117,4
redef fun expr(v)
do
var mtype = self.element_mtype.as(not null)
var array = new Array[RuntimeVariable]
var res = v.array_instance(array, mtype)
var old_comprehension = v.frame.comprehension
v.frame.comprehension = res
for nexpr in self.n_exprs do
v.stmt(nexpr)
end
v.frame.comprehension = old_comprehension
return res
end
src/compiler/abstract_compiler.nit:4134,2--4148,4
redef fun expr(v) do return v.null_instance
src/compiler/abstract_compiler.nit:4318,2--44
redef fun expr(v)
do
var mtype = self.mtype.as(not null)
var name = v.get_name("varonce")
var guard = v.get_name(name + "_guard")
v.add_decl("static {mtype.ctype} {name};")
v.add_decl("static int {guard};")
var res = v.new_var(mtype)
v.add("if (likely({guard})) \{")
v.add("{res} = {name};")
v.add("\} else \{")
var i = v.expr(self.n_expr, mtype)
v.add("{res} = {i};")
v.add("{name} = {res};")
v.add("{guard} = 1;")
v.add("\}")
return res
end
src/compiler/abstract_compiler.nit:4362,2--4379,4
redef fun expr(v)
do
var recv = v.expr(self.n_expr, null)
if is_safe then
v.add "if ({recv}!=NULL) \{"
end
var callsite = self.callsite.as(not null)
if callsite.is_broken then return null
var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments)
var res = v.compile_callsite(callsite, args)
if is_safe then
if res != null then
# `callsite.mpropdef` may reference a method whose
# return type is a primitive type in C. If it is
# the case, we must convert the primitive type to
# a `val*` to support nullable assignment.
# Autobox's job is to convert primitive type to
# nullable type, eg from `Int` to `nullable `Int`.
# The target type reside in `self.mtype`.
var original_res = v.autobox(res, self.mtype.as(not null))
# Here we must create a new_var in case the original
# type is not nullable. We can't call `autobox` to
# convert a complex type to its nullable version.
# eg if we have a type `A`, calling autobox like
# `autobox(A, nullable A)` will return `A` since
# `A` and `nullable A` have the same primitive
# type. The nullable qualifier is only used at
# compile time to add appropriate null checks.
res = v.new_var(self.mtype.as(not null))
v.add("{res} = {original_res};")
v.add("\} else \{")
v.add("{res} = NULL;")
end
v.add("\}")
end
return res
end
src/compiler/abstract_compiler.nit:4383,2--4420,4
redef fun expr(v)
do
var frame = v.frame.as(not null)
var recv = frame.arguments.first
var callsite = self.callsite
if callsite != null then
if callsite.is_broken then return null
var args
if self.n_args.n_exprs.is_empty then
# Add automatic arguments for the super init call
args = [recv]
for i in [0..callsite.msignature.arity[ do
args.add(frame.arguments[i+1])
end
else
args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs)
end
# Super init call
var res = v.compile_callsite(callsite, args)
return res
end
var mpropdef = self.mpropdef.as(not null)
var args
if self.n_args.n_exprs.is_empty then
args = frame.arguments
else
args = v.varargize(mpropdef, signaturemap, recv, self.n_args.n_exprs)
end
# Standard call-next-method
return v.supercall(mpropdef, recv.mtype.as(MClassType), args)
end
src/compiler/abstract_compiler.nit:4454,2--4490,4
redef fun expr(v)
do
var mtype = self.recvtype
assert mtype != null
if mtype.mclass.name == "NativeArray" then
assert self.n_args.n_exprs.length == 1
var l = v.expr(self.n_args.n_exprs.first, null)
assert mtype isa MGenericType
var elttype = mtype.arguments.first
return v.native_array_instance(elttype, l)
end
var callsite = self.callsite
if callsite == null then return v.init_instance_or_extern(mtype)
if callsite.is_broken then return null
var recv
# new factories are badly implemented.
# They assume a stub temporary receiver exists.
# This temporary receiver is required because it
# currently holds the method and the formal types.
#
# However, this object could be reused if the formal types are the same.
# Therefore, the following code will `once` it in these case
if callsite.mproperty.is_new and not mtype.need_anchor then
var name = v.get_name("varoncenew")
var guard = v.get_name(name + "_guard")
v.add_decl("static {mtype.ctype} {name};")
v.add_decl("static int {guard};")
recv = v.new_var(mtype)
v.add("if (likely({guard})) \{")
v.add("{recv} = {name};")
v.add("\} else \{")
var i = v.init_instance_or_extern(mtype)
v.add("{recv} = {i};")
v.add("{name} = {recv};")
v.add("{guard} = 1;")
v.add("\}")
else
recv = v.init_instance_or_extern(mtype)
end
var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs)
var res2 = v.compile_callsite(callsite, args)
if res2 != null then
#self.debug("got {res2} from {mproperty}. drop {recv}")
return res2
end
return recv
end
src/compiler/abstract_compiler.nit:4494,2--4544,4
redef fun expr(v) do return v.bool_instance(true)
src/compiler/abstract_compiler.nit:4310,2--50
redef fun expr(v) do return v.bool_instance(false)
src/compiler/abstract_compiler.nit:4314,2--51
redef fun expr(v)
do
var i = v.expr(self.n_expr, null)
if v.compiler.modelbuilder.toolcontext.opt_no_check_assert.value then return i
if not v.maybe_null(i) then return i
v.add("if (unlikely({i} == NULL)) \{")
v.add_abort("Cast failed")
v.add("\}")
return i
end
src/compiler/abstract_compiler.nit:4343,2--4354,4
redef fun expr(v)
do
var res = v.new_var(self.mtype.as(not null))
var i1 = v.expr(self.n_expr, null)
if not v.maybe_null(i1) then return i1
v.add("if ({i1}!=NULL) \{")
v.assign(res, i1)
v.add("\} else \{")
var i2 = v.expr(self.n_expr2, null)
v.assign(res, i2)
v.add("\}")
return res
end
src/compiler/abstract_compiler.nit:4089,2--4103,4
redef fun expr(v) do return v.string_instance(value)
src/compiler/abstract_compiler.nit:4189,2--53
redef fun expr(v)
do
var type_string = v.mmodule.string_type
# Collect elements of the superstring
var array = new Array[AExpr]
for ne in self.n_exprs do
# Drop literal empty string.
# They appears in things like "{a}" that is ["", a, ""]
if ne isa AStringFormExpr and ne.value == "" then continue # skip empty sub-strings
array.add(ne)
end
# Store the allocated native array in a static variable
# For reusing later
var varonce = v.get_name("varonce")
v.add("if (unlikely({varonce}==NULL)) \{")
# The native array that will contains the elements to_s-ized.
# For fast concatenation.
var a = v.native_array_instance(type_string, v.int_instance(array.length))
v.add_decl("static {a.mtype.ctype} {varonce};")
# Pre-fill the array with the literal string parts.
# So they do not need to be filled again when reused
for i in [0..array.length[ do
var ne = array[i]
if not ne isa AStringFormExpr then continue
var e = v.expr(ne, null)
v.native_array_set(a, i, e)
end
v.add("\} else \{")
# Take the native-array from the store.
# The point is to prevent that some recursive execution use (and corrupt) the same native array
# WARNING: not thread safe! (FIXME?)
v.add("{a} = {varonce};")
v.add("{varonce} = NULL;")
v.add("\}")
# Stringify the elements and put them in the native array
var to_s_method = v.get_property("to_s", v.object_type)
for i in [0..array.length[ do
var ne = array[i]
if ne isa AStringFormExpr then continue
var e = v.expr(ne, null)
# Skip the `to_s` if the element is already a String
if not e.mcasttype.is_subtype(v.compiler.mainmodule, null, type_string) then
e = v.send(to_s_method, [e]).as(not null)
end
v.native_array_set(a, i, e)
end
# Fast join the C string to get the result
var res = v.send(v.get_property("native_to_s", a.mtype), [a])
assert res != null
if is_re then res = make_re(v, res)
# We finish to work with the native array,
# so store it so that it can be reused
v.add("{varonce} = {a};")
return res
end
src/compiler/abstract_compiler.nit:4217,2--4282,4
redef fun expr(v) do
var s = v.string_instance(value)
if is_string then return s
if is_bytestring then
var ns = v.c_string_instance(bytes.items, bytes.length)
var ln = v.int_instance(bytes.length)
var cs = to_bytes_with_copy
assert cs != null
var res = v.compile_callsite(cs, [ns, ln])
assert res != null
s = res
else if is_re then
var res = make_re(v, s)
assert res != null
s = res
else
print "Unimplemented prefix or suffix for {self}"
abort
end
return s
end
src/compiler/abstract_compiler.nit:4193,2--4213,4