From 290d05da88deb7220afb711b383a8b1b17648e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20B=C3=A4rtschi?= Date: Sat, 8 Mar 2025 23:22:58 +0100 Subject: [PATCH] finished functions by fixing arguments --- asm/amd64/codegen.go | 18 ++++++++++++++++++ asm/qbe/qbe.go | 14 +++++++++++++- tast/tast.go | 12 +++++++++++- test.tt | 2 +- ttir/emit.go | 8 ++++++++ ttir/ttir.go | 6 +++++- typechecker/infer.go | 4 +++- 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/asm/amd64/codegen.go b/asm/amd64/codegen.go index 0ced5e4..d93ec52 100644 --- a/asm/amd64/codegen.go +++ b/asm/amd64/codegen.go @@ -44,6 +44,24 @@ func CgProgram(prog *ttir.Program) *Program { func cgFunction(f *ttir.Function) Function { 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 { newInstructions = append(newInstructions, cgInstruction(inst)...) } diff --git a/asm/qbe/qbe.go b/asm/qbe/qbe.go index 74393f8..2be498b 100644 --- a/asm/qbe/qbe.go +++ b/asm/qbe/qbe.go @@ -3,6 +3,7 @@ package qbe import ( "fmt" "io" + "strings" "robaertschi.xyz/robaertschi/tt/ast" "robaertschi.xyz/robaertschi/tt/ttir" @@ -64,7 +65,18 @@ func emitFunction(w io.Writer, f *ttir.Function) error { 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 } for _, i := range f.Instructions { diff --git a/tast/tast.go b/tast/tast.go index d0a079b..ff7f125 100644 --- a/tast/tast.go +++ b/tast/tast.go @@ -57,6 +57,16 @@ type Argument struct { 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 { Token token.Token // The token.FN Body Expression @@ -71,7 +81,7 @@ func (fd *FunctionDeclaration) declarationNode() {} func (fd *FunctionDeclaration) TokenLiteral() string { return fd.Token.Literal } func (fd *FunctionDeclaration) Tok() token.Token { return fd.Token } 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 { diff --git a/test.tt b/test.tt index 4c9dbd4..960c7a7 100644 --- a/test.tt +++ b/test.tt @@ -8,7 +8,7 @@ fn main() = { } }; -fn test2(hello: i64,) = { +fn test2(hello: i64) = { hello // Comment test }; diff --git a/ttir/emit.go b/ttir/emit.go index e08a653..f0b749f 100644 --- a/ttir/emit.go +++ b/ttir/emit.go @@ -44,9 +44,17 @@ func EmitProgram(program *tast.Program) *Program { func emitFunction(function *tast.FunctionDeclaration) *Function { value, instructions := emitExpression(function.Body) instructions = append(instructions, &Ret{Op: value}) + + arguments := []string{} + + for _, arg := range function.Args { + arguments = append(arguments, arg.Name) + } + f := &Function{ Name: function.Name, Instructions: instructions, + Arguments: arguments, HasReturnValue: !function.ReturnType.IsSameType(types.Unit), } diff --git a/ttir/ttir.go b/ttir/ttir.go index fa945b1..3efdc6b 100644 --- a/ttir/ttir.go +++ b/ttir/ttir.go @@ -29,7 +29,11 @@ type Function struct { func (f *Function) String() string { 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 { builder.WriteString(" ") builder.WriteString(i.String()) diff --git a/typechecker/infer.go b/typechecker/infer.go index 930b334..0c1fcb1 100644 --- a/typechecker/infer.go +++ b/typechecker/infer.go @@ -30,12 +30,14 @@ func (c *Checker) inferDeclaration(decl ast.Declaration) (tast.Declaration, erro switch decl := decl.(type) { case *ast.FunctionDeclaration: vars := make(Variables) + arguments := []tast.Argument{} for _, arg := range decl.Args { t, ok := types.From(arg.Type) if !ok { return nil, c.error(decl.Token, "could not find the type %q for argument %q", arg.Type, arg.Name) } vars[arg.Name] = t + arguments = append(arguments, tast.Argument{Name: arg.Name, Type: t}) } body, err := c.inferExpression(vars, decl.Body) c.functionVariables[decl.Name] = vars @@ -44,7 +46,7 @@ func (c *Checker) inferDeclaration(decl ast.Declaration) (tast.Declaration, erro 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") }