func build(files []string, outputFile string, cg string, outputType LLVMCodegen.OutputType, optLevel int) { constructedModules, _ := parseFiles(files) // resolve log.Timed("resolve phase", "", func() { for _, module := range constructedModules { res := &parser.Resolver{Module: module} vis := parser.NewASTVisitor(res) vis.VisitModule(module) } }) // type inference log.Timed("inference phase", "", func() { for _, module := range constructedModules { inf := &parser.TypeInferer{Module: module} inf.Infer() // Dump AST log.Debugln("main", "AST of module `%s`:", module.Name) for _, node := range module.Nodes { log.Debugln("main", "%s", node.String()) } log.Debugln("main", "") } }) // semantic analysis log.Timed("semantic analysis phase", "", func() { for _, module := range constructedModules { sem := semantic.NewSemanticAnalyzer(module, *buildOwnership, *ignoreUnused) vis := parser.NewASTVisitor(sem) vis.VisitModule(module) sem.Finalize() } }) // codegen if cg != "none" { var gen codegen.Codegen switch cg { case "llvm": gen = &LLVMCodegen.Codegen{ OutputName: outputFile, OutputType: outputType, OptLevel: optLevel, } default: log.Error("main", util.Red("error: ")+"Invalid backend choice `"+cg+"`") os.Exit(1) } log.Timed("codegen phase", "", func() { gen.Generate(constructedModules) }) } }
func build(files []string, outputFile string, cg string, outputType LLVMCodegen.OutputType, optLevel int) { constructedModules, moduleLookup := parseFiles(files) // resolve hasMainFunc := false log.Timed("resolve phase", "", func() { for _, module := range constructedModules { parser.Resolve(module, moduleLookup) // Use module scope to check for main function mainIdent := module.ModScope.GetIdent(parser.UnresolvedName{Name: "main"}) if mainIdent != nil && mainIdent.Type == parser.IDENT_FUNCTION && mainIdent.Public { hasMainFunc = true } } }) // and here we check if we should // bother continuing any further... if !hasMainFunc { log.Error("main", util.Red("error: ")+"main function not found\n") os.Exit(1) } // type inference log.Timed("inference phase", "", func() { for _, module := range constructedModules { for _, submod := range module.Parts { inf := &parser.TypeInferer{Submodule: submod} inf.Infer() // Dump AST log.Debugln("main", "AST of submodule `%s/%s`:", module.Name, submod.File.Name) for _, node := range submod.Nodes { log.Debugln("main", "%s", node.String()) } log.Debugln("main", "") } } }) // semantic analysis log.Timed("semantic analysis phase", "", func() { for _, module := range constructedModules { for _, submod := range module.Parts { sem := semantic.NewSemanticAnalyzer(submod, *buildOwnership, *ignoreUnused) vis := parser.NewASTVisitor(sem) vis.VisitSubmodule(submod) sem.Finalize() } } }) // codegen if cg != "none" { var gen codegen.Codegen switch cg { case "llvm": gen = &LLVMCodegen.Codegen{ OutputName: outputFile, OutputType: outputType, OptLevel: optLevel, } default: log.Error("main", util.Red("error: ")+"Invalid backend choice `"+cg+"`") os.Exit(1) } log.Timed("codegen phase", "", func() { gen.Generate(constructedModules) }) } }