blob: b73f4da87bba7628049000b17d8ba43a72c5d05d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package codegen
import (
"fmt"
"reflect"
"github.com/gnolang/parscan/parser"
"github.com/gnolang/parscan/vm1"
)
func postCallExpr(x extNode) error {
switch x.Child[0].Kind {
case parser.Ident:
var numOut int
s, _, ok := x.getSym(x.Child[0].Content(), "")
if !ok {
return fmt.Errorf("invalid symbol %s", x.Child[0].Content())
}
if i, ok := x.codeIndex(s); ok {
// Internal call is always relative to instruction pointer.
x.Emit(x.Node, vm1.Call, int64(i-len(x.Code)))
} else {
// External call, using absolute addr in symtable.
x.Emit(x.Node, vm1.CallX, int64(len(x.Child[1].Child)))
numOut = reflect.TypeOf(x.Data[s.index]).NumOut()
}
if !usedRet(x.anc) {
x.Emit(x.Node, vm1.Pop, int64(numOut))
}
}
return nil
}
func usedRet(n *parser.Node) bool {
switch n.Kind {
case parser.Undefined, parser.StmtBloc:
return false
default:
return true
}
}
|