mirror of
https://github.com/RoBaertschi/tt.git
synced 2025-04-16 05:53:30 +00:00
finished functions by fixing arguments
This commit is contained in:
parent
b633246af8
commit
290d05da88
@ -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)...)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
12
tast/tast.go
12
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 {
|
||||
|
2
test.tt
2
test.tt
@ -8,7 +8,7 @@ fn main() = {
|
||||
}
|
||||
};
|
||||
|
||||
fn test2(hello: i64,) = {
|
||||
fn test2(hello: i64) = {
|
||||
hello // Comment test
|
||||
};
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user