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 {
|
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)...)
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
12
tast/tast.go
12
tast/tast.go
@ -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 {
|
||||||
|
2
test.tt
2
test.tt
@ -8,7 +8,7 @@ fn main() = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn test2(hello: i64,) = {
|
fn test2(hello: i64) = {
|
||||||
hello // Comment test
|
hello // Comment test
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user