package build import ( "bufio" "os" "path/filepath" "git.akyoto.dev/cli/q/build/elf" ) // Build describes a compiler build. type Build struct { ExecutableName string ExecutablePath string WriteExecutable bool } // New creates a new build. func New(directory string) (*Build, error) { directory, err := filepath.Abs(directory) if err != nil { return nil, err } executableName := filepath.Base(directory) build := &Build{ ExecutableName: executableName, ExecutablePath: filepath.Join(directory, executableName), WriteExecutable: true, } return build, nil } // Run parses the input files and generates an executable file. func (build *Build) Run() error { if build.WriteExecutable { sampleCode := []byte{ 0xb8, 0x3c, 0x00, 0x00, 0x00, // mov rax, 60 0xbf, 0x00, 0x00, 0x00, 0x00, // mov rdi, 0 0x0f, 0x05, // syscall } return writeToDisk(build.ExecutablePath, sampleCode, nil) } return nil } // writeToDisk writes the executable file to disk. func writeToDisk(filePath string, code []byte, data []byte) error { file, err := os.Create(filePath) if err != nil { return err } buffer := bufio.NewWriter(file) executable := elf.New(code) executable.Write(buffer) buffer.Flush() err = file.Close() if err != nil { return err } return os.Chmod(filePath, 0755) }