Пример #1
0
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)
}
Пример #2
0
Файл: binary.go Проект: vnev/ark
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)
	}
}
Пример #3
0
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)
}
Пример #4
0
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()
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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()
	})

}