func Expr(expr syntax.Expr, locals []*syntax.Ident) *Funcode {
	stmts := []syntax.Stmt{&syntax.ReturnStmt{Result: expr}}
	return File(stmts, locals, nil).Toplevel
}
Expr compiles an expression to a program consisting of a single toplevel function.
package compile
import (
	"bytes"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"github.com/google/skylark/resolve"
	"github.com/google/skylark/syntax"
)
const debug = false  
const Version = 3
type Opcode uint8
const (
	NOP Opcode = iota  
	DUP   
	DUP2  
	POP   
	EXCH  
	LT
	GT
	GE
	LE
	EQL
	NEQ
	PLUS
	MINUS
	STAR
	SLASH
	SLASHSLASH
	PERCENT
	AMP
	PIPE
	CIRCUMFLEX
	LTLT
	GTGT
	IN
	UPLUS   
	UMINUS  
	TILDE   
	NONE   
	TRUE   
	FALSE  
	ITERPUSH     
	ITERPOP      
	NOT          
	RETURN       
	SETINDEX     
	INDEX        
	SETDICT      
	SETDICTUNIQ  
	APPEND       
	SLICE        
	INPLACE_ADD  
	MAKEDICT     
	JMP      
	CJMP     
	ITERJMP  
	CONSTANT     
	MAKETUPLE    
	MAKELIST     
	MAKEFUNC     
	LOAD         
	SETLOCAL     
	SETGLOBAL    
	LOCAL        
	FREE         
	GLOBAL       
	PREDECLARED  
	UNIVERSAL    
	ATTR         
	SETFIELD     
	UNPACK       
	CALL         
	CALL_VAR     
	CALL_KW      
	CALL_VAR_KW  
	OpcodeArgMin = JMP
	OpcodeMax    = CALL_VAR_KW
)
var opcodeNames = [...]string{
	AMP:         "amp",
	APPEND:      "append",
	ATTR:        "attr",
	CALL:        "call",
	CALL_KW:     "call_kw ",
	CALL_VAR:    "call_var",
	CALL_VAR_KW: "call_var_kw",
	CIRCUMFLEX:  "circumflex",
	CJMP:        "cjmp",
	CONSTANT:    "constant",
	DUP2:        "dup2",
	DUP:         "dup",
	EQL:         "eql",
	FALSE:       "false",
	FREE:        "free",
	GE:          "ge",
	GLOBAL:      "global",
	GT:          "gt",
	GTGT:        "gtgt",
	IN:          "in",
	INDEX:       "index",
	INPLACE_ADD: "inplace_add",
	ITERJMP:     "iterjmp",
	ITERPOP:     "iterpop",
	ITERPUSH:    "iterpush",
	JMP:         "jmp",
	LE:          "le",
	LOAD:        "load",
	LOCAL:       "local",
	LT:          "lt",
	LTLT:        "ltlt",
	MAKEDICT:    "makedict",
	MAKEFUNC:    "makefunc",
	MAKELIST:    "makelist",
	MAKETUPLE:   "maketuple",
	MINUS:       "minus",
	NEQ:         "neq",
	NONE:        "none",
	NOP:         "nop",
	NOT:         "not",
	PERCENT:     "percent",
	PIPE:        "pipe",
	PLUS:        "plus",
	POP:         "pop",
	PREDECLARED: "predeclared",
	RETURN:      "return",
	SETDICT:     "setdict",
	SETDICTUNIQ: "setdictuniq",
	SETFIELD:    "setfield",
	SETGLOBAL:   "setglobal",
	SETINDEX:    "setindex",
	SETLOCAL:    "setlocal",
	SLASH:       "slash",
	SLASHSLASH:  "slashslash",
	SLICE:       "slice",
	STAR:        "star",
	TILDE:       "tilde",
	TRUE:        "true",
	UMINUS:      "uminus",
	UNIVERSAL:   "universal",
	UNPACK:      "unpack",
	UPLUS:       "uplus",
}
const variableStackEffect = 0x7f
var stackEffect = [...]int8{
	AMP:         -1,
	APPEND:      -2,
	ATTR:        0,
	CALL:        variableStackEffect,
	CALL_KW:     variableStackEffect,
	CALL_VAR:    variableStackEffect,
	CALL_VAR_KW: variableStackEffect,
	CIRCUMFLEX:  -1,
	CJMP:        -1,
	CONSTANT:    +1,
	DUP2:        +2,
	DUP:         +1,
	EQL:         -1,
	FALSE:       +1,
	FREE:        +1,
	GE:          -1,
	GLOBAL:      +1,
	GT:          -1,
	GTGT:        -1,
	IN:          -1,
	INDEX:       -1,
	INPLACE_ADD: -1,
	ITERJMP:     variableStackEffect,
	ITERPOP:     0,
	ITERPUSH:    -1,
	JMP:         0,
	LE:          -1,
	LOAD:        -1,
	LOCAL:       +1,
	LT:          -1,
	LTLT:        -1,
	MAKEDICT:    +1,
	MAKEFUNC:    -1,
	MAKELIST:    variableStackEffect,
	MAKETUPLE:   variableStackEffect,
	MINUS:       -1,
	NEQ:         -1,
	NONE:        +1,
	NOP:         0,
	NOT:         0,
	PERCENT:     -1,
	PIPE:        -1,
	PLUS:        -1,
	POP:         -1,
	PREDECLARED: +1,
	RETURN:      -1,
	SETDICT:     -3,
	SETDICTUNIQ: -3,
	SETFIELD:    -2,
	SETGLOBAL:   -1,
	SETINDEX:    -3,
	SETLOCAL:    -1,
	SLASH:       -1,
	SLASHSLASH:  -1,
	SLICE:       -3,
	STAR:        -1,
	TRUE:        +1,
	UNIVERSAL:   +1,
	UNPACK:      variableStackEffect,
}
func (op Opcode) String() string {
	if op < OpcodeMax {
		return opcodeNames[op]
	}
	return fmt.Sprintf("illegal op (%d)", op)
}
type Program struct {
	Loads     []Ident        
	Names     []string       
	Constants []interface{}  
	Functions []*Funcode
	Globals   []Ident   
	Toplevel  *Funcode  
}
type Funcode struct {
	Prog                  *Program
	Pos                   syntax.Position  
	Name                  string           
	Code                  []byte           
	pclinetab             []uint16         
	Locals                []Ident          
	Freevars              []Ident          
	MaxStack              int
	NumParams             int
	HasVarargs, HasKwargs bool
}
type Ident struct {
	Name string
	Pos  syntax.Position
}
type pcomp struct {
	prog *Program  
	names     map[string]uint32
	constants map[interface{}]uint32
	functions map[*Funcode]uint32
}
type fcomp struct {
	fn *Funcode  
	pcomp *pcomp
	pos   syntax.Position  
	loops []loop
	block *block
}
type loop struct {
	break_, continue_ *block
}
type block struct {
	insns []insn
	jmp, cjmp *block
	initialstack int  
	index int  
	addr  uint32
}
type insn struct {
	op   Opcode
	arg  uint32
	line int32
}
func (fn *Funcode) Position(pc uint32) syntax.Position {
	pos := fn.Pos  
	pos.Line = 0
	pos.Col = 0
	var prevpc uint32
	complete := true
	for _, x := range fn.pclinetab {
		nextpc := prevpc + uint32(x>>8)
		if complete && nextpc > pc {
			return pos
		}
		prevpc = nextpc
		pos.Line += int32(int8(x) >> 1)  
		complete = (x & 1) == 0
	}
	return pos
}
func idents(ids []*syntax.Ident) []Ident {
	res := make([]Ident, len(ids))
	for i, id := range ids {
		res[i].Name = id.Name
		res[i].Pos = id.NamePos
	}
	return res
}