package build import ( "fmt" "git.akyoto.dev/cli/q/src/build/asm" "git.akyoto.dev/cli/q/src/build/ast" "git.akyoto.dev/cli/q/src/build/cpu" "git.akyoto.dev/go/color/ansi" ) // compiler is the data structure we embed in each function to preserve compilation state. type compiler struct { err error definitions map[string]*Definition variables map[string]*Variable functions map[string]*Function finished chan struct{} assembler asm.Assembler debug []debug cpu cpu.CPU count counter sideEffects int } // counter stores how often a certain statement appeared so we can generate a unique label from it. type counter struct { loop int } // debug is used to look up the source code at the given position. type debug struct { source ast.Node position int } // PrintInstructions shows the assembly instructions. func (c *compiler) PrintInstructions() { ansi.Dim.Println("╭──────────────────────────────────────╮") for i, x := range c.assembler.Instructions { instruction := c.sourceAt(i) if instruction != nil { ansi.Dim.Println("├──────────────────────────────────────┤") } ansi.Dim.Print("│ ") if x.Mnemonic == asm.LABEL { ansi.Yellow.Printf("%-36s", x.Data.String()+":") } else { ansi.Green.Printf("%-8s", x.Mnemonic.String()) if x.Data != nil { fmt.Printf("%-28s", x.Data.String()) } else { fmt.Printf("%-28s", "") } } ansi.Dim.Print(" │\n") } ansi.Dim.Println("╰──────────────────────────────────────╯") } // sourceAt retrieves the source code at the given position or `nil`. func (c *compiler) sourceAt(position int) ast.Node { for _, record := range c.debug { if record.position == position { return record.source } if record.position > position { return nil } } return nil }