Improve handling of out of order declarations
This commit is contained in:
@@ -2,11 +2,11 @@ package main
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
func r2() (int, int) { return 1, 2 }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(r2())
|
fmt.Println(r2())
|
||||||
}
|
}
|
||||||
|
|
||||||
func r2() (int, int) { return 1, 2 }
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 1 2
|
// 1 2
|
||||||
|
|||||||
@@ -5,6 +5,3 @@ import "github.com/containous/gi/_test/provider"
|
|||||||
func main() {
|
func main() {
|
||||||
provider.F1()
|
provider.F1()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output:
|
|
||||||
// Hello from Foo
|
|
||||||
|
|||||||
@@ -261,9 +261,8 @@ func (a Action) String() string {
|
|||||||
// of CFG, in order to accomodate forward type declarations
|
// of CFG, in order to accomodate forward type declarations
|
||||||
|
|
||||||
// Ast parses src string containing Go code and generates the corresponding AST.
|
// Ast parses src string containing Go code and generates the corresponding AST.
|
||||||
// The AST root node is returned.
|
// The package name and the AST root node are returned.
|
||||||
func (interp *Interpreter) Ast(src string) (*Node, *NodeMap) {
|
func (interp *Interpreter) Ast(src string) (string, *Node) {
|
||||||
def := NodeMap{}
|
|
||||||
fset := token.NewFileSet() // positions are relative to fset
|
fset := token.NewFileSet() // positions are relative to fset
|
||||||
f, err := parser.ParseFile(fset, "sample.go", src, 0)
|
f, err := parser.ParseFile(fset, "sample.go", src, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -494,8 +493,6 @@ func (interp *Interpreter) Ast(src string) (*Node, *NodeMap) {
|
|||||||
// function is not a method, create an empty receiver list
|
// function is not a method, create an empty receiver list
|
||||||
addChild(&root, n, &index, FieldList, Nop)
|
addChild(&root, n, &index, FieldList, Nop)
|
||||||
}
|
}
|
||||||
// Add func name to definitions
|
|
||||||
def[a.Name.Name] = n
|
|
||||||
st.push(n)
|
st.push(n)
|
||||||
|
|
||||||
case *ast.FuncLit:
|
case *ast.FuncLit:
|
||||||
@@ -609,10 +606,7 @@ func (interp *Interpreter) Ast(src string) (*Node, *NodeMap) {
|
|||||||
st.push(addChild(&root, anc, &index, TypeAssertExpr, TypeAssert))
|
st.push(addChild(&root, anc, &index, TypeAssertExpr, TypeAssert))
|
||||||
|
|
||||||
case *ast.TypeSpec:
|
case *ast.TypeSpec:
|
||||||
n := addChild(&root, anc, &index, TypeSpec, Nop)
|
st.push(addChild(&root, anc, &index, TypeSpec, Nop))
|
||||||
// Add type name to definitions
|
|
||||||
def[a.Name.Name] = n
|
|
||||||
st.push(n)
|
|
||||||
|
|
||||||
case *ast.UnaryExpr:
|
case *ast.UnaryExpr:
|
||||||
var kind = UnaryExpr
|
var kind = UnaryExpr
|
||||||
@@ -657,7 +651,7 @@ func (interp *Interpreter) Ast(src string) (*Node, *NodeMap) {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
return root, &def
|
return pkgName, root
|
||||||
}
|
}
|
||||||
|
|
||||||
type nodestack []*Node
|
type nodestack []*Node
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ type Symbol struct {
|
|||||||
node *Node // Node value if index is negative
|
node *Node // Node value if index is negative
|
||||||
index int // index of value in frame or -1
|
index int // index of value in frame or -1
|
||||||
pkgbin *SymMap // Map of package symbols if typ.cat is BinPkgT, or nil
|
pkgbin *SymMap // Map of package symbols if typ.cat is BinPkgT, or nil
|
||||||
pkgsrc *NodeMap // Map of package symbols if typ.cat is SrcPkgT, or nil
|
|
||||||
bin interface{} // Symbol from imported bin package if typ.cat is BinT, or nil
|
bin interface{} // Symbol from imported bin package if typ.cat is BinT, or nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,14 +49,14 @@ type FrameIndex struct {
|
|||||||
// PkgContext type stores current state of a package during compiling
|
// PkgContext type stores current state of a package during compiling
|
||||||
type PkgContext struct {
|
type PkgContext struct {
|
||||||
frameIndex *FrameIndex
|
frameIndex *FrameIndex
|
||||||
nodeMap *NodeMap
|
NodeMap
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cfg generates a control flow graph (CFG) from AST (wiring successors in AST)
|
// Cfg generates a control flow graph (CFG) from AST (wiring successors in AST)
|
||||||
// and pre-compute frame sizes and indexes for all un-named (temporary) and named
|
// and pre-compute frame sizes and indexes for all un-named (temporary) and named
|
||||||
// variables. A list of nodes of init functions is returned.
|
// variables. A list of nodes of init functions is returned.
|
||||||
// Following this pass, the CFG is ready to run
|
// Following this pass, the CFG is ready to run
|
||||||
func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
func (interp *Interpreter) Cfg(root *Node) []*Node {
|
||||||
scope := &Scope{sym: map[string]*Symbol{}}
|
scope := &Scope{sym: map[string]*Symbol{}}
|
||||||
frameIndex := &FrameIndex{}
|
frameIndex := &FrameIndex{}
|
||||||
var loop, loopRestart *Node
|
var loop, loopRestart *Node
|
||||||
@@ -66,13 +65,7 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
var exports *SymMap
|
var exports *SymMap
|
||||||
var expval *ValueMap
|
var expval *ValueMap
|
||||||
var iotaValue int
|
var iotaValue int
|
||||||
var srcPkg *NodeMap
|
var pkgName string
|
||||||
|
|
||||||
// Fill root scope with initial symbol definitions
|
|
||||||
for name, node := range *sdef {
|
|
||||||
scope.sym[name] = &Symbol{node: node, index: -1}
|
|
||||||
}
|
|
||||||
log.Println(interp.srcPkg["provider"])
|
|
||||||
|
|
||||||
root.Walk(func(n *Node) bool {
|
root.Walk(func(n *Node) bool {
|
||||||
// Pre-order processing
|
// Pre-order processing
|
||||||
@@ -91,10 +84,9 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
scope = scope.push(0)
|
scope = scope.push(0)
|
||||||
|
|
||||||
case File:
|
case File:
|
||||||
pkgName := n.child[0].ident
|
pkgName = n.child[0].ident
|
||||||
srcPkg = interp.srcPkg[pkgName]
|
if _, ok := interp.context[pkgName]; !ok {
|
||||||
if srcPkg == nil {
|
interp.context[pkgName] = PkgContext{NodeMap: NodeMap{}}
|
||||||
srcPkg = &NodeMap{}
|
|
||||||
}
|
}
|
||||||
if pkg, ok := interp.Exports[pkgName]; ok {
|
if pkg, ok := interp.Exports[pkgName]; ok {
|
||||||
exports = pkg
|
exports = pkg
|
||||||
@@ -174,6 +166,7 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
}
|
}
|
||||||
// TODO: deprecate use of interp.types in favor of scope.sym
|
// TODO: deprecate use of interp.types in favor of scope.sym
|
||||||
interp.types[n.child[0].ident] = n.typ
|
interp.types[n.child[0].ident] = n.typ
|
||||||
|
interp.context[pkgName].NodeMap[n.child[0].ident] = n
|
||||||
scope.sym[n.child[0].ident] = &Symbol{typ: n.typ}
|
scope.sym[n.child[0].ident] = &Symbol{typ: n.typ}
|
||||||
// TODO: export type for use by runtime
|
// TODO: export type for use by runtime
|
||||||
return false
|
return false
|
||||||
@@ -427,6 +420,8 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
n.typ = interp.types[def.child[2].child[j].child[0].child[0].ident]
|
n.typ = interp.types[def.child[2].child[j].child[0].child[0].ident]
|
||||||
}
|
}
|
||||||
n.fsize = l
|
n.fsize = l
|
||||||
|
} else {
|
||||||
|
log.Println(n.index, "call to unknown def")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if n.child[0].kind == SelectorSrc {
|
} else if n.child[0].kind == SelectorSrc {
|
||||||
@@ -578,6 +573,9 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
n.typ = n.child[2].typ
|
n.typ = n.child[2].typ
|
||||||
n.val = n
|
n.val = n
|
||||||
scope.sym[funcName].typ = n.typ
|
scope.sym[funcName].typ = n.typ
|
||||||
|
scope.sym[funcName].node = n
|
||||||
|
scope.sym[funcName].index = -1
|
||||||
|
interp.context[pkgName].NodeMap[funcName] = n
|
||||||
|
|
||||||
case FuncLit:
|
case FuncLit:
|
||||||
n.typ = n.child[2].typ
|
n.typ = n.child[2].typ
|
||||||
@@ -628,12 +626,12 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
} else if n.typ != nil {
|
} else if n.typ != nil {
|
||||||
if n.typ.cat == BinPkgT {
|
if n.typ.cat == BinPkgT {
|
||||||
n.val = sym.pkgbin
|
n.val = sym.pkgbin
|
||||||
} else if n.typ.cat == SrcPkgT {
|
|
||||||
n.val = sym.pkgsrc
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
n.sym = sym
|
||||||
}
|
}
|
||||||
n.recv = n
|
n.recv = n
|
||||||
} else if node, ok := (*srcPkg)[n.ident]; ok {
|
} else if node, ok := interp.context[pkgName].NodeMap[n.ident]; ok {
|
||||||
n.val = node
|
n.val = node
|
||||||
n.typ = node.typ
|
n.typ = node.typ
|
||||||
n.kind = node.kind
|
n.kind = node.kind
|
||||||
@@ -649,17 +647,20 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
symFrameIndex := frameIndex
|
symFrameIndex := frameIndex
|
||||||
symScope := scope
|
symScope := scope
|
||||||
level := 0
|
level := 0
|
||||||
|
// Back to package level scope
|
||||||
for symFrameIndex.anc != nil {
|
for symFrameIndex.anc != nil {
|
||||||
level++
|
level++
|
||||||
symScope = symScope.anc
|
|
||||||
symFrameIndex = symFrameIndex.anc
|
symFrameIndex = symFrameIndex.anc
|
||||||
}
|
}
|
||||||
|
for symScope.anc != nil {
|
||||||
|
symScope = symScope.anc
|
||||||
|
}
|
||||||
symFrameIndex.max++
|
symFrameIndex.max++
|
||||||
symScope.sym[n.ident] = &Symbol{index: symFrameIndex.max}
|
symScope.sym[n.ident] = &Symbol{index: symFrameIndex.max}
|
||||||
(*sdef)[n.ident] = n
|
interp.context[pkgName].NodeMap[n.ident] = n
|
||||||
n.findex = symFrameIndex.max
|
n.findex = symFrameIndex.max
|
||||||
n.level = level
|
n.level = level
|
||||||
log.Println(n.index, n.ident, n.anc.kind, "unresolved, create new at pkg level", n.findex, level)
|
n.sym = symScope.sym[n.ident]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +720,7 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
} else {
|
} else {
|
||||||
// TODO: make sure we do not import a src package more than once
|
// TODO: make sure we do not import a src package more than once
|
||||||
interp.importSrcFile(ipath)
|
interp.importSrcFile(ipath)
|
||||||
scope.sym[name] = &Symbol{typ: &Type{cat: SrcPkgT}, pkgsrc: interp.srcPkg[name]}
|
scope.sym[name] = &Symbol{typ: &Type{cat: SrcPkgT}}
|
||||||
}
|
}
|
||||||
|
|
||||||
case KeyValueExpr:
|
case KeyValueExpr:
|
||||||
@@ -818,15 +819,13 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
n.run = nop
|
n.run = nop
|
||||||
} else if n.typ.cat == SrcPkgT {
|
} else if n.typ.cat == SrcPkgT {
|
||||||
// Resolve source package symbol
|
// Resolve source package symbol
|
||||||
pkgSrc := n.child[0].val.(*NodeMap)
|
if node, ok := interp.context[n.child[0].ident].NodeMap[n.child[1].ident]; ok {
|
||||||
name := n.child[1].ident
|
|
||||||
if node, ok := (*pkgSrc)[name]; ok {
|
|
||||||
n.val = node
|
n.val = node
|
||||||
n.run = nop
|
n.run = nop
|
||||||
n.kind = SelectorSrc
|
n.kind = SelectorSrc
|
||||||
n.typ = node.typ
|
n.typ = node.typ
|
||||||
} else {
|
} else {
|
||||||
log.Println(n.index, "selector unresolved:", n.child[0].ident+"."+name)
|
log.Println(n.index, "selector unresolved:", n.child[0].ident+"."+n.child[1].ident)
|
||||||
}
|
}
|
||||||
} else if fi := n.typ.fieldIndex(n.child[1].ident); fi >= 0 {
|
} else if fi := n.typ.fieldIndex(n.child[1].ident); fi >= 0 {
|
||||||
// Resolve struct field index
|
// Resolve struct field index
|
||||||
@@ -896,7 +895,6 @@ func (interp *Interpreter) Cfg(root *Node, sdef *NodeMap) []*Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
log.Println(sdef)
|
|
||||||
return initNodes
|
return initNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package interp
|
package interp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ type Node struct {
|
|||||||
flen int // frame length (function definition)
|
flen int // frame length (function definition)
|
||||||
level int // number of frame indirections to access value
|
level int // number of frame indirections to access value
|
||||||
kind Kind // kind of node
|
kind Kind // kind of node
|
||||||
|
sym *Symbol // associated symbol
|
||||||
typ *Type // type of value in frame, or nil
|
typ *Type // type of value in frame, or nil
|
||||||
recv *Node // method receiver node for call, or nil
|
recv *Node // method receiver node for call, or nil
|
||||||
frame *Frame // frame pointer, only used for script callbacks from runtime (wrapNode)
|
frame *Frame // frame pointer, only used for script callbacks from runtime (wrapNode)
|
||||||
@@ -41,6 +43,8 @@ type NodeMap map[string]*Node
|
|||||||
// PkgSrcMap stores package source nodes
|
// PkgSrcMap stores package source nodes
|
||||||
type PkgSrcMap map[string]*NodeMap
|
type PkgSrcMap map[string]*NodeMap
|
||||||
|
|
||||||
|
type PkgCtxMap map[string]PkgContext
|
||||||
|
|
||||||
// SymMap stores executable symbols indexed by name
|
// SymMap stores executable symbols indexed by name
|
||||||
type SymMap map[string]interface{}
|
type SymMap map[string]interface{}
|
||||||
|
|
||||||
@@ -66,7 +70,7 @@ type Interpreter struct {
|
|||||||
Opt
|
Opt
|
||||||
Frame *Frame
|
Frame *Frame
|
||||||
types TypeMap
|
types TypeMap
|
||||||
srcPkg PkgSrcMap
|
context PkgCtxMap
|
||||||
binPkg PkgMap
|
binPkg PkgMap
|
||||||
Exports PkgMap
|
Exports PkgMap
|
||||||
Expval PkgValueMap
|
Expval PkgValueMap
|
||||||
@@ -91,7 +95,7 @@ func NewInterpreter(opt Opt) *Interpreter {
|
|||||||
return &Interpreter{
|
return &Interpreter{
|
||||||
Opt: opt,
|
Opt: opt,
|
||||||
types: defaultTypes,
|
types: defaultTypes,
|
||||||
srcPkg: make(PkgSrcMap),
|
context: make(PkgCtxMap),
|
||||||
binPkg: make(PkgMap),
|
binPkg: make(PkgMap),
|
||||||
Exports: make(PkgMap),
|
Exports: make(PkgMap),
|
||||||
Expval: make(PkgValueMap),
|
Expval: make(PkgValueMap),
|
||||||
@@ -116,16 +120,17 @@ func (i *Interpreter) ImportBin(pkg *map[string]*map[string]interface{}) {
|
|||||||
|
|
||||||
// Eval evaluates Go code represented as a string. It returns a map on
|
// Eval evaluates Go code represented as a string. It returns a map on
|
||||||
// current interpreted package exported symbols
|
// current interpreted package exported symbols
|
||||||
func (i *Interpreter) Eval(src string) (string, *NodeMap) {
|
func (i *Interpreter) Eval(src string) string {
|
||||||
// Parse source to AST
|
// Parse source to AST
|
||||||
root, sdef := i.Ast(src)
|
pkgName, root := i.Ast(src)
|
||||||
|
log.Println(pkgName)
|
||||||
if i.AstDot {
|
if i.AstDot {
|
||||||
root.AstDot(DotX())
|
root.AstDot(DotX())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotate AST with CFG infos
|
// Annotate AST with CFG infos
|
||||||
initNodes := i.Cfg(root, sdef)
|
initNodes := i.Cfg(root)
|
||||||
if entry, ok := (*sdef)[i.Entry]; ok {
|
if entry, ok := i.context[pkgName].NodeMap[i.Entry]; ok {
|
||||||
initNodes = append(initNodes, entry)
|
initNodes = append(initNodes, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,5 +146,5 @@ func (i *Interpreter) Eval(src string) (string, *NodeMap) {
|
|||||||
Run(n, i.Frame, nil, nil, nil, nil, true, false)
|
Run(n, i.Frame, nil, nil, nil, nil, true, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return root.child[0].ident, sdef
|
return root.child[0].ident
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1839,11 +1839,11 @@ package main
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
func r2() (int, int) { return 1, 2 }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println(r2())
|
fmt.Println(r2())
|
||||||
}
|
}
|
||||||
|
|
||||||
func r2() (int, int) { return 1, 2 }
|
|
||||||
`
|
`
|
||||||
i := NewInterpreter(Opt{Entry: "main"})
|
i := NewInterpreter(Opt{Entry: "main"})
|
||||||
i.ImportBin(export.Pkg)
|
i.ImportBin(export.Pkg)
|
||||||
@@ -2594,6 +2594,21 @@ func main() {
|
|||||||
// Hello from Foo
|
// Hello from Foo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Example_src4() {
|
||||||
|
src := `
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/containous/gi/_test/provider"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
provider.F1()
|
||||||
|
}`
|
||||||
|
i := NewInterpreter(Opt{Entry: "main"})
|
||||||
|
i.ImportBin(export.Pkg)
|
||||||
|
i.Eval(src)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func Example_str() {
|
func Example_str() {
|
||||||
src := `
|
src := `
|
||||||
package main
|
package main
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package interp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -128,7 +127,15 @@ func value(n *Node, f *Frame) interface{} {
|
|||||||
case Rvalue:
|
case Rvalue:
|
||||||
return n.rval
|
return n.rval
|
||||||
default:
|
default:
|
||||||
//log.Println(n.index, n.ident, n.findex, n.level, f)
|
if n.sym != nil {
|
||||||
|
if n.sym.index < 0 {
|
||||||
|
return value(n.sym.node, f)
|
||||||
|
}
|
||||||
|
for level := n.level; level > 0; level-- {
|
||||||
|
f = f.anc
|
||||||
|
}
|
||||||
|
return f.data[n.sym.index]
|
||||||
|
}
|
||||||
for level := n.level; level > 0; level-- {
|
for level := n.level; level > 0; level-- {
|
||||||
f = f.anc
|
f = f.anc
|
||||||
}
|
}
|
||||||
@@ -140,11 +147,19 @@ func value(n *Node, f *Frame) interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addrValue(n *Node, f *Frame) *interface{} {
|
func addrValue(n *Node, f *Frame) *interface{} {
|
||||||
log.Println(n.index, n.ident, n.kind, n.level, n.findex)
|
|
||||||
switch n.kind {
|
switch n.kind {
|
||||||
case BasicLit, FuncDecl, Rvalue:
|
case BasicLit, FuncDecl, Rvalue:
|
||||||
return &n.val
|
return &n.val
|
||||||
default:
|
default:
|
||||||
|
if n.sym != nil {
|
||||||
|
if n.sym.index < 0 {
|
||||||
|
return addrValue(n.sym.node, f)
|
||||||
|
}
|
||||||
|
for level := n.level; level > 0; level-- {
|
||||||
|
f = f.anc
|
||||||
|
}
|
||||||
|
return &f.data[n.sym.index]
|
||||||
|
}
|
||||||
for level := n.level; level > 0; level-- {
|
for level := n.level; level > 0; level-- {
|
||||||
f = f.anc
|
f = f.anc
|
||||||
}
|
}
|
||||||
@@ -307,6 +322,7 @@ func call(n *Node, f *Frame) {
|
|||||||
recv = n.child[0].recv
|
recv = n.child[0].recv
|
||||||
rseq = n.child[0].child[1].val.([]int)
|
rseq = n.child[0].child[1].val.([]int)
|
||||||
}
|
}
|
||||||
|
//log.Println(n.index, "call", n.child[0].ident, value(n.child[0], f))
|
||||||
fn := value(n.child[0], f).(*Node)
|
fn := value(n.child[0], f).(*Node)
|
||||||
var ret []int
|
var ret []int
|
||||||
if len(fn.child[2].child) > 1 {
|
if len(fn.child[2].child) > 1 {
|
||||||
@@ -390,11 +406,12 @@ func callBin(n *Node, f *Frame) {
|
|||||||
in[i] = value(c, f).(reflect.Value)
|
in[i] = value(c, f).(reflect.Value)
|
||||||
c.frame = f
|
c.frame = f
|
||||||
} else {
|
} else {
|
||||||
|
//log.Println(value(c, f), c.sym, c.level)
|
||||||
in[i] = reflect.ValueOf(value(c, f))
|
in[i] = reflect.ValueOf(value(c, f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun := value(n.child[0], f).(reflect.Value)
|
fun := value(n.child[0], f).(reflect.Value)
|
||||||
log.Println("in:", in)
|
//log.Println(n.index, "in:", in)
|
||||||
v := fun.Call(in)
|
v := fun.Call(in)
|
||||||
for i := 0; i < n.fsize; i++ {
|
for i := 0; i < n.fsize; i++ {
|
||||||
f.data[n.findex+i] = v[i].Interface()
|
f.data[n.findex+i] = v[i].Interface()
|
||||||
@@ -720,7 +737,7 @@ func slice(n *Node, f *Frame) {
|
|||||||
|
|
||||||
// slice expression, no low value
|
// slice expression, no low value
|
||||||
func slice0(n *Node, f *Frame) {
|
func slice0(n *Node, f *Frame) {
|
||||||
log.Println(n.index, n.child[0].ident, value(n.child[0], f))
|
//log.Println(n.index, n.child[0].ident, value(n.child[0], f))
|
||||||
a := value(n.child[0], f).([]interface{})
|
a := value(n.child[0], f).([]interface{})
|
||||||
switch len(n.child) {
|
switch len(n.child) {
|
||||||
case 1:
|
case 1:
|
||||||
|
|||||||
@@ -26,13 +26,9 @@ func (interp *Interpreter) importSrcFile(path string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
pkgName, sdef := interp.Eval(string(buf))
|
pkgName := interp.Eval(string(buf))
|
||||||
if interp.srcPkg[pkgName] == nil {
|
if _, ok := interp.context[pkgName]; !ok {
|
||||||
s := make(NodeMap)
|
interp.context[pkgName] = PkgContext{NodeMap: NodeMap{}}
|
||||||
interp.srcPkg[pkgName] = &s
|
|
||||||
}
|
|
||||||
for name, node := range *sdef {
|
|
||||||
(*interp.srcPkg[pkgName])[name] = node
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user