fspl/generator/function.go

80 lines
2.1 KiB
Go

package generator
import "git.tebibyte.media/sashakoshka/fspl/llvm"
import "git.tebibyte.media/sashakoshka/fspl/entity"
func (this *generator) generateFunction (
function *entity.Function,
) (
*llvm.Function,
error,
) {
params := make([]*llvm.Parameter, len(function.Signature.Arguments))
ret, err := this.generateType(function.Signature.Return)
if err != nil { return nil, err }
for index, argument := range function.Signature.Arguments {
paramType, err := this.generateType(argument.Type())
if err != nil { return nil, err }
params[index] = llvm.NewParameter(argument.Name, paramType)
}
irFunc := this.module.NewFunction(function.Signature.Name, ret, params...)
if function.Body != nil {
this.blockManager = this.pushBlockManager(irFunc)
defer this.popBlockManager()
this.blockManager.addDeclarationsInFunction(function)
body, err := this.generateExpression(function.Body)
if err != nil { return nil, err }
if function.Signature.Return == nil {
this.blockManager.NewRet(nil)
} else {
this.blockManager.NewRet(body)
}
}
return irFunc, nil
}
func (this *generator) generateMethod (
method *entity.Method,
) (
*llvm.Function,
error,
) {
params := make([]*llvm.Parameter, len(method.Signature.Arguments) + 1)
ret, err := this.generateType(method.Signature.Return)
if err != nil { return nil, err }
for index, argument := range method.Signature.Arguments {
paramType, err := this.generateType(argument.Type())
if err != nil { return nil, err }
params[index + 1] = llvm.NewParameter(argument.Name, paramType)
}
params[0] = llvm.NewParameter("this", new(llvm.TypePointer))
irFunc := this.module.NewFunction (
method.TypeName + "." + method.Signature.Name,
ret, params...)
if method.Body != nil {
this.blockManager = this.pushBlockManager(irFunc)
defer this.popBlockManager()
this.blockManager.addDeclarationsInFunction(method)
body, err := this.generateExpression(method.Body)
if err != nil { return nil, err }
if method.Signature.Return == nil {
this.blockManager.NewRet(nil)
} else {
this.blockManager.NewRet(body)
}
}
return irFunc, nil
}