67 lines
1.8 KiB
Go
67 lines
1.8 KiB
Go
package analyzer
|
|
|
|
import "git.tebibyte.media/fspl/fspl/errors"
|
|
import "git.tebibyte.media/fspl/fspl/entity"
|
|
|
|
func (this *Tree) analyzeFunction (
|
|
pos errors.Position,
|
|
key entity.Key,
|
|
) (
|
|
*entity.Function,
|
|
error,
|
|
) {
|
|
var err error
|
|
|
|
// return if exists already
|
|
if function, exists := this.Functions[key]; exists {
|
|
return function, nil
|
|
}
|
|
|
|
// error if function is missing
|
|
function, exists := this.rawFunctions[key]
|
|
if !exists {
|
|
return nil, errors.Errorf(pos, "no function named %s", key.Name)
|
|
}
|
|
|
|
// set unit
|
|
function.Unt = key.Unit
|
|
|
|
// functions cannot be marked as opaque
|
|
if function.Acc == entity.AccessOpaque {
|
|
return nil, errors.Errorf(pos, "cannot mark function as opaque")
|
|
}
|
|
|
|
// create a new scope context for this function
|
|
this.pushScopeContext(function)
|
|
this.pushScope(function)
|
|
defer this.popScopeContext()
|
|
defer this.popScope()
|
|
|
|
// analyze signature and add arguments to root scope of function
|
|
function.Signature, err = this.assembleSignatureMap(function.Signature)
|
|
if err != nil { return function, err }
|
|
for name, argument := range function.Signature.ArgumentMap {
|
|
argument.Ty, err = this.analyzeType(argument.Ty, false)
|
|
this.addVariable(argument)
|
|
function.Signature.ArgumentMap[name] = argument
|
|
if err != nil { return function, err }
|
|
}
|
|
function.Signature.Return, err =
|
|
this.analyzeType(function.Signature.Return, false)
|
|
if err != nil { return function, err }
|
|
|
|
// add incomplete function to complete functions because there is enough
|
|
// information for it to be complete from the point of view of other
|
|
// parts of the code
|
|
this.Functions[key] = function
|
|
|
|
// analyze function body
|
|
if function.Body != nil {
|
|
body, err := this.analyzeExpression (
|
|
function.Signature.Return, strict, function.Body)
|
|
if err != nil { return nil, err }
|
|
function.Body = body
|
|
}
|
|
return function, nil
|
|
}
|