Add frames (in progress)

This commit is contained in:
Marc Vertes
2018-02-02 09:21:06 +01:00
parent 75f96aeac7
commit 2f1e444aab
4 changed files with 34 additions and 16 deletions

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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]