github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/eval/eval.go (about)

     1  // Copyright 2015 The Neugram Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package eval
     6  
     7  import (
     8  	"bufio"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"math/big"
    12  	"os"
    13  	"path/filepath"
    14  	"reflect"
    15  	"runtime/debug"
    16  	"strings"
    17  	"sync"
    18  	"unsafe"
    19  
    20  	"neugram.io/ng/eval/environ"
    21  	"neugram.io/ng/eval/gowrap"
    22  	"neugram.io/ng/eval/gowrap/genwrap"
    23  	_ "neugram.io/ng/eval/gowrap/wrapbuiltin" // registers with gowrap
    24  	"neugram.io/ng/eval/shell"
    25  	"neugram.io/ng/format"
    26  	"neugram.io/ng/gengo"
    27  	"neugram.io/ng/gotool"
    28  	"neugram.io/ng/internal/bigcplx"
    29  	"neugram.io/ng/parser"
    30  	"neugram.io/ng/syntax/expr"
    31  	"neugram.io/ng/syntax/stmt"
    32  	"neugram.io/ng/syntax/tipe"
    33  	"neugram.io/ng/syntax/token"
    34  	"neugram.io/ng/typecheck"
    35  )
    36  
    37  type Scope struct {
    38  	Parent  *Scope
    39  	VarName string
    40  	Var     reflect.Value
    41  
    42  	// Implicit is set if the Scope was created mid block and should be
    43  	// unrolled when block ends.
    44  	Implicit bool
    45  
    46  	Label bool
    47  
    48  	fct    string     // function name if this is a function scope
    49  	defers []deferCtx // LIFO-list of defers to run
    50  }
    51  
    52  func (s *Scope) Lookup(name string) reflect.Value {
    53  	for scope := s; scope != nil; scope = scope.Parent {
    54  		if scope.VarName == name {
    55  			return scope.Var
    56  		}
    57  	}
    58  	return reflect.Value{}
    59  }
    60  
    61  func (s *Scope) funcScope() *Scope {
    62  	for scope := s; scope != nil; scope = scope.Parent {
    63  		if scope.fct != "" {
    64  			return scope
    65  		}
    66  	}
    67  	return nil
    68  }
    69  
    70  type deferCtx struct {
    71  	Func reflect.Value
    72  	Args []reflect.Value
    73  }
    74  
    75  type Program struct {
    76  	Universe  *Scope
    77  	Cur       *Scope
    78  	Types     *typecheck.Checker
    79  	Pkgs      map[string]*gowrap.Pkg
    80  	Path      string
    81  	reflector *reflector
    82  
    83  	ShellState *shell.State
    84  
    85  	sigint     <-chan os.Signal
    86  	sigintSeen bool
    87  
    88  	branchType      branchType
    89  	branchLabel     string
    90  	mostRecentLabel string
    91  
    92  	typePlugins map[*tipe.Named]string // type to package path TODO lock?
    93  }
    94  
    95  type branchType int
    96  
    97  const (
    98  	brNone = branchType(iota)
    99  	brBreak
   100  	brContinue
   101  	brGoto
   102  	brFallthrough
   103  	brReturn
   104  )
   105  
   106  type evalMap interface {
   107  	GetVal(key interface{}) interface{}
   108  	SetVal(key, val interface{})
   109  }
   110  
   111  func New(path string, shellState *shell.State) *Program {
   112  	if shellState == nil {
   113  		shellState = &shell.State{
   114  			Env:   environ.New(),
   115  			Alias: environ.New(),
   116  		}
   117  	}
   118  	universe := new(Scope)
   119  	p := &Program{
   120  		Universe: universe,
   121  		Types:    typecheck.New(path),
   122  		Pkgs:     make(map[string]*gowrap.Pkg),
   123  		Path:     path,
   124  		Cur: &Scope{
   125  			Parent: universe,
   126  			fct:    "۰ng-main",
   127  		},
   128  		ShellState:  shellState,
   129  		reflector:   newReflector(),
   130  		typePlugins: make(map[*tipe.Named]string),
   131  	}
   132  	addUniverse := func(name string, val interface{}) {
   133  		p.Universe = &Scope{
   134  			Parent:  p.Universe,
   135  			VarName: name,
   136  			Var:     reflect.ValueOf(val),
   137  		}
   138  		p.Cur.Parent = p.Universe
   139  	}
   140  	addUniverse("true", true)
   141  	addUniverse("false", false)
   142  	addUniverse("env", (evalMap)(p.ShellState.Env))
   143  	addUniverse("alias", (evalMap)(p.ShellState.Alias))
   144  	addUniverse("nil", nil)
   145  	addUniverse("print", func(val ...interface{}) {
   146  		fmt.Println(val...)
   147  	})
   148  	addUniverse("printf", func(format string, val ...interface{}) {
   149  		fmt.Printf(format, val...)
   150  	})
   151  	addUniverse("errorf", fmt.Errorf)
   152  	addUniverse("len", func(c interface{}) int {
   153  		if c == nil {
   154  			return 0
   155  		}
   156  		if s, ok := c.(UntypedString); ok {
   157  			return len(s.String)
   158  		}
   159  		return reflect.ValueOf(c).Len()
   160  	})
   161  	addUniverse("cap", func(c interface{}) int {
   162  		if c == nil {
   163  			return 0
   164  		}
   165  		return reflect.ValueOf(c).Cap()
   166  	})
   167  	addUniverse("panic", func(c interface{}) {
   168  		c = promoteUntyped(c)
   169  		panic(Panic{c})
   170  	})
   171  	addUniverse("recover", func() interface{} {
   172  		return recover()
   173  	})
   174  	addUniverse("close", func(ch interface{}) {
   175  		rv := reflect.ValueOf(ch)
   176  		rv.Close()
   177  	})
   178  	addUniverse("copy", func(dst, src interface{}) int {
   179  		src = promoteUntyped(src)
   180  		vdst, vsrc := reflect.ValueOf(dst), reflect.ValueOf(src)
   181  		if vsrc.Kind() == reflect.String && vdst.Kind() == reflect.Slice && vdst.Type().Elem().Kind() == reflect.Uint8 {
   182  			// Go 1.9 does not implement reflect.Copy for
   183  			// strings, so we do it manually.
   184  			return copy(vdst.Bytes(), vsrc.String())
   185  
   186  		}
   187  		return reflect.Copy(vdst, vsrc)
   188  	})
   189  	addUniverse("append", builtinAppend)
   190  	addUniverse("delete", func(m, k interface{}) {
   191  		k = promoteUntyped(k)
   192  		reflect.ValueOf(m).SetMapIndex(reflect.ValueOf(k), reflect.Value{})
   193  	})
   194  	addUniverse("make", builtinMake)
   195  	addUniverse("new", builtinNew)
   196  	addUniverse("complex", builtinComplex)
   197  	addUniverse("real", func(v interface{}) interface{} {
   198  		switch v := v.(type) {
   199  		case UntypedComplex:
   200  			// FIXME: return UntypedFloat instead
   201  			// to handle: imag(1+2i) + float32(2.3)
   202  			// re := UntypedFloat{big.NewFloat(0).Set(v.Real)}
   203  			re, _ := v.Real.Float64()
   204  			return builtinResult(re)
   205  		case complex64:
   206  			return builtinResult(real(v))
   207  		case complex128:
   208  			return builtinResult(real(v))
   209  		}
   210  		panic(fmt.Errorf("invalid type real(%T)", v))
   211  	})
   212  	addUniverse("imag", func(v interface{}) interface{} {
   213  		switch v := v.(type) {
   214  		case UntypedComplex:
   215  			// FIXME: return UntypedFloat instead.
   216  			// to handle: imag(1+2i) + float32(2.3)
   217  			// im := UntypedFloat{big.NewFloat(0).Set(v.Imag)}
   218  			im, _ := v.Imag.Float64()
   219  			return builtinResult(im)
   220  		case complex64:
   221  			return builtinResult(imag(v))
   222  		case complex128:
   223  			return builtinResult(imag(v))
   224  		}
   225  		panic(fmt.Errorf("invalid type imag(%T)", v))
   226  	})
   227  	return p
   228  }
   229  
   230  func EvalFile(path string, shellState *shell.State) error {
   231  	path, err := filepath.Abs(path)
   232  	if err != nil {
   233  		return fmt.Errorf("eval: %v", err)
   234  	}
   235  	p := New(path, shellState)
   236  	return p.evalFile()
   237  }
   238  
   239  func (p *Program) evalFile() error {
   240  	prsr := parser.New(p.Path)
   241  	f, err := os.Open(p.Path)
   242  	if err != nil {
   243  		return fmt.Errorf("eval: %v", err)
   244  	}
   245  	defer f.Close()
   246  
   247  	// TODO: position information in the parser will replace i.
   248  	scanner := bufio.NewScanner(f)
   249  	for i := 0; scanner.Scan(); i++ {
   250  		line := scanner.Bytes()
   251  		res := prsr.ParseLine(line)
   252  		if len(res.Errs) > 0 {
   253  			return fmt.Errorf("%d: %v", i+1, res.Errs[0])
   254  		}
   255  		for _, s := range res.Stmts {
   256  			if _, err := p.Eval(s, p.sigint); err != nil {
   257  				if _, isPanic := err.(Panic); isPanic {
   258  					return err
   259  				}
   260  				return fmt.Errorf("%d: %v", i+1, err)
   261  			}
   262  		}
   263  		for _, cmd := range res.Cmds {
   264  			j := &shell.Job{
   265  				State:  p.ShellState,
   266  				Cmd:    cmd,
   267  				Stdin:  os.Stdin,
   268  				Stdout: os.Stdout,
   269  				Stderr: os.Stderr,
   270  			}
   271  			if err := j.Start(); err != nil {
   272  				return err
   273  			}
   274  			done, err := j.Wait()
   275  			if err != nil {
   276  				return err
   277  			}
   278  			if !done {
   279  				break // TODO not right, instead we should just have one cmd, not Cmds here.
   280  			}
   281  		}
   282  	}
   283  	return nil
   284  
   285  }
   286  
   287  // builtinResult emulates a run time type parameter for builtins.
   288  //
   289  // Several Go built-in functions are defined in a way that cannot
   290  // be expressed in the Go type system. For example append has the
   291  // type signature:
   292  //
   293  //	func <T> append([]T, ...T) []T
   294  //
   295  // Here the return type is some concrete Go type.
   296  // We cannot return <T>, the closest we can do is interface{}.
   297  // Which is very close, but not exactly the same.
   298  // When the interpreter writes the return value from the builtin
   299  // function into a reflect.Value, it gets the empty interface
   300  // boxing written into it too, which is incorrect.
   301  // To avoid this, we deliberately box the return type in a
   302  // known interface type, which the evaluator looks for and unboxes
   303  // on sight, acting as communication to the evaluator that the
   304  // function it just ran is a builtin with special type needs.
   305  type builtinResult interface{}
   306  
   307  func builtinAppend(s interface{}, v ...interface{}) interface{} {
   308  	res := reflect.ValueOf(s)
   309  	for _, elem := range v {
   310  		res = reflect.Append(res, reflect.ValueOf(elem))
   311  	}
   312  	return builtinResult(res.Interface())
   313  }
   314  
   315  func builtinNew(v interface{}) interface{} {
   316  	t := v.(reflect.Type)
   317  	return builtinResult(reflect.New(t).Interface())
   318  }
   319  
   320  func builtinMake(v ...interface{}) builtinResult {
   321  	t := v[0].(reflect.Type)
   322  	switch t.Kind() {
   323  	case reflect.Chan:
   324  		size := 0
   325  		if len(v) > 1 {
   326  			size = v[1].(int)
   327  		}
   328  		return builtinResult(reflect.MakeChan(t, size).Interface())
   329  	case reflect.Slice:
   330  		var slen, scap int
   331  		if len(v) > 1 {
   332  			slen = v[1].(int)
   333  		}
   334  		if len(v) > 2 {
   335  			scap = v[2].(int)
   336  		} else {
   337  			scap = slen
   338  		}
   339  		return builtinResult(reflect.MakeSlice(t, slen, scap).Interface())
   340  	case reflect.Map:
   341  		return builtinResult(reflect.MakeMap(t).Interface())
   342  	}
   343  	return nil
   344  }
   345  
   346  func builtinComplex(re, im interface{}) interface{} {
   347  	switch re := re.(type) {
   348  	case UntypedInt:
   349  		switch im := im.(type) {
   350  		case UntypedInt:
   351  			return builtinResult(complex(float64(re.Int64()), float64(im.Int64())))
   352  		case UntypedFloat:
   353  			f, _ := im.Float64()
   354  			return builtinResult(complex(float64(re.Int64()), f))
   355  		case float32:
   356  			return builtinResult(complex(float32(re.Int64()), im))
   357  		case float64:
   358  			return builtinResult(complex(float64(re.Int64()), im))
   359  		}
   360  	case UntypedFloat:
   361  		switch im := im.(type) {
   362  		case UntypedInt:
   363  			fre, _ := re.Float64()
   364  			fim := float64(im.Int64())
   365  			return builtinResult(complex(fre, fim))
   366  		case UntypedFloat:
   367  			fre, _ := re.Float64()
   368  			fim, _ := im.Float64()
   369  			return builtinResult(complex(fre, fim))
   370  		case float32:
   371  			fre, _ := re.Float64()
   372  			return builtinResult(complex(float32(fre), float32(im)))
   373  		case float64:
   374  			fre, _ := re.Float64()
   375  			return builtinResult(complex(fre, im))
   376  		}
   377  	case float32:
   378  		switch im := im.(type) {
   379  		case UntypedInt:
   380  			fim := float32(im.Int64())
   381  			return builtinResult(complex(re, fim))
   382  		case UntypedFloat:
   383  			fim, _ := im.Float64()
   384  			return builtinResult(complex(re, float32(fim)))
   385  		case float32:
   386  			return builtinResult(complex(re, im))
   387  		case float64:
   388  			panic("impossible")
   389  		}
   390  	case float64:
   391  		switch im := im.(type) {
   392  		case UntypedInt:
   393  			fim := float64(im.Int64())
   394  			return builtinResult(complex(re, fim))
   395  		case UntypedFloat:
   396  			fim, _ := im.Float64()
   397  			return builtinResult(complex(re, fim))
   398  		case float32:
   399  			panic("impossible")
   400  		case float64:
   401  			return builtinResult(complex(re, im))
   402  		}
   403  	}
   404  	panic(fmt.Errorf("invalid types %T,%T", re, im))
   405  }
   406  
   407  func (p *Program) Environ() *environ.Environ {
   408  	return p.Universe.Lookup("env").Interface().(*environ.Environ)
   409  }
   410  
   411  func (p *Program) Alias() *environ.Environ {
   412  	return p.Universe.Lookup("alias").Interface().(*environ.Environ)
   413  }
   414  
   415  // Get is part of the implementation of shell.Params.
   416  func (p *Program) Get(name string) string {
   417  	v := p.Cur.Lookup(name)
   418  	if v == (reflect.Value{}) {
   419  		return p.Environ().Get(name)
   420  	}
   421  	vi := v.Interface()
   422  	if s, ok := vi.(string); ok {
   423  		return s
   424  	}
   425  	return fmt.Sprint(vi)
   426  }
   427  
   428  // Set is part of the implementation of shell.Params.
   429  func (p *Program) Set(name, value string) {
   430  	s := &Scope{
   431  		Parent:   p.Cur,
   432  		VarName:  name,
   433  		Var:      reflect.ValueOf(value),
   434  		Implicit: true,
   435  	}
   436  	p.Cur = s
   437  }
   438  
   439  func (p *Program) interrupted() bool {
   440  	if p.sigintSeen {
   441  		return true
   442  	}
   443  	select {
   444  	case <-p.sigint:
   445  		p.sigintSeen = true
   446  		return true
   447  	default:
   448  		return false
   449  	}
   450  }
   451  
   452  var nosig = (<-chan os.Signal)(make(chan os.Signal))
   453  
   454  func (p *Program) Eval(s stmt.Stmt, sigint <-chan os.Signal) (res []reflect.Value, err error) {
   455  	if sigint != nil {
   456  		p.sigint = sigint
   457  	} else {
   458  		p.sigint = nosig
   459  	}
   460  	defer func() {
   461  		p.sigint = nosig
   462  		p.sigintSeen = false
   463  		x := recover()
   464  		if x == nil {
   465  			return
   466  		}
   467  		switch p := x.(type) {
   468  		case interpPanic:
   469  			err = p.reason
   470  			return
   471  		case Panic:
   472  			err = p
   473  			return
   474  		default:
   475  			//panic(x)
   476  			err = fmt.Errorf("ng eval panic: %v", x)
   477  			fmt.Fprintf(os.Stderr, "%v\n", err)
   478  			debug.PrintStack()
   479  			res = nil
   480  		}
   481  	}()
   482  
   483  	p.Types.Add(s)
   484  	if errs := p.Types.Errs(); len(errs) > 0 {
   485  		// Friendly interactive shell error messages.
   486  		if s, isSimple := s.(*stmt.Simple); isSimple {
   487  			if e, isIdent := s.Expr.(*expr.Ident); isIdent && (e.Name == "exit" || e.Name == "logout") {
   488  				if p.Cur.Lookup(e.Name) == (reflect.Value{}) {
   489  					return nil, fmt.Errorf("use Ctrl-D to exit")
   490  				}
   491  			}
   492  		}
   493  
   494  		return nil, fmt.Errorf("typecheck: %v\n", errs[0])
   495  	}
   496  
   497  	p.branchType = brNone
   498  	p.branchLabel = ""
   499  	res = p.evalStmt(s)
   500  	return res, nil
   501  }
   502  
   503  func (p *Program) pushScope() {
   504  	p.Cur = &Scope{
   505  		Parent: p.Cur,
   506  	}
   507  }
   508  
   509  func (p *Program) popScope() {
   510  	for p.Cur.Implicit {
   511  		p.Cur = p.Cur.Parent
   512  	}
   513  	p.Cur = p.Cur.Parent
   514  }
   515  
   516  func (p *Program) evalStmt(s stmt.Stmt) []reflect.Value {
   517  	mostRecentLabel := p.mostRecentLabel
   518  	p.mostRecentLabel = ""
   519  	switch s := s.(type) {
   520  	case *stmt.Const:
   521  		return p.evalConst(s)
   522  	case *stmt.ConstSet:
   523  		for _, v := range s.Consts {
   524  			p.evalConst(v)
   525  		}
   526  		return nil
   527  	case *stmt.Var:
   528  		return p.evalVar(s)
   529  	case *stmt.VarSet:
   530  		for _, v := range s.Vars {
   531  			p.evalVar(v)
   532  		}
   533  		return nil
   534  	case *stmt.Assign:
   535  		types := make([]tipe.Type, 0, len(s.Left))
   536  		vals := make([]reflect.Value, 0, len(s.Left))
   537  		for _, rhs := range s.Right {
   538  			v := p.evalExpr(rhs)
   539  			t := p.Types.Type(rhs)
   540  			if tuple, isTuple := t.(*tipe.Tuple); isTuple {
   541  				types = append(types, tuple.Elems...)
   542  			} else {
   543  				types = append(types, t)
   544  			}
   545  			// TODO: insert an implicit interface type conversion here
   546  			vals = append(vals, v...)
   547  		}
   548  
   549  		vars := make([]reflect.Value, len(s.Left))
   550  		if s.Decl {
   551  			for i, lhs := range s.Left {
   552  				if lhs.(*expr.Ident).Name == "_" {
   553  					continue
   554  				}
   555  				t := p.reflector.ToRType(types[i])
   556  
   557  				s := &Scope{
   558  					Parent:   p.Cur,
   559  					VarName:  lhs.(*expr.Ident).Name,
   560  					Var:      reflect.New(t).Elem(),
   561  					Implicit: true,
   562  				}
   563  				p.Cur = s
   564  				vars[i] = s.Var
   565  			}
   566  		} else {
   567  			for i, lhs := range s.Left {
   568  				if e, isIdent := lhs.(*expr.Ident); isIdent && e.Name == "_" {
   569  					continue
   570  				}
   571  				if e, isIndex := lhs.(*expr.Index); isIndex {
   572  					if _, isMap := tipe.Underlying(p.Types.Type(e.Left)).(*tipe.Map); isMap {
   573  						container := p.evalExprOne(e.Left)
   574  						k := p.evalExprOne(e.Indicies[0])
   575  						if env, ok := container.Interface().(evalMap); ok {
   576  							env.SetVal(k.String(), vals[i].String())
   577  						} else {
   578  							container.SetMapIndex(k, vals[i])
   579  						}
   580  						continue
   581  					}
   582  				}
   583  				v := p.evalExprOne(lhs)
   584  				vars[i] = v
   585  			}
   586  		}
   587  
   588  		for i := range vars {
   589  			if vars[i].IsValid() {
   590  				vars[i].Set(vals[i])
   591  			}
   592  		}
   593  
   594  		return nil
   595  	case *stmt.Block:
   596  		p.pushScope()
   597  		defer p.popScope()
   598  		for _, s := range s.Stmts {
   599  			res := p.evalStmt(s)
   600  			if p.branchType != brNone || p.interrupted() {
   601  				return res
   602  			}
   603  		}
   604  		return nil
   605  	case *stmt.For:
   606  		if s.Init != nil {
   607  			p.pushScope()
   608  			defer p.popScope()
   609  			p.evalStmt(s.Init)
   610  		}
   611  	loop:
   612  		for {
   613  			if s.Cond != nil {
   614  				cond := p.evalExprOne(s.Cond)
   615  				if cond.Kind() == reflect.Bool && !cond.Bool() {
   616  					break
   617  				}
   618  			}
   619  			p.evalStmt(s.Body)
   620  			// Note there are three extremely similar loops:
   621  			//	*stmt.For, *stmt.Range (slice, and map)
   622  			if p.interrupted() {
   623  				break
   624  			}
   625  			switch p.branchType {
   626  			default:
   627  				break loop
   628  			case brNone:
   629  			case brBreak:
   630  				if p.branchLabel == mostRecentLabel {
   631  					p.branchType = brNone
   632  					p.branchLabel = ""
   633  				}
   634  				break loop
   635  			case brContinue:
   636  				if p.branchLabel == mostRecentLabel {
   637  					p.branchType = brNone
   638  					p.branchLabel = ""
   639  					if s.Post != nil {
   640  						p.evalStmt(s.Post)
   641  					}
   642  					continue loop
   643  				}
   644  				break loop
   645  			}
   646  			if s.Post != nil {
   647  				p.evalStmt(s.Post)
   648  			}
   649  		}
   650  		return nil
   651  	case *stmt.Go:
   652  		fn, args := p.prepCall(s.Call)
   653  		for i, arg := range args {
   654  			v := reflect.New(arg.Type()).Elem()
   655  			v.Set(arg)
   656  			args[i] = v
   657  		}
   658  		go fn.Call(args)
   659  		return nil
   660  	case *stmt.If:
   661  		if s.Init != nil {
   662  			p.pushScope()
   663  			defer p.popScope()
   664  			p.evalStmt(s.Init)
   665  		}
   666  		cond := p.evalExprOne(s.Cond)
   667  		if cond.Kind() == reflect.Bool && cond.Bool() {
   668  			return p.evalStmt(s.Body)
   669  		} else if s.Else != nil {
   670  			return p.evalStmt(s.Else)
   671  		}
   672  		return nil
   673  	case *stmt.ImportSet:
   674  		for _, imp := range s.Imports {
   675  			p.evalStmt(imp)
   676  		}
   677  		return nil
   678  	case *stmt.Import:
   679  		var pkg *gowrap.Pkg
   680  		path := s.Path
   681  		ngPkg := strings.HasSuffix(path, ".ng")
   682  		if ngPkg {
   683  			var filename string
   684  			if strings.HasPrefix(path, "./") {
   685  				filename = filepath.Join(filepath.Dir(p.Path), path)
   686  				filename, _ = filepath.Abs(filename)
   687  				path = "rel" + filename
   688  			} else {
   689  				panic(Panic{val: fmt.Errorf("TODO: look for .ng file in GOPATH")})
   690  			}
   691  			path = strings.TrimSuffix(path, ".ng") + "_ng"
   692  			pkg = gowrap.Pkgs[path]
   693  			if pkg == nil {
   694  				adjPkgPath, dir, err := gotool.M.Dir(path)
   695  				pkgb, err := gengo.GenGo(filename, filepath.Base(path))
   696  				if err != nil {
   697  					panic(Panic{val: err})
   698  				}
   699  				if err := ioutil.WriteFile(filepath.Join(dir, filepath.Base(path)+".go"), pkgb, 0666); err != nil {
   700  					panic(Panic{val: err})
   701  				}
   702  				src, err := genwrap.GenGo(adjPkgPath, "main", false)
   703  				if err != nil {
   704  					panic(Panic{val: fmt.Errorf("plugin: wrapper gen failed for Go package %q: %v", s.Name, err)})
   705  				}
   706  				if _, err := gotool.M.Create(adjPkgPath, src); err != nil {
   707  					panic(Panic{val: err})
   708  				}
   709  				pkg = gowrap.Pkgs[adjPkgPath]
   710  				if pkg == nil {
   711  					panic(Panic{val: fmt.Errorf("plugin: contents missing from Go package %q", s.Name)})
   712  				}
   713  				gowrap.Pkgs[path] = pkg
   714  			}
   715  		} else {
   716  			pkg = gowrap.Pkgs[path]
   717  			if pkg == nil {
   718  				src, err := genwrap.GenGo(path, "main", false)
   719  				if err != nil {
   720  					panic(Panic{val: fmt.Errorf("plugin: wrapper gen failed for Go package %q: %v", s.Name, err)})
   721  				}
   722  				if _, err := gotool.M.Create(path, src); err != nil {
   723  					panic(Panic{val: err})
   724  				}
   725  				pkg = gowrap.Pkgs[s.Path]
   726  				if pkg == nil {
   727  					panic(Panic{val: fmt.Errorf("plugin: contents missing from Go package %q", s.Name)})
   728  				}
   729  			}
   730  		}
   731  		p.Cur = &Scope{
   732  			Parent:   p.Cur,
   733  			VarName:  s.Name,
   734  			Var:      reflect.ValueOf(pkg),
   735  			Implicit: true,
   736  		}
   737  		return nil
   738  	case *stmt.Range:
   739  		p.pushScope()
   740  		defer p.popScope()
   741  		var key, val reflect.Value
   742  		if s.Decl {
   743  			if s.Key != nil {
   744  				key = reflect.New(p.reflector.ToRType(p.Types.Type(s.Key))).Elem()
   745  				name := s.Key.(*expr.Ident).Name
   746  				p.Cur = &Scope{
   747  					Parent:   p.Cur,
   748  					VarName:  name,
   749  					Var:      key,
   750  					Implicit: true,
   751  				}
   752  			}
   753  			if s.Val != nil {
   754  				val = reflect.New(p.reflector.ToRType(p.Types.Type(s.Val))).Elem()
   755  				name := s.Val.(*expr.Ident).Name
   756  				p.Cur = &Scope{
   757  					Parent:   p.Cur,
   758  					VarName:  name,
   759  					Var:      val,
   760  					Implicit: true,
   761  				}
   762  			}
   763  		} else {
   764  			if s.Key != nil && s.Key.(*expr.Ident).Name != "_" {
   765  				key = p.evalExprOne(s.Key)
   766  			}
   767  			if s.Val != nil && s.Val.(*expr.Ident).Name != "_" {
   768  				val = p.evalExprOne(s.Val)
   769  			}
   770  		}
   771  		src := p.evalExprOne(s.Expr)
   772  		switch src.Kind() {
   773  		case reflect.Array, reflect.Slice:
   774  			slen := src.Len()
   775  		sliceLoop:
   776  			for i := 0; i < slen; i++ {
   777  				key.SetInt(int64(i))
   778  				if val != (reflect.Value{}) {
   779  					val.Set(src.Index(i))
   780  				}
   781  				p.evalStmt(s.Body)
   782  				if p.interrupted() {
   783  					break
   784  				}
   785  				switch p.branchType {
   786  				default:
   787  					break sliceLoop
   788  				case brNone:
   789  				case brBreak:
   790  					if p.branchLabel == mostRecentLabel {
   791  						p.branchType = brNone
   792  						p.branchLabel = ""
   793  					}
   794  					break sliceLoop
   795  				case brContinue:
   796  					if p.branchLabel == mostRecentLabel {
   797  						p.branchType = brNone
   798  						p.branchLabel = ""
   799  						continue sliceLoop
   800  					}
   801  					break sliceLoop
   802  				}
   803  			}
   804  		case reflect.Map:
   805  			keys := src.MapKeys()
   806  		mapLoop:
   807  			for _, k := range keys {
   808  				if key != (reflect.Value{}) {
   809  					key.Set(k)
   810  				}
   811  				if val != (reflect.Value{}) {
   812  					v := src.MapIndex(k)
   813  					val.Set(v)
   814  				}
   815  				p.evalStmt(s.Body)
   816  				if p.interrupted() {
   817  					break
   818  				}
   819  				switch p.branchType {
   820  				default:
   821  					break mapLoop
   822  				case brNone:
   823  				case brBreak:
   824  					if p.branchLabel == mostRecentLabel {
   825  						p.branchType = brNone
   826  						p.branchLabel = ""
   827  					}
   828  					break mapLoop
   829  				case brContinue:
   830  					if p.branchLabel == mostRecentLabel {
   831  						p.branchType = brNone
   832  						p.branchLabel = ""
   833  						continue mapLoop
   834  					}
   835  					break mapLoop
   836  				}
   837  			}
   838  		case reflect.Chan:
   839  		chanLoop:
   840  			for {
   841  				v, ok := src.Recv()
   842  				if !ok {
   843  					break chanLoop
   844  				}
   845  				key.Set(v)
   846  				p.evalStmt(s.Body)
   847  				if p.interrupted() {
   848  					break
   849  				}
   850  				switch p.branchType {
   851  				default:
   852  					break chanLoop
   853  				case brNone:
   854  				case brBreak:
   855  					if p.branchLabel == mostRecentLabel {
   856  						p.branchType = brNone
   857  						p.branchLabel = ""
   858  					}
   859  					break chanLoop
   860  				case brContinue:
   861  					if p.branchLabel == mostRecentLabel {
   862  						p.branchType = brNone
   863  						p.branchLabel = ""
   864  						continue chanLoop
   865  					}
   866  					break chanLoop
   867  				}
   868  			}
   869  		default:
   870  			panic(interpPanic{fmt.Errorf("unknown range type: %T", src)})
   871  		}
   872  		return nil
   873  	case *stmt.Return:
   874  		var res []reflect.Value
   875  		for _, expr := range s.Exprs {
   876  			res = append(res, p.evalExpr(expr)...)
   877  		}
   878  		p.branchType = brReturn
   879  		p.branchLabel = ""
   880  		return res
   881  	case *stmt.Defer:
   882  		fscope := p.Cur.funcScope()
   883  		if fscope == nil {
   884  			panic(interpPanic{fmt.Errorf("defer outside a function scope")})
   885  		}
   886  		call := s.Expr.(*expr.Call)
   887  		fct, args := p.prepCall(call)
   888  		fscope.defers = append(fscope.defers, deferCtx{
   889  			Func: fct,
   890  			Args: args,
   891  		})
   892  		return nil
   893  
   894  	case *stmt.Simple:
   895  		res := p.evalExpr(s.Expr)
   896  		if fn, isFunc := s.Expr.(*expr.FuncLiteral); isFunc && fn.Name != "" {
   897  			s := &Scope{
   898  				Parent:   p.Cur,
   899  				VarName:  fn.Name,
   900  				Var:      res[0],
   901  				Implicit: true,
   902  			}
   903  			p.Cur = s
   904  		}
   905  		return res
   906  	case *stmt.Send:
   907  		ch := p.evalExprOne(s.Chan)
   908  		v := p.evalExprOne(s.Value)
   909  		ch.Send(v)
   910  		return nil
   911  	case *stmt.TypeDeclSet:
   912  		for _, decl := range s.TypeDecls {
   913  			p.evalStmt(decl)
   914  		}
   915  		return nil
   916  	case *stmt.TypeDecl:
   917  		if _, isIface := s.Type.Type.(*tipe.Interface); isIface {
   918  			p.ifaceDecl(s.Type)
   919  		}
   920  		return nil
   921  	case *stmt.MethodikDecl:
   922  		p.methodikDecl(s)
   923  		return nil
   924  	case *stmt.Labeled:
   925  		p.Cur = &Scope{
   926  			Parent:  p.Cur,
   927  			VarName: s.Label,
   928  			Label:   true,
   929  		}
   930  		defer p.popScope()
   931  		p.mostRecentLabel = s.Label
   932  		return p.evalStmt(s.Stmt)
   933  	case *stmt.Branch:
   934  		p.branchLabel = s.Label
   935  		switch s.Type {
   936  		case token.Continue:
   937  			p.branchType = brContinue
   938  		case token.Break:
   939  			p.branchType = brBreak
   940  		case token.Goto:
   941  			p.branchType = brGoto
   942  		case token.Fallthrough:
   943  			p.branchType = brFallthrough
   944  		default:
   945  			panic("bad branch type: " + s.Type.String())
   946  		}
   947  		return nil
   948  	case *stmt.Switch:
   949  		if s.Init != nil {
   950  			p.pushScope()
   951  			defer p.popScope()
   952  			p.evalStmt(s.Init)
   953  		}
   954  		cond := reflect.ValueOf(true)
   955  		if s.Cond != nil {
   956  			cond = p.evalExprOne(s.Cond)
   957  		}
   958  		var (
   959  			dflt    *stmt.SwitchCase
   960  			match   = false
   961  			through = false
   962  		)
   963  	loopCases:
   964  		for i, cse := range s.Cases {
   965  			if cse.Default {
   966  				dflt = &s.Cases[i]
   967  			}
   968  			// only go through the evaluation of the cases when not
   969  			// in fallthrough mode.
   970  			if !through {
   971  				for j := range cse.Conds {
   972  					e := p.evalExprOne(cse.Conds[j])
   973  					if reflect.DeepEqual(cond.Interface(), e.Interface()) {
   974  						match = true
   975  						break
   976  					}
   977  				}
   978  			}
   979  			if match || through {
   980  				through = false
   981  				p.evalStmt(cse.Body)
   982  				switch p.branchType {
   983  				case brFallthrough:
   984  					through = true
   985  					p.branchType = brNone
   986  					continue loopCases
   987  				}
   988  				return nil
   989  			}
   990  		}
   991  		// no case were triggered.
   992  		// execute the default one, if any.
   993  		if !match && dflt != nil {
   994  			p.evalStmt(dflt.Body)
   995  		}
   996  		return nil
   997  	case *stmt.TypeSwitch:
   998  		if s.Init != nil {
   999  			p.pushScope()
  1000  			defer p.popScope()
  1001  			p.evalStmt(s.Init)
  1002  		}
  1003  		p.pushScope()
  1004  		defer p.popScope()
  1005  		var v reflect.Value
  1006  		switch st := s.Assign.(type) {
  1007  		case *stmt.Simple:
  1008  			v = p.evalStmt(st)[0]
  1009  		case *stmt.Assign:
  1010  			p.evalStmt(st)
  1011  			v = p.Cur.Lookup(st.Left[0].(*expr.Ident).Name)
  1012  		default:
  1013  			panic(Panic{fmt.Sprintf("invalid type-switch guard type (%T)", st)})
  1014  		}
  1015  		t := reflect.TypeOf(v.Interface())
  1016  		var dflt *stmt.TypeSwitchCase
  1017  		for i, cse := range s.Cases {
  1018  			if cse.Default {
  1019  				dflt = &s.Cases[i]
  1020  				continue
  1021  			}
  1022  			for _, typ := range cse.Types {
  1023  				rt := p.reflector.ToRType(typ)
  1024  				if t == rt {
  1025  					return p.evalStmt(cse.Body)
  1026  				}
  1027  			}
  1028  		}
  1029  		// no case were triggered.
  1030  		// execute the default one, if any.
  1031  		if dflt != nil {
  1032  			return p.evalStmt(dflt.Body)
  1033  		}
  1034  		return nil
  1035  	case *stmt.Select:
  1036  		cases := make([]reflect.SelectCase, len(s.Cases))
  1037  		works := make([]struct {
  1038  			Chan     reflect.Value
  1039  			Vars     []reflect.Value
  1040  			Names    []string
  1041  			Implicit []bool
  1042  		}, len(s.Cases))
  1043  		for i, cse := range s.Cases {
  1044  			if cse.Default {
  1045  				cases[i].Dir = reflect.SelectDefault
  1046  				continue
  1047  			}
  1048  			switch cse := cse.Stmt.(type) {
  1049  			case *stmt.Assign:
  1050  				works[i].Chan = p.evalExprOne(cse.Right[0].(*expr.Unary).Expr)
  1051  				works[i].Names = make([]string, len(cse.Left))
  1052  				works[i].Vars = make([]reflect.Value, len(cse.Left))
  1053  				works[i].Implicit = make([]bool, len(cse.Left))
  1054  				if cse.Decl {
  1055  					for j, lhs := range cse.Left {
  1056  						works[i].Implicit[j] = true
  1057  						name := lhs.(*expr.Ident).Name
  1058  						if name == "_" {
  1059  							continue
  1060  						}
  1061  						works[i].Names[j] = name
  1062  					}
  1063  				}
  1064  				cases[i].Chan = works[i].Chan
  1065  				cases[i].Dir = reflect.SelectRecv
  1066  			case *stmt.Simple:
  1067  				works[i].Chan = p.evalExprOne(cse.Expr.(*expr.Unary).Expr)
  1068  				cases[i].Chan = works[i].Chan
  1069  				cases[i].Dir = reflect.SelectRecv
  1070  			case *stmt.Send:
  1071  				works[i].Chan = p.evalExprOne(cse.Chan)
  1072  				send := p.evalExprOne(cse.Value)
  1073  				cases[i].Dir = reflect.SelectSend
  1074  				cases[i].Chan = works[i].Chan
  1075  				cases[i].Send = send
  1076  			default:
  1077  				panic(interpPanic{fmt.Errorf("unknown select case type: %T", cse)})
  1078  			}
  1079  		}
  1080  		chosen, recv, recvOK := reflect.Select(cases)
  1081  		p.pushScope()
  1082  		defer p.popScope()
  1083  		work := &works[chosen]
  1084  		// prepare scope for body evaluation
  1085  		switch cases[chosen].Dir {
  1086  		case reflect.SelectRecv:
  1087  			switch n := len(work.Vars); n {
  1088  			case 0:
  1089  			case 1:
  1090  				work.Vars[0] = recv
  1091  				s := &Scope{
  1092  					Parent:   p.Cur,
  1093  					VarName:  work.Names[0],
  1094  					Var:      recv,
  1095  					Implicit: work.Implicit[0],
  1096  				}
  1097  				p.Cur = s
  1098  			case 2:
  1099  				work.Vars[0] = recv
  1100  				work.Vars[1] = reflect.New(reflect.TypeOf(recvOK)).Elem()
  1101  				work.Vars[1].SetBool(recvOK)
  1102  				for i := range work.Vars {
  1103  					name := work.Names[i]
  1104  					if name == "" {
  1105  						continue
  1106  					}
  1107  					s := &Scope{
  1108  						Parent:   p.Cur,
  1109  						VarName:  name,
  1110  						Var:      work.Vars[i],
  1111  						Implicit: work.Implicit[i],
  1112  					}
  1113  					p.Cur = s
  1114  				}
  1115  			default:
  1116  				panic(interpPanic{fmt.Errorf("internal error: invalid number of vars (%d)", n)})
  1117  			}
  1118  		case reflect.SelectSend:
  1119  		case reflect.SelectDefault:
  1120  		default:
  1121  			panic(interpPanic{fmt.Errorf("invalid select case chan-dir: %v", cases[chosen].Dir)})
  1122  		}
  1123  		cse := &s.Cases[chosen]
  1124  		p.evalStmt(cse.Body)
  1125  		return nil
  1126  	}
  1127  	panic(fmt.Sprintf("TODO evalStmt: %s", format.Stmt(s)))
  1128  }
  1129  
  1130  func (p *Program) evalExprOne(e expr.Expr) reflect.Value {
  1131  	v := p.evalExpr(e)
  1132  	if len(v) != 1 {
  1133  		panic(interpPanic{fmt.Errorf("expression returns %d values instead of 1", len(v))})
  1134  	}
  1135  	return v[0]
  1136  }
  1137  
  1138  func (p *Program) evalConst(s *stmt.Const) []reflect.Value {
  1139  	types := make([]tipe.Type, 0, len(s.NameList))
  1140  	vals := make([]reflect.Value, 0, len(s.NameList))
  1141  	for _, rhs := range s.Values {
  1142  		v := p.evalExpr(rhs)
  1143  		t := p.Types.Type(rhs)
  1144  		if tuple, isTuple := t.(*tipe.Tuple); isTuple {
  1145  			types = append(types, tuple.Elems...)
  1146  		} else {
  1147  			types = append(types, t)
  1148  		}
  1149  		// TODO: insert an implicit interface type conversion here
  1150  		vals = append(vals, v...)
  1151  	}
  1152  	if s.Type != nil {
  1153  		types = make([]tipe.Type, len(s.NameList))
  1154  		for i := range types {
  1155  			types[i] = s.Type
  1156  		}
  1157  	}
  1158  
  1159  	vars := make([]reflect.Value, len(s.NameList))
  1160  	for i, name := range s.NameList {
  1161  		if name == "_" {
  1162  			continue
  1163  		}
  1164  		t := p.reflector.ToRType(types[i])
  1165  		s := &Scope{
  1166  			Parent:   p.Cur,
  1167  			VarName:  name,
  1168  			Var:      reflect.New(t).Elem(),
  1169  			Implicit: true,
  1170  		}
  1171  		p.Cur = s
  1172  		vars[i] = s.Var
  1173  	}
  1174  	for i := range vars {
  1175  		if !vars[i].IsValid() {
  1176  			continue
  1177  		}
  1178  		if len(vals) <= i {
  1179  			continue
  1180  		}
  1181  		v := vals[i]
  1182  		if vars[i].Type() != v.Type() {
  1183  			v = v.Convert(vars[i].Type())
  1184  		}
  1185  		vars[i].Set(v)
  1186  	}
  1187  	return nil
  1188  }
  1189  
  1190  func (p *Program) evalVar(s *stmt.Var) []reflect.Value {
  1191  	types := make([]tipe.Type, 0, len(s.NameList))
  1192  	vals := make([]reflect.Value, 0, len(s.NameList))
  1193  	for _, rhs := range s.Values {
  1194  		v := p.evalExpr(rhs)
  1195  		t := p.Types.Type(rhs)
  1196  		if tuple, isTuple := t.(*tipe.Tuple); isTuple {
  1197  			types = append(types, tuple.Elems...)
  1198  		} else {
  1199  			types = append(types, t)
  1200  		}
  1201  		// TODO: insert an implicit interface type conversion here
  1202  		vals = append(vals, v...)
  1203  	}
  1204  	if s.Type != nil {
  1205  		types = make([]tipe.Type, len(s.NameList))
  1206  		for i := range types {
  1207  			types[i] = s.Type
  1208  		}
  1209  	}
  1210  
  1211  	vars := make([]reflect.Value, len(s.NameList))
  1212  	for i, name := range s.NameList {
  1213  		if name == "_" {
  1214  			continue
  1215  		}
  1216  		t := p.reflector.ToRType(types[i])
  1217  		s := &Scope{
  1218  			Parent:   p.Cur,
  1219  			VarName:  name,
  1220  			Var:      reflect.New(t).Elem(),
  1221  			Implicit: true,
  1222  		}
  1223  		p.Cur = s
  1224  		vars[i] = s.Var
  1225  	}
  1226  	for i := range vars {
  1227  		if !vars[i].IsValid() {
  1228  			continue
  1229  		}
  1230  		if len(vals) <= i {
  1231  			continue
  1232  		}
  1233  		v := vals[i]
  1234  		if vars[i].Type() != v.Type() {
  1235  			v = v.Convert(vars[i].Type())
  1236  		}
  1237  		vars[i].Set(v)
  1238  	}
  1239  	return nil
  1240  }
  1241  
  1242  type UntypedInt struct{ *big.Int }
  1243  type UntypedFloat struct{ *big.Float }
  1244  type UntypedComplex struct{ Real, Imag *big.Float }
  1245  type UntypedString struct{ String string }
  1246  type UntypedRune struct{ Rune rune }
  1247  type UntypedBool struct{ Bool bool }
  1248  
  1249  func (uc UntypedComplex) String() string {
  1250  	op := "+"
  1251  	if uc.Imag.Sign() < 0 {
  1252  		op = "" // minus sign will be handled by c.Imag.String()
  1253  	}
  1254  	return "(" + uc.Real.String() + op + uc.Imag.String() + "i)"
  1255  }
  1256  
  1257  func promoteUntyped(x interface{}) interface{} {
  1258  	switch x := x.(type) {
  1259  	case UntypedInt:
  1260  		return int(x.Int64())
  1261  	case UntypedFloat:
  1262  		f, _ := x.Float64()
  1263  		return float64(f)
  1264  	case UntypedComplex:
  1265  		r, _ := x.Real.Float64()
  1266  		i, _ := x.Imag.Float64()
  1267  		return complex(r, i)
  1268  	case UntypedString:
  1269  		return x.String
  1270  	case UntypedRune:
  1271  		return x.Rune
  1272  	case UntypedBool:
  1273  		return x.Bool
  1274  	default:
  1275  		return x
  1276  	}
  1277  }
  1278  
  1279  // TODO merge convert func into typeConv func?
  1280  func convert(v reflect.Value, t reflect.Type) reflect.Value {
  1281  	if v.Type() == t {
  1282  		return v
  1283  	}
  1284  	switch val := v.Interface().(type) {
  1285  	case reflect.Type:
  1286  		return v // type conversion
  1287  	case UntypedInt:
  1288  		switch t {
  1289  		case reflect.TypeOf(UntypedFloat{}):
  1290  			res := UntypedFloat{new(big.Float)}
  1291  			res.Float.SetInt(val.Int)
  1292  			return reflect.ValueOf(res)
  1293  		case reflect.TypeOf(UntypedComplex{}):
  1294  			res := UntypedComplex{new(big.Float), new(big.Float)}
  1295  			res.Real.SetInt(val.Int)
  1296  			return reflect.ValueOf(res)
  1297  		}
  1298  		ret := reflect.New(t).Elem()
  1299  		switch t.Kind() {
  1300  		case reflect.Interface:
  1301  			ret.Set(reflect.ValueOf(int(val.Int64())))
  1302  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1303  			ret.SetUint(val.Uint64())
  1304  		case reflect.Float32, reflect.Float64:
  1305  			ret.SetFloat(float64(val.Int64()))
  1306  		case reflect.Complex64, reflect.Complex128:
  1307  			ret.SetComplex(complex(float64(val.Int64()), 0))
  1308  		default:
  1309  			ret.SetInt(val.Int64())
  1310  		}
  1311  		return ret
  1312  	case UntypedFloat:
  1313  		switch t {
  1314  		case reflect.TypeOf(UntypedComplex{}):
  1315  			res := UntypedComplex{new(big.Float), new(big.Float)}
  1316  			res.Real.Set(val.Float)
  1317  			return reflect.ValueOf(res)
  1318  		}
  1319  		ret := reflect.New(t).Elem()
  1320  		f, _ := val.Float64()
  1321  		switch t.Kind() {
  1322  		case reflect.Interface:
  1323  			ret.Set(reflect.ValueOf(float64(f)))
  1324  		case reflect.Complex64, reflect.Complex128:
  1325  			ret.SetComplex(complex(float64(f), 0))
  1326  		default:
  1327  			ret.SetFloat(f)
  1328  		}
  1329  		return ret
  1330  	case UntypedComplex:
  1331  		ret := reflect.New(t).Elem()
  1332  		r, _ := val.Real.Float64()
  1333  		i, _ := val.Imag.Float64()
  1334  		if t.Kind() == reflect.Interface {
  1335  			ret.Set(reflect.ValueOf(complex(r, i)))
  1336  		} else {
  1337  			ret.SetComplex(complex(r, i))
  1338  		}
  1339  		return ret
  1340  	case UntypedString:
  1341  		ret := reflect.New(t).Elem()
  1342  		s := val.String
  1343  		if t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
  1344  			ret.Set(reflect.ValueOf([]byte(s)))
  1345  		} else if t.Kind() == reflect.Interface {
  1346  			ret.Set(reflect.ValueOf(s))
  1347  		} else {
  1348  			ret.SetString(s)
  1349  		}
  1350  		return ret
  1351  	case UntypedRune:
  1352  		ret := reflect.New(t).Elem()
  1353  		r := val.Rune
  1354  		if t.Kind() == reflect.Interface {
  1355  			ret.Set(reflect.ValueOf(r))
  1356  		} else {
  1357  			ret.SetInt(int64(r))
  1358  		}
  1359  		return ret
  1360  	case UntypedBool:
  1361  		ret := reflect.New(t).Elem()
  1362  		b := val.Bool
  1363  		if t.Kind() == reflect.Interface {
  1364  			ret.Set(reflect.ValueOf(b))
  1365  		} else {
  1366  			ret.SetBool(b)
  1367  		}
  1368  		return ret
  1369  	default:
  1370  		ret := reflect.New(t).Elem()
  1371  		ret.Set(v)
  1372  		return ret
  1373  	}
  1374  }
  1375  
  1376  type interpPanic struct {
  1377  	reason error
  1378  }
  1379  
  1380  func (p interpPanic) Error() string {
  1381  	return p.reason.Error()
  1382  }
  1383  
  1384  func (p *Program) prepCall(e *expr.Call) (fn reflect.Value, args []reflect.Value) {
  1385  	fn = p.evalExprOne(e.Func)
  1386  	args = make([]reflect.Value, 0, len(e.Args))
  1387  	i := 0
  1388  	for _, arg := range e.Args {
  1389  		vals := p.evalExpr(arg)
  1390  		for _, v := range vals {
  1391  			if t := fn.Type(); t.Kind() == reflect.Func && !t.IsVariadic() {
  1392  				// Implicit interface conversion on use.
  1393  				// Bonus: this makes up for the fact that the
  1394  				// evaluator currently stores custom ng
  1395  				// interfaces in a Go empty interface{}.
  1396  				argt := fn.Type().In(i)
  1397  				if argt.Kind() == reflect.Interface && argt != v.Type() {
  1398  					underlying := reflect.ValueOf(v.Interface())
  1399  					v = reflect.New(argt).Elem()
  1400  					v.Set(underlying) // re-box with right type
  1401  				}
  1402  			}
  1403  			args = append(args, v)
  1404  			i++
  1405  		}
  1406  	}
  1407  	if e.Ellipsis {
  1408  		last := args[len(args)-1] // this is a slice
  1409  		args = args[:len(args)-1]
  1410  		for i, l := 0, last.Len(); i < l; i++ {
  1411  			args = append(args, last.Index(i))
  1412  		}
  1413  	}
  1414  	return fn, args
  1415  }
  1416  
  1417  func (p *Program) evalExpr(e expr.Expr) []reflect.Value {
  1418  	switch e := e.(type) {
  1419  	case *expr.BasicLiteral:
  1420  		var v reflect.Value
  1421  		switch val := e.Value.(type) {
  1422  		case *big.Int:
  1423  			v = reflect.ValueOf(UntypedInt{val})
  1424  		case *big.Float:
  1425  			v = reflect.ValueOf(UntypedFloat{val})
  1426  		case *bigcplx.Complex:
  1427  			v = reflect.ValueOf(UntypedComplex{val.Real, val.Imag})
  1428  		case string:
  1429  			v = reflect.ValueOf(UntypedString{val})
  1430  		case rune:
  1431  			v = reflect.ValueOf(UntypedRune{val})
  1432  		case bool:
  1433  			v = reflect.ValueOf(UntypedBool{val})
  1434  		default:
  1435  			v = reflect.ValueOf(val)
  1436  		}
  1437  		t := p.reflector.ToRType(p.Types.Type(e))
  1438  		return []reflect.Value{convert(v, t)}
  1439  	case *expr.Binary:
  1440  		lhs := p.evalExpr(e.Left)
  1441  		switch e.Op {
  1442  		case token.LogicalAnd:
  1443  			v := lhs[0].Interface()
  1444  			if !v.(bool) {
  1445  				return []reflect.Value{reflect.ValueOf(false)}
  1446  			}
  1447  			rhs := p.evalExpr(e.Right)
  1448  			v = rhs[0].Interface()
  1449  			return []reflect.Value{reflect.ValueOf(v)}
  1450  		case token.LogicalOr:
  1451  			v := lhs[0].Interface()
  1452  			if v.(bool) {
  1453  				return []reflect.Value{reflect.ValueOf(true)}
  1454  			}
  1455  			rhs := p.evalExpr(e.Right)
  1456  			v = rhs[0].Interface()
  1457  			return []reflect.Value{reflect.ValueOf(v)}
  1458  		}
  1459  		rhs := p.evalExpr(e.Right)
  1460  		if e.Op == token.Equal || e.Op == token.NotEqual {
  1461  			lk := lhs[0].Kind()
  1462  			rk := rhs[0].Kind()
  1463  			switch {
  1464  			case lk == reflect.Func || rk == reflect.Func:
  1465  				// functions can only be compared to nil
  1466  				lv := lhs[0].IsNil()
  1467  				rv := rhs[0].IsNil()
  1468  				if lv || rv {
  1469  					switch e.Op {
  1470  					case token.Equal:
  1471  						return []reflect.Value{reflect.ValueOf(lv == rv)}
  1472  					case token.NotEqual:
  1473  						return []reflect.Value{reflect.ValueOf(lv != rv)}
  1474  					}
  1475  				}
  1476  				panic("comparing uncomparable type " + format.Type(p.Types.Type(e.Left)))
  1477  
  1478  			case lk == reflect.Map || rk == reflect.Map,
  1479  				lk == reflect.Chan || rk == reflect.Chan,
  1480  				lk == reflect.Slice || rk == reflect.Slice:
  1481  				lv := lhs[0].IsNil()
  1482  				rv := rhs[0].IsNil()
  1483  				if lv || rv {
  1484  					switch e.Op {
  1485  					case token.Equal:
  1486  						return []reflect.Value{reflect.ValueOf(lv == rv)}
  1487  					case token.NotEqual:
  1488  						return []reflect.Value{reflect.ValueOf(lv != rv)}
  1489  					}
  1490  				}
  1491  			}
  1492  		}
  1493  		x := lhs[0].Interface()
  1494  		y := rhs[0].Interface()
  1495  		v, err := binOp(e.Op, x, y)
  1496  		if err != nil {
  1497  			panic(interpPanic{err})
  1498  		}
  1499  		t := p.reflector.ToRType(p.Types.Type(e))
  1500  		return []reflect.Value{convert(reflect.ValueOf(v), t)}
  1501  	case *expr.Call:
  1502  		fn, args := p.prepCall(e)
  1503  		if t, isTypeConv := fn.Interface().(reflect.Type); isTypeConv {
  1504  			return []reflect.Value{typeConv(t, args[0])}
  1505  		}
  1506  		res := fn.Call(args)
  1507  		for i := range res {
  1508  			if !res[i].IsValid() {
  1509  				continue
  1510  			}
  1511  			if v, isBuiltin := res[i].Interface().(builtinResult); isBuiltin {
  1512  				res[i] = reflect.ValueOf(v.(interface{}))
  1513  			}
  1514  		}
  1515  		if e.ElideError {
  1516  			// Dynamic elision of final error.
  1517  			errv := res[len(res)-1]
  1518  			if errv.IsValid() && errv.CanInterface() && errv.Interface() != nil {
  1519  				panic(Panic{val: errv.Interface()})
  1520  			}
  1521  			res = res[:len(res)-1]
  1522  			if len(res) == 0 {
  1523  				res = nil
  1524  			}
  1525  		}
  1526  		return res
  1527  	case *expr.CompLiteral:
  1528  		t := p.reflector.ToRType(e.Type)
  1529  		switch t.Kind() {
  1530  		case reflect.Struct:
  1531  			st := reflect.New(t).Elem()
  1532  			if len(e.Keys) > 0 {
  1533  				for i, elem := range e.Values {
  1534  					name := e.Keys[i].(*expr.Ident).Name
  1535  					v := p.evalExprOne(elem)
  1536  					setField(st.FieldByName(name), v)
  1537  				}
  1538  			} else {
  1539  				for i, expr := range e.Values {
  1540  					v := p.evalExprOne(expr)
  1541  					setField(st.Field(i), v)
  1542  				}
  1543  			}
  1544  			return []reflect.Value{st}
  1545  		case reflect.Array:
  1546  			return p.evalArrayLiteral(t, e.Keys, e.Values)
  1547  		case reflect.Slice:
  1548  			return p.evalSliceLiteral(t, e.Keys, e.Values)
  1549  		case reflect.Map:
  1550  			m := reflect.MakeMap(t)
  1551  			for i, kexpr := range e.Keys {
  1552  				k := p.evalExprOne(kexpr)
  1553  				v := p.evalExprOne(e.Values[i])
  1554  				m.SetMapIndex(k, v)
  1555  			}
  1556  			return []reflect.Value{m}
  1557  		}
  1558  	case *expr.FuncLiteral:
  1559  		return []reflect.Value{p.evalFuncLiteral(e, nil)}
  1560  	case *expr.Ident:
  1561  		if e.Name == "nil" { // TODO: make sure it's the Universe nil
  1562  			t := p.reflector.ToRType(p.Types.Type(e))
  1563  			return []reflect.Value{reflect.New(t).Elem()}
  1564  		}
  1565  		if v := p.Cur.Lookup(e.Name); v != (reflect.Value{}) {
  1566  			return []reflect.Value{v}
  1567  		}
  1568  		t := p.Types.Type(e)
  1569  		if t != nil {
  1570  			return []reflect.Value{reflect.ValueOf(p.reflector.ToRType(p.Types.Type(e)))}
  1571  		}
  1572  		panic(interpPanic{fmt.Errorf("eval: undefined identifier: %q", e.Name)})
  1573  	case *expr.Index:
  1574  		container := p.evalExprOne(e.Left)
  1575  		if len(e.Indicies) != 1 {
  1576  			panic(interpPanic{fmt.Errorf("eval: TODO table slicing")})
  1577  		}
  1578  		if e, isSlice := e.Indicies[0].(*expr.Slice); isSlice {
  1579  			var i, j int
  1580  			if e.Low != nil {
  1581  				i = int(p.evalExprOne(e.Low).Int())
  1582  			}
  1583  			if e.High != nil {
  1584  				j = int(p.evalExprOne(e.High).Int())
  1585  			} else {
  1586  				j = container.Len()
  1587  			}
  1588  			if e.Max != nil {
  1589  				k := int(p.evalExprOne(e.Max).Int())
  1590  				return []reflect.Value{container.Slice3(i, j, k)}
  1591  			}
  1592  			return []reflect.Value{container.Slice(i, j)}
  1593  		}
  1594  		k := p.evalExprOne(e.Indicies[0])
  1595  		if env, ok := container.Interface().(evalMap); ok {
  1596  			return []reflect.Value{reflect.ValueOf(env.GetVal(k.String()))}
  1597  		}
  1598  		switch container.Kind() {
  1599  		case reflect.Array, reflect.Slice, reflect.String:
  1600  			i := int(k.Int())
  1601  			if int64(i) != k.Int() {
  1602  				panic(interpPanic{fmt.Errorf("eval: index too big: %d", k.Int())})
  1603  			}
  1604  			return []reflect.Value{container.Index(i)}
  1605  		case reflect.Map:
  1606  			v := container.MapIndex(k)
  1607  			exists := v != (reflect.Value{})
  1608  			if !exists {
  1609  				v = reflect.Zero(container.Type().Elem())
  1610  			}
  1611  			if _, returnExists := p.Types.Type(e).(*tipe.Tuple); returnExists {
  1612  				return []reflect.Value{v, reflect.ValueOf(exists)}
  1613  			}
  1614  			return []reflect.Value{v}
  1615  		case reflect.Ptr:
  1616  			panic(interpPanic{fmt.Errorf("eval: *expr.Index unsupported ptr kind: %v", container.Elem().Kind())})
  1617  		default:
  1618  			panic(interpPanic{fmt.Errorf("eval: *expr.Index unsupported kind: %v", container.Kind())})
  1619  		}
  1620  	case *expr.MapLiteral:
  1621  		t := p.reflector.ToRType(e.Type)
  1622  		m := reflect.MakeMap(t)
  1623  		for i, kexpr := range e.Keys {
  1624  			k := p.evalExprOne(kexpr)
  1625  			v := p.evalExprOne(e.Values[i])
  1626  			m.SetMapIndex(k, v)
  1627  		}
  1628  		return []reflect.Value{m}
  1629  	case *expr.Selector:
  1630  		lhs := p.evalExprOne(e.Left)
  1631  		if lhs.Kind() == reflect.Ptr {
  1632  			if pkg, ok := lhs.Interface().(*gowrap.Pkg); ok {
  1633  				name := e.Right.Name
  1634  				return []reflect.Value{pkg.Exports[name]}
  1635  			}
  1636  		}
  1637  		v := lhs.MethodByName(e.Right.Name)
  1638  		if v == (reflect.Value{}) && lhs.Kind() != reflect.Ptr && lhs.CanAddr() {
  1639  			v = lhs.Addr().MethodByName(e.Right.Name)
  1640  		}
  1641  		if v == (reflect.Value{}) && lhs.Kind() == reflect.Struct {
  1642  			v = lhs.FieldByName(e.Right.Name)
  1643  		}
  1644  		if v == (reflect.Value{}) && lhs.Kind() == reflect.Ptr {
  1645  			lhs := lhs.Elem()
  1646  			v = lhs.MethodByName(e.Right.Name)
  1647  			if v == (reflect.Value{}) && lhs.Kind() == reflect.Struct {
  1648  				v = lhs.FieldByName(e.Right.Name)
  1649  			}
  1650  		}
  1651  		return []reflect.Value{v}
  1652  	case *expr.Shell:
  1653  		p.pushScope()
  1654  		defer p.popScope()
  1655  		res, err := shell.Run(p.ShellState, p, e)
  1656  		str := reflect.ValueOf(res)
  1657  		if e.ElideError {
  1658  			// Dynamic elision of final error.
  1659  			if err != nil {
  1660  				panic(Panic{val: err})
  1661  			}
  1662  			return []reflect.Value{str}
  1663  		}
  1664  		if err != nil {
  1665  			return []reflect.Value{str, reflect.ValueOf(err)}
  1666  		}
  1667  		errt := reflect.TypeOf((*error)(nil)).Elem()
  1668  		nilerr := reflect.New(errt).Elem()
  1669  		return []reflect.Value{str, nilerr}
  1670  	case *expr.ArrayLiteral:
  1671  		t := p.reflector.ToRType(e.Type)
  1672  		return p.evalArrayLiteral(t, e.Keys, e.Values)
  1673  	case *expr.SliceLiteral:
  1674  		t := p.reflector.ToRType(e.Type)
  1675  		return p.evalSliceLiteral(t, e.Keys, e.Values)
  1676  	case *expr.Type:
  1677  		t := p.reflector.ToRType(e.Type)
  1678  		return []reflect.Value{reflect.ValueOf(t)}
  1679  	case *expr.TypeAssert:
  1680  		v := p.evalExprOne(e.Left)
  1681  		if e.Type == nil {
  1682  			// this is coming from a switch x.(type) statement
  1683  			return []reflect.Value{v}
  1684  		}
  1685  		t := p.reflector.ToRType(e.Type)
  1686  		convertible := v.Type().ConvertibleTo(t)
  1687  		if convertible {
  1688  			v = v.Convert(t)
  1689  		} else {
  1690  			if v.CanInterface() {
  1691  				viface := v.Interface()
  1692  				v = reflect.ValueOf(viface)
  1693  				convertible = v.Type().ConvertibleTo(t)
  1694  				if convertible {
  1695  					v = v.Convert(t)
  1696  				}
  1697  			}
  1698  			if !convertible {
  1699  				v = reflect.Zero(t)
  1700  			}
  1701  		}
  1702  		if _, commaOK := p.Types.Type(e).(*tipe.Tuple); commaOK {
  1703  			return []reflect.Value{v, reflect.ValueOf(convertible)}
  1704  		}
  1705  		if !convertible {
  1706  			panic(Panic{val: fmt.Errorf("value of type %s cannot be converted to %s", v.Type(), e.Type)})
  1707  		}
  1708  		return []reflect.Value{v}
  1709  	case *expr.Unary:
  1710  		var v reflect.Value
  1711  		switch e.Op {
  1712  		case token.LeftParen:
  1713  			v = p.evalExprOne(e.Expr)
  1714  		case token.Ref:
  1715  			v = p.evalExprOne(e.Expr)
  1716  			return []reflect.Value{v.Addr()}
  1717  		case token.Mul: // deref
  1718  			v := p.evalExprOne(e.Expr)
  1719  			return []reflect.Value{v.Elem()}
  1720  		case token.Not:
  1721  			v = p.evalExprOne(e.Expr)
  1722  			b := v.Bool()
  1723  			if !v.CanAddr() {
  1724  				v = reflect.New(reflect.TypeOf(false)).Elem()
  1725  			}
  1726  			v.SetBool(!b)
  1727  		case token.Add, token.Sub:
  1728  			rhs := p.evalExprOne(e.Expr)
  1729  			var lhs interface{}
  1730  			switch rhs.Interface().(type) {
  1731  			case int:
  1732  				lhs = int(0)
  1733  			case int64:
  1734  				lhs = int64(0)
  1735  			case float32:
  1736  				lhs = float32(0)
  1737  			case float64:
  1738  				lhs = float64(0)
  1739  			case complex64:
  1740  				lhs = complex64(0)
  1741  			case complex128:
  1742  				lhs = complex128(0)
  1743  			case UntypedInt:
  1744  				lhs = UntypedInt{big.NewInt(0)}
  1745  			case UntypedFloat:
  1746  				lhs = UntypedFloat{big.NewFloat(0)}
  1747  			case UntypedComplex:
  1748  				lhs = UntypedComplex{Real: big.NewFloat(0), Imag: big.NewFloat(0)}
  1749  			}
  1750  			res, err := binOp(e.Op, lhs, rhs.Interface())
  1751  			if err != nil {
  1752  				panic(interpPanic{err})
  1753  			}
  1754  			v = reflect.ValueOf(res)
  1755  		case token.ChanOp:
  1756  			ch := p.evalExprOne(e.Expr)
  1757  			res, ok := ch.Recv()
  1758  			switch et := p.Types.Type(e).(type) {
  1759  			case *tipe.Tuple:
  1760  				t := p.reflector.ToRType(et.Elems[0])
  1761  				return []reflect.Value{convert(res, t), reflect.ValueOf(ok)}
  1762  			}
  1763  			v = res
  1764  		}
  1765  		t := p.reflector.ToRType(p.Types.Type(e))
  1766  		return []reflect.Value{convert(v, t)}
  1767  	}
  1768  	panic(interpPanic{fmt.Errorf("TODO evalExpr(%s), %T", format.Expr(e), e)})
  1769  }
  1770  
  1771  // setField sets a struct field to value.
  1772  // It sets the value even if the field is unexported.
  1773  func setField(field, value reflect.Value) {
  1774  	fieldPtr := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr()))
  1775  	fieldPtr.Elem().Set(value)
  1776  }
  1777  
  1778  func (p *Program) evalFuncLiteral(e *expr.FuncLiteral, recvt *tipe.Named) reflect.Value {
  1779  	s := &Scope{
  1780  		Parent: p.Universe,
  1781  		fct:    e.Name,
  1782  	}
  1783  	if e.Name == "" {
  1784  		// FIXME(sbinet): generate unique names
  1785  		s.fct = "func-1"
  1786  	}
  1787  	fscope := s
  1788  	for _, name := range e.Type.FreeVars {
  1789  		if s.VarName != "" {
  1790  			s = &Scope{Parent: s}
  1791  		}
  1792  		s.VarName = name
  1793  		s.Var = p.Cur.Lookup(name)
  1794  	}
  1795  
  1796  	funct := *e.Type
  1797  	if recvt != nil {
  1798  		params := make([]tipe.Type, 1+len(funct.Params.Elems))
  1799  		copy(params[1:], funct.Params.Elems)
  1800  		params[0] = &tipe.Interface{} // not recvt, breaking cycle
  1801  		funct.Params = &tipe.Tuple{params}
  1802  	}
  1803  	rt := p.reflector.ToRType(&funct)
  1804  	fn := reflect.MakeFunc(rt, func(args []reflect.Value) (res []reflect.Value) {
  1805  		p := &Program{
  1806  			Universe:    p.Universe,
  1807  			Types:       p.Types, // TODO race cond, clone type list
  1808  			Cur:         s,
  1809  			reflector:   p.reflector,
  1810  			typePlugins: p.typePlugins,
  1811  		}
  1812  		p.pushScope()
  1813  		defer p.popScope()
  1814  		if recvt != nil {
  1815  			p.evalMethRecv(e, recvt, args[0])
  1816  			args = args[1:]
  1817  		}
  1818  		for i, name := range e.ParamNames {
  1819  			// A function argument defines an addressable value,
  1820  			// but the reflect.Value args passed to a MakeFunc
  1821  			// implementation are not addressable.
  1822  			// So we copy them here.
  1823  			arg := reflect.New(args[i].Type()).Elem()
  1824  			arg.Set(args[i])
  1825  			p.Cur = &Scope{
  1826  				Parent:   p.Cur,
  1827  				VarName:  name,
  1828  				Var:      arg,
  1829  				Implicit: true,
  1830  			}
  1831  		}
  1832  		if funct.Results != nil {
  1833  			// Define new result values to hold return
  1834  			// types so any necessary interface boxing
  1835  			// is done. For example:
  1836  			//
  1837  			//	func f(x int) interface{} { return x }
  1838  			//
  1839  			// The int x needs to become an interface{}.
  1840  			res = make([]reflect.Value, len(funct.Results.Elems))
  1841  			for i, et := range funct.Results.Elems {
  1842  				t := p.reflector.ToRType(et)
  1843  				res[i] = reflect.New(t).Elem()
  1844  			}
  1845  		}
  1846  		if n := len(e.ResultNames); n > 0 {
  1847  			for i, name := range e.ResultNames {
  1848  				p.Cur = &Scope{
  1849  					Parent:   p.Cur,
  1850  					VarName:  name,
  1851  					Var:      res[i],
  1852  					Implicit: true,
  1853  				}
  1854  			}
  1855  		}
  1856  
  1857  		if fscope.defers != nil {
  1858  			fscope.defers = fscope.defers[:0]
  1859  		}
  1860  
  1861  		resValues := p.evalStmt(e.Body.(*stmt.Block))
  1862  		for i, v := range resValues {
  1863  			res[i].Set(v)
  1864  		}
  1865  
  1866  		for i := len(fscope.defers) - 1; i >= 0; i-- {
  1867  			d := fscope.defers[i]
  1868  			d.Func.Call(d.Args)
  1869  		}
  1870  		return res
  1871  	})
  1872  	return fn
  1873  }
  1874  
  1875  func (p *Program) evalArrayLiteral(t reflect.Type, keys, values []expr.Expr) []reflect.Value {
  1876  	array := reflect.New(t).Elem()
  1877  	switch len(keys) {
  1878  	case 0:
  1879  		for i, elem := range values {
  1880  			v := p.evalExprOne(elem)
  1881  			array.Index(i).Set(v)
  1882  		}
  1883  	default:
  1884  		for i := range keys {
  1885  			k := int(p.evalExprOne(keys[i]).Int())
  1886  			v := p.evalExprOne(values[i])
  1887  			array.Index(k).Set(v)
  1888  		}
  1889  	}
  1890  	return []reflect.Value{array}
  1891  }
  1892  
  1893  func (p *Program) evalSliceLiteral(t reflect.Type, keys, values []expr.Expr) []reflect.Value {
  1894  	switch len(keys) {
  1895  	case 0:
  1896  		slice := reflect.MakeSlice(t, len(values), len(values))
  1897  		for i, elem := range values {
  1898  			v := p.evalExprOne(elem)
  1899  			slice.Index(i).Set(v)
  1900  		}
  1901  		return []reflect.Value{slice}
  1902  	default:
  1903  		n := len(values)
  1904  		indices := make([]int, n)
  1905  		for i := range keys {
  1906  			k := int(keys[i].(*expr.BasicLiteral).Value.(*big.Int).Int64())
  1907  			if k+1 > n {
  1908  				n = k + 1
  1909  			}
  1910  			indices[i] = k
  1911  		}
  1912  		slice := reflect.MakeSlice(t, n, n)
  1913  		for i, elem := range values {
  1914  			v := p.evalExprOne(elem)
  1915  			slice.Index(indices[i]).Set(v)
  1916  		}
  1917  		return []reflect.Value{slice}
  1918  	}
  1919  }
  1920  
  1921  type reflector struct {
  1922  	mu  sync.RWMutex
  1923  	fwd map[tipe.Type]reflect.Type
  1924  	rev map[reflect.Type]tipe.Type
  1925  }
  1926  
  1927  func newReflector() *reflector {
  1928  	return &reflector{
  1929  		fwd: make(map[tipe.Type]reflect.Type),
  1930  		rev: make(map[reflect.Type]tipe.Type),
  1931  	}
  1932  }
  1933  
  1934  func (r *reflector) ToRType(t tipe.Type) reflect.Type {
  1935  	if t == nil {
  1936  		return nil
  1937  	}
  1938  
  1939  	r.mu.RLock()
  1940  	rtype := r.fwd[t]
  1941  	r.mu.RUnlock()
  1942  
  1943  	if rtype != nil {
  1944  		return rtype
  1945  	}
  1946  
  1947  	r.mu.Lock()
  1948  	defer r.mu.Unlock()
  1949  	return r.toRType(t)
  1950  }
  1951  
  1952  func (r *reflector) toRType(t tipe.Type) reflect.Type {
  1953  	rtype := r.fwd[t]
  1954  	if rtype != nil {
  1955  		return rtype
  1956  	}
  1957  
  1958  	if t == tipe.Byte {
  1959  		rtype = reflect.TypeOf(byte(0))
  1960  		r.fwd[t] = rtype
  1961  		return rtype
  1962  	}
  1963  	if t == tipe.Rune {
  1964  		rtype = reflect.TypeOf(rune(0))
  1965  		r.fwd[t] = rtype
  1966  		return rtype
  1967  	}
  1968  	t = tipe.Unalias(t)
  1969  	switch t := t.(type) {
  1970  	case tipe.Basic:
  1971  		switch t {
  1972  		case tipe.Invalid:
  1973  			return nil
  1974  		case tipe.Num:
  1975  			panic("TODO rtype for Num")
  1976  		case tipe.Bool:
  1977  			rtype = reflect.TypeOf(false)
  1978  		case tipe.Integer:
  1979  			rtype = reflect.TypeOf((*big.Int)(nil))
  1980  		case tipe.Float:
  1981  			rtype = reflect.TypeOf((*big.Float)(nil))
  1982  		case tipe.Complex:
  1983  			panic("TODO rtype for Complex")
  1984  		case tipe.String:
  1985  			rtype = reflect.TypeOf("")
  1986  		case tipe.Int:
  1987  			rtype = reflect.TypeOf(int(0))
  1988  		case tipe.Int8:
  1989  			rtype = reflect.TypeOf(int8(0))
  1990  		case tipe.Int16:
  1991  			rtype = reflect.TypeOf(int16(0))
  1992  		case tipe.Int32:
  1993  			rtype = reflect.TypeOf(int32(0))
  1994  		case tipe.Int64:
  1995  			rtype = reflect.TypeOf(int64(0))
  1996  		case tipe.Uint:
  1997  			rtype = reflect.TypeOf(uint(0))
  1998  		case tipe.Uint8:
  1999  			rtype = reflect.TypeOf(uint8(0))
  2000  		case tipe.Uint16:
  2001  			rtype = reflect.TypeOf(uint16(0))
  2002  		case tipe.Uint32:
  2003  			rtype = reflect.TypeOf(uint32(0))
  2004  		case tipe.Uint64:
  2005  			rtype = reflect.TypeOf(uint64(0))
  2006  		case tipe.Float32:
  2007  			rtype = reflect.TypeOf(float32(0))
  2008  		case tipe.Float64:
  2009  			rtype = reflect.TypeOf(float64(0))
  2010  		case tipe.Complex64:
  2011  			rtype = reflect.TypeOf(complex64(0))
  2012  		case tipe.Complex128:
  2013  			rtype = reflect.TypeOf(complex128(0))
  2014  		case tipe.UntypedNil:
  2015  			panic("TODO UntypedNil")
  2016  		case tipe.UntypedInteger:
  2017  			rtype = reflect.TypeOf(UntypedInt{})
  2018  		case tipe.UntypedFloat:
  2019  			rtype = reflect.TypeOf(UntypedFloat{})
  2020  		case tipe.UntypedComplex:
  2021  			rtype = reflect.TypeOf(UntypedComplex{})
  2022  		case tipe.UntypedString:
  2023  			rtype = reflect.TypeOf(UntypedString{})
  2024  		case tipe.UntypedRune:
  2025  			rtype = reflect.TypeOf(UntypedRune{})
  2026  		case tipe.UntypedBool:
  2027  			rtype = reflect.TypeOf(UntypedBool{})
  2028  		}
  2029  	case *tipe.Func:
  2030  		var in, out []reflect.Type
  2031  		if t.Params != nil {
  2032  			for _, p := range t.Params.Elems {
  2033  				in = append(in, r.toRType(p))
  2034  			}
  2035  		}
  2036  		if t.Results != nil {
  2037  			for _, p := range t.Results.Elems {
  2038  				out = append(out, r.toRType(p))
  2039  			}
  2040  		}
  2041  		rtype = reflect.FuncOf(in, out, t.Variadic)
  2042  	case *tipe.Struct:
  2043  		var fields []reflect.StructField
  2044  		for _, f := range t.Fields {
  2045  			fields = append(fields, reflect.StructField{
  2046  				Name:      f.Name,
  2047  				Type:      r.toRType(f.Type),
  2048  				Tag:       reflect.StructTag(f.Tag),
  2049  				Anonymous: f.Embedded,
  2050  			})
  2051  		}
  2052  		rtype = reflect.StructOf(fields)
  2053  	case *tipe.Named:
  2054  		if typecheck.IsError(t) {
  2055  			rtype = reflect.TypeOf((*error)(nil)).Elem()
  2056  		} else if t.PkgPath != "" {
  2057  			path := t.PkgPath
  2058  			v := gowrap.Pkgs[path].Exports[t.Name]
  2059  			if typ, isType := v.Interface().(reflect.Type); isType {
  2060  				rtype = typ
  2061  			} else if _, isIface := tipe.Underlying(t).(*tipe.Interface); isIface {
  2062  				rtype = v.Type().Elem()
  2063  			} else {
  2064  				rtype = v.Type()
  2065  			}
  2066  		} else {
  2067  			rtype = r.toRType(t.Type)
  2068  		}
  2069  	case *tipe.Array:
  2070  		rtype = reflect.ArrayOf(int(t.Len), r.toRType(t.Elem))
  2071  	case *tipe.Slice:
  2072  		rtype = reflect.SliceOf(r.toRType(t.Elem))
  2073  	case *tipe.Ellipsis:
  2074  		rtype = reflect.SliceOf(r.toRType(t.Elem))
  2075  	// TODO case *Table:
  2076  	case *tipe.Pointer:
  2077  		rtype = reflect.PtrTo(r.toRType(t.Elem))
  2078  	case *tipe.Chan:
  2079  		var dir reflect.ChanDir
  2080  		switch t.Direction {
  2081  		case tipe.ChanBoth:
  2082  			dir = reflect.BothDir
  2083  		case tipe.ChanSend:
  2084  			dir = reflect.SendDir
  2085  		case tipe.ChanRecv:
  2086  			dir = reflect.RecvDir
  2087  		default:
  2088  			panic(fmt.Sprintf("bad channel direction: %v", t.Direction))
  2089  		}
  2090  		rtype = reflect.ChanOf(dir, r.toRType(t.Elem))
  2091  	case *tipe.Map:
  2092  		rtype = reflect.MapOf(r.toRType(t.Key), r.toRType(t.Value))
  2093  	// TODO case *Interface:
  2094  	// TODO need more reflect support, MakeInterface
  2095  	// TODO needs reflect.InterfaceOf
  2096  	//case *Tuple:
  2097  	//case *Package:
  2098  	default:
  2099  		rtype = reflect.TypeOf((*interface{})(nil)).Elem()
  2100  	}
  2101  	r.fwd[t] = rtype
  2102  	return rtype
  2103  }
  2104  
  2105  func (r *reflector) FromRType(rtype reflect.Type) tipe.Type {
  2106  	panic("TODO FromRType")
  2107  }
  2108  
  2109  func isError(t tipe.Type) bool {
  2110  	return typecheck.Universe.Objs["error"].Type == t
  2111  }
  2112  
  2113  type Panic struct {
  2114  	val interface{}
  2115  }
  2116  
  2117  func (p Panic) Error() string {
  2118  	return fmt.Sprintf("neugram panic: %v", p.val)
  2119  }