81 lines
1.6 KiB
Go
Raw Normal View History

2023-10-17 13:10:35 +00:00
package build
2023-10-17 18:29:36 +00:00
import (
"bufio"
"os"
"path/filepath"
"git.akyoto.dev/cli/q/build/elf"
)
2023-10-17 13:10:35 +00:00
// 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 {
2023-10-17 18:29:36 +00:00
if build.WriteExecutable {
sampleCode := []byte{
2023-10-18 15:03:31 +00:00
0xb8, 0x01, 0x00, 0x00, 0x00, // mov eax, 1
0xbf, 0x01, 0x00, 0x00, 0x00, // mov edi, 1
0xbe, 0x80 + 0x22, 0x00, 0x40, 0x00, // mov esi, 0x4000A2
0xba, 0x06, 0x00, 0x00, 0x00, // mov edx, 6
2023-10-17 18:29:36 +00:00
0x0f, 0x05, // syscall
2023-10-18 15:03:31 +00:00
0xb8, 0x3c, 0x00, 0x00, 0x00, // mov eax, 60
0xbf, 0x00, 0x00, 0x00, 0x00, // mov edi, 0
0x0f, 0x05, // syscall
'H', 'e', 'l', 'l', 'o', '\n',
2023-10-17 18:29:36 +00:00
}
return writeToDisk(build.ExecutablePath, sampleCode, nil)
}
2023-10-17 13:10:35 +00:00
return nil
}
2023-10-17 18:29:36 +00:00
// 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)
2023-10-17 20:08:40 +00:00
executable := elf.New(code)
2023-10-17 18:29:36 +00:00
executable.Write(buffer)
buffer.Flush()
err = file.Close()
if err != nil {
return err
}
return os.Chmod(filePath, 0755)
}