mirror of
https://github.com/RoBaertschi/tt.git
synced 2025-04-18 23:13:29 +00:00
continue build
This commit is contained in:
parent
b53d40d101
commit
6f542bfc3f
158
build/build.go
158
build/build.go
@ -4,10 +4,19 @@ package build
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"robaertschi.xyz/robaertschi/tt/asm"
|
"robaertschi.xyz/robaertschi/tt/asm"
|
||||||
|
"robaertschi.xyz/robaertschi/tt/asm/amd64"
|
||||||
|
"robaertschi.xyz/robaertschi/tt/lexer"
|
||||||
|
"robaertschi.xyz/robaertschi/tt/parser"
|
||||||
|
"robaertschi.xyz/robaertschi/tt/token"
|
||||||
|
"robaertschi.xyz/robaertschi/tt/ttir"
|
||||||
|
"robaertschi.xyz/robaertschi/tt/typechecker"
|
||||||
"robaertschi.xyz/robaertschi/tt/utils"
|
"robaertschi.xyz/robaertschi/tt/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -71,6 +80,21 @@ func (rft *removeFileTask) Run(id int, doneChan chan taskResult) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type funcTask struct {
|
||||||
|
f func() error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFuncTask(f func() error) task {
|
||||||
|
return &funcTask{f: f}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rft *funcTask) Run(id int, doneChan chan taskResult) {
|
||||||
|
doneChan <- taskResult{
|
||||||
|
Id: id,
|
||||||
|
Err: rft.f(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type taskResult struct {
|
type taskResult struct {
|
||||||
Id int
|
Id int
|
||||||
Err error
|
Err error
|
||||||
@ -132,12 +156,144 @@ func runTasks(nodes map[int]*node, rootNodes []int) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if allDone {
|
||||||
|
node := nodes[*node.next]
|
||||||
|
go node.task.Run(*node.next, doneChan)
|
||||||
|
running = append(running, *node.next)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *SourceProgram) Build(backend asm.Backend) {
|
func build(input string, output string) error {
|
||||||
|
file, err := os.Open(input)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not open file %q because: %v", input, err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
inputText, err := io.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Could not read file %q because: %v", input, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := lexer.New(string(inputText), input)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error while creating lexer: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.WithErrorCallback(func(l token.Loc, s string, a ...any) {
|
||||||
|
fmt.Printf("%s:%d:%d: %s\n", l.File, l.Line, l.Col, fmt.Sprintf(s, a...))
|
||||||
|
})
|
||||||
|
|
||||||
|
p := parser.New(l)
|
||||||
|
p.WithErrorCallback(func(t token.Token, s string, a ...any) {
|
||||||
|
loc := t.Loc
|
||||||
|
fmt.Printf("%s:%d:%d: %s\n", loc.File, loc.Line, loc.Col, fmt.Sprintf(s, a...))
|
||||||
|
})
|
||||||
|
|
||||||
|
program := p.ParseProgram()
|
||||||
|
if p.Errors() > 0 {
|
||||||
|
return fmt.Errorf("parser encountered 1 or more errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
tprogram, err := typechecker.New().CheckProgram(program)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ir := ttir.EmitProgram(tprogram)
|
||||||
|
asm := amd64.CgProgram(ir)
|
||||||
|
|
||||||
|
asmOutput := asm.Emit()
|
||||||
|
|
||||||
|
asmOutputFile, err := os.Create(output)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create/truncate asm file %q because: %v\n", output, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = asmOutputFile.WriteString(asmOutput)
|
||||||
|
asmOutputFile.Close()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to write to file %q because: %v\n", output, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sp *SourceProgram) Build(backend asm.Backend) error {
|
||||||
|
var gasPath string
|
||||||
|
fasmPath, err := exec.LookPath("fasm")
|
||||||
|
if err != nil {
|
||||||
|
fasmPath, err = exec.LookPath("fasm2")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not find fasm or fasm2, please install any those two using your systems package manager or from https://flatassembler.net")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if backend == asm.Qbe {
|
||||||
|
gasPath, err = exec.LookPath("as")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not find as assembler, pleas install it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes := make(map[int]*node)
|
||||||
|
rootNodes := []int{}
|
||||||
|
id := 0
|
||||||
|
|
||||||
|
addRootNode := func(task task) int {
|
||||||
|
node := &node{task: task}
|
||||||
|
nodes[id] = node
|
||||||
|
rootNodes = append(rootNodes, id)
|
||||||
|
id += 1
|
||||||
|
return id - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
addNode := func(task task, deps ...int) int {
|
||||||
|
node := &node{task: task}
|
||||||
|
nodes[id] = node
|
||||||
|
|
||||||
|
for _, dep := range deps {
|
||||||
|
nodeDep := nodes[dep]
|
||||||
|
if nodeDep.next != nil {
|
||||||
|
panic(fmt.Sprintf("dep %d already has an next", dep))
|
||||||
|
}
|
||||||
|
newId := id
|
||||||
|
nodeDep.next = &newId
|
||||||
|
node.previous = append(node.previous, dep)
|
||||||
|
}
|
||||||
|
|
||||||
|
rootNodes = append(rootNodes, id)
|
||||||
|
id += 1
|
||||||
|
return id - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var mainFile int
|
||||||
|
switch backend {
|
||||||
|
case asm.Fasm:
|
||||||
|
mainAsmOutput := strings.TrimSuffix(sp.InputFile, filepath.Ext(sp.InputFile)) + ".asm"
|
||||||
|
sp.InputAssemblies = append(sp.InputAssemblies, mainAsmOutput)
|
||||||
|
mainFile = addRootNode(NewFuncTask(func() error {
|
||||||
|
return build(sp.InputFile, mainAsmOutput)
|
||||||
|
}))
|
||||||
|
case asm.Qbe:
|
||||||
|
panic("qbe support not finished")
|
||||||
|
}
|
||||||
|
|
||||||
|
asmFiles := []int{}
|
||||||
|
for _, file := range sp.InputAssemblies {
|
||||||
|
output := strings.TrimSuffix(file, filepath.Ext(file)) + ".o"
|
||||||
|
if filepath.Ext(file) == ".asm" {
|
||||||
|
asmFiles = append(asmFiles, addNode(
|
||||||
|
NewProcessTask(id, fasmPath, file, output), mainFile,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
asmFiles = append(asmFiles, addNode(NewProcessTask(id, gasPath, file, "-o", output)))
|
||||||
|
}
|
||||||
|
sp.ObjectFiles = append(sp.ObjectFiles, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
return runTasks(nodes, rootNodes)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user