handle multiple assign/return statements
This commit is contained in:
6
assign.gi
Normal file
6
assign.gi
Normal file
@@ -0,0 +1,6 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
a, b := 1, 2 // Multiple assign
|
||||
println(a, b)
|
||||
}
|
||||
@@ -22,15 +22,25 @@ func Ast(src string) *Node {
|
||||
var st nodestack
|
||||
// Populate our own private ast from go ast. A stack of ancestor nodes
|
||||
// is used to keep track of curent ancestor for each depth level
|
||||
ast.Inspect(f, func(n ast.Node) bool {
|
||||
ast.Inspect(f, func(node ast.Node) bool {
|
||||
anc = st.top()
|
||||
switch n.(type) {
|
||||
switch n := node.(type) {
|
||||
case nil:
|
||||
anc = st.pop()
|
||||
case *ast.AssignStmt:
|
||||
index++
|
||||
var i interface{}
|
||||
nod := &Node{anc: anc, index: index, anode: &node, val: &i, lhs: len(n.Lhs)}
|
||||
if anc == nil {
|
||||
root = nod
|
||||
} else {
|
||||
anc.Child = append(anc.Child, nod)
|
||||
}
|
||||
st.push(nod)
|
||||
default:
|
||||
index++
|
||||
var i interface{}
|
||||
nod := &Node{anc: anc, index: index, anode: &n, val: &i}
|
||||
nod := &Node{anc: anc, index: index, anode: &node, val: &i}
|
||||
if anc == nil {
|
||||
root = nod
|
||||
} else {
|
||||
|
||||
@@ -19,6 +19,7 @@ type Node struct {
|
||||
findex int // index of value in frame or frame size (func def)
|
||||
run RunFun // function to run at CFG execution
|
||||
val interface{} // pointer on generic value (CFG execution)
|
||||
lhs int // number of left hand side nodes, set if node is an assign statement
|
||||
ident string // set if node is a var or func
|
||||
isNop bool // node run function us a no-op
|
||||
isConst bool // true if node value is constant
|
||||
|
||||
@@ -43,7 +43,22 @@ func value(n *Node, f *Frame) interface{} {
|
||||
}
|
||||
|
||||
func assign(n *Node, f *Frame) {
|
||||
(*f)[n.findex] = value(n.Child[1], f)
|
||||
// FIXME: should have different assign flavors set by CFG instead
|
||||
if n.lhs > 1 {
|
||||
if len(n.Child)-n.lhs > 1 {
|
||||
// multiple single assign
|
||||
for i := 0; i < n.lhs; i++ {
|
||||
(*f)[n.Child[i].findex] = value(n.Child[len(n.Child)-n.lhs+i], f)
|
||||
}
|
||||
} else {
|
||||
// Multiple vars set from a single call
|
||||
for i := 0; i < n.lhs; i++ {
|
||||
(*f)[n.Child[i].findex] = (*f)[n.Child[len(n.Child)-1].findex+i]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(*f)[n.findex] = value(n.Child[1], f)
|
||||
}
|
||||
}
|
||||
|
||||
func and(n *Node, f *Frame) {
|
||||
@@ -52,7 +67,7 @@ func and(n *Node, f *Frame) {
|
||||
|
||||
func printa(n []*Node, f *Frame) {
|
||||
for _, m := range n {
|
||||
fmt.Printf("%v", value(m, f))
|
||||
fmt.Printf("%v ", value(m, f))
|
||||
}
|
||||
fmt.Println("")
|
||||
}
|
||||
@@ -104,7 +119,7 @@ func nop(n *Node, i *Frame) {}
|
||||
|
||||
func _return(n *Node, f *Frame) {
|
||||
for i, c := range n.Child {
|
||||
(*f)[i] = (*f)[c.findex]
|
||||
(*f)[i] = value(c, f)
|
||||
}
|
||||
// FIXME: should be done during compiling, not run
|
||||
n.tnext = nil
|
||||
|
||||
Reference in New Issue
Block a user