70 lines
1.2 KiB
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()
|
|
}
|