+
+ # Compile an intern method using Java primitives
+ fun compile_intern_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool do
+ var pname = mpropdef.mproperty.name
+ var cname = mpropdef.mclassdef.mclass.name
+ var ret = mpropdef.msignature.as(not null).return_mtype
+ if cname == "Int" then
+ if pname == "output" then
+ v.add("System.out.println({arguments[0]});")
+ v.ret(v.null_instance)
+ return true
+ else if pname == "object_id" then
+ v.ret(arguments.first)
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(byte){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "ascii" then
+ v.ret(v.new_expr("(char){arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "Char" then
+ if pname == "output" then
+ v.add("System.out.print({arguments[0]});")
+ v.ret(v.null_instance)
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "successor" then
+ v.ret(v.new_expr("(char)({arguments[0]} + {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "predecessor" then
+ v.ret(v.new_expr("(char)({arguments[0]} - {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "ascii" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "Byte" then
+ if pname == "output" then
+ v.add("System.out.println({arguments[0]});")
+ v.ret(v.null_instance)
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("(byte)({arguments[0]} + {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("(byte)({arguments[0]} - {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("(byte)(-{arguments[0]})", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("(byte)({arguments[0]} * {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("(byte)({arguments[0]} / {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("(byte)({arguments[0]} % {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("(byte)({arguments[0]} << {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("(byte)({arguments[0]} >> {arguments[1]})", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "ascii" then
+ v.ret(v.new_expr("{arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "Bool" then
+ if pname == "output" then
+ v.add("System.out.println({arguments[0]});")
+ v.ret(v.null_instance)
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("{arguments[0]}?1:0", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ end
+ else if cname == "Float" then
+ if pname == "output" then
+ v.add "if({arguments[0]} == Double.POSITIVE_INFINITY) \{"
+ v.add "System.out.println(\"inf\");"
+ v.add "\} else if({arguments[0]} == Double.POSITIVE_INFINITY) \{"
+ v.add "System.out.println(\"-inf\");"
+ v.add "\} else \{"
+ var df = v.get_name("df")
+ v.add "java.text.DecimalFormat {df} = new java.text.DecimalFormat(\"0.000000\");"
+ v.add "System.out.println({df}.format({arguments[0]}));"
+ v.add "\}"
+ v.ret(v.null_instance)
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "succ" then
+ v.ret(v.new_expr("{arguments[0]} + 1", ret.as(not null)))
+ return true
+ else if pname == "prec" then
+ v.ret(v.new_expr("{arguments[0]} - 1", ret.as(not null)))
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(int){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(byte){arguments[0]}", ret.as(not null)))
+ return true
+ end
+ end
+ if pname == "exit" then
+ v.add("System.exit({arguments[1]});")
+ v.ret(v.null_instance)
+ return true
+ else if pname == "sys" then
+ # TODO singleton
+ var main_type = v.compiler.mainmodule.sys_type.as(not null)
+ var sys = main_type.mclass
+ v.ret(v.new_expr("new RTVal({sys.rt_name}.get{sys.rt_name}())", main_type))
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("{arguments[0]}.hashCode()", ret.as(not null)))
+ return true
+ else if pname == "is_same_type" then
+ v.ret(v.is_same_type_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "is_same_instance" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "output_class_name" then
+ v.add("System.out.println({arguments[0]}.rtclass.class_name);")
+ v.ret(v.null_instance)
+ return true
+ end
+ return false
+ end
+end
+
+redef class AAttrPropdef
+ redef fun compile_to_java(v, mpropdef, arguments) do
+ v.current_node = self
+ if mpropdef == mreadpropdef then
+ compile_getter(v, mpropdef, arguments)
+ else if mpropdef == mwritepropdef then
+ compile_setter(v, mpropdef, arguments)
+ else
+ abort
+ end
+ v.current_node = null
+ end
+
+ # Compile the setter method
+ private fun compile_setter(v: JavaCompilerVisitor, mpropdef: MPropDef, arguments: Array[RuntimeVariable]) do
+ var mtype = v.compiler.mainmodule.object_type
+ var recv = arguments.first
+ var val = v.new_expr("args[1]", mtype)
+ v.write_attribute(self.mpropdef.as(not null).mproperty, recv, val)
+ v.ret v.null_instance
+ end
+
+ # Compile the getter method
+ private fun compile_getter(v: JavaCompilerVisitor, mpropdef: MPropDef, arguments: Array[RuntimeVariable]) do
+ var recv = arguments.first
+ v.ret v.read_attribute(self.mpropdef.as(not null).mproperty, recv)
+ end
+
+ private fun init_expr(v: JavaCompilerVisitor, recv: RuntimeVariable) do
+ if has_value and not is_lazy and not n_expr isa ANullExpr then evaluate_expr(v, recv)
+ end
+
+ # Evaluate, store and return the default value of the attribute
+ private fun evaluate_expr(v: JavaCompilerVisitor, recv: RuntimeVariable): RuntimeVariable do
+ var old = v.frame
+ var frame = new JavaStaticFrame(v, self.mreadpropdef.as(not null), recv.mcasttype.undecorate.as(MClassType), [recv])
+ v.frame = frame
+
+ var value
+ var mtype = self.mtype
+ assert mtype != null
+
+ var nexpr = self.n_expr
+ var nblock = self.n_block
+ if nexpr != null then
+ value = v.expr(nexpr, mtype)
+ else if nblock != null then
+ value = v.new_var(mtype)
+ frame.returnvar = value
+ frame.returnlabel = v.get_name("RET_LABEL")
+ v.add("{frame.returnlabel.as(not null)}: \{")
+ v.stmt(nblock)
+ v.add("\}")
+ else
+ abort
+ end
+
+ v.write_attribute(self.mpropdef.as(not null).mproperty, recv, value)
+ v.frame = old
+ return value
+ end