finished functions by fixing arguments

This commit is contained in:
Robin Bärtschi 2025-03-08 23:22:58 +01:00
parent b633246af8
commit 290d05da88
7 changed files with 59 additions and 5 deletions

View File

@ -44,6 +44,24 @@ func CgProgram(prog *ttir.Program) *Program {
func cgFunction(f *ttir.Function) Function { func cgFunction(f *ttir.Function) Function {
newInstructions := []Instruction{} newInstructions := []Instruction{}
for i, arg := range f.Arguments {
if i < len(callConvArgs) {
newInstructions = append(newInstructions, &SimpleInstruction{
Opcode: Mov,
Lhs: Pseudo(arg),
Rhs: Register(callConvArgs[i]),
})
} else {
newInstructions = append(newInstructions,
&SimpleInstruction{
Opcode: Mov,
Lhs: Pseudo(arg),
Rhs: Stack(16 + (8 * (i - len(callConvArgs)))),
},
)
}
}
for _, inst := range f.Instructions { for _, inst := range f.Instructions {
newInstructions = append(newInstructions, cgInstruction(inst)...) newInstructions = append(newInstructions, cgInstruction(inst)...)
} }

View File

@ -3,6 +3,7 @@ package qbe
import ( import (
"fmt" "fmt"
"io" "io"
"strings"
"robaertschi.xyz/robaertschi/tt/ast" "robaertschi.xyz/robaertschi/tt/ast"
"robaertschi.xyz/robaertschi/tt/ttir" "robaertschi.xyz/robaertschi/tt/ttir"
@ -64,7 +65,18 @@ func emitFunction(w io.Writer, f *ttir.Function) error {
return err return err
} }
} }
if err := emitf(w, "$%s() {\n@start\n", f.Name); err != nil {
b := strings.Builder{}
for i, arg := range f.Arguments {
if i > 0 {
b.WriteString(", ")
}
b.WriteString("l %")
b.WriteString(arg)
}
if err := emitf(w, "$%s(%v) {\n@start\n", f.Name, b.String()); err != nil {
return err return err
} }
for _, i := range f.Instructions { for _, i := range f.Instructions {

View File

@ -57,6 +57,16 @@ type Argument struct {
Type types.Type Type types.Type
} }
func ArgsToString(args []Argument) string {
var b strings.Builder
for _, arg := range args {
b.WriteString(fmt.Sprintf("%s %s,", arg.Name, arg.Type.Name()))
}
return b.String()
}
type FunctionDeclaration struct { type FunctionDeclaration struct {
Token token.Token // The token.FN Token token.Token // The token.FN
Body Expression Body Expression
@ -71,7 +81,7 @@ func (fd *FunctionDeclaration) declarationNode() {}
func (fd *FunctionDeclaration) TokenLiteral() string { return fd.Token.Literal } func (fd *FunctionDeclaration) TokenLiteral() string { return fd.Token.Literal }
func (fd *FunctionDeclaration) Tok() token.Token { return fd.Token } func (fd *FunctionDeclaration) Tok() token.Token { return fd.Token }
func (fd *FunctionDeclaration) String() string { func (fd *FunctionDeclaration) String() string {
return fmt.Sprintf("fn %v(): %v = %v;", fd.Name, fd.ReturnType.Name(), fd.Body.String()) return fmt.Sprintf("fn %v(%v): %v = %v;", fd.Name, ArgsToString(fd.Args), fd.ReturnType.Name(), fd.Body.String())
} }
type IntegerExpression struct { type IntegerExpression struct {

View File

@ -8,7 +8,7 @@ fn main() = {
} }
}; };
fn test2(hello: i64,) = { fn test2(hello: i64) = {
hello // Comment test hello // Comment test
}; };

View File

@ -44,9 +44,17 @@ func EmitProgram(program *tast.Program) *Program {
func emitFunction(function *tast.FunctionDeclaration) *Function { func emitFunction(function *tast.FunctionDeclaration) *Function {
value, instructions := emitExpression(function.Body) value, instructions := emitExpression(function.Body)
instructions = append(instructions, &Ret{Op: value}) instructions = append(instructions, &Ret{Op: value})
arguments := []string{}
for _, arg := range function.Args {
arguments = append(arguments, arg.Name)
}
f := &Function{ f := &Function{
Name: function.Name, Name: function.Name,
Instructions: instructions, Instructions: instructions,
Arguments: arguments,
HasReturnValue: !function.ReturnType.IsSameType(types.Unit), HasReturnValue: !function.ReturnType.IsSameType(types.Unit),
} }

View File

@ -29,7 +29,11 @@ type Function struct {
func (f *Function) String() string { func (f *Function) String() string {
var builder strings.Builder var builder strings.Builder
builder.WriteString(fmt.Sprintf("fn %s\n", f.Name)) builder.WriteString(fmt.Sprintf("fn %s", f.Name))
for _, arg := range f.Arguments {
builder.WriteString(" " + arg)
}
builder.WriteRune('\n')
for _, i := range f.Instructions { for _, i := range f.Instructions {
builder.WriteString(" ") builder.WriteString(" ")
builder.WriteString(i.String()) builder.WriteString(i.String())

View File

@ -30,12 +30,14 @@ func (c *Checker) inferDeclaration(decl ast.Declaration) (tast.Declaration, erro
switch decl := decl.(type) { switch decl := decl.(type) {
case *ast.FunctionDeclaration: case *ast.FunctionDeclaration:
vars := make(Variables) vars := make(Variables)
arguments := []tast.Argument{}
for _, arg := range decl.Args { for _, arg := range decl.Args {
t, ok := types.From(arg.Type) t, ok := types.From(arg.Type)
if !ok { if !ok {
return nil, c.error(decl.Token, "could not find the type %q for argument %q", arg.Type, arg.Name) return nil, c.error(decl.Token, "could not find the type %q for argument %q", arg.Type, arg.Name)
} }
vars[arg.Name] = t vars[arg.Name] = t
arguments = append(arguments, tast.Argument{Name: arg.Name, Type: t})
} }
body, err := c.inferExpression(vars, decl.Body) body, err := c.inferExpression(vars, decl.Body)
c.functionVariables[decl.Name] = vars c.functionVariables[decl.Name] = vars
@ -44,7 +46,7 @@ func (c *Checker) inferDeclaration(decl ast.Declaration) (tast.Declaration, erro
return nil, err return nil, err
} }
return &tast.FunctionDeclaration{Token: decl.Token, Body: body, ReturnType: body.Type(), Name: decl.Name}, nil return &tast.FunctionDeclaration{Token: decl.Token, Args: arguments, Body: body, ReturnType: body.Type(), Name: decl.Name}, nil
} }
return nil, errors.New("unhandled declaration in type inferer") return nil, errors.New("unhandled declaration in type inferer")
} }