Make function calls work.
Function calls with parameters passed as value now work. Return value handling and scopes still missing.
This commit is contained in:
@@ -25,8 +25,6 @@ func (e *Node) Cfg(i *Interpreter) int {
|
||||
case *ast.FuncDecl:
|
||||
n.findex = maxIndex
|
||||
n.isConst = true
|
||||
// Node value is func body entry point
|
||||
n.val = n.Child[2]
|
||||
i.def[n.Child[0].ident] = n
|
||||
case *ast.BlockStmt:
|
||||
wireChild(n)
|
||||
@@ -69,6 +67,8 @@ func (e *Node) Cfg(i *Interpreter) int {
|
||||
}
|
||||
maxIndex++
|
||||
n.findex = maxIndex
|
||||
case *ast.Field:
|
||||
n.findex = n.Child[0].findex
|
||||
case *ast.CallExpr:
|
||||
wireChild(n)
|
||||
n.run = i.call
|
||||
@@ -108,13 +108,15 @@ func (e *Node) Cfg(i *Interpreter) int {
|
||||
}
|
||||
case *ast.Ident:
|
||||
// Lookup identifier in frame symbol table. If not found
|
||||
// should check that ident is assign target.
|
||||
// should check if ident can be defined (assign, param passing...)
|
||||
// or should lookup in upper scope of variables
|
||||
// For now, simply allocate a new entry in local sym table
|
||||
n.ident = x.Name
|
||||
if n.findex = symIndex[n.ident]; n.findex == 0 {
|
||||
maxIndex++
|
||||
symIndex[n.ident] = maxIndex
|
||||
n.findex = symIndex[n.ident]
|
||||
}
|
||||
n.findex = symIndex[n.ident]
|
||||
default:
|
||||
println("unknown type:", reflect.TypeOf(*n.anode).String())
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ type Frame struct {
|
||||
|
||||
// Interpreter contains global resources and state
|
||||
type Interpreter struct {
|
||||
size int
|
||||
frame *Frame
|
||||
out interface{}
|
||||
def map[string]*Node // map of defined symbols
|
||||
@@ -67,12 +66,12 @@ 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()
|
||||
i.size = root.Cfg(i)
|
||||
root.CfgDot()
|
||||
entry := root.Child[1].Child[2] // FIXME: entry point should be resolved from 'main' name
|
||||
//root.AstDot()
|
||||
root.Cfg(i)
|
||||
//root.CfgDot()
|
||||
entry := root.Child[1] // FIXME: entry point should be resolved from 'main' name
|
||||
//entry.OptimCfg()
|
||||
//entry.CfgDot()
|
||||
i.Run(entry.Start)
|
||||
Run(entry, nil, nil)
|
||||
return i.out
|
||||
}
|
||||
|
||||
@@ -2,13 +2,25 @@ package interp
|
||||
|
||||
import "fmt"
|
||||
|
||||
func (i *Interpreter) Run(entry *Node) {
|
||||
// Init Frame
|
||||
f := &Frame{val: make([]interface{}, i.size)}
|
||||
i.frame = f
|
||||
// Run a Go function
|
||||
func Run(def *Node, uf *Frame, args []*Node) {
|
||||
body := def.Child[2]
|
||||
param := def.Child[1].Child[0]
|
||||
|
||||
// Init new Frame
|
||||
f := &Frame{val: make([]interface{}, def.findex), up: uf}
|
||||
if uf != nil {
|
||||
uf.down = f
|
||||
}
|
||||
|
||||
// Pass func parameters as value: copy each func parameter from old to new frame
|
||||
// Frame locations were pre-computed during cfg
|
||||
for i := 0; i < len(args); i++ {
|
||||
f.val[param.Child[i].findex] = uf.val[args[i].findex]
|
||||
}
|
||||
|
||||
// Start execution by runnning entry function and go to next
|
||||
for n := entry; n != nil; {
|
||||
for n := body.Start; n != nil; {
|
||||
n.run(n, f)
|
||||
if n.fnext == nil || value(n, f).(bool) {
|
||||
n = n.tnext
|
||||
@@ -29,6 +41,7 @@ func value(n *Node, f *Frame) interface{} {
|
||||
}
|
||||
|
||||
func assign(n *Node, f *Frame) {
|
||||
fmt.Println("assign", n.index, n.Child[0].ident, n.findex)
|
||||
f.val[n.findex] = value(n.Child[1], f)
|
||||
}
|
||||
|
||||
@@ -48,9 +61,12 @@ func (i *Interpreter) call(n *Node, f *Frame) {
|
||||
printa(n.Child[1:], f)
|
||||
return
|
||||
}
|
||||
fn := i.def[n.Child[0].ident]
|
||||
fmt.Println("call node", fn.index, fn.Child[2].findex)
|
||||
panic("function not implemented")
|
||||
// FIXME: resolve fn during compile, not exec ?
|
||||
if fn := i.def[n.Child[0].ident]; fn != nil {
|
||||
Run(fn, f, n.Child[1:])
|
||||
} else {
|
||||
panic("function not found")
|
||||
}
|
||||
}
|
||||
|
||||
func equal(n *Node, f *Frame) {
|
||||
|
||||
Reference in New Issue
Block a user