func timed(title string, fn func()) { log.Verboseln("main", util.TEXT_BOLD+util.TEXT_GREEN+"Started "+title+util.TEXT_RESET) start := time.Now() fn() duration := time.Since(start) log.Verboseln("main", util.TEXT_BOLD+util.TEXT_GREEN+"Ended "+title+util.TEXT_RESET+" (%.2fms)", float32(duration)/1000000) }
func (v *Codegen) createBinary() { if v.OutputType == OUTPUT_LLVM_IR { for _, mod := range v.input { log.Timed("creating ir", mod.Name.String(), func() { v.createIR(mod) }) } return } else if v.OutputType == OUTPUT_ASSEMBLY { for _, mod := range v.input { log.Timed("creating assembly", mod.Name.String(), func() { v.createObjectOrAssembly(mod, llvm.AssemblyFile) }) } return } linkArgs := append(v.LinkerArgs, "-fno-PIE", "-nodefaultlibs", "-lc", "-lm") objFiles := []string{} for _, mod := range v.input { log.Timed("creating object", mod.Name.String(), func() { objName := v.createObjectOrAssembly(mod, llvm.ObjectFile) objFiles = append(objFiles, objName) linkArgs = append(linkArgs, objName) for _, lib := range mod.LinkedLibraries { linkArgs = append(linkArgs, fmt.Sprintf("-l%s", lib)) } }) } if v.OutputType == OUTPUT_OBJECT { return } if v.OutputName == "" { panic("OutputName is empty") } linkArgs = append(linkArgs, "-o", v.OutputName) if v.Linker == "" { v.Linker = "cc" } log.Timed("linking", "", func() { log.Verboseln("codegen", "%s %v", v.Linker, linkArgs) cmd := exec.Command(v.Linker, linkArgs...) if out, err := cmd.CombinedOutput(); err != nil { v.err("failed to link object files: `%s`\n%s", err.Error(), string(out)) } }) for _, objFile := range objFiles { os.Remove(objFile) } }
func (v *Docgen) Generate() { log.Verboseln("docgen", util.TEXT_BOLD+util.TEXT_GREEN+"Started docgenning"+util.TEXT_RESET) t := time.Now() v.output = make([]*File, 0) v.traverse() v.generate() dur := time.Since(t) log.Verbose("docgen", util.TEXT_BOLD+util.TEXT_GREEN+"Finished docgenning"+util.TEXT_RESET+" (%.2fms)\n", float32(dur.Nanoseconds())/1000000) }
func (v *Codegen) Generate(input []*parser.Module, modules map[string]*parser.Module) { v.input = input v.builder = llvm.NewBuilder() v.variableLookup = make(map[*parser.Variable]llvm.Value) v.structLookup_UseHelperFunction = make(map[*parser.StructType]llvm.Type) passManager := llvm.NewPassManager() passBuilder := llvm.NewPassManagerBuilder() passBuilder.SetOptLevel(3) //passBuilder.Populate(passManager) //leave this off until the compiler is better v.modules = make(map[string]*parser.Module) v.blockDeferData = make(map[*parser.Block][]*deferData) for _, infile := range input { log.Verboseln("codegen", util.TEXT_BOLD+util.TEXT_GREEN+"Started codegenning "+util.TEXT_RESET+infile.Name) t := time.Now() infile.Module = llvm.NewModule(infile.Name) v.curFile = infile v.modules[v.curFile.Name] = v.curFile v.declareDecls(infile.Nodes) for _, node := range infile.Nodes { v.genNode(node) } if err := llvm.VerifyModule(infile.Module, llvm.ReturnStatusAction); err != nil { infile.Module.Dump() v.err("%s", err.Error()) } passManager.Run(infile.Module) if log.AtLevel(log.LevelVerbose) { infile.Module.Dump() } dur := time.Since(t) log.Verbose("codegen", util.TEXT_BOLD+util.TEXT_GREEN+"Finished codegenning "+util.TEXT_RESET+infile.Name+" (%.2fms)\n", float32(dur.Nanoseconds())/1000000) } passManager.Dispose() v.createBinary() }
func Lex(input *Sourcefile) []*Token { v := &lexer{ input: input, startPos: 0, endPos: 0, curPos: Position{Filename: input.Name, Line: 1, Char: 1}, tokStart: Position{Filename: input.Name, Line: 1, Char: 1}, } log.Verboseln("lexer", util.TEXT_BOLD+util.TEXT_GREEN+"Starting lexing "+util.TEXT_RESET+input.Name) t := time.Now() v.lex() dur := time.Since(t) log.Verbose("lexer", util.TEXT_BOLD+util.TEXT_GREEN+"Finished lexing"+util.TEXT_RESET+" %s (%.2fms)\n", input.Name, float32(dur)/1000000) return v.input.Tokens }
func Parse(input *lexer.Sourcefile) *ParseTree { p := &parser{ input: input, binOpPrecedences: newBinOpPrecedenceMap(), tree: &ParseTree{Source: input}, } log.Verboseln("parser", util.TEXT_BOLD+util.TEXT_GREEN+"Started parsing "+util.TEXT_RESET+input.Name) t := time.Now() p.parse() dur := time.Since(t) log.Verbose("parser", util.TEXT_BOLD+util.TEXT_GREEN+"Finished parsing"+util.TEXT_RESET+" %s (%.2fms)\n", input.Name, float32(dur.Nanoseconds())/1000000) return p.tree }
func Construct(tree *ParseTree, treeFiles map[string]*ParseTree, modules map[string]*Module) *Module { c := &Constructor{ tree: tree, treeFiles: treeFiles, module: &Module{ Nodes: make([]Node, 0), File: tree.Source, Path: tree.Source.Path, Name: tree.Source.Name, }, scope: NewGlobalScope(), nameMap: MapNames(tree.Nodes, tree, treeFiles, nil), } c.module.GlobalScope = c.scope c.modules = modules modules[tree.Source.Name] = c.module // add a C module here which will contain // all of the c bindings and what not to // keep everything separate cModule := &Module{ Nodes: make([]Node, 0), Path: "", // not really a path for this module Name: "C", GlobalScope: NewCScope(), } c.module.GlobalScope.UsedModules["C"] = cModule log.Verboseln("constructor", util.TEXT_BOLD+util.TEXT_GREEN+"Started constructing "+util.TEXT_RESET+tree.Source.Name) t := time.Now() c.construct() dur := time.Since(t) log.Verbose("constructor", util.TEXT_BOLD+util.TEXT_GREEN+"Finished parsing"+util.TEXT_RESET+" %s (%.2fms)\n", tree.Source.Name, float32(dur.Nanoseconds())/1000000) return c.module }
func (v *Codegen) Generate(input []*parser.Module, modules map[string]*parser.Module) { v.input = input v.builder = llvm.NewBuilder() v.variableLookup = make(map[*parser.Variable]llvm.Value) v.structLookup_UseHelperFunction = make(map[*parser.StructType]llvm.Type) v.enumLookup_UseHelperFunction = make(map[*parser.EnumType]llvm.Type) // initialize llvm target llvm.InitializeNativeTarget() // setup target stuff var err error v.target, err = llvm.GetTargetFromTriple(llvm.DefaultTargetTriple()) if err != nil { panic(err) } v.targetMachine = v.target.CreateTargetMachine(llvm.DefaultTargetTriple(), "", "", llvm.CodeGenLevelNone, llvm.RelocDefault, llvm.CodeModelDefault) v.targetData = v.targetMachine.TargetData() passManager := llvm.NewPassManager() passBuilder := llvm.NewPassManagerBuilder() if v.OptLevel > 0 { passBuilder.SetOptLevel(v.OptLevel) passBuilder.Populate(passManager) } v.modules = make(map[string]*parser.Module) v.blockDeferData = make(map[*parser.Block][]*deferData) for _, infile := range input { log.Verboseln("codegen", util.TEXT_BOLD+util.TEXT_GREEN+"Started codegenning "+util.TEXT_RESET+infile.Name) t := time.Now() infile.Module = llvm.NewModule(infile.Name) v.curFile = infile v.modules[v.curFile.Name] = v.curFile v.declareDecls(infile.Nodes) for _, node := range infile.Nodes { v.genNode(node) } if err := llvm.VerifyModule(infile.Module, llvm.ReturnStatusAction); err != nil { infile.Module.Dump() v.err("%s", err.Error()) } passManager.Run(infile.Module) if log.AtLevel(log.LevelVerbose) { infile.Module.Dump() } dur := time.Since(t) log.Verbose("codegen", util.TEXT_BOLD+util.TEXT_GREEN+"Finished codegenning "+util.TEXT_RESET+infile.Name+" (%.2fms)\n", float32(dur.Nanoseconds())/1000000) } passManager.Dispose() log.Timed("create binary", func() { v.createBinary() }) }