Implemented source tracking and type checking
All checks were successful
/ test (push) Successful in 21s
All checks were successful
/ test (push) Successful in 21s
This commit is contained in:
parent
70c2da4a4d
commit
329fcfff6f
30 changed files with 427 additions and 125 deletions
|
@ -1,20 +1,18 @@
|
|||
package ssa
|
||||
|
||||
type Arguments struct {
|
||||
Args []Value
|
||||
}
|
||||
type Arguments []Value
|
||||
|
||||
func (v *Arguments) Dependencies() []Value {
|
||||
return v.Args
|
||||
func (v Arguments) Dependencies() []Value {
|
||||
return v
|
||||
}
|
||||
|
||||
func (a Arguments) Equals(b Arguments) bool {
|
||||
if len(a.Args) != len(b.Args) {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range a.Args {
|
||||
if !a.Args[i].Equals(b.Args[i]) {
|
||||
for i := range a {
|
||||
if !a[i].Equals(b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"git.urbach.dev/cli/q/src/expression"
|
||||
"git.urbach.dev/cli/q/src/token"
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type BinaryOperation struct {
|
||||
|
@ -12,7 +13,7 @@ type BinaryOperation struct {
|
|||
Right Value
|
||||
Op token.Kind
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (v *BinaryOperation) Dependencies() []Value {
|
||||
|
@ -26,10 +27,6 @@ func (a *BinaryOperation) Equals(v Value) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if a.Source.Kind != b.Source.Kind {
|
||||
return false
|
||||
}
|
||||
|
||||
if !a.Left.Equals(b.Left) {
|
||||
return false
|
||||
}
|
||||
|
@ -47,4 +44,8 @@ func (v *BinaryOperation) IsConst() bool {
|
|||
|
||||
func (v *BinaryOperation) String() string {
|
||||
return fmt.Sprintf("%s %s %s", v.Left, expression.Operators[v.Op].Symbol, v.Right)
|
||||
}
|
||||
|
||||
func (v *BinaryOperation) Type() types.Type {
|
||||
return v.Left.Type()
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
package ssa
|
||||
|
||||
import "bytes"
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Bytes struct {
|
||||
Bytes []byte
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (v *Bytes) Dependencies() []Value {
|
||||
|
@ -27,5 +32,9 @@ func (v *Bytes) IsConst() bool {
|
|||
}
|
||||
|
||||
func (v *Bytes) String() string {
|
||||
return string(v.Bytes)
|
||||
return strconv.Quote(string(v.Bytes))
|
||||
}
|
||||
|
||||
func (v *Bytes) Type() types.Type {
|
||||
return types.String
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
package ssa
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Call struct {
|
||||
Arguments
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (a *Call) Equals(v Value) bool {
|
||||
|
@ -23,5 +27,15 @@ func (v *Call) IsConst() bool {
|
|||
}
|
||||
|
||||
func (v *Call) String() string {
|
||||
return fmt.Sprintf("call%v", v.Args)
|
||||
return fmt.Sprintf("%s(%v)", v.Arguments[0], v.Arguments[1:])
|
||||
}
|
||||
|
||||
func (v *Call) Type() types.Type {
|
||||
typ := v.Arguments[0].(*Function).Typ
|
||||
|
||||
if len(typ.Output) == 0 {
|
||||
return types.Void
|
||||
}
|
||||
|
||||
return typ.Output[0]
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
package ssa
|
||||
|
||||
import "git.urbach.dev/cli/q/src/types"
|
||||
|
||||
type Function struct {
|
||||
UniqueName string
|
||||
Typ *types.Function
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (v *Function) Dependencies() []Value {
|
||||
|
@ -26,4 +29,8 @@ func (v *Function) IsConst() bool {
|
|||
|
||||
func (v *Function) String() string {
|
||||
return v.UniqueName
|
||||
}
|
||||
|
||||
func (v *Function) Type() types.Type {
|
||||
return v.Typ
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package ssa
|
||||
|
||||
import "git.urbach.dev/cli/q/src/token"
|
||||
|
||||
type HasToken struct {
|
||||
Source token.Token
|
||||
}
|
||||
|
||||
func (v *HasToken) Token() token.Token {
|
||||
return v.Source
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package ssa
|
||||
|
||||
import "git.urbach.dev/cli/q/src/types"
|
||||
|
||||
// IR is a list of basic blocks.
|
||||
type IR struct {
|
||||
Blocks []*Block
|
||||
|
@ -39,16 +41,9 @@ func (f *IR) AppendInt(x int) *Int {
|
|||
return v
|
||||
}
|
||||
|
||||
// AppendRegister adds a new register value to the last block.
|
||||
func (f *IR) AppendRegister(index int) *Parameter {
|
||||
v := &Parameter{Index: uint8(index)}
|
||||
f.Append(v)
|
||||
return v
|
||||
}
|
||||
|
||||
// AppendFunction adds a new function value to the last block.
|
||||
func (f *IR) AppendFunction(name string) *Function {
|
||||
v := &Function{UniqueName: name}
|
||||
func (f *IR) AppendFunction(name string, typ *types.Function) *Function {
|
||||
v := &Function{UniqueName: name, Typ: typ}
|
||||
f.Append(v)
|
||||
return v
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@ package ssa
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Int struct {
|
||||
Int int
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (v *Int) Dependencies() []Value {
|
||||
|
@ -30,4 +32,8 @@ func (v *Int) IsConst() bool {
|
|||
|
||||
func (v *Int) String() string {
|
||||
return fmt.Sprintf("%d", v.Int)
|
||||
}
|
||||
|
||||
func (v *Int) Type() types.Type {
|
||||
return types.AnyInt
|
||||
}
|
|
@ -1,11 +1,17 @@
|
|||
package ssa
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Parameter struct {
|
||||
Index uint8
|
||||
Name string
|
||||
Typ types.Type
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (v *Parameter) Dependencies() []Value {
|
||||
|
@ -27,5 +33,9 @@ func (v *Parameter) IsConst() bool {
|
|||
}
|
||||
|
||||
func (v *Parameter) String() string {
|
||||
return fmt.Sprintf("arg[%d]", v.Index)
|
||||
return fmt.Sprintf("in[%d]", v.Index)
|
||||
}
|
||||
|
||||
func (v *Parameter) Type() types.Type {
|
||||
return v.Typ
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
package ssa
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Return struct {
|
||||
Arguments
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (a *Return) AddUse(user Value) { panic("return is not a value") }
|
||||
|
@ -17,12 +21,12 @@ func (a *Return) Equals(v Value) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if len(a.Args) != len(b.Args) {
|
||||
if len(a.Arguments) != len(b.Arguments) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range a.Args {
|
||||
if !a.Args[i].Equals(b.Args[i]) {
|
||||
for i := range a.Arguments {
|
||||
if !a.Arguments[i].Equals(b.Arguments[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -35,5 +39,9 @@ func (v *Return) IsConst() bool {
|
|||
}
|
||||
|
||||
func (v *Return) String() string {
|
||||
return fmt.Sprintf("return %v", v.Args)
|
||||
return fmt.Sprintf("return %v", v.Arguments)
|
||||
}
|
||||
|
||||
func (v *Return) Type() types.Type {
|
||||
return types.Void
|
||||
}
|
13
src/ssa/Source.go
Normal file
13
src/ssa/Source.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package ssa
|
||||
|
||||
import "git.urbach.dev/cli/q/src/token"
|
||||
|
||||
type Source token.List
|
||||
|
||||
func (v Source) Start() token.Position {
|
||||
return v[0].Position
|
||||
}
|
||||
|
||||
func (v Source) End() token.Position {
|
||||
return v[len(v)-1].End()
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
package ssa
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Syscall struct {
|
||||
Arguments
|
||||
Liveness
|
||||
HasToken
|
||||
Source
|
||||
}
|
||||
|
||||
func (a *Syscall) Equals(v Value) bool {
|
||||
|
@ -23,5 +27,9 @@ func (v *Syscall) IsConst() bool {
|
|||
}
|
||||
|
||||
func (v *Syscall) String() string {
|
||||
return fmt.Sprintf("syscall%v", v.Args)
|
||||
return fmt.Sprintf("syscall(%v)", v.Arguments)
|
||||
}
|
||||
|
||||
func (v *Syscall) Type() types.Type {
|
||||
return types.Any
|
||||
}
|
|
@ -1,13 +1,18 @@
|
|||
package ssa
|
||||
|
||||
import "git.urbach.dev/cli/q/src/token"
|
||||
import (
|
||||
"git.urbach.dev/cli/q/src/token"
|
||||
"git.urbach.dev/cli/q/src/types"
|
||||
)
|
||||
|
||||
type Value interface {
|
||||
AddUse(Value)
|
||||
Alive() int
|
||||
Dependencies() []Value
|
||||
End() token.Position
|
||||
Equals(Value) bool
|
||||
IsConst() bool
|
||||
String() string
|
||||
Token() token.Token
|
||||
Start() token.Position
|
||||
Type() types.Type
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue