Add frames (in progress)
This commit is contained in:
@@ -11,38 +11,45 @@ import (
|
||||
|
||||
// n.Cfg() generates a control flow graph (CFG) from AST (wiring successors in AST)
|
||||
func (e *Node) Cfg() {
|
||||
//var findex int
|
||||
symIndex := make(map[string]int)
|
||||
maxIndex := 0
|
||||
|
||||
e.Walk(nil, func(n *Node) {
|
||||
switch x := (*n.anode).(type) {
|
||||
case *ast.BlockStmt:
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
// FIXME: could bypass this node at CFG and wire directly last child
|
||||
n.isNop = true
|
||||
n.run = nop
|
||||
n.val = n.Child[len(n.Child)-1].val
|
||||
n.findex = n.Child[len(n.Child)-1].findex
|
||||
case *ast.IncDecStmt:
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
switch x.Tok {
|
||||
case token.INC:
|
||||
n.run = inc
|
||||
}
|
||||
maxIndex++
|
||||
n.findex = maxIndex
|
||||
case *ast.AssignStmt:
|
||||
n.run = assign
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
case *ast.ExprStmt:
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
// FIXME: could bypass this node at CFG and wire directly last child
|
||||
n.isNop = true
|
||||
n.run = nop
|
||||
n.val = n.Child[len(n.Child)-1].val
|
||||
n.findex = n.Child[len(n.Child)-1].findex
|
||||
case *ast.ParenExpr:
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
// FIXME: could bypass this node at CFG and wire directly last child
|
||||
n.isNop = true
|
||||
n.run = nop
|
||||
n.val = n.Child[len(n.Child)-1].val
|
||||
n.findex = n.Child[len(n.Child)-1].findex
|
||||
case *ast.BinaryExpr:
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
switch x.Op {
|
||||
case token.AND:
|
||||
n.run = and
|
||||
@@ -51,9 +58,13 @@ func (e *Node) Cfg() {
|
||||
case token.LSS:
|
||||
n.run = lower
|
||||
}
|
||||
maxIndex++
|
||||
n.findex = maxIndex
|
||||
case *ast.CallExpr:
|
||||
wire_child(n)
|
||||
wireChild(n)
|
||||
n.run = call
|
||||
maxIndex++
|
||||
n.findex = maxIndex
|
||||
case *ast.IfStmt:
|
||||
n.isNop = true
|
||||
n.run = nop
|
||||
@@ -88,6 +99,10 @@ func (e *Node) Cfg() {
|
||||
}
|
||||
case *ast.Ident:
|
||||
n.ident = x.Name
|
||||
if n.findex = symIndex[n.ident]; n.findex == 0 {
|
||||
maxIndex++
|
||||
symIndex[n.ident] = maxIndex
|
||||
}
|
||||
default:
|
||||
println("unknown type:", reflect.TypeOf(*n.anode).String())
|
||||
}
|
||||
@@ -95,7 +110,7 @@ func (e *Node) Cfg() {
|
||||
}
|
||||
|
||||
// Wire AST nodes of sequential blocks
|
||||
func wire_child(n *Node) {
|
||||
func wireChild(n *Node) {
|
||||
for _, child := range n.Child {
|
||||
if !child.isLeaf() {
|
||||
n.Start = child.Start
|
||||
|
||||
@@ -57,7 +57,7 @@ func (n *Node) CfgDot() {
|
||||
case *ast.Ident:
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(dotin, "%d [label=\"%d\"]\n", n.index, n.index)
|
||||
fmt.Fprintf(dotin, "%d [label=\"%d %d\"]\n", n.index, n.index, n.findex)
|
||||
if n.next[1] != nil {
|
||||
fmt.Fprintf(dotin, "%d -> %d [color=green]\n", n.index, n.next[1].index)
|
||||
}
|
||||
|
||||
@@ -34,10 +34,9 @@ type Frame struct {
|
||||
|
||||
// Interpreter contains global resources and state
|
||||
type Interpreter struct {
|
||||
sym map[string]*interface{}
|
||||
constant map[string]*interface{}
|
||||
frame *Frame
|
||||
out interface{}
|
||||
sym map[string]*interface{}
|
||||
frame *Frame
|
||||
out interface{}
|
||||
}
|
||||
|
||||
// n.isLeaf() returns true if Node n is a leaf in the AST
|
||||
@@ -67,11 +66,11 @@ func NewInterpreter() *Interpreter {
|
||||
// i.Eval(s) evaluates Go code represented as a string
|
||||
func (i *Interpreter) Eval(src string) interface{} {
|
||||
root := Ast(src)
|
||||
//root.AstDot()
|
||||
root.AstDot()
|
||||
entry := root.Child[1].Child[2] // FIXME: entry point should be resolved from 'main' name
|
||||
entry.Cfg()
|
||||
entry.OptimCfg()
|
||||
//entry.CfgDot()
|
||||
entry.CfgDot()
|
||||
i.Run(entry.Start)
|
||||
return i.out
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package interp
|
||||
import "fmt"
|
||||
|
||||
func (i *Interpreter) Run(entry *Node) {
|
||||
// Init Frame
|
||||
|
||||
// Start execution by runnning entry function and go to next
|
||||
for n := entry; n != nil; {
|
||||
n.run(n, i)
|
||||
if n.snext != nil {
|
||||
@@ -22,6 +25,7 @@ func (i *Interpreter) Run(entry *Node) {
|
||||
//var sym map[string]*interface{} // FIXME: should be part of interpreter
|
||||
|
||||
func assign(n *Node, i *Interpreter) {
|
||||
fmt.Println("assign findex", n.Child[0].findex)
|
||||
name := n.Child[0].ident // symbol name is in the expr LHS
|
||||
i.sym[name] = n.Child[1].val // Set symbol value
|
||||
n.Child[0].val = i.sym[name]
|
||||
|
||||
Reference in New Issue
Block a user