Added support for single file builds

This commit is contained in:
Eduard Urbach 2024-06-12 12:10:29 +02:00
parent ef11656e47
commit 2d990b0bee
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
4 changed files with 57 additions and 24 deletions

View File

@ -2,25 +2,27 @@ package build
import ( import (
"path/filepath" "path/filepath"
"strings"
) )
// Build describes a compiler build. // Build describes a compiler build.
type Build struct { type Build struct {
Directory string Files []string
WriteExecutable bool WriteExecutable bool
} }
// New creates a new build. // New creates a new build.
func New(directory string) *Build { func New(files ...string) *Build {
return &Build{ return &Build{
Directory: directory, Files: files,
WriteExecutable: true, WriteExecutable: true,
} }
} }
// Run parses the input files and generates an executable file. // Run parses the input files and generates an executable file.
func (build *Build) Run() error { func (build *Build) Run() error {
functions, err := Compile(build.Directory) functions, errors := Scan(build.Files)
allFunctions, err := Compile(functions, errors)
if err != nil { if err != nil {
return err return err
@ -31,11 +33,17 @@ func (build *Build) Run() error {
} }
path := build.Executable() path := build.Executable()
code, data := Finalize(functions) code, data := Finalize(allFunctions)
return Write(path, code, data) return Write(path, code, data)
} }
// Executable returns the path to the executable. // Executable returns the path to the executable.
func (build *Build) Executable() string { func (build *Build) Executable() string {
return filepath.Join(build.Directory, filepath.Base(build.Directory)) directory, _ := filepath.Abs(build.Files[0])
if strings.HasSuffix(directory, ".q") {
directory = filepath.Dir(directory)
}
return filepath.Join(directory, filepath.Base(directory))
} }

View File

@ -5,8 +5,7 @@ import (
) )
// Compile compiles all the functions. // Compile compiles all the functions.
func Compile(directory string) (map[string]*Function, error) { func Compile(functions <-chan *Function, errors <-chan error) (map[string]*Function, error) {
functions, errors := Scan(directory)
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
allFunctions := map[string]*Function{} allFunctions := map[string]*Function{}

View File

@ -11,12 +11,12 @@ import (
) )
// Scan scans the directory. // Scan scans the directory.
func Scan(path string) (<-chan *Function, <-chan error) { func Scan(files []string) (<-chan *Function, <-chan error) {
functions := make(chan *Function) functions := make(chan *Function)
errors := make(chan error) errors := make(chan error)
go func() { go func() {
scan(path, functions, errors) scan(files, functions, errors)
close(functions) close(functions)
close(errors) close(errors)
}() }()
@ -25,29 +25,51 @@ func Scan(path string) (<-chan *Function, <-chan error) {
} }
// scan scans the directory without channel allocations. // scan scans the directory without channel allocations.
func scan(path string, functions chan<- *Function, errors chan<- error) { func scan(files []string, functions chan<- *Function, errors chan<- error) {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
err := directory.Walk(path, func(name string) { for _, file := range files {
if !strings.HasSuffix(name, ".q") { stat, err := os.Stat(file)
if err != nil {
errors <- err
return return
} }
fullPath := filepath.Join(path, name) if stat.IsDir() {
wg.Add(1) err = directory.Walk(file, func(name string) {
if !strings.HasSuffix(name, ".q") {
return
}
go func() { fullPath := filepath.Join(file, name)
defer wg.Done() wg.Add(1)
err := scanFile(fullPath, functions)
go func() {
defer wg.Done()
err := scanFile(fullPath, functions)
if err != nil {
errors <- err
}
}()
})
if err != nil { if err != nil {
errors <- err errors <- err
} }
}() } else {
}) wg.Add(1)
if err != nil { go func() {
errors <- err defer wg.Done()
err := scanFile(file, functions)
if err != nil {
errors <- err
}
}()
}
} }
wg.Wait() wg.Wait()

View File

@ -10,7 +10,7 @@ import (
// Build builds an executable. // Build builds an executable.
func Build(args []string) int { func Build(args []string) int {
b := build.New(".") b := build.New()
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
switch args[i] { switch args[i] {
@ -26,10 +26,14 @@ func Build(args []string) int {
return 2 return 2
} }
b.Directory = args[i] b.Files = append(b.Files, args[i])
} }
} }
if len(b.Files) == 0 {
b.Files = append(b.Files, ".")
}
err := b.Run() err := b.Run()
if err != nil { if err != nil {