+
+ # Initialize a visitor specific for a compiler engine
+ fun new_visitor: GlobalCompilerVisitor do return new GlobalCompilerVisitor(self)
+
+ var count_type_test_tags: Array[String] = ["isa", "as", "auto", "covariance", "erasure"]
+ var count_type_test_resolved: HashMap[String, Int] = init_count_type_test_tags
+ var count_type_test_unresolved: HashMap[String, Int] = init_count_type_test_tags
+ var count_type_test_skipped: HashMap[String, Int] = init_count_type_test_tags
+
+ private fun init_count_type_test_tags: HashMap[String, Int]
+ do
+ var res = new HashMap[String, Int]
+ for tag in count_type_test_tags do
+ res[tag] = 0
+ end
+ return res
+ end
+
+ # Generate the main C function.
+ # This function:
+ # allocate the Sys object if it exists
+ # call init if is exists
+ # call main if it exists
+ fun compile_main_function
+ do
+ var v = self.new_visitor
+ v.add_decl("int glob_argc;")
+ v.add_decl("char **glob_argv;")
+ v.add_decl("val *glob_sys;")
+
+ if self.modelbuilder.toolcontext.opt_typing_test_metrics.value then
+ for tag in count_type_test_tags do
+ v.add_decl("long count_type_test_resolved_{tag};")
+ v.add_decl("long count_type_test_unresolved_{tag};")
+ v.add_decl("long count_type_test_skipped_{tag};")
+ v.compiler.header.add_decl("extern long count_type_test_resolved_{tag};")
+ v.compiler.header.add_decl("extern long count_type_test_unresolved_{tag};")
+ v.compiler.header.add_decl("extern long count_type_test_skipped_{tag};")
+ end
+ end
+ v.add_decl("int main(int argc, char** argv) \{")
+ v.add("glob_argc = argc; glob_argv = argv;")
+ var main_type = mainmodule.sys_type
+ if main_type != null then
+ var mainmodule = v.compiler.mainmodule
+ var glob_sys = v.init_instance(main_type)
+ v.add("glob_sys = {glob_sys};")
+ var main_init = mainmodule.try_get_primitive_method("init", main_type)
+ if main_init != null then
+ v.send(main_init, [glob_sys])
+ end
+ var main_method = mainmodule.try_get_primitive_method("main", main_type)
+ if main_method != null then
+ v.send(main_method, [glob_sys])
+ end
+ end
+
+ if self.modelbuilder.toolcontext.opt_typing_test_metrics.value then
+ v.add_decl("long count_type_test_resolved_total = 0;")
+ v.add_decl("long count_type_test_unresolved_total = 0;")
+ v.add_decl("long count_type_test_skipped_total = 0;")
+ v.add_decl("long count_type_test_total_total = 0;")
+ for tag in count_type_test_tags do
+ v.add_decl("long count_type_test_total_{tag};")
+ v.add("count_type_test_total_{tag} = count_type_test_resolved_{tag} + count_type_test_unresolved_{tag} + count_type_test_skipped_{tag};")
+ v.add("count_type_test_resolved_total += count_type_test_resolved_{tag};")
+ v.add("count_type_test_unresolved_total += count_type_test_unresolved_{tag};")
+ v.add("count_type_test_skipped_total += count_type_test_skipped_{tag};")
+ v.add("count_type_test_total_total += count_type_test_total_{tag};")
+ end
+ v.add("printf(\"# dynamic count_type_test: total %l\\n\");")
+ v.add("printf(\"\\tresolved\\tunresolved\\tskipped\\ttotal\\n\");")
+ var tags = count_type_test_tags.to_a
+ tags.add("total")
+ for tag in tags do
+ v.add("printf(\"{tag}\");")
+ v.add("printf(\"\\t%ld (%.2f%%)\", count_type_test_resolved_{tag}, 100.0*count_type_test_resolved_{tag}/count_type_test_total_total);")
+ v.add("printf(\"\\t%ld (%.2f%%)\", count_type_test_unresolved_{tag}, 100.0*count_type_test_unresolved_{tag}/count_type_test_total_total);")
+ v.add("printf(\"\\t%ld (%.2f%%)\", count_type_test_skipped_{tag}, 100.0*count_type_test_skipped_{tag}/count_type_test_total_total);")
+ v.add("printf(\"\\t%ld (%.2f%%)\\n\", count_type_test_total_{tag}, 100.0*count_type_test_total_{tag}/count_type_test_total_total);")
+ end
+ end
+ v.add("return 0;")
+ v.add("\}")
+
+ end
+
+ fun div(a,b:Int):String
+ do
+ if b == 0 then return "n/a"
+ return ((a*10000/b).to_f / 100.0).to_precision(2)
+ end
+
+ fun display_stats
+ do
+ if self.modelbuilder.toolcontext.opt_typing_test_metrics.value then
+ print "# static count_type_test"
+ print "\tresolved:\tunresolved\tskipped\ttotal"
+ var count_type_test_total = init_count_type_test_tags
+ count_type_test_resolved["total"] = 0
+ count_type_test_unresolved["total"] = 0
+ count_type_test_skipped["total"] = 0
+ count_type_test_total["total"] = 0
+ for tag in count_type_test_tags do
+ count_type_test_total[tag] = count_type_test_resolved[tag] + count_type_test_unresolved[tag] + count_type_test_skipped[tag]
+ count_type_test_resolved["total"] += count_type_test_resolved[tag]
+ count_type_test_unresolved["total"] += count_type_test_unresolved[tag]
+ count_type_test_skipped["total"] += count_type_test_skipped[tag]
+ count_type_test_total["total"] += count_type_test_total[tag]
+ end
+ var count_type_test = count_type_test_total["total"]
+ var tags = count_type_test_tags.to_a
+ tags.add("total")
+ for tag in tags do
+ printn tag
+ printn "\t{count_type_test_resolved[tag]} ({div(count_type_test_resolved[tag],count_type_test)}%)"
+ printn "\t{count_type_test_unresolved[tag]} ({div(count_type_test_unresolved[tag],count_type_test)}%)"
+ printn "\t{count_type_test_skipped[tag]} ({div(count_type_test_skipped[tag],count_type_test)}%)"
+ printn "\t{count_type_test_total[tag]} ({div(count_type_test_total[tag],count_type_test)}%)"
+ print ""
+ end
+ end
+ end
+
+ private var collect_types_cache: HashMap[MType, Array[MClassType]] = new HashMap[MType, Array[MClassType]]