q/src/build/compile.go

70 lines
1.2 KiB
Go

package build
import (
"sync"
"git.akyoto.dev/cli/q/src/errors"
)
// compile waits for the scan to finish and compiles all functions.
func compile(functions <-chan *Function, errs <-chan error) (Result, error) {
result := Result{}
allFunctions := map[string]*Function{}
for functions != nil || errs != nil {
select {
case err, ok := <-errs:
if !ok {
errs = nil
continue
}
return result, err
case function, ok := <-functions:
if !ok {
functions = nil
continue
}
allFunctions[function.Name] = function
}
}
compileFunctions(allFunctions)
for _, function := range allFunctions {
if function.err != nil {
return result, function.err
}
result.InstructionCount += len(function.assembler.Instructions)
}
main, exists := allFunctions["main"]
if !exists {
return result, errors.MissingMainFunction
}
result.Main = main
result.Functions = allFunctions
return result, nil
}
// compileFunctions starts a goroutine for each function compilation and waits for completion.
func compileFunctions(functions map[string]*Function) {
wg := sync.WaitGroup{}
for _, function := range functions {
wg.Add(1)
go func() {
defer wg.Done()
function.Compile()
}()
}
wg.Wait()
}