Simplified file structure
This commit is contained in:
parent
1b13539b22
commit
66569446b1
146
README.md
146
README.md
@ -24,79 +24,6 @@ Build a Linux x86-64 ELF executable from `examples/hello` and run it:
|
|||||||
./q run examples/hello
|
./q run examples/hello
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
### [main.go](main.go)
|
|
||||||
|
|
||||||
Entry point. It simply calls `cli.Main` which we can use for testing.
|
|
||||||
|
|
||||||
### [src/cli/Main.go](src/cli/Main.go)
|
|
||||||
|
|
||||||
The command line interface expects a command like `build` as the first argument.
|
|
||||||
Commands are implemented as functions in the [src/cli](src/cli) directory.
|
|
||||||
Each command has its own set of parameters.
|
|
||||||
|
|
||||||
### [src/cli/Build.go](src/cli/Build.go)
|
|
||||||
|
|
||||||
The build command creates a new `Build` instance with the given directory and calls the `Run` method.
|
|
||||||
|
|
||||||
If no directory is specified, it will use the current directory.
|
|
||||||
|
|
||||||
If the `--dry` flag is specified, it will perform all tasks except the final write to disk.
|
|
||||||
This flag should be used in most tests and benchmarks to avoid needless disk writes.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
q build
|
|
||||||
q build examples/hello
|
|
||||||
q build examples/hello --dry
|
|
||||||
```
|
|
||||||
|
|
||||||
Adding the `-a` or `--assembler` flag shows the generated assembly instructions:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
q build examples/hello -a
|
|
||||||
```
|
|
||||||
|
|
||||||
Adding the `-v` or `--verbose` flag shows verbose compiler information:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
q build examples/hello -v
|
|
||||||
```
|
|
||||||
|
|
||||||
### [src/build/Build.go](src/build/Build.go)
|
|
||||||
|
|
||||||
The `Build` type defines all the information needed to start building an executable file.
|
|
||||||
The name of the executable will be equal to the name of the build directory.
|
|
||||||
|
|
||||||
`Run` starts the build which will scan all `.q` source files in the build directory.
|
|
||||||
Every source file is scanned in its own goroutine for performance reasons.
|
|
||||||
Parallelization here is possible because the order of files in a directory is not significant.
|
|
||||||
|
|
||||||
The main thread is meanwhile waiting for new function objects to arrive from the scanners.
|
|
||||||
Once a function has arrived, it will be stored for compilation later.
|
|
||||||
We need to wait with the compilation step until we have enough information about all identifiers from the scan.
|
|
||||||
|
|
||||||
Then all the functions that were scanned will be compiled in parallel.
|
|
||||||
We create a separate goroutine for each function compilation.
|
|
||||||
Each function will then be translated to generic assembler instructions.
|
|
||||||
|
|
||||||
All the functions that are required to run the program will be added to the final assembler.
|
|
||||||
The final assembler resolves label addresses, optimizes the performance and generates the specific x86-64 machine code from the generic instruction set.
|
|
||||||
|
|
||||||
### [src/build/core/Function.go](src/build/core/Function.go)
|
|
||||||
|
|
||||||
This is the "heart" of the compiler.
|
|
||||||
Each function runs `f.Compile` which organizes the source code into an abstract syntax tree that is then compiled via `f.CompileAST`.
|
|
||||||
You can think of AST nodes as the individual statements in your source code.
|
|
||||||
|
|
||||||
### [src/build/ast/Parse.go](src/build/ast/Parse.go)
|
|
||||||
|
|
||||||
This is what generates the AST from tokens.
|
|
||||||
|
|
||||||
### [src/build/expression/Parse.go](src/build/expression/Parse.go)
|
|
||||||
|
|
||||||
This is what generates expressions from tokens.
|
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
### Compiler
|
### Compiler
|
||||||
@ -176,6 +103,79 @@ This is what generates expressions from tokens.
|
|||||||
- [ ] Mac
|
- [ ] Mac
|
||||||
- [ ] Windows
|
- [ ] Windows
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### [main.go](main.go)
|
||||||
|
|
||||||
|
Entry point. It simply calls `cli.Main` which we can use for testing.
|
||||||
|
|
||||||
|
### [src/cli/Main.go](src/cli/Main.go)
|
||||||
|
|
||||||
|
The command line interface expects a command like `build` as the first argument.
|
||||||
|
Commands are implemented as functions in the [src/cli](src/cli) directory.
|
||||||
|
Each command has its own set of parameters.
|
||||||
|
|
||||||
|
### [src/cli/Build.go](src/cli/Build.go)
|
||||||
|
|
||||||
|
The build command creates a new `Build` instance with the given directory and calls the `Run` method.
|
||||||
|
|
||||||
|
If no directory is specified, it will use the current directory.
|
||||||
|
|
||||||
|
If the `--dry` flag is specified, it will perform all tasks except the final write to disk.
|
||||||
|
This flag should be used in most tests and benchmarks to avoid needless disk writes.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
q build
|
||||||
|
q build examples/hello
|
||||||
|
q build examples/hello --dry
|
||||||
|
```
|
||||||
|
|
||||||
|
Adding the `-a` or `--assembler` flag shows the generated assembly instructions:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
q build examples/hello -a
|
||||||
|
```
|
||||||
|
|
||||||
|
Adding the `-v` or `--verbose` flag shows verbose compiler information:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
q build examples/hello -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### [src/build/Build.go](src/build/Build.go)
|
||||||
|
|
||||||
|
The `Build` type defines all the information needed to start building an executable file.
|
||||||
|
The name of the executable will be equal to the name of the build directory.
|
||||||
|
|
||||||
|
`Run` starts the build which will scan all `.q` source files in the build directory.
|
||||||
|
Every source file is scanned in its own goroutine for performance reasons.
|
||||||
|
Parallelization here is possible because the order of files in a directory is not significant.
|
||||||
|
|
||||||
|
The main thread is meanwhile waiting for new function objects to arrive from the scanners.
|
||||||
|
Once a function has arrived, it will be stored for compilation later.
|
||||||
|
We need to wait with the compilation step until we have enough information about all identifiers from the scan.
|
||||||
|
|
||||||
|
Then all the functions that were scanned will be compiled in parallel.
|
||||||
|
We create a separate goroutine for each function compilation.
|
||||||
|
Each function will then be translated to generic assembler instructions.
|
||||||
|
|
||||||
|
All the functions that are required to run the program will be added to the final assembler.
|
||||||
|
The final assembler resolves label addresses, optimizes the performance and generates the specific x86-64 machine code from the generic instruction set.
|
||||||
|
|
||||||
|
### [src/core/Function.go](src/core/Function.go)
|
||||||
|
|
||||||
|
This is the "heart" of the compiler.
|
||||||
|
Each function runs `f.Compile` which organizes the source code into an abstract syntax tree that is then compiled via `f.CompileAST`.
|
||||||
|
You can think of AST nodes as the individual statements in your source code.
|
||||||
|
|
||||||
|
### [src/ast/Parse.go](src/ast/Parse.go)
|
||||||
|
|
||||||
|
This is what generates the AST from tokens.
|
||||||
|
|
||||||
|
### [src/expression/Parse.go](src/expression/Parse.go)
|
||||||
|
|
||||||
|
This is what generates expressions from tokens.
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
4
go.mod
4
go.mod
@ -1,10 +1,10 @@
|
|||||||
module git.akyoto.dev/cli/q
|
module git.akyoto.dev/cli/q
|
||||||
|
|
||||||
go 1.22.4
|
go 1.22.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.akyoto.dev/go/assert v0.1.3
|
git.akyoto.dev/go/assert v0.1.3
|
||||||
git.akyoto.dev/go/color v0.1.1
|
git.akyoto.dev/go/color v0.1.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require golang.org/x/sys v0.22.0 // indirect
|
require golang.org/x/sys v0.23.0 // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -2,5 +2,5 @@ git.akyoto.dev/go/assert v0.1.3 h1:QwCUbmG4aZYsNk/OuRBz1zWVKmGlDUHhOnnDBfn8Qw8=
|
|||||||
git.akyoto.dev/go/assert v0.1.3/go.mod h1:0GzMaM0eURuDwtGkJJkCsI7r2aUKr+5GmWNTFPgDocM=
|
git.akyoto.dev/go/assert v0.1.3/go.mod h1:0GzMaM0eURuDwtGkJJkCsI7r2aUKr+5GmWNTFPgDocM=
|
||||||
git.akyoto.dev/go/color v0.1.1 h1:mMAoMIwLBPNy7ocRSxdsCFs7onPC3GfDEiJErCneqRE=
|
git.akyoto.dev/go/color v0.1.1 h1:mMAoMIwLBPNy7ocRSxdsCFs7onPC3GfDEiJErCneqRE=
|
||||||
git.akyoto.dev/go/color v0.1.1/go.mod h1:ywOjoD0O0sk6bIn92uAJf7mErlEFCuQInL84y4Lqi3Q=
|
git.akyoto.dev/go/color v0.1.1/go.mod h1:ywOjoD0O0sk6bIn92uAJf7mErlEFCuQInL84y4Lqi3Q=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package arm64
|
package arm64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
X0 cpu.Register = iota
|
X0 cpu.Register = iota
|
@ -1,6 +1,6 @@
|
|||||||
package riscv
|
package riscv
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
X0 cpu.Register = iota
|
X0 cpu.Register = iota
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddRegisterNumber adds a number to the given register.
|
// AddRegisterNumber adds a number to the given register.
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AndRegisterNumber performs a bitwise AND using a register and a number.
|
// AndRegisterNumber performs a bitwise AND using a register and a number.
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// Compares the register with the number and sets the status flags in the EFLAGS register.
|
// Compares the register with the number and sets the status flags in the EFLAGS register.
|
||||||
func CompareRegisterNumber(code []byte, register cpu.Register, number int) []byte {
|
func CompareRegisterNumber(code []byte, register cpu.Register, number int) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// DivRegister divides RDX:RAX by the value in the register.
|
// DivRegister divides RDX:RAX by the value in the register.
|
||||||
func DivRegister(code []byte, divisor cpu.Register) []byte {
|
func DivRegister(code []byte, divisor cpu.Register) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -3,7 +3,7 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// LoadRegister loads from memory into a register.
|
// LoadRegister loads from memory into a register.
|
||||||
func LoadRegister(code []byte, destination cpu.Register, offset byte, length byte, source cpu.Register) []byte {
|
func LoadRegister(code []byte, destination cpu.Register, offset byte, length byte, source cpu.Register) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -3,7 +3,7 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -3,8 +3,8 @@ package x64
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/cli/q/src/build/sizeof"
|
"git.akyoto.dev/cli/q/src/sizeof"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MoveRegisterNumber moves an integer into the given register.
|
// MoveRegisterNumber moves an integer into the given register.
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// MulRegisterNumber multiplies a register with a number.
|
// MulRegisterNumber multiplies a register with a number.
|
||||||
func MulRegisterNumber(code []byte, destination cpu.Register, number int) []byte {
|
func MulRegisterNumber(code []byte, destination cpu.Register, number int) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// NegateRegister negates the value in the register.
|
// NegateRegister negates the value in the register.
|
||||||
func NegateRegister(code []byte, register cpu.Register) []byte {
|
func NegateRegister(code []byte, register cpu.Register) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OrRegisterNumber performs a bitwise OR using a register and a number.
|
// OrRegisterNumber performs a bitwise OR using a register and a number.
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// PopRegister pops a value from the stack and saves it into the register.
|
// PopRegister pops a value from the stack and saves it into the register.
|
||||||
func PopRegister(code []byte, register cpu.Register) []byte {
|
func PopRegister(code []byte, register cpu.Register) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// PushRegister pushes the value inside the register onto the stack.
|
// PushRegister pushes the value inside the register onto the stack.
|
||||||
func PushRegister(code []byte, register cpu.Register) []byte {
|
func PushRegister(code []byte, register cpu.Register) []byte {
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -3,7 +3,7 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RAX cpu.Register = iota
|
RAX cpu.Register = iota
|
@ -3,7 +3,7 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ShiftLeftNumber shifts the register value by `bitCount` bits to the left.
|
// ShiftLeftNumber shifts the register value by `bitCount` bits to the left.
|
@ -3,7 +3,7 @@ package x64
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StoreNumber stores a number into the memory address included in the given register.
|
// StoreNumber stores a number into the memory address included in the given register.
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SubRegisterNumber subtracts a number from the given register.
|
// SubRegisterNumber subtracts a number from the given register.
|
@ -3,8 +3,8 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// XorRegisterNumber performs a bitwise XOR using a register and a number.
|
// XorRegisterNumber performs a bitwise XOR using a register and a number.
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// encode is the core function that encodes an instruction.
|
// encode is the core function that encodes an instruction.
|
||||||
func encode(code []byte, mod AddressMode, reg cpu.Register, rm cpu.Register, numBytes byte, opCodes ...byte) []byte {
|
func encode(code []byte, mod AddressMode, reg cpu.Register, rm cpu.Register, numBytes byte, opCodes ...byte) []byte {
|
@ -3,8 +3,8 @@ package x64
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
"git.akyoto.dev/cli/q/src/build/sizeof"
|
"git.akyoto.dev/cli/q/src/sizeof"
|
||||||
)
|
)
|
||||||
|
|
||||||
// encodeNum encodes an instruction with up to two registers and a number parameter.
|
// encodeNum encodes an instruction with up to two registers and a number parameter.
|
@ -1,6 +1,6 @@
|
|||||||
package x64
|
package x64
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// memoryAccess encodes a memory access.
|
// memoryAccess encodes a memory access.
|
||||||
func memoryAccess(code []byte, opCode8 byte, opCode32 byte, register cpu.Register, offset byte, numBytes byte, source cpu.Register) []byte {
|
func memoryAccess(code []byte, opCode8 byte, opCode32 byte, register cpu.Register, offset byte, numBytes byte, source cpu.Register) []byte {
|
@ -3,7 +3,7 @@ package x64_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/go/assert"
|
"git.akyoto.dev/go/assert"
|
||||||
)
|
)
|
||||||
|
|
@ -3,7 +3,7 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"maps"
|
"maps"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/data"
|
"git.akyoto.dev/cli/q/src/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assembler contains a list of instructions.
|
// Assembler contains a list of instructions.
|
@ -6,10 +6,10 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/config"
|
"git.akyoto.dev/cli/q/src/config"
|
||||||
"git.akyoto.dev/cli/q/src/build/elf"
|
"git.akyoto.dev/cli/q/src/elf"
|
||||||
"git.akyoto.dev/cli/q/src/build/sizeof"
|
"git.akyoto.dev/cli/q/src/sizeof"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Finalize generates the final machine code.
|
// Finalize generates the final machine code.
|
@ -1,6 +1,6 @@
|
|||||||
package asm
|
package asm
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
type Memory struct {
|
type Memory struct {
|
||||||
Base cpu.Register
|
Base cpu.Register
|
@ -3,7 +3,7 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MemoryRegister operates with a memory address and a number.
|
// MemoryRegister operates with a memory address and a number.
|
@ -1,6 +1,6 @@
|
|||||||
package asm
|
package asm
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/cpu"
|
import "git.akyoto.dev/cli/q/src/cpu"
|
||||||
|
|
||||||
// unnecessary returns true if the register/register operation can be skipped.
|
// unnecessary returns true if the register/register operation can be skipped.
|
||||||
func (a *Assembler) unnecessary(mnemonic Mnemonic, left cpu.Register, right cpu.Register) bool {
|
func (a *Assembler) unnecessary(mnemonic Mnemonic, left cpu.Register, right cpu.Register) bool {
|
@ -1,7 +1,7 @@
|
|||||||
package asm
|
package asm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Register operates with a single register.
|
// Register operates with a single register.
|
@ -3,7 +3,7 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterLabel operates with a register and a label.
|
// RegisterLabel operates with a register and a label.
|
@ -3,7 +3,7 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterNumber operates with a register and a number.
|
// RegisterNumber operates with a register and a number.
|
@ -3,7 +3,7 @@ package asm
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/cpu"
|
"git.akyoto.dev/cli/q/src/cpu"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterRegister operates with two registers.
|
// RegisterRegister operates with two registers.
|
@ -1,7 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assert represents a condition that must be true, otherwise the program stops.
|
// Assert represents a condition that must be true, otherwise the program stops.
|
@ -1,7 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Assign represents an assignment to an existing variable or memory location.
|
// Assign represents an assignment to an existing variable or memory location.
|
@ -1,6 +1,6 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/expression"
|
import "git.akyoto.dev/cli/q/src/expression"
|
||||||
|
|
||||||
// Call represents a function call.
|
// Call represents a function call.
|
||||||
type Call struct {
|
type Call struct {
|
@ -1,6 +1,6 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/token"
|
import "git.akyoto.dev/cli/q/src/token"
|
||||||
|
|
||||||
// Count counts how often the given token appears in the AST.
|
// Count counts how often the given token appears in the AST.
|
||||||
func Count(body AST, buffer []byte, kind token.Kind, name string) uint8 {
|
func Count(body AST, buffer []byte, kind token.Kind, name string) uint8 {
|
@ -1,7 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Define represents a variable definition.
|
// Define represents a variable definition.
|
@ -1,6 +1,6 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import "git.akyoto.dev/cli/q/src/build/token"
|
import "git.akyoto.dev/cli/q/src/token"
|
||||||
|
|
||||||
// EachInstruction calls the function on each instruction.
|
// EachInstruction calls the function on each instruction.
|
||||||
func EachInstruction(body token.List, call func(token.List) error) error {
|
func EachInstruction(body token.List, call func(token.List) error) error {
|
@ -1,7 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// If represents an if statement.
|
// If represents an if statement.
|
@ -1,8 +1,8 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parse generates an AST from a list of tokens.
|
// Parse generates an AST from a list of tokens.
|
@ -1,7 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Return represents a return statement.
|
// Return represents a return statement.
|
@ -1,7 +1,7 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Switch represents a switch statement.
|
// Switch represents a switch statement.
|
@ -1,9 +1,9 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// parseKeyword generates a keyword node from an instruction.
|
// parseKeyword generates a keyword node from an instruction.
|
@ -1,9 +1,9 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// parseNode generates an AST node from an instruction.
|
// parseNode generates an AST node from an instruction.
|
@ -1,8 +1,8 @@
|
|||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// parseSwitch generates the cases inside a switch statement.
|
// parseSwitch generates the cases inside a switch statement.
|
@ -4,8 +4,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/compiler"
|
"git.akyoto.dev/cli/q/src/compiler"
|
||||||
"git.akyoto.dev/cli/q/src/build/scanner"
|
"git.akyoto.dev/cli/q/src/scanner"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build describes a compiler build.
|
// Build describes a compiler build.
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
package expression
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewList generates a list of expressions from comma separated parameters.
|
|
||||||
func NewList(tokens token.List) []*Expression {
|
|
||||||
var list []*Expression
|
|
||||||
|
|
||||||
EachParameter(tokens, func(parameter token.List) error {
|
|
||||||
expression := Parse(parameter)
|
|
||||||
list = append(list, expression)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
// EachParameter calls the callback function on each parameter in a comma separated list.
|
|
||||||
func EachParameter(tokens token.List, call func(token.List) error) error {
|
|
||||||
start := 0
|
|
||||||
groupLevel := 0
|
|
||||||
|
|
||||||
for i, t := range tokens {
|
|
||||||
switch t.Kind {
|
|
||||||
case token.GroupStart, token.ArrayStart, token.BlockStart:
|
|
||||||
groupLevel++
|
|
||||||
|
|
||||||
case token.GroupEnd, token.ArrayEnd, token.BlockEnd:
|
|
||||||
groupLevel--
|
|
||||||
|
|
||||||
case token.Separator:
|
|
||||||
if groupLevel > 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter := tokens[start:i]
|
|
||||||
err := call(parameter)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
start = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if start != len(tokens) {
|
|
||||||
parameter := tokens[start:]
|
|
||||||
return call(parameter)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package token_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
|
||||||
"git.akyoto.dev/go/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIndexKind(t *testing.T) {
|
|
||||||
tokens := token.Tokenize([]byte("a{{}}"))
|
|
||||||
assert.Equal(t, tokens.IndexKind(token.NewLine), -1)
|
|
||||||
assert.Equal(t, tokens.LastIndexKind(token.NewLine), -1)
|
|
||||||
assert.Equal(t, tokens.IndexKind(token.BlockStart), 1)
|
|
||||||
assert.Equal(t, tokens.LastIndexKind(token.BlockStart), 2)
|
|
||||||
assert.Equal(t, tokens.IndexKind(token.BlockEnd), 3)
|
|
||||||
assert.Equal(t, tokens.LastIndexKind(token.BlockEnd), 4)
|
|
||||||
}
|
|
@ -6,8 +6,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build"
|
"git.akyoto.dev/cli/q/src/build"
|
||||||
"git.akyoto.dev/cli/q/src/build/config"
|
"git.akyoto.dev/cli/q/src/config"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build parses the arguments and creates a build.
|
// Build parses the arguments and creates a build.
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Run builds and runs the executable.
|
// Run builds and runs the executable.
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/config"
|
"git.akyoto.dev/cli/q/src/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// System shows system information.
|
// System shows system information.
|
||||||
|
@ -3,9 +3,9 @@ package compiler
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/core"
|
"git.akyoto.dev/cli/q/src/core"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/fs"
|
"git.akyoto.dev/cli/q/src/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Compile waits for the scan to finish and compiles all functions.
|
// Compile waits for the scan to finish and compiles all functions.
|
@ -5,11 +5,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/asm"
|
"git.akyoto.dev/cli/q/src/asm"
|
||||||
"git.akyoto.dev/cli/q/src/build/core"
|
"git.akyoto.dev/cli/q/src/core"
|
||||||
"git.akyoto.dev/cli/q/src/build/elf"
|
"git.akyoto.dev/cli/q/src/elf"
|
||||||
"git.akyoto.dev/cli/q/src/build/os/linux"
|
"git.akyoto.dev/cli/q/src/os/linux"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Result contains all the compiled functions in a build.
|
// Result contains all the compiled functions in a build.
|
@ -1,10 +1,10 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Compare evaluates a boolean expression.
|
// Compare evaluates a boolean expression.
|
@ -1,7 +1,7 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileAST compiles an abstract syntax tree.
|
// CompileAST compiles an abstract syntax tree.
|
@ -1,7 +1,7 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileASTNode compiles a node in the AST.
|
// CompileASTNode compiles a node in the AST.
|
@ -3,8 +3,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/asm"
|
"git.akyoto.dev/cli/q/src/asm"
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileAssert compiles an assertion.
|
// CompileAssert compiles an assertion.
|
@ -1,9 +1,9 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileAssign compiles an assign statement.
|
// CompileAssign compiles an assign statement.
|
@ -1,9 +1,9 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/asm"
|
"git.akyoto.dev/cli/q/src/asm"
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileAssignArray compiles an assign statement for array elements.
|
// CompileAssignArray compiles an assign statement for array elements.
|
@ -1,10 +1,10 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/arch/x64"
|
"git.akyoto.dev/cli/q/src/arch/x64"
|
||||||
"git.akyoto.dev/cli/q/src/build/asm"
|
"git.akyoto.dev/cli/q/src/asm"
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileAssignDivision compiles an assign statement that has quotient and remainder on the left side and division on the right.
|
// CompileAssignDivision compiles an assign statement that has quotient and remainder on the left side and division on the right.
|
@ -3,9 +3,9 @@ package core
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/asm"
|
"git.akyoto.dev/cli/q/src/asm"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileCall executes a function call.
|
// CompileCall executes a function call.
|
@ -3,8 +3,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/token"
|
"git.akyoto.dev/cli/q/src/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileCondition inserts code to jump to the start label or end label depending on the truth of the condition.
|
// CompileCondition inserts code to jump to the start label or end label depending on the truth of the condition.
|
@ -1,11 +1,11 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.akyoto.dev/cli/q/src/build/asm"
|
"git.akyoto.dev/cli/q/src/asm"
|
||||||
"git.akyoto.dev/cli/q/src/build/ast"
|
"git.akyoto.dev/cli/q/src/ast"
|
||||||
"git.akyoto.dev/cli/q/src/build/errors"
|
"git.akyoto.dev/cli/q/src/errors"
|
||||||
"git.akyoto.dev/cli/q/src/build/expression"
|
"git.akyoto.dev/cli/q/src/expression"
|
||||||
"git.akyoto.dev/cli/q/src/build/types"
|
"git.akyoto.dev/cli/q/src/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompileDefinition compiles a variable definition.
|
// CompileDefinition compiles a variable definition.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user