Пример #1
0
func run(t *testing.T, dir, input string, success successPredicate) bool {
	fmt.Printf("Input: %s\n", input)

	start := time.Now()

	var inputs []string
	for _, i := range strings.Split(input, " ") {
		if strings.HasSuffix(i, ".go") {
			i = dir + i
		}
		inputs = append(inputs, i)
	}

	var conf loader.Config
	if _, err := conf.FromArgs(inputs, true); err != nil {
		t.Errorf("FromArgs(%s) failed: %s", inputs, err)
		return false
	}

	conf.Import("runtime")

	// Print a helpful hint if we don't make it to the end.
	var hint string
	defer func() {
		if hint != "" {
			fmt.Println("FAIL")
			fmt.Println(hint)
		} else {
			fmt.Println("PASS")
		}

		interp.CapturedOutput = nil
	}()

	hint = fmt.Sprintf("To dump SSA representation, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -build=CFP %s\n", input)

	iprog, err := conf.Load()
	if err != nil {
		t.Errorf("conf.Load(%s) failed: %s", inputs, err)
		return false
	}

	prog := ssautil.CreateProgram(iprog, ssa.SanityCheckFunctions)
	prog.BuildAll()

	var mainPkg *ssa.Package
	var initialPkgs []*ssa.Package
	for _, info := range iprog.InitialPackages() {
		if info.Pkg.Path() == "runtime" {
			continue // not an initial package
		}
		p := prog.Package(info.Pkg)
		initialPkgs = append(initialPkgs, p)
		if mainPkg == nil && p.Func("main") != nil {
			mainPkg = p
		}
	}
	if mainPkg == nil {
		testmainPkg := prog.CreateTestMainPackage(initialPkgs...)
		if testmainPkg == nil {
			t.Errorf("CreateTestMainPackage(%s) returned nil", mainPkg)
			return false
		}
		if testmainPkg.Func("main") == nil {
			t.Errorf("synthetic testmain package has no main")
			return false
		}
		mainPkg = testmainPkg
	}

	var out bytes.Buffer
	interp.CapturedOutput = &out

	hint = fmt.Sprintf("To trace execution, run:\n%% go build golang.org/x/tools/cmd/ssadump && ./ssadump -build=C -run --interp=T %s\n", input)
	exitCode := interp.Interpret(mainPkg, 0, &types.StdSizes{8, 8}, inputs[0], []string{})

	// The definition of success varies with each file.
	if err := success(exitCode, out.String()); err != nil {
		t.Errorf("interp.Interpret(%s) failed: %s", inputs, err)
		return false
	}

	hint = "" // call off the hounds

	if false {
		fmt.Println(input, time.Since(start)) // test profiling
	}

	return true
}
Пример #2
0
func doMain() error {
	flag.Parse()
	args := flag.Args()

	conf := loader.Config{Build: &build.Default}

	// Choose types.Sizes from conf.Build.
	var wordSize int64 = 8
	switch conf.Build.GOARCH {
	case "386", "arm":
		wordSize = 4
	}
	conf.TypeChecker.Sizes = &types.StdSizes{
		MaxAlign: 8,
		WordSize: wordSize,
	}

	var interpMode interp.Mode
	for _, c := range *interpFlag {
		switch c {
		case 'T':
			interpMode |= interp.EnableTracing
		case 'R':
			interpMode |= interp.DisableRecover
		default:
			return fmt.Errorf("unknown -interp option: '%c'", c)
		}
	}

	if len(args) == 0 {
		fmt.Fprint(os.Stderr, usage)
		os.Exit(1)
	}

	// Profiling support.
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	// Use the initial packages from the command line.
	args, err := conf.FromArgs(args, *testFlag)
	if err != nil {
		return err
	}

	// The interpreter needs the runtime package.
	if *runFlag {
		conf.Import("runtime")
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		return err
	}

	// Create and build SSA-form program representation.
	prog := ssautil.CreateProgram(iprog, *modeFlag)

	// Build and display only the initial packages
	// (and synthetic wrappers), unless -run is specified.
	for _, info := range iprog.InitialPackages() {
		prog.Package(info.Pkg).Build()
	}

	// Run the interpreter.
	if *runFlag {
		prog.Build()

		var main *ssa.Package
		pkgs := prog.AllPackages()
		if *testFlag {
			// If -test, run all packages' tests.
			if len(pkgs) > 0 {
				main = prog.CreateTestMainPackage(pkgs...)
			}
			if main == nil {
				return fmt.Errorf("no tests")
			}
		} else {
			// Otherwise, run main.main.
			for _, pkg := range pkgs {
				if pkg.Pkg.Name() == "main" {
					main = pkg
					if main.Func("main") == nil {
						return fmt.Errorf("no func main() in main package")
					}
					break
				}
			}
			if main == nil {
				return fmt.Errorf("no main package")
			}
		}

		if runtime.GOARCH != build.Default.GOARCH {
			return fmt.Errorf("cross-interpretation is not supported (target has GOARCH %s, interpreter has %s)",
				build.Default.GOARCH, runtime.GOARCH)
		}

		interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Pkg.Path(), args)
	}
	return nil
}
Пример #3
0
func doTestable(args []string) error {

	conf := loader.Config{
		Build: &build.Default,
	}

	// TODO(adonovan): make go/types choose its default Sizes from
	// build.Default or a specified *build.Context.
	var wordSize int64 = 8
	switch conf.Build.GOARCH {
	case "386", "arm":
		wordSize = 4
	}

	//if !(*runFlag) {
	wordSize = 4               // TARDIS Go addition to force default int size to 32 bits
	conf.Build.GOARCH = "haxe" // TARDIS Go addition - 32-bit int
	conf.Build.GOOS = "nacl"   // or haxe? TARDIS Go addition - simplest OS-specific code to emulate?
	//}

	conf.Build.BuildTags = strings.Split(*buidTags, " ")

	conf.TypeChecker.Sizes = &types.StdSizes{ // must equal haxe.haxeStdSizes when (!*runFlag)
		MaxAlign: 8,
		WordSize: wordSize,
	}

	var mode ssa.BuilderMode
	/*
		for _, c := range *buildFlag {
			switch c {
			case 'D':
				mode |= ssa.GlobalDebug
			case 'P':
				mode |= ssa.PrintPackages
			case 'F':
				mode |= ssa.PrintFunctions
			case 'S':
				mode |= ssa.LogSource | ssa.BuildSerially
			case 'C':
				mode |= ssa.SanityCheckFunctions
			case 'N':
				mode |= ssa.NaiveForm
			case 'L':
				mode |= ssa.BuildSerially
			case 'I':
				mode |= ssa.BareInits
			default:
				return fmt.Errorf("unknown -build option: '%c'", c)
			}
		}
	*/

	// TARDIS go addition
	if *debugFlag {
		mode |= ssa.GlobalDebug
	}

	var interpMode interp.Mode
	for _, c := range *interpFlag {
		switch c {
		case 'T':
			interpMode |= interp.EnableTracing
		case 'R':
			interpMode |= interp.DisableRecover
		default:
			log.Fatalf("Unknown -interp option: '%c'.", c)
		}
	}

	if len(args) == 0 {
		//fmt.Fprint(os.Stderr, usage)
		return fmt.Errorf("%v", usage)
	}

	// Profiling support.
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			return err
		}
		err = pprof.StartCPUProfile(f)
		if err != nil {
			return err
		}
		defer pprof.StopCPUProfile()
	}

	// TODO Eventually this might be better as an environment variable
	//if !(*runFlag) {
	if *tgoroot == "" {
		if conf.Build.GOPATH == "" {
			return fmt.Errorf("GOPATH must be set")
		}
		conf.Build.GOROOT = strings.Split(conf.Build.GOPATH, ":")[0] + "/src/github.com/tardisgo/tardisgo/goroot/haxe/go1.4"
	} else {
		conf.Build.GOROOT = *tgoroot
	}
	//}
	//fmt.Println("DEBUG GOPATH", conf.Build.GOPATH)
	//fmt.Println("DEBUG GOROOT", conf.Build.GOROOT)

	if *testFlag {
		conf.ImportWithTests(args[0]) // assumes you give the full cannonical name of the package to test
		args = args[1:]
	}

	// Use the initial packages from the command line.
	_, err := conf.FromArgs(args, *testFlag)
	if err != nil {
		return err
	}

	// The interpreter needs the runtime package.
	//if *runFlag {
	conf.Import("runtime")
	//} else {
	// TARDIS GO additional line to add the language specific go runtime code
	conf.Import(pogo.LanguageList[pogo.TargetLang].Goruntime) // TODO add code to set pogo.TargetLang when more than one of them
	//}

	// Load, parse and type-check the whole program, including the type definitions.
	iprog, err := conf.Load()
	if err != nil {
		return err
	}

	// Create and build SSA-form program representation.
	*modeFlag |= mode | ssa.SanityCheckFunctions
	prog := ssautil.CreateProgram(iprog, *modeFlag)

	prog.BuildAll()

	// Run the interpreter.
	if *runFlag {
		var main *ssa.Package
		pkgs := prog.AllPackages()
		if *testFlag {
			// If -test, run all packages' tests.
			if len(pkgs) > 0 {
				main = prog.CreateTestMainPackage(pkgs...)
			}
			if main == nil {
				return fmt.Errorf("no tests")
			}
		} else {
			// Otherwise, run main.main.
			for _, pkg := range pkgs {
				if pkg.Object.Name() == "main" {
					main = pkg
					if main.Func("main") == nil {
						return fmt.Errorf("no func main() in main package")
					}
					break
				}
			}
			if main == nil {
				return fmt.Errorf("no main package")
			}
		}

		// NOTE TARDIS Go removal of this test required if we alter the GOARCH to stop architecture-specific code
		//if runtime.GOARCH != build.Default.GOARCH {
		//	return fmt.Errorf("cross-interpretation is not yet supported (target has GOARCH %s, interpreter has %s)",
		//		build.Default.GOARCH, runtime.GOARCH)
		//}

		interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Object.Path(), args)
	} else {
		// if not interpreting...
		// TARDIS Go additions: copy run interpreter code above, but call pogo class
		var main *ssa.Package
		pkgs := prog.AllPackages()
		//fmt.Println("DEBUG pkgs:", pkgs)

		if *testFlag {
			// If -test, run all packages' tests.
			if len(pkgs) > 0 {
				main = prog.CreateTestMainPackage(pkgs...)
			}
			if main == nil {
				return fmt.Errorf("no tests")
			}
			fd, err := os.Open(TestFS)
			fd.Close()
			if err == nil {
				LoadTestZipFS = true
				for l := range pogo.LanguageList {
					pogo.LanguageList[l].TestFS = TestFS
				}
			}
		} else {
			// Otherwise, run main.main.
			for _, pkg := range pkgs {
				if pkg.Object.Name() == "main" {
					main = pkg
					if main.Func("main") == nil {
						return fmt.Errorf("no func main() in main package")
					}
					break
				}
			}
			if main == nil {
				return fmt.Errorf("no main package")
			}
		}
		/*
			if runtime.GOARCH != build.Default.GOARCH {
				return fmt.Errorf("cross-interpretation is not yet supported (target has GOARCH %s, interpreter has %s)",
					build.Default.GOARCH, runtime.GOARCH)
			}

			interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Object.Path(), args)
		*/
		pogo.DebugFlag = *debugFlag
		pogo.TraceFlag = *traceFlag
		err = pogo.EntryPoint(main) // TARDIS Go entry point, returns an error
		if err != nil {
			return err
		}
		results := make(chan resChan)
		switch *allFlag {
		case "": // NoOp
		case "all", "bench":
			//for _, dir := range dirs {
			//	err := os.RemoveAll(dir)
			//	if err != nil {
			//		fmt.Println("Error deleting existing '" + dir + "' directory: " + err.Error())
			//	}
			//}

			var targets [][][]string
			if *allFlag == "bench" {
				targets = allBenchmark // fast execution time
			} else {
				targets = allCompile // fast compile time
			}
			for _, cmd := range targets {
				go doTarget(cmd, results)
			}
			for _ = range targets {
				r := <-results
				fmt.Println(r.output)
				if (r.err != nil || len(strings.TrimSpace(r.output)) == 0) && *allFlag != "bench" {
					os.Exit(1) // exit with an error if the test fails, but not for benchmarking
				}
				r.backChan <- true
			}

		case "math": // which is faster for the test with correct math processing, cpp or js?
			//err := os.RemoveAll("tardis/cpp")
			//if err != nil {
			//	fmt.Println("Error deleting existing '" + "tardis/cpp" + "' directory: " + err.Error())
			//}
			mathCmds := [][][]string{
				[][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-cpp", "tardis/cpp"},
					[]string{"echo", `"CPP:"`},
					[]string{"time", "./tardis/cpp/Go"},
				},
				[][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-D", "fullunsafe", "-js", "tardis/go-fu.js"},
					[]string{"echo", `"Node/JS using fullunsafe memory mode (js dataview):"`},
					[]string{"time", "node", "tardis/go-fu.js"},
				},
			}
			for _, cmd := range mathCmds {
				go doTarget(cmd, results)
			}
			for _ = range mathCmds {
				r := <-results
				fmt.Println(r.output)
				if r.err != nil {
					os.Exit(1) // exit with an error if the test fails
				}
				r.backChan <- true
			}

		case "interp", "cpp", "cs", "js", "jsfu", "java": // for running tests
			switch *allFlag {
			case "interp":
				go doTarget([][]string{
					[]string{"echo", ``}, // Output from this line is ignored
					[]string{"echo", `"Neko (haxe --interp):"`},
					[]string{"time", "haxe", "-main", "tardis.Go", "-cp", "tardis", "--interp"},
				}, results)
			case "cpp":
				go doTarget([][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-cpp", "tardis/cpp"},
					[]string{"echo", `"CPP:"`},
					[]string{"time", "./tardis/cpp/Go"},
				}, results)
			case "cs":
				go doTarget([][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-cs", "tardis/cs"},
					[]string{"echo", `"CS:"`},
					[]string{"time", "mono", "./tardis/cs/bin/Go.exe"},
				}, results)
			case "js":
				go doTarget([][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-D", "uselocalfunctions", "-js", "tardis/go.js"},
					[]string{"echo", `"Node/JS:"`},
					[]string{"time", "node", "tardis/go.js"},
				}, results)
			case "jsfu":
				go doTarget([][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-D", "uselocalfunctions", "-D", "fullunsafe", "-js", "tardis/go-fu.js"},
					[]string{"echo", `"Node/JS using fullunsafe memory mode (js dataview):"`},
					[]string{"time", "node", "tardis/go-fu.js"},
				}, results)
			case "java":
				go doTarget([][]string{
					[]string{"haxe", "-main", "tardis.Go", "-cp", "tardis", "-dce", "full", "-D", "inlinepointers", "-java", "tardis/java"},
					[]string{"echo", `"Java:"`},
					[]string{"time", "java", "-jar", "tardis/java/Go.jar"},
				}, results)
			}
			r := <-results
			fmt.Println(r.output)
			if r.err != nil {
				os.Exit(1) // exit with an error if the test fails
			}
			r.backChan <- true

		default:
			panic("invalid value for -haxe flag: " + *allFlag)
		}
	}
	return nil
}
Пример #4
0
func doMain() error {
	flag.Parse()
	args := flag.Args()

	conf := loader.Config{
		Build:         &build.Default,
		SourceImports: true,
	}
	// TODO(adonovan): make go/types choose its default Sizes from
	// build.Default or a specified *build.Context.
	var wordSize int64 = 8
	switch conf.Build.GOARCH {
	case "386", "arm":
		wordSize = 4
	}
	conf.TypeChecker.Sizes = &types.StdSizes{
		MaxAlign: 8,
		WordSize: wordSize,
	}

	var mode ssa.BuilderMode
	for _, c := range *buildFlag {
		switch c {
		case 'D':
			mode |= ssa.GlobalDebug
		case 'P':
			mode |= ssa.PrintPackages
		case 'F':
			mode |= ssa.PrintFunctions
		case 'S':
			mode |= ssa.LogSource | ssa.BuildSerially
		case 'C':
			mode |= ssa.SanityCheckFunctions
		case 'N':
			mode |= ssa.NaiveForm
		case 'G':
			conf.SourceImports = false
		case 'L':
			mode |= ssa.BuildSerially
		case 'I':
			mode |= ssa.BareInits
		default:
			return fmt.Errorf("unknown -build option: '%c'", c)
		}
	}

	var interpMode interp.Mode
	for _, c := range *interpFlag {
		switch c {
		case 'T':
			interpMode |= interp.EnableTracing
		case 'R':
			interpMode |= interp.DisableRecover
		default:
			return fmt.Errorf("unknown -interp option: '%c'", c)
		}
	}

	if len(args) == 0 {
		fmt.Fprint(os.Stderr, usage)
		os.Exit(1)
	}

	// Profiling support.
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	// Use the initial packages from the command line.
	args, err := conf.FromArgs(args, *testFlag)
	if err != nil {
		return err
	}

	// The interpreter needs the runtime package.
	if *runFlag {
		conf.Import("runtime")
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		return err
	}

	// Create and build SSA-form program representation.
	prog := ssa.Create(iprog, mode)
	prog.BuildAll()

	// Run the interpreter.
	if *runFlag {
		var main *ssa.Package
		pkgs := prog.AllPackages()
		if *testFlag {
			// If -test, run all packages' tests.
			if len(pkgs) > 0 {
				main = prog.CreateTestMainPackage(pkgs...)
			}
			if main == nil {
				return fmt.Errorf("no tests")
			}
		} else {
			// Otherwise, run main.main.
			for _, pkg := range pkgs {
				if pkg.Object.Name() == "main" {
					main = pkg
					if main.Func("main") == nil {
						return fmt.Errorf("no func main() in main package")
					}
					break
				}
			}
			if main == nil {
				return fmt.Errorf("no main package")
			}
		}

		if runtime.GOARCH != build.Default.GOARCH {
			return fmt.Errorf("cross-interpretation is not supported (target has GOARCH %s, interpreter has %s)",
				build.Default.GOARCH, runtime.GOARCH)
		}

		interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Object.Path(), args)
	}
	return nil
}
Пример #5
0
func doTestable(args []string) error {

	conf := loader.Config{
		Build: &build.Default,
	}

	// TARDISgo addition
	langName := *targetFlag
	langEntry, e := pogo.FindTargetLang(langName)
	if e != nil {
		return e
	}

	// TODO(adonovan): make go/types choose its default Sizes from
	// build.Default or a specified *build.Context.
	var wordSize int64 = 8
	switch conf.Build.GOARCH {
	case "386", "arm":
		wordSize = 4
	}

	if *runFlag {
		// nothing here at the moment
	} else {
		wordSize = 4                 // TARDIS Go addition to force default int size to 32 bits
		conf.Build.GOOS = "nacl"     // TARDIS Go addition - simplest OS-specific code to emulate?
		conf.Build.GOARCH = langName // TARDIS Go addition
	}

	conf.Build.BuildTags = strings.Split(*buidTags, " ")

	conf.TypeChecker.Sizes = &types.StdSizes{ // must equal haxe.haxeStdSizes when (!*runFlag)
		MaxAlign: 8,
		WordSize: wordSize,
	}

	var mode ssa.BuilderMode
	/*
		for _, c := range *buildFlag {
			switch c {
			case 'D':
				mode |= ssa.GlobalDebug
			case 'P':
				mode |= ssa.PrintPackages
			case 'F':
				mode |= ssa.PrintFunctions
			case 'S':
				mode |= ssa.LogSource | ssa.BuildSerially
			case 'C':
				mode |= ssa.SanityCheckFunctions
			case 'N':
				mode |= ssa.NaiveForm
			case 'L':
				mode |= ssa.BuildSerially
			case 'I':
				mode |= ssa.BareInits
			default:
				return fmt.Errorf("unknown -build option: '%c'", c)
			}
		}
	*/

	// TARDIS go addition
	if *debugFlag {
		mode |= ssa.GlobalDebug
	}

	var interpMode interp.Mode
	for _, c := range *interpFlag {
		switch c {
		case 'T':
			interpMode |= interp.EnableTracing
		case 'R':
			interpMode |= interp.DisableRecover
		default:
			log.Fatalf("Unknown -interp option: '%c'.", c)
		}
	}

	if len(args) == 0 {
		//fmt.Fprint(os.Stderr, usage)
		return fmt.Errorf("%v", usage)
	}

	// Profiling support.
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			return err
		}
		err = pprof.StartCPUProfile(f)
		if err != nil {
			return err
		}
		defer pprof.StopCPUProfile()
	}

	if !(*runFlag) {
		if *tgoroot == "" {
			if conf.Build.GOPATH == "" {
				return fmt.Errorf("GOPATH must be set")
			}
			langGOROOT := pogo.LanguageList[langEntry].GOROOT
			if langGOROOT != "" {
				conf.Build.GOROOT = strings.Split(conf.Build.GOPATH, ":")[0] + langGOROOT
			} else {
				if conf.Build.GOROOT == "" {
					return fmt.Errorf("GOROOT must be set (hint: use -tgoroot flag)")
				}
			}
		} else {
			conf.Build.GOROOT = *tgoroot
		}
	}
	//fmt.Println("DEBUG GOPATH", conf.Build.GOPATH)
	//fmt.Println("DEBUG GOROOT", conf.Build.GOROOT)

	if *testFlag {
		conf.ImportWithTests(args[0]) // assumes you give the full cannonical name of the package to test
		args = args[1:]
	}

	// Use the initial packages from the command line.
	_, err := conf.FromArgs(args, *testFlag)
	if err != nil {
		return err
	}

	// The interpreter needs the runtime package.
	if *runFlag {
		conf.Import("runtime")
	} else {
		// TARDIS GO additional line to add the language specific go runtime code
		rt := pogo.LanguageList[langEntry].Goruntime
		if rt != "" {
			conf.Import(rt)
		}
	}

	// Load, parse and type-check the whole program.
	iprog, err := conf.Load()
	if err != nil {
		return err
	}

	// Create and build SSA-form program representation.
	*modeFlag |= mode | ssa.SanityCheckFunctions
	prog := ssautil.CreateProgram(iprog, *modeFlag)

	prog.Build()

	var main *ssa.Package
	pkgs := prog.AllPackages()
	//fmt.Println("DEBUG pkgs:", pkgs)

	testFSname := ""
	if *testFlag {
		// If -test, run all packages' tests.
		if len(pkgs) > 0 {
			main = prog.CreateTestMainPackage(pkgs...)
		}
		if main == nil {
			return fmt.Errorf("no tests")
		}
		fd, openErr := os.Open(testFS)
		closeErr := fd.Close()
		if openErr == nil && closeErr == nil {
			loadTestZipFS = true
			testFSname = testFS
		}
	} else {
		// Otherwise, run main.main.
		for _, pkg := range pkgs {
			if pkg.Pkg.Name() == "main" {
				main = pkg
				if main.Func("main") == nil {
					return fmt.Errorf("no func main() in main package")
				}
				break
			}
		}
		if main == nil {
			return fmt.Errorf("no main package")
		}
	}

	if *runFlag { // Run the golang.org/x/tools/go/ssa/interp interpreter.
		interp.Interpret(main, interpMode, conf.TypeChecker.Sizes, main.Pkg.Path(), args)
	} else {
		comp, err := pogo.Compile(main, *debugFlag, *traceFlag, langName, testFSname) // TARDIS Go entry point, returns an error
		if err != nil {
			return err
		}
		comp.Recycle()

		switch langName {
		case "haxe":
			haxe.RunHaxe(allFlag, loadTestZipFS, testFSname)
		}
	}
	return nil
}